🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.sources.apple2
1 messages
1 total messages Started by Jonathan A. Chandross Wed, 01 May 1991 22:11
v001SRC036: Nulib - Archive Library Tools (Unix) 05/10
#35
Author: Jonathan A. Chandross
Date: Wed, 01 May 1991 22:11
1782 lines
52111 bytes
Submitted-by: Andy McFadden (fadden@cory.berkeley.edu)
Posting-number: Volume 1, Source:36
Archive-name: archive/unix/nulib/part05.10
Architecture: UNIX
Version-number: 3.03


=nuetc.c
-/*
- * nuetc.c - extra stuff; most is #ifdefed to death (mostly time routines
- *           and file stuff that are highly system dependent)
- *
- * NuLib v3.0  February 1991  Freeware (distribute, don't sell)
- * By Andy McFadden (fadden@cory.berkeley.edu)
- */
-#ifdef APW
-segment "NuMain"
-#endif
-
-#include "nudefs.h"
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>	  /* errno declarations */
-#include <ctype.h>	  /* for tolower(), isupper() */
-
-#ifdef UNIX
-# include <time.h>	  /* need localtime() */
-# include <sys/types.h>   /* defn of time_t */
-# include <sys/stat.h>
-#endif
-#ifdef APW
-# include <stdlib.h>	   /* exit(), etc. */
-# include <types.h>	   /* has _toolErr in it */
-# include <prodos.h>
-# include "apwerr.h"	   /* APW/ProDOS error codes */
-#endif
-#ifdef MSDOS
-# include <process.h>
-# include <stdlib.h>
-# include <io.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <time.h>
-#endif
-
-#include "nuetc.h"
-/* note "nuread.h" is not included... none of the routines here assume */
-/* any knowledge of NuFX archives.                                     */
-
-#ifndef MSDOS
-extern char *malloc(); /* all systems ... except DOS : RBH */
-#endif  /* +PORT+ */
-
-extern void free();
-extern char *getenv();
-#ifdef APW
-extern Time ReadTimeHex();  /* should be TimeRec, from misctool.h */
-#endif
-
-/* This is a generally available TEMPORARY filename buffer */
-char tmpNameBuf[MAXFILENAME];
-
-
-/******************** general misc routines ********************/
-
-/*
- * Fatal error handler
- */
-void Fatal(deathstr, procName)
-char *deathstr, *procName;
-{
-    fflush(stdout);
-    fprintf(stderr, "\n%s: fatal error: %s\n--- ", prgName, deathstr);
-    perror(procName);
-    Quit (-1);
-}
-
-
-/*
- * Quit can be used to perform cleanup operations before exiting.
- */
-void Quit(val)
-int val;
-{
-    exit(val);
-}
-
-
-/*
- * Safe malloc()... checks return value
- */
-char *Malloc(size)
-int size;
-{
-    char *ptr = (char *) malloc(size);
-
-    if (ptr != (char *) NULL) {
-	return(ptr);
-    } else {
-       /* 8910.31 - RBH: report byte size that failed */
-       printf("Malloc: memory alloc error [%u : bytes]\n", size);
-#ifdef MSDOS
-       printf("(Largest Available Block: %u)\n", _memmax());
-#endif
-	Quit (-1);
-    }
-}
-
-/******************** UNIX compatibility routines ********************/
-
-#ifdef UNIX
-/*
- * Convert expanded date to a number of seconds for UNIX systems.
- *
- * Remember that *atime follows the NuFX docs for time values, which
- * don't necessarily match those in UNIX manual pages.
- * Adapted from _Advanced UNIX Programming_ by Marc J. Rochkind.
- *
- * Returns 0 if date/time is invalid.
- */
-long timecvt(atime)
-Time *atime;
-{
-    long tm;
-    int days;
-    BOOLEAN isleapyear;
-    int tzone;
-    char *getenv(), *tz;
-
-    if ((tz = getenv("TZ")) == NULL)
-	tzone = 8;  /* pacific std time */
-    else
-	tzone = atoi(&tz[3]);
-
-    isleapyear = (atime->year != 0) && (atime->year%4 == 0);  /* 2000 isn't */
-    if (atime->year < 70)
-	atime->year += 100;  /* years after 2000 */
-    days = (atime->year - 70) * 365L;
-    days += ((atime->year - 69L) / 4);  /* previous years' leap days */
-
-    switch (atime->month +1) {  /* month is 0-11 */
-    case 12:
-	days += 30;  /* Nov */
-    case 11:
-	days += 31;  /* Oct */
-    case 10:
-	days += 30;  /* Sep */
-    case 9:
-	days += 31;  /* Aug */
-    case 8:
-	days += 31;  /* Jul */
-    case 7:
-	days += 30;  /* Jun */
-    case 6:
-	days += 31;  /* May */
-    case 5:
-	days += 30;  /* Apr */
-    case 4:
-	days += 31;  /* Mar */
-    case 3:
-	days += (isleapyear ? 29 : 28);  /* Feb */
-    case 2:
-	days += 31;  /* Jan */
-    case 1:
-	break;
-    default:
-	/*printf("Invalid month\n");*/
-	return (0L);
-    }
-
-    if (atime->day > 31) {
-	/*printf("Invalid day\n");*/
-	return (0L);
-    }
-    tm = (days + atime->day) * 24L * 60L * 60L;
-
-    if (atime->hour > 23) {
-	/*printf("Invalid hour\n");*/
-	return (0L);
-    }
-    atime->hour += tzone;  /* correct for time zone */
-    tm += atime->hour * 60L * 60L;
-
-    if (atime->minute > 59) {
-	/*printf("Invalid minute\n");*/
-	return (0L);
-    }
-    tm += atime->minute * 60L;
-
-    if (atime->second > 59) {
-	/*printf("Invalid second\n");*/
-	return (0L);
-    }
-    tm += atime->second;
-
-    if (localtime(&tm)->tm_isdst)  /* was that day in dst? */
-	tm -= 60L * 60L;  /* adjust for daylight savings */
-    return (tm);
-}
-#endif /* UNIX */
-
-/******************** APW compatibility routines ********************/
-
-#ifdef APW
-/*
- * Normally a C library function to print out a description of the most
- * recent system (non-toolbox, non-ProDOS) error.  Exists under UNIX and
- * MS C 5.1, so I'm assuming it exists most everywhere else...
- */
-void perror(errstr)
-char *errstr;
-{
-    fflush(stdout);
-    if ( (errno > 0) && (errno < sys_nerr) ) {	/* known APW error? */
-	fprintf(stderr, "%s: %s\n", errstr, sys_errlist[errno]);
-    } else {
-	fprintf(stderr, "%s: ", errstr);
-	fflush(stderr);
-	ERROR( errno );
-    }
-    Quit (-1);
-}
-
-
-/* Check for //gs toolbox errors; all are fatal */
-void ToolErrChk()
-{
-    int err = _toolErr;
-
-    if (err) {
-	if (err < MPErr) {  /* was a ProDOS error? */
-	    fprintf(stderr, "Error: $%.2x %s\n", (char) err,
-		ProDOSErr[err]);
-	} else {
-	    fprintf(stderr, "Tool err ($%.4x): ", err);
-	    fflush(stderr);
-	    ERROR( err );
-	}
-	Quit (-1);
-    }
-}
-
-#endif /* APW */
-
-/******************** miscellaneous string routines ********************/
-
-/*
- * Compare strings, ignoring case (may be in standard C lib; stricmp()?)
- */
-int strcasecmp(str1, str2)
-register char *str1, *str2;
-{
-    register char one, two;
-    register int val;
-
-    for ( ; *str1 && *str2; str1++, str2++) {
-	one = (isupper(*str1) ? tolower(*str1) : *str1);
-	two = (isupper(*str2) ? tolower(*str2) : *str2);
-	if (val = two - one)
-	    return (val);
-    }
-    if (!(*str1) && !(*str2))  /* both zero -> equivalent */
-	return (0);
-    else {  /* one is shorter; return result */
-	one = (isupper(*str1) ? tolower(*str1) : *str1);
-	two = (isupper(*str2) ? tolower(*str2) : *str2);
-	return (two - one);
-    }
-}
-
-int strncasecmp(str1, str2, num)
-register char *str1, *str2;
-int num;
-{
-    register int i;
-    register char one, two;
-    register int val;  /* keep going 'til no more registers... */
-
-    for (i = 0; (i < num) && (*str1) && (*str2); i++, str1++, str2++) {
-	one = (isupper(*str1) ? tolower(*str1) : *str1);
-	two = (isupper(*str2) ? tolower(*str2) : *str2);
-	if (val = two - one)
-	    return (val);
-    }
-    if (i == num)  /* first num characters are equal, so return zero */
-	return (0);
-    else {  /* one ended early; return result */
-	one = (isupper(*str1) ? tolower(*str1) : *str1);
-	two = (isupper(*str2) ? tolower(*str2) : *str2);
-	return (two - one);
-    }
-}
-
-/******************* file-related routines ********************/
-
-/*
- * Do operating system-dependent CREATE stuff
- *
- * Creates a NuFX archive file, with type info where necessary.
- * Does not leave file open.
- */
-void ArcfiCreate(filename)
-char *filename;
-{
-    static char *procName = "ArcfiCreate";
-#ifdef UNIX
-    int fd;
-
-    if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0)
-	Fatal("Unable to create file", procName);
-    close(fd);
-#else
-# ifdef APW
-    FileRec create_p;
-
-    c2pstr(filename);
-    create_p.pathname = filename;
-    create_p.fAccess = 0x00e3;
-    create_p.fileType = 0x00e0;  /* LBR */
-    create_p.auxType = 0x8002;	 /* SHK */
-    create_p.storageType = 0x0001;
-    create_p.createDate = 0x0000;  /* let ProDOS fill in the blanks */
-    create_p.createTime = 0x0000;
-    CREATE( &create_p );
-    ToolErrChk();
-    p2cstr(filename);
-# endif /* APW */
-# ifdef MSDOS
-    int fd;
-
-    if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0)
-	Fatal("Unable to create file", procName);
-    close(fd);
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    int fd;
-
-    if ((fd = open(filename, O_CREAT|O_RDWR, WPERMS)) < 0)
-	Fatal("Unable to create file", procName);
-    close(fd);
-# endif /* none2 */
-# endif /* none1 */
-#endif /* UNIX */
-}
-
-
-/*
- * Determine if a file already exists.
- */
-BOOLEAN Exists(filename)
-char *filename;
-{
-    static char *procName = "Exists";
-#ifdef UNIX
-    struct stat sm;
-
-    if (stat(filename, &sm) < 0) {
-	if (errno == ENOENT)  /* if doesn't exist, then okay */
-	    return (FALSE);
-	else  /* some other problem killed stat(), probably serious */
-	    fprintf(stderr, "Unable to stat() '%s'\n", filename);
-	    Fatal("Bad stat()", procName); /*serious prob*/
-    } else  /* successful call - file exists */
-	return (TRUE);
-#else
-# ifdef APW
-    FileRec info_p;  /* check if file exists, is dir */
-    int err;
-
-    c2pstr(filename);
-    info_p.pathname = filename;
-    GET_FILE_INFO( &info_p );
-    err = _toolErr;
-    p2cstr(filename);
-    if (err == pathNotFound || err == fileNotFound)
-	return (FALSE);
-    else if (!err)
-	return (TRUE);
-    else {
-	_toolErr = err;
-	ToolErrChk();
-	return (TRUE);
-    }
-# endif /* APW */
-# ifdef MSDOS
-    struct stat sm;
-
-    if (stat(filename, &sm) < 0) {
-       if (errno == ENOENT)  /* if doesn't exist, then okay */
-           return (FALSE);
-       else  /* some other problem killed stat(), probably serious */
-           fprintf(stderr, "Unable to stat() '%s'\n", filename);
-           Fatal("Bad stat()", procName); /*serious prob*/
-    } else  /* successful call - file exists */
-       return (TRUE);
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    printf("Need [other] Exists()\n");  /* +PORT+ */
-    return (FALSE);
-# endif /* none2 */
-# endif /* none1 */
-#endif /* UNIX */
-}
-
-
-/*
- * Generate a temporary file name (system dependent).
- * Assumes space is allocated for buffer.
- */
-char *MakeTemp(buffer)
-char *buffer;
-{
-    static char *procName = "MakeTemp";
-#ifdef UNIX
-    extern char *mktemp();
-
-    strcpy(buffer, "nulb.tmpXXXXXX");
-    return (mktemp(buffer));
-#else
-# ifdef APW
-    int idx = 0;
-
-    do {
-        sprintf(buffer, "nulb.tmp%d", idx++);
-    } while (Exists(buffer));
-    return (buffer);
-# endif /* APW */
-# ifdef MSDOS
-    extern char *mktemp();
-
-    strcpy(buffer, "nulbXXXX.tmp");
-    return (mktemp(buffer));
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    strcpy(buffer, "nulb.tmp");  /* +PORT+ */
-    return (buffer);
-# endif /* none2 */
-# endif /* none1 */
-#endif /* UNIX */
-}
-
-#ifdef NO_RENAME
-/*
- * This is a replacement for the library call, in case somebody's C library
- * doesn't have it.
- */
-int rename(fromname, toname)
-{
-    if (link(fromname, toname) < 0)
-	return (-1);
-    if (unlink(fromname) < 0)
-	return (-1);
-}
-#endif
-
-
-/*
- * Rename a file.
- */
-void Rename(fromname, toname)
-char *fromname, *toname;
-{
-    static char *procName = "Rename";
-#ifdef UNIX
-    if (Exists(toname)) {
-	fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n",
-	    prgName, fromname, toname);
-	fflush(stderr);
-    }
-# ifdef AOSVS					/* BAK 04/30/90 */
-    printf("Work on AOS/VS rename command\n");	/* BAK 04/30/90 */
-# else						/* BAK 04/30/90 */
-    else {
-	if (rename(fromname, toname) < 0) {  /* this should "never" fail */
-	    fprintf(stderr,
-		"\n%s: WARNING: Unable to rename '%s' as '%s'\n",
-		prgName, fromname, toname);
-	    Fatal("Bad rename()", procName); /*serious prob*/
-	}
-    }
-# endif
-#else
-# ifdef APW
-    PathNameRec cpath_p;
-
-    if (Exists(toname)) {
-	fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n",
-	    prgName, fromname, toname);
-	fflush(stderr);
-	return;
-    }
-
-    cpath_p.pathname = fromname;
-    cpath_p.newPathname = toname;
-    c2pstr(fromname);
-    c2pstr(toname);
-    CHANGE_PATH( &cpath_p );
-    ToolErrChk();
-    p2cstr(fromname);
-    p2cstr(toname);
-# endif /* APW */
-# ifdef MSDOS
-    if (Exists(toname)) {
-	fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n",
-	    prgName, fromname, toname);
-	fflush(stderr);
-	return;
-    }
-    printf("Work on MSDOS rename command\n");
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    if (Exists(toname)) {
-	fprintf(stderr, "\n%s: WARNING: Unable to rename '%s' as '%s'\n",
-	    prgName, fromname, toname);
-	fflush(stderr);
-	return;
-    }
-    printf("Need [other] rename command\n");  /* +PORT+ */
-# endif /* none2 */
-# endif /* none1 */
-#endif /*UNIX*/
-}
-
-/******************** date/time routines ********************/
-
-/*
- * Expand date/time from file-sys dependent format to eight byte NuFX format.
- * tptr is filesys format, TimePtr is NuFX format
- */
-void ExpandTime(tptr, TimePtr)	   /* (BSD) UNIX version */
-onebyt *tptr;  /* usually points to a time_t (long) */
-Time *TimePtr;
-{
-#ifdef UNIX
-    time_t *tp = (time_t *) tptr;
-    struct tm *unixt;
-
-    unixt = localtime(tp);  /* expand time_t into components */
-    TimePtr->second = unixt->tm_sec;
-    TimePtr->minute = unixt->tm_min;
-    TimePtr->hour = unixt->tm_hour;
-    TimePtr->year = unixt->tm_year;
-    TimePtr->day = unixt->tm_mday -1;  /* want 0-xx, not 1-xx */
-    TimePtr->month = unixt->tm_mon;
-    TimePtr->extra = 0;
-    TimePtr->weekDay = unixt->tm_wday +1;  /* Sunday = 1, not 0 like UNIX */
-#else
-# ifdef APW			    /* APW version */
-    twobyt date, time;
-
-    date = (twobyt)tptr[0] + ((twobyt)tptr[1] << 8);
-    time = (twobyt)tptr[2] + ((twobyt)tptr[3] << 8);
-    TimePtr->second = 0;  /* not stored in ProDOS file info */
-    TimePtr->minute = (char) time;  /* truncated to char */
-    TimePtr->hour = time >> 8;
-    TimePtr->year = date >> 9;
-    TimePtr->day = (date & 0x1f) - 1;
-    TimePtr->month = ((date & 0x01e0) >> 5) - 1;
-    TimePtr->extra = 0;
-    TimePtr->weekDay = 0;
-# endif /* APW */
-# ifdef MSDOS
-    struct tm *newtime;
-    time_t *tp = (time_t *) tptr;
-
-    newtime = localtime (tp);
-    TimePtr->second = (onebyt)newtime->tm_sec;
-    TimePtr->minute = (onebyt)newtime->tm_min;
-    TimePtr->hour   = (onebyt)newtime->tm_hour;
-    TimePtr->year   = (onebyt)newtime->tm_year;
-    TimePtr->day    = (onebyt)newtime->tm_mday - 1;
-    TimePtr->month  = (onebyt)newtime->tm_mon;
-    TimePtr->extra  = 0;
-    TimePtr->weekDay= (onebyt)newtime->tm_wday + 1;
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    printf("Need [other] time-expander\n");  /* +PORT+ */
-    TimePtr->second = 0;
-    TimePtr->minute = 0;
-    TimePtr->hour = 0;
-    TimePtr->year = 0;
-    TimePtr->day = 0;
-    TimePtr->month = 0;
-    TimePtr->extra = 0;
-    TimePtr->weekDay = 0;
-# endif /* none1 */
-# endif /* none2 */
-#endif /* UNIX */
-}
-
-
-/*
- * Get current time, put in struct
- */
-Time *GetTime()
-{
-    static Time t;
-#ifdef UNIX
-    struct tm *unixt;
-    time_t now = time(NULL);
-
-    unixt = localtime(&now);
-    t.second = unixt->tm_sec;
-    t.minute = unixt->tm_min;
-    t.hour = unixt->tm_hour;
-    t.year = unixt->tm_year;
-    t.day = unixt->tm_mday -1;	/* want 0-xx, not 1-xx */
-    t.month = unixt->tm_mon;
-    t.extra = 0;
-    t.weekDay = unixt->tm_wday +1;  /* Sunday = 1, not 0 like UNIX */
-    /* return (&t) */
-#else
-# ifdef APW
-    t = ReadTimeHex(t);
-    /* return (&t) */
-# endif /* APW */
-# ifdef MSDOS
-    struct tm *pctime;
-    time_t now = time(NULL);
-
-    pctime = localtime(&now);
-    t.second = (onebyt)pctime->tm_sec;
-    t.minute = (onebyt)pctime->tm_min;
-    t.hour   = (onebyt)pctime->tm_hour;
-    t.year   = (onebyt)pctime->tm_year;
-    t.day    = (onebyt)pctime->tm_mday -1; /* want 0-xx, not 1-xx */
-    t.month  = (onebyt)pctime->tm_mon;
-    t.extra  = 0;
-    t.weekDay= (onebyt)pctime->tm_wday +1;  /* Sunday = 1, not 0 */
-    /* return (&t) */
-# endif /* MSDOS */
-
-# ifndef APW
-# ifndef MSDOS
-    printf("\nNeed [other] GetTime\n");  /* +PORT+ */
-    t->second = 0;
-    t->minute = 0;
-    t->hour = 0;
-    t->year = 0;
-    t->day = 0;
-    t->month = 0;
-    t->filler = 0;
-    t->weekDay = 0;
-    /* return (&t) */
-# endif /* none1 */
-# endif /* none2 */
-#endif /* UNIX */
-    return (&t);
-}
-
-
-/*
- * Convert a NuFX Time struct to a compact system-dependent format
- *
- * This is used to set a file's date when extracting.  Most systems don't
- * dedicate 8 bytes to storing the date; this reduces it to the format
- * used by a "set_file_date" command.
- */
-long ReduceTime(tptr)
-Time *tptr;
-{
-#ifdef UNIX
-    long t = timecvt(tptr);
-
-    return (t ? t : time(NULL));	/* if stored time is invalid, */
-					/* return current time */
-#else
-# ifdef APW
-    twobyt date, time;
-    long val;
-
-    date = ((twobyt)tptr->year << 9) | ((((twobyt)tptr->month)+1) << 5) |
-   	(((twobyt)tptr->day)+1);
-    time = ((twobyt)tptr->hour << 8) | ((twobyt)tptr->minute);
-
-    val = (long) date + ((long) time << 16);
-    return (val);
-# endif /* APW */
-# ifdef MSDOS
-    return (time(NULL)); /* not sure what to do, return current : RBH */
-# endif /* MSDOS */
-
-#ifndef APW
-#ifndef MSDOS
-    printf("Need [other] ReduceTime\n");  /* +PORT+ */
-# endif /* none2 */
-# endif /* none1 */
-#endif /* UNIX */
-}
-
=numain.c
-/*
- * numain.c - shell-based front end for NuLib
- *
- * NuLib v3.0  February 1991  Freeware (distribute, don't sell)
- * By Andy McFadden (fadden@cory.berkeley.edu)
- */
-#ifdef APW
-segment "main"
-#endif
-
-static char *header =
- "NuLib v3.03  February 1991  Freeware   Copyright 1989-91 By Andy McFadden";
-
-#include "nudefs.h"	/* system-dependent defines */
-#include <stdio.h>	/* standard I/O library */
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>	/* C type stuff, like tolower() */
-#ifdef BSD43
-# include <strings.h>
-#else  /* SYSV, APW, MSC */
-# include <string.h>	/* string stuff */
-#endif
-
-#ifdef APW
-# include <stdlib.h>
-# include <types.h>
-# include <strings.h>
-# include <shell.h>
-#endif
-
-#include "nuread.h"	/* structs for archive info, archive read routines */
-#include "nuview.h"	/* archive listing functions */
-#include "nuadd.h"	/* archive operations (add, create, move) */
-#include "nuext.h"	/* archive operations (extract) */
-#include "nupdel.h"	/* archive operations (delete, update, freshen) */
-#include "nublu.h"	/* Binary II archive operations */
-#include "nupak.h"	/* need PAKBUFSIZ */	
-#include "nuetc.h"	/* Malloc(), Fatal(), etc. */
-
-extern char *getenv();  /* +PORT+ */
-
-#define Whoops(str) printf("WARNING: typedef %s may be set incorrectly\n",str);
-#define ENVAR	"NULIBOPT"  /* environment variable with options in it */
-
-/*
- * global to entire program
- */
-int HiLo;		/* byte ordering; FALSE on low-first (65816) */
-int verbose;		/* print verbose? */
-int interact;		/* interactive overwrite mode? */
-int dopack;		/* do we want to pack/unpack? */
-int doExpand;		/* do we want to expand archive filenames? */
-int doSubdir;		/* process subdirectories at all? */
-int doMessages;		/* do comments instead of data */
-int transfrom;	/* how to do CR<->LF translation (from what?)  (-1 = off) */
-int transto;	/* translate to ? */
-int packMethod;		/* how to pack a file */
-fourbyt defFileType;	/* default file type */
-fourbyt defAuxType;	/* default aux type */
-onebyt *pakbuf;  /* used by compression routines; created once to reduce */
-		 /* overhead involved in malloc()ing a 64K buffer */
-char *prgName = "NuLib";    /* for error messages; don't like argv[0] */
-			    /* besides, the name changes every 3 weeks */
-
-/*
- * Print simple usage info
- */
-static void Usage(argv0)
-char *argv0;
-{
-    printf("\nUsage: %s option[suboptions] archive-name [filespec]\n", argv0);
-    printf("\nType \"%s h\" for help.\n", argv0);
-}
-
-
-/*
- * Print usage info
- */
-static void Help(argv0, options)
-char *argv0, *options;
-{
-    if (INDEX(options+1, 'n')) {  /* using 'n' suboption? */
-	printf("%s\n", header);
-	printf("\nCompression methods:\n");
-	printf("  #  Name                        Abbr  Pack?  Unpack?\n");
-	printf("  0: Uncompressed                unc     Y      Y\n");
-	printf("  1: SQueezed (sq/usq)           squ     N      Y\n");
-	printf("  2: Dynamic LZW-I (ShrinkIt)    shk     Y      Y\n");
-	printf("  3: Dynamic LZW-II (ShrinkIt)   sh2     N      N\n");
-	printf("  4: UNIX 12-bit compress        u12     Y      Y\n");
-	printf("  5: UNIX 16-bit compress        u16     Y      Y\n");
-	printf("The default is #2\n");
-	printf("\nText conversion methods (during extraction):\n");
-	printf("  0: Convert from CR to this system (ProDOS files)\n");
-	printf("  1: Convert from LF to this system (UNIX files)\n");
-	printf("  2: Convert from CRLF to this system (MS-DOS files)\n");
-
-    } else if (INDEX(options+1, 'w')) {  /* print author info */
-
-	printf("%s\n", header);
-	printf(
-       "Internet: fadden@cory.berkeley.edu   Usenet: ...!ucbvax!cory!fadden\n");
-	printf("\nShrinkIt and NuFX standard by Andy Nicholas.\n");
-	printf(
-  "ShrinkIt LZW compression by Kent Dickey.  LZW/II (a modified version of\n");
-	printf("  Kent's algorithm) by Andy Nicholas.\n");
-	printf("\nUNIX compress code adapted from COMPRESS v4.3.\n");
-	printf(
-"\nBinary II unpack and unsqueeze C code adapted from unblu.c and usq.c by\n");
-	printf("  Marcel J.E. Mol (usq.c based on usq2/sq3 by Don Elton).\n");
-	printf("\nMS-DOS port by Robert B. Hess and Bruce Kahn.\n");
-	printf(
-"\nThis program is Freeware.  Please distribute as widely as possible, but\n");
-	printf(
-      "  don't sell it.  Source code is available via e-mail upon request.\n");
-	printf(
-	   "\nUsers without Usenet/Internet access may send mail to me at:\n");
-	printf("  1474 Saskatchewan Drive\n");
-	printf("  Sunnyvale, CA 94087\n");
-
-    } else if (INDEX(options+1, 's')) {  /* suboption info */
-	printf("%s\n", header);
-	printf("\nUsual meaning of suboptions:\n");
-	printf("  c  - compression type, followed by a number\n");
-	printf(
-	    "  f  - file/aux type to add, followed by file/aux type spec\n");
-	printf("  i  - interactive; prompt before overwriting file\n");
-	printf("  m  - messages (add/extract comments instead of data)\n");
-	printf("  r  - don't recursively descend subdirectories\n");
-	printf("  s  - storage type (store as compressed w/o compressing), ");
-	printf("followed by number\n");
-	printf(
-	   "  t  - text translation (CR<->LF), followed by conversion mode\n");
-	printf("  u  - store as uncompressed (same as c0)\n");
-	printf("  v  - verbose mode\n");
-#ifndef NO_BLU
-	printf("  x  - extract during Binary II operations\n");
-#endif
-	printf("  +  - match partial pathnames for extract and delete\n");
-	printf("\nTable of contents suboptions:\n");
-	printf("  v  - verbose output (same as V option)\n");
-	printf("  a  - ARC/ZOO style format\n");
-	printf("  z  - full output, prints all aspects of archive\n");
-
-	printf("\nSample shell variable command (csh):\n");
-	printf(
-      "  setenv NULIBOPT=verbose,interactive,type=SRC,aux=000a,compress=5\n");
-	printf("  (default is non-verbose, non-interactive, type=NON, ");
-	printf(  "aux=0000, compress=2)\n");
-	
-    } else {  /* default help screen */
-
-	printf("%s\n", header);
-	printf(
-	     "\nUsage: %s option[suboptions] archive-name [filespec]\n", argv0);
-	printf("Option must be one of:\n");
-	printf("  a[vucsrf]   add to archive\n");
-#ifndef NO_BLU
-	printf("  b[xvti]     Binary II archive operations\n");
-#endif
-	printf(
-       "  c[vucsrf]   create archive (add, but suppress 'create' message)\n");
-	printf("  d[v+]       delete file from archive\n");
-	printf("  f[vucsrf]   freshen files in archive\n");
-	printf("  h[snw]      show help screen (subopt/numbers/who's who)\n");
-	printf("  i[v]        verify archive integrity\n");
-	printf("  m[vucsrf]   move files to archive (add, delete original)\n");
-	printf("  p[vmt+]     print archived file to stdout\n");
-	printf("  t[vaz]      display table of contents\n");
-	printf("  u[vucsrf]   update files in archive\n");
-	printf("  v           verbose listing (ProDOS 8 ShrinkIt format)\n");
-	printf("  x,e[vumti+] extract from archive\n");
-    }
-}
-
-
-/*
- * Check machine dependencies
- */
-static void CheckMach()
-{
-    onebyt one;
-    onebyt *oneptr;
-    twobyt two;
-    fourbyt four;
-
-#ifdef UNIX
-# ifdef APW
-    ^^ "ERROR: You have both APW and UNIX defined" ^^
-# endif
-# ifdef MSDOS
-    ^^ "ERROR: You have both MSDOS and UNIX defined" ^^
-# endif
-#endif /*UNIX*/
-#ifdef APW
-# ifdef MSDOS
-    ^^ "ERROR: You have both APW and MSDOS defined" ^^
-# endif
-#endif
-
-    /* some compilers complain about (unsigned) -1 , so I'm doing it this */
-    /* way to keep everybody quiet.					  */
-
-    one = 0x100;
-    if (one)
-	Whoops("onebyt");  /* one > 1 */
-    two = 0x10000;
-    if (two)
-	Whoops("twobyt");  /* two > 2 */
-    two = 0x1000;
-    if (!two)
-	Whoops("twobyt");  /* two < 2 */
-    four = 0xffffffff;
-    four++;
-    if (four)
-	Whoops("fourbyt");  /* four > 4 */
-    four = 0x10000;
-    if (!four)
-	Whoops("fourbyt");  /* four < 4 */
-
-    /* check byte ordering */
-    two = 0x1122;
-    oneptr = (onebyt *) &two;
-    if (*oneptr == 0x11)
-	HiLo = TRUE;
-    else if (*oneptr == 0x22)
-	HiLo = FALSE;
-    else {
-	printf("WARNING: Unable to determine a value for HiLo\n");
-	HiLo = FALSE;
-    }
-
-    /* check some other stuff... compilers may (should?) give warnings here */
-    if (ATTSIZE < MHsize)
-	printf("WARNING: ATTSIZE must be >= than MHsize\n");
-    if (RECBUFSIZ < ATTSIZE)
-	printf("WARNING: RECBUFSIZ should be larger than ATTSIZE\n");
-    if (MHsize != 48 || THsize != 16)
-	printf("WARNING: Bad MHsize or THsize\n");
-    if (sizeof(Time) != 8)
-	printf("WARNING: struct Time not 8 bytes\n");
-}
-
-
-/*
- * Check to see if string 2 is in string 1.
- *
- * Returns the position of string 2 within string 1; -1 if not found.
- */
-static int strc(host, sub)
-char *host, *sub;
-{
-    int hlen = strlen(host);
-    int slen = strlen(sub);
-    int i;
-
-    if (slen > hlen)  /* substring longer than host string */
-	return (-1);
-
-    /* generic linear search... */
-    for (i = 0; i <= (hlen - slen); i++)
-	if ((*(host+i) == *sub) && (!strncmp(host+i, sub, slen)))
-	    return (i);
-    
-    return (-1);
-}
-
-
-/*
- * Yank a number from a character string.
- */
-int OptNum(ptr)
-char *ptr;
-{
-    int val = 0;
-
-    while (*ptr && isdigit(*ptr)) {
-	val *= 10;
-	val += (*ptr - '0');
-	ptr++;
-    }
-    return (val);
-}
-
-
-/*
- * Set default values for globals.
- *
- * Should be of form "NULIBOPT=..."
- *   verbose		: default to verbose output
- *   interactive	: default to interactive mode when overwriting
- *   type=xxx		: set storage type to ProDOS type "xxx"
- *   aux=xxxx		: set aux storage type to 4-byte hex number "xxxx"
- */
-void GetDefaults(options)
-char *options;
-{
-    char *envptr;
-    int off, idx, pt;
-    int len = strlen(options);
-    char type[5];
-
-    /* set program default values */
-    verbose = FALSE;	/* silent mode */
-    interact = FALSE;	/* don't ask questions */
-    doSubdir = TRUE;	/* process subdirectories unless told not to */
-    dopack = TRUE;	/* don't pack unless told to */
-    doExpand = FALSE;	/* don't expand archived filenames */
-    doMessages = FALSE;	/* do comments instead of data */
-    packMethod = 0x0002;/* ShrinkIt LZW */
-    transfrom = -1;	/* no text translation */
-    transto = -1;
-    defFileType = (fourbyt) 0;	/* NON */
-    defAuxType = (fourbyt) 0;	/* $0000 */
-
-    /* read from global envir var */
-    if (envptr = getenv(ENVAR)) {
-	if (strc(envptr, "verbose") >= 0) {
-	    verbose = TRUE;
-	}
-	if (strc(envptr, "interactive") >= 0) {
-	    interact = TRUE;
-	}
-	if ((off = strc(envptr, "compress=")) >= 0) {
-	    off += 9;
-	    if (off+1 > strlen(envptr)) {
-		fprintf(stderr, "Error with 'compress=n' in NULIBOPT var\n");
-		Quit (-1);
-	    }
-	    packMethod = atoi(envptr+off);
-	}
-	if ((off = strc(envptr, "type=")) >= 0) {
-	    off += 5;
-	    if (off+3 > strlen(envptr)) {
-		fprintf(stderr, "Error with 'type=xxx' in NULIBOPT var\n");
-		Quit (-1);
-	    }
-	    strncpy(type, envptr+off, 3);
-	    type[3] = '\0';
-	    for (idx = 0; idx < 256; idx++)  /* scan for file type */
-		if (!strcasecmp(FT[idx], type)) {
-		    defFileType = (fourbyt) idx;
-		    break;  /* out of for */
-		}
-	}
-	if ((off = strc(envptr, "aux=")) >= 0) {
-	    off += 4;
-	    if (off+4 > strlen(envptr)) {
-		fprintf(stderr, "Error with 'aux=$xxxx' in NULIBOPT var\n");
-		Quit (-1);
-	    }
-	    strncpy(type, envptr+off, 4);
-	    type[4] = '\0';
-	    sscanf(type, "%x", &defAuxType);
-	}
-    }
-
-    /* handle command line suboption string */
-    for (pt = 1; pt < len; pt++) {  /* skip option char */
-	switch(options[pt]) {
-	case '+':	/* expand */
-	    doExpand = TRUE;
-	    break;
-	case 'a':	/* ARC/ZOO output format */
-	    /* do nothing */
-	    break;
-	case 'c':	/* compress method */
-	    packMethod = OptNum(&options[pt+1]);
-	    while (pt < len && isdigit(options[pt+1]))  /* advance to next */
-		pt++;
-	    dopack = TRUE;
-	    break;
-	case 'f':	/* filetype specified */
-	    strncpy(type, &options[pt+1], 3);
-	    type[3] = '\0';
-	    for (idx = 0; idx < 256; idx++)  /* scan for file type */
-		if (!strcasecmp(FT[idx], type)) {
-		    defFileType = (fourbyt) idx;
-		    break;  /* out of for */
-		}
-
-	    pt += strlen(type);
-	    if (options[pt+1] == '/') {  /* auxtype specification */
-		pt++;
-		strncpy(type, &options[pt+1], 4);
-		type[4] = '\0';
-		sscanf(type, "%lx", &defAuxType);
-		pt += strlen(type);
-	    }
-	    break;
-	case 'i':	/* interactive overwrites */
-	    interact = TRUE;
-	    break;
-	case 'm':	/* do messages instead of data */
-	    doMessages = TRUE;
-	    break;
-	case 'n':	/* help with numbers */
-	    /* do nothing */
-	    break;
-	case 'r':	/* don't recursively descend subdir */
-	    doSubdir = FALSE;
-	    break;
-	case 's':	/* store method */
-	    packMethod = OptNum(&options[pt+1]);
-	    while (pt < len && isdigit(options[pt+1]))  /* advance to next */
-		pt++;
-	    dopack = FALSE;
-	    break;
-	case 't':	/* how to translate text? */
-	    transfrom = OptNum(&options[pt+1]);
-	    while (pt < len && isdigit(options[pt+1]))
-		pt++;
-	    break;
-	case 'u':	/* don't use compression */
-	    dopack = FALSE;  /* this doesn't matter, but FALSE may be faster */
-	    packMethod = 0x0000;  /* archive w/o compression */
-	    break;
-	case 'v':	/* verbose mode */
-	    verbose = TRUE;
-	    break;
-	case 'w':	/* help on people */
-	    /* do nothing */
-	    break;
-	case 'x':	/* extract BLU files */
-	    /* do nothing */
-	    break;
-	case 'z':	/* in view files */
-	    /* do nothing */
-	    break;
-	default:	/* unknown */
-	    fprintf(stderr, "%s: unknown subopt '%c'\n", prgName, options[pt]);
-	    break;  /* do nothing */
-	}
-    }  /* for */
-}
-
-
-#ifdef APW
-/*
- * Expand a ProDOS filename using APW wildcard calls (even if the file doesn't
- * exist).
- *
- * Returns a pointer to a buffer holding the filename.
- */
-char *ExpandFilename(filename)
-char *filename;
-{
-    char *ptr;
-
-    c2pstr(filename);
-    if (!(*filename)) {
-	printf("Internal error: can't expand null filename\n");
-	Quit (-1);
-    }
-
-    INIT_WILDCARD(filename, 0);
-    ToolErrChk();
-    p2cstr(filename);
-
-    NEXT_WILDCARD(tmpNameBuf);
-    p2cstr(tmpNameBuf);
-    if (strlen(tmpNameBuf))  /* found it */
-	return(tmpNameBuf);
-    else {
-	/* file does not exist; expand path */
-	strcpy(tmpNameBuf, filename);
-	ptr = RINDEX(tmpNameBuf, '/');	/* remove filename */
-	if (!ptr)  /* filename only */
-	    return (filename);
-
-	*ptr = '\0';
-	if (!strlen(tmpNameBuf)) {  /* something weird... */
-	    printf("Unable to expand '%s'\n", filename);
-	    Quit (-1);
-	}
-
-	c2pstr(tmpNameBuf);
-	INIT_WILDCARD(tmpNameBuf, 0);
-	ToolErrChk();
-
-	NEXT_WILDCARD(tmpNameBuf);
-	p2cstr(tmpNameBuf);
-	if (!strlen(tmpNameBuf))  {
-	    printf("Unable to fully expand '%s'\n", filename);
-	    Quit (-1);
-	}
-
-	strcat(tmpNameBuf, RINDEX(filename, '/'));
-	return (tmpNameBuf);
-    }
-}
-#endif /* APW */
-
-
-/*
- * Parse args, call functions.
- */
-main(argc, argv)
-int argc;
-char **argv;
-{
-    char *filename;  /* hold expanded archive file name */
-    int idx;
-
-    filename = (char *) Malloc(MAXFILENAME);
-    CheckMach();  /* check compiler options, and set HiLo */
-
-    if (argc < 2) {  /* no arguments supplied */
-	Usage(argv[0]);
-	Quit (0);
-    }
-
-    if (argv[1][0] == '-') {  /* skip initial dashes */
-	argv[1]++;
-    }
-    for (idx = 0; argv[1][idx]; idx++)	/* conv opts to lower case */
-	if (isupper(argv[1][idx]))
-	    argv[1][idx] = tolower(argv[1][idx]);
-
-    if (argc < 3) {  /* no archive file specified; show help screen */
-	if (argv[1][0] == 'h')  /* could be HS, HN, or HW */
-	    Help(argv[0], argv[1]);
-	else			/* not 'H' option; show generic help scrn */
-	    Help(argv[0], "h");
-	Quit (0);
-    }
-
-#ifdef APW
-    strcpy(filename, ExpandFilename(argv[2]));
-#else
-    strcpy(filename, argv[2]);
-#endif
-    GetDefaults(argv[1]);  /* get defaults, process suboption string */
-
-    pakbuf = (onebyt *) Malloc(PAKBUFSIZ);  /* allocate global pack buf */
-    switch (argv[1][0]) {
-    case 'a':  /* add */
-    case 'c':  /* create */
-    case 'm':  /* move */
-	NuAdd(filename, argc-3, argv+3, argv[1]);  /* NuAdd will read */
-	break;
-#ifndef NO_BLU
-    case 'b':  /* Binary II operations */
-	NuBNY(filename, argc-3, argv+3, argv[1]);
-	break;
-#endif
-    case 'd':  /* delete */
-	NuDelete(filename, argc-3, argv+3, argv[1]);
-	break;
-    case 'f':  /* freshen */
-    case 'u':  /* update */
-	NuUpdate(filename, argc-3, argv+3, argv[1]);
-	break;
-    case 'i':  /* verify integrity */
-	NuTest(filename, argv[1]);
-	break;
-    case 't':  /* table of contents */
-    case 'v':  /* verbose output */
-	NuView(filename, argv[1]);
-	break;
-    case 'e':  /* extract */
-    case 'x':
-    case 'p':
-	NuExtract(filename, argc-3, argv+3, argv[1]);
-	break;
-    default:   /* need help */
-	fprintf(stderr, "%s: unknown option '%c'\n", argv[0], argv[1][0]);
-	break;
-    }
-
-    free (filename);
-    free (pakbuf);
-    Quit (0);
-}
-
=nupak.c
-/*
- * nupak.c - interface to the compression routines
- *
- * NuLib v3.0  February 1991  Freeware (distribute, don't sell)
- * By Andy McFadden (fadden@cory.berkeley.edu)
- */
-#ifdef APW
-segment "Compress"
-#endif
-
-#include "nudefs.h"
-#include <stdio.h>
-/*#include <fcntl.h>*/	/* "nucomp.h" includes <fcntl.h> for us */
-#include "nuread.h"	/* need THblock */
-#include "nucomp.h"	/* includes "nucompfn.h" + "types.h" */
-
-#ifdef MSDOS  /* for file I/O */
-# include <io.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <errno.h>
-#endif
-
-#include "nupak.h"
-#include "nuetc.h"
-
-#define CONVSIZ	1024
-
-long packedSize;  /* global - size of file after packing */
-onebyt lastseen;  /* used in crlf(); must be set by caller */
-
-
-/*
- * Make a little spinning thing.
- *
- * This just lets the user know that the whole thing hasn't stalled on him.
- * Prints a character, then backspaces so that the next thing will overwrite
- * it.
- *
- * Currently called by FCopy(), unpak_SHK(), pak_SHK()
- */
-void Spin()
-{
-    static char *sp = "/-\\|";
-    static int posn = 0;
-
-    posn++;
-    if ((posn < 0) || (posn > 3))
-	posn = 0;
-    putchar(sp[posn]);
-    putchar('\b');
-    fflush(stdout);
-}
-
-
-/*
- * Convert the end-of-line terminator between systems.
- *
- * Compile-time defines determine the value that things are translated to;
- * the value of "translate" determines what they are translated from.  This
- * will write the contents of the buffer to the passed file descriptor,
- * altering bytes as necessary.  Max buffer size is 64K.  Note that the
- * syntax is the same as for write();
- *
- * This would have been a lot easier without IBM...  lastseen is the last
- * character seen (used only in CRLF translations).  This needs to be set
- * by the caller (FCopy(), extract_files()).
- *
- * The putc_ncr() procedure in nusq.c does its own processing; this was
- * somewhat unavoidable.
- *
- * BUGS: This proc will have to be re-written.  It would be nice to be
- * able to pack files with a CRLF translation, not just unpack... but you
- * can't just do buffer writes for that.  It'll take some work, and will
- * probably appear in the next version.
- */
-unsigned int crlf(dstfd, buffer, length)
-int dstfd;
-onebyt *buffer;
-unsigned int length;
-{
-    register BOOLEAN doconv;
-    register onebyt *bptr = buffer;
-    register unsigned int idx;
-    static char *procName = "crlf";
-    unsigned int partial;   /* size for partial read/write */
-    onebyt tobuf[2048];
-    onebyt *toptr;
-    int conv;
-    unsigned int origlength = length;
-
-    if ((transfrom == -1) && (transto == -1)) {  /* no translation necessary */
-	return (write(dstfd, buffer, length));
-    }
-    if (transfrom < -1 || transfrom > 2) {
-	fprintf(stderr, "%s: unknown translation type %d\n",
-							prgName, transfrom);
-	fprintf(stderr, "%s: assuming conversion 0 (from CR)\n", prgName);
-	transfrom = 0;
-    }
-    if (transto < -1 || transto > 2) {
-	fprintf(stderr, "%s: unknown translation type %d\n",
-							prgName, transto);
-	fprintf(stderr, "%s: assuming conversion 0 (to CR)\n", prgName);
-	transto = 0;
-    }
-
-    /* macro defs for system-dependent actions */
-#ifdef UNIX
-# define DEFCONVFROM	if (*bptr == 0x0a)  /* LF */ \
-			    doconv = TRUE
-#  define DEFCONVTO	*(toptr++) = 0x0a
-#else
-# ifdef APW
-#  define DEFCONVFROM	if (*bptr == 0x0d)  /* CR */ \
-			    doconv = TRUE
-#  define DEFCONVTO	*(toptr++) = 0x0d
-# endif
-# ifdef MSDOS
-#  define DEFCONVFROM	if ((*bptr == 0x0a) && (lastseen == 0x0d)) { \
-			    doconv = TRUE; \
-			    toptr--;  /*already put CR; back up over it*/ \
-			} \
-			lastseen = *bptr
-#  define DEFCONVTO	*(toptr++) = 0x0d; \
-			*(toptr++) = 0x0a
-# endif
-# ifndef APW
-# ifndef MSDOS
-#  define DEFCONVFROM	if (*bptr == 0x0a)  /* LF */ \
-			    doconv = TRUE
-# endif /* none2 */
-# endif /* none1 */
-#endif /* UNIX */
-
-    while (length != 0) {
-	if (length > CONVSIZ) {
-	    partial = CONVSIZ;
-	    length -= CONVSIZ;
-	} else {
-	    partial = length;
-	    length = 0;
-	}
-
-	/* uses an explicit flag rather than "continue" for clarity... */
-	toptr = tobuf;
-	for (idx = partial; idx > 0; idx--, bptr++) {
-	    doconv = FALSE;
-	    switch (transfrom) {
-	    case -1:  /* convert from current system's terminator */
-		DEFCONVFROM;
-		break;
-	    case 0:
-		if (*bptr == 0x0d)  /* CR */
-		    doconv = TRUE;
-		break;
-	    case 1:
-		if (*bptr == 0x0a)  /* LF */
-		    doconv = TRUE;
-		break;
-	    case 2:
-		if ((*bptr == 0x0a) && (lastseen == 0x0d)) {
-		    doconv = TRUE;
-		    toptr--;  /*already outputed CR; back up over it*/
-		}
-		lastseen = *bptr;
-		break;
-	    }
-
-
-	    if (doconv) {
-		switch (transto) {
-		case -1:  /* convert to current system's terminator */
-		    DEFCONVTO;
-		    break;
-		case 0:
-		    *(toptr++) = 0x0d;
-		    break;
-		case 1:
-		    *(toptr++) = 0x0a;
-		    break;
-		case 2:
-		    *(toptr++) = 0x0d;
-		    *(toptr++) = 0x0a;
-		    break;
-		}
-	    } else {
-		*(toptr++) = *bptr;
-	    }
-	} /* for loop */
-		    
-	if (write(dstfd, tobuf, (toptr-tobuf)) != (toptr-tobuf))
-	    Fatal("Dest write failed", procName);
-    }  /* while loop */
-    return (origlength);
-}
-
-
-/*
- * Read a file, and place in another file at current posn.  We can't read more
- * than PAKBUFSIZ at a time, so for some files it will have to be broken down
- * into pieces.  Note PAKBUFSIZ is expected to be an int (defined in nupak.h),
- * and can't be any larger than read() can handle (64K... unsigned 16-bit int).
- *
- * The transl option is present for NuUpdate and NuDelete, which have to
- * copy old records to a new archive w/o performing translation.
- */
-void FCopy(srcfd, dstfd, length, copybuf, transl)
-int srcfd;    /* source file descriptor (must be open & seek()ed) */
-int dstfd;    /* destination file descriptor (must be open & seek()ed) */
-fourbyt length; /* number of bytes to copy */
-onebyt *copybuf;
-BOOLEAN transl;  /* maybe do text translation? */
-{
-    unsigned int partial;   /* size for partial read/write */
-    static char *procName = "FCopy";
-
-    if (transl) lastseen = '\0';
-    while (length != 0L) {
-	if (length > (long) PAKBUFSIZ) {
-	    partial = (unsigned int) PAKBUFSIZ;
-	    length -= (long) PAKBUFSIZ;
-	    if (verbose) Spin();
-	} else {
-	    partial = (unsigned int) length;
-	    length = 0L;
-	}
-
-	if (read(srcfd, copybuf, partial) != partial)
-	    Fatal("Source read failed", procName);
-	if (transl) {  /* do text translation if user wants it */
-	    if (crlf(dstfd, copybuf, partial) != partial)
-		Fatal("Dest write failed (c)", procName);
-	} else {  /* NEVER do translation */
-	    if (write(dstfd, copybuf, partial) != partial)
-		Fatal("Dest write failed (w)", procName);
-	}
-    }
-}
-
-
-/*
- * Add a range of bytes from one file into another, packing them.
- *
- * Set up stuff, then call the appropriate pack routine.  Returns the actual
- * algorithm used (thread_format), since the compression algorithm could
- * fail, storing the file in uncompressed format instead.  The packed length
- * is stored in a global variable.
- *
- * Since we're only using version 0 records, we don't need to propagate the
- * thread_crc.
- *
- * Compression routines must do the following:
- * - compress data from one file descriptor to another, given two seeked
- *   file descriptors and a length value.  They may not rely on EOF conditions
- *   for either file.
- * - return the packing method actually used.  If they cope with failure
- *   by starting over with something different, the successful method should
- *   be returned.  Failure may be handled in the switch statement below.
- */
-twobyt PackFile(srcfd, dstfd, thread_eof, thread_format, buffer)
-int srcfd;    /* source file descriptor (must be open & seek()ed) */
-int dstfd;    /* destination file descriptor (must be open & seek()ed) */
-fourbyt thread_eof; /* size of input */
-int thread_format; /* how to pack the bytes */
-onebyt *buffer; /* alloc in main prog so we don't have to each time */
-{
-    long length = (long) thread_eof;
-    twobyt retval = thread_format;  /* default = successful pack */
-    long srcposn, dstposn;
-    static char *procName = "PackFile";
-
-    switch (thread_format) {
-    case 0x0000:  /* uncompressed */
-	if (verbose) { printf("storing...", thread_format);  fflush(stdout); }
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	packedSize = length;
-	break;
-
-    case 0x0001:  /* SQUeeze */
-	if (verbose) {
-	    printf("[can't squeeze; storing]...");
-	    fflush(stdout);
-	} else {
-	    printf("WARNING: can't squeeze; files stored uncompressed\n");
-	}
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	packedSize = length;
-	retval = 0x0000;  /* uncompressed */
-	break;
-
-    case 0x0002:  /* LZW (ShrinkIt) */
-	if (verbose) { printf("shrinking...");  fflush(stdout); }
-	/* packedSize set by pak_SHK */
-	retval = pak_SHK(srcfd, dstfd, length, buffer);
-	break;
-    case 0x0003:  /* LZW II (ShrinkIt) */
-	if (verbose) {
-	    printf("[can't do LZW II; storing]...");
-	    fflush(stdout);
-	} else {
-	    printf("WARNING: can't do LZW II; files stored uncompressed\n");
-	}
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	packedSize = length;
-	retval = 0x0000;  /* uncompressed */
-	break;
-    case 0x0004:  /* UNIX 12-bit compress */
-#ifdef NO_UCOMP
-	if (verbose) {
-	    printf("[can't do 12-bit UNIX compress; storing]...");
-	    fflush(stdout);
-	} else {
-	    printf(
-	    "WARNING: can't do 12-bit compress; files stored uncompressed\n");
-	}
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	packedSize = length;
-	retval = 0x0000;  /* uncompressed */
-#else
-	maxbits = 12;	/* global compress parameter */
-	if (verbose) { printf("compressing...");  fflush(stdout); }
-	/* packedSize set by compress() */
-	if (u_compress(srcfd, dstfd, length) == OK)
-	    retval = 0x0004;
-	else
-	    retval = 0x0004;	/* FIX this */
-#endif
-	break;
-
-    case 0x0005:  /* UNIX 16-bit compress */
-#ifdef NO_UCOMP
-	if (verbose) {
-	    printf("[can't do 16-bit UNIX compress; storing]...");
-	    fflush(stdout);
-	} else {
-	    printf(
-	    "WARNING: can't do 16-bit compress; files stored uncompressed\n");
-	}
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	packedSize = length;
-	retval = 0x0000;  /* uncompressed */
-#else
-	maxbits = 16;	/* global compress parameter */
-	if (verbose) { printf("compressing...");  fflush(stdout); }
-	/* packedSize set by compress() */
-	srcposn = lseek(srcfd, 0L, S_REL);	/* save posn */
-	dstposn = lseek(dstfd, 0L, S_REL);
-	if (u_compress(srcfd, dstfd, length) == OK) {
-	    /* compress succeeded */
-	    retval = 0x0005;
-	} else {
-	    /* compression failed */
-	    if (verbose) { printf("storing..."); fflush(stdout); }
-	    lseek(srcfd, srcposn, S_ABS);	/* reposn files */
-	    lseek(dstfd, dstposn, S_ABS);
-	    FCopy(srcfd, dstfd, length, buffer, TRUE);
-	    packedSize = length;
-	    retval = 0x0000;
-	}
-#endif
-	break;
-
-    default:
-	fprintf(stderr, "\nUnknown compression method %d\n", thread_format);
-	fprintf(stderr, "Aborting.\n");
-	Quit(-1);
-    }
-
-    return (retval);
-}
-
-
-/*
- * Extract a range of bytes from one file into another, unpacking them.
- *
- * (hacked to unpack disks, also.  Forces the thread_eof to be the total
- *  size of the disk, since ShrinkIt doesn't really define it, esp for DOS 3.3
- *  disks).
- *
- * Set up stuff, then call the appropriate unpack routine.  Leaves the srcfd
- * positioned past the data to be unpacked; the calling routine should not
- * have to do any seeks.
- *
- * Returns TRUE if able to unpack, FALSE if not able to.  Note that srcfd
- * WILL be seeked even if the compression method is not handled.
- *
- * New uncompression routines should have the following characteristics:
- * - they should be able to uncompress a range of bytes from one file
- *   to another given two seeked file descriptors and a length parameter.
- * - they should return TRUE if they succeed and FALSE otherwise.  Special
- *   condition codes can be handled in the switch statement below.
- */
-int UnpackFile(srcfd, dstfd, THptr, thread_format, buffer)
-int srcfd;	/* source file descriptor (must be open & lseek()ed) */
-int dstfd;	/* destination file descriptor (must be open & lseek()ed) */
-THblock *THptr;	/* pointer to thread structure */
-int thread_format; /* how to unpack the bytes (NOT THptr->thread_format) */
-onebyt *buffer;
-{
-    long length;
-    fourbyt thread_eof,		/* #of bytes to output */
-	    comp_thread_eof;	/* #of bytes in source */
-    twobyt thread_crc;
-    BOOLEAN retval = TRUE;  /* default to success */
-    static char *procName = "UnpackFile";
-
-    thread_eof = THptr->thread_eof;
-    comp_thread_eof = THptr->comp_thread_eof;
-    thread_crc = THptr->thread_crc;	/* never used? */
-    length = (long) comp_thread_eof;	/* type checking goes easier */
-
-    switch (thread_format) {
-    case 0x0000:  /* uncompressed */
-	if (verbose) { printf("extracting...", thread_format); fflush(stdout);}
-	FCopy(srcfd, dstfd, length, buffer, TRUE);
-	break;
-
-    case 0x0001:  /* unSQUeeze */
-#ifdef NO_BLU
-	if (verbose) {
-	    printf("[can't unsqueeze - aborting]...");
-	    fflush(stdout);
-	} else {
-	    printf("ERROR: can't unsqueeze; 'squ' files not extracted\n");
-	}
-	lseek(srcfd, length, S_REL);  /* set file posn */
-	retval = FALSE;
-#else
-	if (verbose) { printf("unsqueezing..."); fflush(stdout); }
-	unpak_SQU(srcfd, dstfd, length);  /* thread_eof not needed */
-#endif
-	break;
-
-    case 0x0002:  /* LZW (ShrinkIt) */
-	if (verbose) { printf("unshrinking (I)..."); fflush(stdout); }
-	unpak_SHK(srcfd, dstfd, comp_thread_eof, thread_eof, buffer, FALSE);
-	break;
-
-    case 0x0003:  /* LZW II (ShrinkIt) */
-#ifdef TRY_II
-	if (verbose) { printf("unshrinking (II)..."); fflush(stdout); }
-	unpak_SHK(srcfd, dstfd, comp_thread_eof, thread_eof, buffer, TRUE);
-#else
-	if (verbose) {
-	    printf("[can't unshrink type II - aborting]...");
-	    fflush(stdout);
-	} else {
-	    printf(
-		"ERROR: can't unshrink type II; 'sh2' files not extracted\n");
-	}
-	lseek(srcfd, length, S_REL);  /* set file posn */
-	retval = FALSE;
-#endif
-	break;
-
-    case 0x0004:  /* 12-bit UNIX compress */
-#ifdef NO_UCOMP
-	if (verbose) {
-	    printf("[can't undo 12-bit UNIX compress - aborting]...");
-	    fflush(stdout);
-	} else {
-	    printf(
-	"ERROR: can't undo 12-bit UNIX compress; 'u12' files not extracted\n");
-	}
-	lseek(srcfd, length, S_REL);  /* set file posn */
-	retval = FALSE;
-#else
-	if (verbose) { printf("uncompressing..."); fflush(stdout); }
-	if (u_decompress(srcfd, dstfd, (long) comp_thread_eof) != OK)
-	    retval = FALSE;
-#endif
-	break;
-
-    case 0x0005:  /* 16-bit UNIX compress */
-#ifdef NO_UCOMP
-	if (verbose) {
-	    printf("[can't undo 16-bit UNIX compress - aborting]...");
-	    fflush(stdout);
-	} else {
-	    printf(
-	"ERROR: can't undo 16-bit UNIX compress; 'u16' files not extracted\n");
-	}
-	lseek(srcfd, length, S_REL);  /* set file posn */
-	retval = FALSE;
-#else
-	if (verbose) { printf("uncompressing..."); fflush(stdout); }
-	if (u_decompress(srcfd, dstfd, (long) comp_thread_eof) != OK)
-	    retval = FALSE;
-#endif
-	break;
-
-    default:
-	fprintf(stderr, "Unknown uncompression method %d\n", thread_format);
-	lseek(srcfd, length, S_REL);  /* set file posn */
-	retval = FALSE;
-	break;
-    }
-
-    return (retval);
-}
-
+ END OF ARCHIVE
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads