jac@yoko.rutgers.edu (Jonathan A. Chandross) (05/02/91)
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