dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (05/27/89)
Checksum: 90299107 (Verify with "brik -cv") Posting-number: Volume 03, Issue 003 Originally-from: dhesi@bsu-cs.bsu.edu (Rahul Dhesi) Archive-name: booz/booz.shar #! /bin/sh # Future postings in this newsgroup will be mostly in zoo archive # format. Here is a small, relatively portable zoo archive extractor. # It is written in portable C though it requires read(), write(), and # lseek() system calls or their emulations to be available. I will # also be posting the MS-DOS zoo 2.01 executable. # # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # addbfcrc.c # booz.c # booz.doc # booz.prj # func.h # lzd.c # makefile.msc # makefile.nix # oozext.c # oozio.h # options.h # portable.c # zoo.h # This archive created: Fri Aug 26 02:41:13 1988 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'addbfcrc.c'" '(2921 characters)' if test -f 'addbfcrc.c' then echo shar: "will not over-write existing file 'addbfcrc.c'" else sed 's/^X//' << \SHAR_EOF > 'addbfcrc.c' X/* adbfcrc.c */ X X/* Xaddbfcrc() accepts a buffer address and a count and adds the CRC for Xall bytes in the buffer to the global variable crccode using XCRC-16. X XCRC computation algorithm taken from source code for ARC 5.12, which Xin turn took it from an article by David Schwaderer in the April 1985 Xissue of PC Tech Journal. X XI claim no copyright over the contents of this file. X X -- Rahul Dhesi 1986/12/31 X*/ X Xunsigned int crccode; Xunsigned int crctab[] = { X 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, X 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, X 0x0d80, 0xcd41, 0x0F00, 0xcFc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, X 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, X 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdF81, 0x1F40, 0xdd01, X 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, X 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, X 0x1040, 0xF001, 0x30c0, 0x3180, 0xF141, 0x3300, 0xF3c1, 0xF281, 0x3240, X 0x3600, 0xF6c1, 0xF781, 0x3740, 0xF501, 0x35c0, 0x3480, 0xF441, 0x3c00, X 0xFcc1, 0xFd81, 0x3d40, 0xFF01, 0x3Fc0, 0x3e80, 0xFe41, 0xFa01, 0x3ac0, X 0x3b80, 0xFb41, 0x3900, 0xF9c1, 0xF881, 0x3840, 0x2800, 0xe8c1, 0xe981, X 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2F80, 0xeF41, X 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, X 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, X 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, X 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaF01, 0x6Fc0, 0x6e80, 0xae41, 0xaa01, X 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, X 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7F80, X 0xbF41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, X 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, X 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, X 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, X 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5F00, 0x9Fc1, 0x9e81, 0x5e40, X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, X 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, X 0x8F81, 0x4F40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, X 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, X 0x4100, 0x81c1, 0x8081, 0x4040 X}; X Xint addbfcrc(buffer,count) Xchar *buffer; Xint count; X X{ X register unsigned int localcrc; X register int i; X localcrc = crccode; X X for (i=0; i<count; i++) X localcrc = (localcrc>>8) ^ crctab[(localcrc ^ (buffer[i])) & 0x00ff]; X crccode = localcrc; X} SHAR_EOF if test 2921 -ne "`wc -c < 'addbfcrc.c'`" then echo shar: "error transmitting 'addbfcrc.c'" '(should have been 2921 characters)' fi fi echo shar: "extracting 'booz.c'" '(8123 characters)' if test -f 'booz.c' then echo shar: "will not over-write existing file 'booz.c'" else sed 's/^X//' << \SHAR_EOF > 'booz.c' X#define VERSION "Version 1.02 (1988/08/25)\n" X X/* booz.c -- small, memory-efficient Barebones Ooz to extract Zoo archives. X XFor maximum portability, Booz does not use the data type `unsigned long'. X XThe functions and system calls required by Tiny Booz are: X read() X write() X strlen() X exit() X malloc() X lseek() X open() and/or creat() X close() X unlink() -- may be defined to be an empty function X X XSmall Booz additionally uses the following functions: X strcat() X strcpy() X XBig Booz additionally use the following function: X strncat() X*/ X X/* XThe contents of this file are hereby released to the public domain. X X -- Rahul Dhesi 1988/08/25 X*/ X X#include "options.h" X#include "func.h" X#include "zoo.h" X Xmain(argc,argv) Xregister int argc; Xregister char **argv; X{ X#ifdef TINY X static char usage[]= X "Usage: booz archive.zoo\n"; X if (argc < 2) { X putstr ("Public domain Barebones Ooz\nZoo archive extractor (Tiny) by Rahul Dhesi\n"); X putstr (VERSION); X putstr (usage); X exit (1); X } X#endif X X#ifdef SMALL X static char usage[]= X "Usage: booz archive[.zoo] [ file ... ]\n"; X if (argc < 2) { X putstr ("Public domain Barebones Ooz\nZoo archive extractor (Small) by Rahul Dhesi\n"); X putstr (VERSION); X putstr (usage); X exit (1); X } X#endif X X#ifdef BIG X static char usage[]= X "Usage: booz {lxt} archive[.zoo] [ file ... ]\n"; X if (argc < 3) { X putstr ("Public domain Barebones Ooz\nZoo archive extractor/lister (Big) by Rahul Dhesi\n"); X putstr (VERSION); X putstr (usage); X putstr ("l = list, x = extract, t = test\n"); X exit (1); X } X#endif X X#ifdef TINY X oozext (argv[1]); X#endif X X#ifdef SMALL X oozext (argv[1], argc - 2, &argv[2]); X#endif X X#ifdef BIG X { X char *p; X p = argv[1]; X if (*p == 'L') X *p = 'l'; X if (*p == 'X') X *p = 'x'; X if (*p == 'T') X *p = 't'; X if (*p != 'l' && *p != 'x' && *p != 't') { X putstr (usage); X exit (1); X } X oozext (argv[2], p, argc - 3, &argv[3]); X } X#endif X X exit (0); X} X X/**********************/ X/* putstr() XThis function prints a string to the standard output handle without Xusing printf() or the standard I/O library. If a null string, nothing Xis printed (not even the null character). X*/ Xint putstr (str) Xregister char *str; X{ X if (str != (char *) 0) X write (1, str, strlen(str)); X} X X/**********************/ X/* prterror() XPrints an error message. The first character controls the severity Xof the error and the result. X X 'm' informative message X 'w' warning -- execution continues X 'e' error -- execution continues X 'f' fatal error -- program exits X*/ X Xint prterror (level, a, b, c) Xint level; Xchar *a, *b, *c; X X{ X X#ifdef DEBUG X { X char tmp[2]; X tmp[0] = level & 0x7f; X tmp[1] = '\0'; X putstr ("prterror: level = "); X putstr (tmp); X putstr ("\n"); X } X#endif X X switch (level & 0x7f) { X case 'm': break; X case 'w': putstr ("WARNING: "); break; X case 'e': putstr ("ERROR: "); break; X case 'f': putstr ("FATAL: "); break; X default: prterror ('f', "Internal error\n", ((char *) 0), ((char *) 0)); X } X putstr (a); X putstr (b); X putstr (c); X X if (level == 'f') /* and abort on fatal error 'f' but not 'F' */ X exit (1); X} X X/************* XThis function copies count characters from the source file to the Xdestination Function return value is 0 if no error, 2 if write error, Xand 3 if read error. X XThe global variable crccode is updated. X*/ Xextern char out_buf_adr[]; X Xint getfile(input_han, output_han, count) Xint input_han, output_han; Xlong count; X{ X register int how_much; X X while (count > 0) { X if (count > OUT_BUF_SIZE) X how_much = OUT_BUF_SIZE; X else X how_much = count; X count -= how_much; X if (read (input_han, out_buf_adr, how_much) != how_much) X return (3); X addbfcrc (out_buf_adr, how_much); X if (output_han != -2 && X write (output_han, out_buf_adr, how_much) != how_much) X return (2); X } X return (0); X} X X#ifndef TINY X Xint needed (fname, argc, argv) Xchar *fname; Xint argc; Xchar *argv[]; X{ X register int i; X if (argc == 0) X return (1); X for (i = 0; i < argc; i++) { X if (match (fname, argv[i])) X return (1); X } X return (0); X} X X/***********************/ X/* Xmatch() compares a pattern with a string. Wildcards accepted in Xthe pattern are: "*" for zero or more arbitrary characters; "?" Xfor any one characters. Unlike the MS-DOS wildcard match, "*" is Xcorrectly handled even if it isn't at the end of the pattern. ".' Xis not special. X XOriginally written by Jeff Damens of Columbia University Center for XComputing Activities. Taken from the source code for C-Kermit version X4C. X*/ X Xint match (string, pattern) Xregister char *string, *pattern; X{ X char *psave,*ssave; /* back up pointers for failure */ X psave = ssave = ((char *) 0); X while (1) { X for (; *pattern == *string; pattern++,string++) /* skip first */ X if (*string == '\0') X return(1); /* end of strings, succeed */ X if (*string != '\0' && *pattern == '?') { X pattern++; /* '?', let it match */ X string++; X } else if (*pattern == '*') { /* '*' ... */ X psave = ++pattern; /* remember where we saw it */ X ssave = string; /* let it match 0 chars */ X } else if (ssave != ((char *) 0) && *ssave != '\0') { /* if not at end */ X /* ...have seen a star */ X string = ++ssave; /* skip 1 char from string */ X pattern = psave; /* and back up pattern */ X } else X return(0); /* otherwise just fail */ X } X} X X#endif /* ndef TINY */ X Xint memerr() X{ X prterror ('f', "Ran out of memory\n"); X} X X#ifdef BIG X/* cfactor() calculates the compression factor given a directory entry */ Xint cfactor (org_size, size_now) Xlong org_size, size_now; X{ X register int size_factor; X X while (org_size > 10000) { /* avoid overflow below */ X org_size = org_size >> 4; X size_now = size_now >> 4; X } X if (org_size == 0) /* avoid division by zero */ X size_factor = 0; X else { X size_factor = X ( X (1000 * X (org_size - size_now) X ) / org_size + 5 X ) / 10; X } X return (size_factor); X} X X/****** XFunction itoa() converts a positive long integer into a text string of Xdigits. The buffer pointer buf must point to a buffer to receive the Xdigit string. The digit string is stored right justified in the Xbuffer with leading blanks. If the supplied number is negative, or if Xoverflow occurs, a single '*' is returned. X*/ X Xchar *itoa (pad_ch, n, buf, buflen) Xchar pad_ch; /* leading pad character */ Xlong n; /* positive long int to convert */ Xchar *buf; /* buffer to receive digit string */ Xint buflen; /* length of buffer */ X{ X char *p; X int i; X for (i = 0; i < buflen; i++) /* fill buffer with pad char */ X buf[i] = pad_ch; X p = buf + buflen - 1; X *p-- = '\0'; /* ensure null termination */ X i = buflen - 1; X for (;;) { X if (n < 0) { /* can't handle negative n */ X goto overflow; X } else { X *p-- = (int) (n % 10) + '0'; /* store a converted digit */ X n = n / 10; X i--; X if (n == 0 || i == 0) X break; X } /* end of else of if (n < 0) */ X } /* end while (buflen > 0) */ X if (n != 0) /* buffer overflow */ X goto overflow; X return (buf); X Xoverflow: /* bad value filled with stars */ X for (i = 0; i < buflen; i++) X buf[i] = '*'; X buf[buflen-1] = '\0'; X return (buf); X} X X#endif /* BIG */ SHAR_EOF if test 8123 -ne "`wc -c < 'booz.c'`" then echo shar: "error transmitting 'booz.c'" '(should have been 8123 characters)' fi fi echo shar: "extracting 'booz.doc'" '(6645 characters)' if test -f 'booz.doc' then echo shar: "will not over-write existing file 'booz.doc'" else sed 's/^X//' << \SHAR_EOF > 'booz.doc' X Booz 1.02 -- Barebones Ooz X a X Zoo Extractor/Lister X by X Rahul Dhesi X XBooz 1.02 is a small, memory-efficient Zoo archive extractor/lister. XIt is not fancy. It does not recognize the advanced features Xavailable in current versions of Zoo, such as long filenames, Xdirectory names, comments, and multiple file generations. Extraction Xalways uses a short MS-DOS format filename and all extracted files go Xinto the current directory. X XBut Booz 1.02 is simple and portable and can be implemented in about Xfifteen minutes on any system with a reasonably good C compiler that Xprovides **IX-compatible read(), write(), and lseek() functions. XAnd Booz 1.02 can extract and list all archives created by all Xcurrently-existing versions of Zoo. X XAt compilation time, conditional compilation selects one of three Xlevels of sophistication for Booz 1.02. The three options are as Xfollows. X XThe Tiny option: Booz compiled with the Tiny option is very frugal Xand should compile and run under CP/M and other systems with limited Xmemory. Tiny Booz always extracts an entire archive at a time and Xdoes not attempt to prevent an exctracted file from overwriting Xanother. Tiny Booz requires you to type the entire filename of the Xarchive being extracted, including the ".zoo" extension. X XThe Small option: Booz compiled with the Small option is a little Xmore sophisticated than Tiny Booz. Small Booz assumes the default Xextension ".zoo" for an archive if it is not specified. It will let Xyou specify which files should be extracted from an archive. Small XBooz accepts these wildcard symbols in the names of files to be Xextracted: "?" stands for any one character and "*" stands for any Xsequence of zero or more characters. Combinations of these are Xpermitted so, for example, "*c?t*h" matches filenames ending with "h" Xand containing "c" and "t" separated by one character. Small Booz is Xnearly as memory-efficient as Tiny Booz and it very likely that it Xwill compile and run under CP/M. X XThe Big option: Booz compiled with the Big option does everything Xthat Small Booz does and in addition it can give the directory Xlisting of a Zoo archive or test its integrity. Despite its name, XBig Booz is still quite frugal. Under MS-DOS, when compiled with Xthe Microsoft C compiler version 3.00, it runs in about 50 kilobytes Xof free memory and occupies about 9.5 kilobytes on disk. X X X COMPILING BOOZ 1.02 X X1. XMake sure that the two macros OPEN and CREATE are correctly defined Xfor your system in file `oozio.h'. Some sample macros are provided. XThe macros must be defined to open files in binary mode (i.e., Xwithout newline conversions). X XThe macro OPEN is supplied a filename and it must open the file for Xreading and return an open file descriptor, or -1 if the open fails. XIt is used to open the archive being extracted or listed, and to test Xthe existence of a file about to be extracted. X XThe macro CREATE is supplied a filename and it must create a new file Xfor writing and return an open file descriptor, or -1 if the create Xfails. It is used for creating each file that is extracted. X X2. XIf your C library does not provide the unlink() function (which Xdeletes a file given its name), define an empty function by that Xname, or define a suitable (possibly empty) macro by that name in Xfile `oozio.h'. X X3. XDecide which of the three options, Tiny, Small, or Big, you will use. XIf memory is tight use the Tiny option first to get a Zoo extractor Xquickly running on your system. Then experiment with the other Xoptions. If memory is not tight, use the Big option. Define any one Xof the symbols TINY, SMALL, or BIG in the file `options.h' (or Xalternatively define it on the command line that invokes your C Xcompiler). Exactly one of these three symbols must be defined. X X4. XChoose appropriate sizes for the input/output buffers and for the Xsize of the decompression stack in file `options.h'. If memory Xpermits, make the buffers 8192 each. (Bigger sizes, perhaps up to X16384, could be used but they have not been tested and could Xconceivably cause overflow in certain bit-shift operations in file X`lzd.c'). A reasonable stack size is 2000, but in pathological cases Xextraction of a file could require a larger stack. X XIf memory is tight, decrease the input/output buffers to 1024 each Xeach and the stack to 1000. X X5. XCompile and link all the C files. Two makefiles are supplied, one Xsuitable for **IX systems and the other for Microsoft C 3.0 under XMS-DOS. Modify these as necessary for your system. Also supplied is Xa project file booz.prj for use with Turbo C 1.0 on MS-DOS. X X X MACHINE DEPENDENCE X XBooz is relatively independent of machine architecture, except that X(a) the machine must be a 2's complement machine (all modern machines Xare) and (b) `char' must be exactly 8 bits, `int' must be 16 bits or Xlarger, and `long' must be 32 bits or larger (though a `long' of a Xlittle less than 32 bits may work). X XBooz makes no assumptions about the filename syntax of the host Xmachine, except that Small and Big Booz assume that dot "." is used to Xseparate the extension "zoo" from the rest of the name of the Xarchive. They will append ".zoo" to the archive name if it contains Xno dot; this fails if an archive name of the type "../junk" is Xspecified. X XIf your system uses a different filename syntax, you may need to Xchange the code. Also, if your system cannot accept some of the Xcharacters legal in MS-DOS filenames, you may need to add a function Xthat will fix the filename before extraction. A sample function X`fixfname()' is included in the file `oozext.c'. It becomes activated Xonly if the preprocessor symbol FIXFNAME is defined. X X NOTE X XThis program does not attempt to be case-insensitive. Therefore you Xwill need to type names of files to be extracted in the correct Xcase. Note, however, that some operating systems (possibly CP/M) may Xfold command line arguments to uppercase. If this happens, your Xbest bet is to extract all files from an archive instead of Xspecifying specific names. X X REVISION HISTORY X XVersion 1.00 X Corresponded to just the Tiny booz 1.02 X XVersion 1.01 X Included TINY, SMALL, BIG compilation options. Had a bug in X function needed() that sometimes cause file extraction to fail. X XVersion 1.02 X Fixed bug in function needed(). Added support for Turbo C 1.0. X Revised this documentation and some comments in the source code. X X -- Rahul Dhesi 1988/08/25 SHAR_EOF if test 6645 -ne "`wc -c < 'booz.doc'`" then echo shar: "error transmitting 'booz.doc'" '(should have been 6645 characters)' fi fi echo shar: "extracting 'booz.prj'" '(138 characters)' if test -f 'booz.prj' then echo shar: "will not over-write existing file 'booz.prj'" else sed 's/^X//' << \SHAR_EOF > 'booz.prj' Xbooz.c (options.h zoo.h func.h) Xaddbfcrc.c Xlzd.c (options.h func.h) Xoozext.c (options.h zoo.h oozio.h func.h) Xportable.c (func.h zoo.h) SHAR_EOF if test 138 -ne "`wc -c < 'booz.prj'`" then echo shar: "error transmitting 'booz.prj'" '(should have been 138 characters)' fi fi echo shar: "extracting 'func.h'" '(505 characters)' if test -f 'func.h' then echo shar: "will not over-write existing file 'func.h'" else sed 's/^X//' << \SHAR_EOF > 'func.h' X/* XThe contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1987/02/08 X*/ X X/* Functions defined by Booz */ X Xint getfile (); Xint lzd (); Xint readdir (); Xint rd_zooh (); Xint rd_dir (); Xint addbfcrc(); Xint prterror(); Xint oozext (); Xint putstr (); Xchar *itoa (); Xint fixfname (); X X/* Standard functions */ X Xchar *malloc (); Xint close (); Xint creat (); Xint open (); Xint read (); Xint unlink (); Xint write (); Xlong lseek (); Xunsigned int strlen (); SHAR_EOF if test 505 -ne "`wc -c < 'func.h'`" then echo shar: "error transmitting 'func.h'" '(should have been 505 characters)' fi fi echo shar: "extracting 'lzd.c'" '(5823 characters)' if test -f 'lzd.c' then echo shar: "will not over-write existing file 'lzd.c'" else sed 's/^X//' << \SHAR_EOF > 'lzd.c' X/* XLempel-Ziv decompression. Mostly based on Tom Pfau's assembly language Xcode. The contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1986/11/14, 1987/02/08 X*/ X X#include "func.h" X#include "options.h" X X#define INBUFSIZ (IN_BUF_SIZE - SPARE) X#define OUTBUFSIZ (OUT_BUF_SIZE - SPARE) X#define MEMERR 2 X#define IOERR 1 X#define MAXBITS 13 X#define CLEAR 256 /* clear code */ X#define Z_EOF 257 /* end of file marker */ X#define FIRST_FREE 258 /* first free code */ X#define MAXMAX 8192 /* max code + 1 */ X X#define SPARE 5 X Xstruct tabentry { X unsigned next; X char z_ch; X}; X Xstruct tabentry *table; Xint gotmem = 0; X Xint init_dtab(); Xunsigned rd_dcode(); Xint wr_dchar(); Xint ad_dcode(); X Xunsigned lzd_sp = 0; Xunsigned lzd_stack[STACKSIZE + SPARE]; X Xint push(ch) Xint ch; X{ X lzd_stack[lzd_sp++] = ch; X if (lzd_sp >= STACKSIZE) X prterror ('f', "Stack overflow in lzd()\n", (char *) 0, (char *) 0); X} X X#define pop() (lzd_stack[--lzd_sp]) X Xchar out_buf_adr[IN_BUF_SIZE + SPARE]; Xchar in_buf_adr[OUT_BUF_SIZE + SPARE]; X Xchar memflag = 0; /* memory allocated? flag */ X Xunsigned cur_code; Xunsigned old_code; Xunsigned in_code; X Xunsigned free_code; Xint nbits; Xunsigned max_code; X Xchar fin_char; Xchar k; Xunsigned masks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff }; Xunsigned bit_offset; Xunsigned output_offset; Xint in_han, out_han; X Xint lzd(input_handle, output_handle) Xint input_handle, output_handle; /* input & output file handles */ X{ X in_han = input_handle; /* make it avail to other fns */ X out_han = output_handle; /* ditto */ X nbits = 9; X max_code = 512; X free_code = FIRST_FREE; X lzd_sp = 0; X bit_offset = 0; X output_offset = 0; X X if (gotmem == 0) { X table = (struct tabentry *) X malloc (MAXMAX * sizeof (struct tabentry) + SPARE); X gotmem++; X } X if (table == (struct tabentry *) 0) X memerr(); X X if (read(in_han, in_buf_adr, INBUFSIZ) == -1) X return(IOERR); X X init_dtab(); /* initialize table */ X Xloop: X cur_code = rd_dcode(); X if (cur_code == Z_EOF) { X if (output_offset != 0) { X if (out_han != -2) { X if (write(out_han, out_buf_adr, output_offset) != output_offset) X prterror ('f', "Output error in lzd()\n", X (char *) 0, (char *) 0); X } X addbfcrc(out_buf_adr, output_offset); X } X return (0); X } X X if (cur_code == CLEAR) { X init_dtab(); X fin_char = k = old_code = cur_code = rd_dcode(); X wr_dchar(k); X goto loop; X } X X in_code = cur_code; X if (cur_code >= free_code) { /* if code not in table (k<w>k<w>k) */ X cur_code = old_code; /* previous code becomes current */ X push(fin_char); X } X X while (cur_code > 255) { /* if code, not character */ X push(table[cur_code].z_ch); /* push suffix char */ X cur_code = table[cur_code].next; /* <w> := <w>.code */ X } X X k = fin_char = cur_code; X push(k); X while (lzd_sp != 0) { X wr_dchar(pop()); X } X ad_dcode(); X old_code = in_code; X X goto loop; X} /* lzd() */ X X/* rd_dcode() reads a code from the input (compressed) file and returns Xits value. */ Xunsigned rd_dcode() X{ X register char *ptra, *ptrb; /* miscellaneous pointers */ X unsigned word; /* first 16 bits in buffer */ X unsigned byte_offset; X char nextch; /* next 8 bits in buffer */ X unsigned ofs_inbyte; /* offset within byte */ X X ofs_inbyte = bit_offset % 8; X byte_offset = bit_offset / 8; X bit_offset = bit_offset + nbits; X X if (byte_offset >= INBUFSIZ - 5) { X int space_left; X X bit_offset = ofs_inbyte + nbits; X space_left = INBUFSIZ - byte_offset; X ptrb = byte_offset + in_buf_adr; /* point to char */ X ptra = in_buf_adr; X /* we now move the remaining characters down buffer beginning */ X while (space_left > 0) { X *ptra++ = *ptrb++; X space_left--; X } X if (read(in_han, ptra, byte_offset) == -1) X prterror ('f', "I/O error in lzd:rd_dcode\n", X (char *) 0, (char *) 0); X byte_offset = 0; X } X ptra = byte_offset + in_buf_adr; X /* NOTE: "word = *((int *) ptra)" would not be independent of byte order. */ X word = (unsigned char) *ptra; ptra++; X word = word | ((unsigned char) *ptra) << 8; ptra++; X X nextch = *ptra; X if (ofs_inbyte != 0) { X /* shift nextch right by ofs_inbyte bits */ X /* and shift those bits right into word; */ X word = (word >> ofs_inbyte) | (((unsigned)nextch) << (16-ofs_inbyte)); X } X return (word & masks[nbits]); X} /* rd_dcode() */ X Xint init_dtab() X{ X nbits = 9; X max_code = 512; X free_code = FIRST_FREE; X} X Xint wr_dchar (ch) Xchar ch; X{ X if (output_offset >= OUTBUFSIZ) { /* if buffer full */ X if (out_han != -2) { X if (write(out_han, out_buf_adr, output_offset) != output_offset) X prterror ('f', "Write error in lzd:wr_dchar\n", X (char *) 0, (char *) 0); X } X addbfcrc(out_buf_adr, output_offset); /* update CRC */ X output_offset = 0; /* restore empty buffer */ X } X out_buf_adr[output_offset++] = ch; /* store character */ X} /* wr_dchar() */ X X/* adds a code to table */ Xint ad_dcode() X{ X table[free_code].z_ch = k; /* save suffix char */ X table[free_code].next = old_code; /* save prefix code */ X free_code++; X if (free_code >= max_code) { X if (nbits < MAXBITS) { X nbits++; X max_code = max_code << 1; /* double max_code */ X } X } X} SHAR_EOF if test 5823 -ne "`wc -c < 'lzd.c'`" then echo shar: "error transmitting 'lzd.c'" '(should have been 5823 characters)' fi fi echo shar: "extracting 'makefile.msc'" '(414 characters)' if test -f 'makefile.msc' then echo shar: "will not over-write existing file 'makefile.msc'" else sed 's/^X//' << \SHAR_EOF > 'makefile.msc' X#Make Booz -- makefile for Microsoft C 3.0. Rename to `makefile' before use. X XOOZOBJS = addbfcrc.obj lzd.obj booz.obj oozext.obj portable.obj X Xcswitch = -c -Oas -DMSC X X.c.obj : X cl $(cswitch) $*.c X Xbooz.exe : $(OOZOBJS) X cl $(OOZOBJS) -o booz X Xbooz.obj : options.h zoo.h func.h booz.c X Xlzd.obj : options.h func.h lzd.c X Xoozext.obj : options.h zoo.h oozio.h func.h oozext.c X Xportable.obj : func.h zoo.h portable.c SHAR_EOF if test 414 -ne "`wc -c < 'makefile.msc'`" then echo shar: "error transmitting 'makefile.msc'" '(should have been 414 characters)' fi fi echo shar: "extracting 'makefile.nix'" '(380 characters)' if test -f 'makefile.nix' then echo shar: "will not over-write existing file 'makefile.nix'" else sed 's/^X//' << \SHAR_EOF > 'makefile.nix' X#Make Booz -- makefile for **IX. Rename to `makefile' before use. X XOOZOBJS = addbfcrc.o lzd.o booz.o oozext.o portable.o X Xcswitch = -c -O -DNIX_IO X X.c.o : X cc $(cswitch) $*.c X Xbooz : $(OOZOBJS) X cc $(OOZOBJS) -o booz X Xbooz.o : options.h zoo.h func.h booz.c X Xlzd.o : options.h func.h lzd.c X Xoozext.o : options.h zoo.h oozio.h func.h oozext.c X Xportable.o : func.h zoo.h portable.c SHAR_EOF if test 380 -ne "`wc -c < 'makefile.nix'`" then echo shar: "error transmitting 'makefile.nix'" '(should have been 380 characters)' fi fi echo shar: "extracting 'oozext.c'" '(8196 characters)' if test -f 'oozext.c' then echo shar: "will not over-write existing file 'oozext.c'" else sed 's/^X//' << \SHAR_EOF > 'oozext.c' X/* oozext.c -- extracts files from archive */ X X/* The contents of this file are hereby released to the public domain. X X -- Rahul Dhesi 1987/02/08 X XThe function fixfname() is currently defined to be empty but may be Xactivated if needed to fix filename syntax to be legal for your Xcomputer system. Look near the end of this file for instructions and Xa sample implementation of fixfname(). Currently, fixfname() is used Xonly if the symbol FIXFNAME is defined. X*/ X X#include "options.h" X#include "zoo.h" X#include "oozio.h" X#include "func.h" X Xextern unsigned int crccode; X X#ifndef TINY Xint needed (); X#endif X X#ifdef TINY Xint oozext (zoo_path) Xchar *zoo_path; X#endif X X#ifdef SMALL Xint oozext (zoo_path, argc, argv) Xchar *zoo_path; Xint argc; Xchar *argv[]; X#endif X X#ifdef BIG Xint oozext (zoo_path, option, argc, argv) Xchar *zoo_path; Xchar *option; Xint argc; Xchar *argv[]; X#endif X X{ Xint zoo_han; /* handle for open archive */ Xint this_han; /* handle of file to extract */ Xlong next_ptr; /* pointer to within archive */ Xstruct zoo_header zoo_header; /* header for archive */ Xint status; /* error status */ Xstruct direntry direntry; /* directory entry */ Xint all = 0; /* overwrite all? */ Xstatic char vermsg[] = "A higher version of Ooz is needed to extract "; Xint exitstat = 0; /* return code */ X X#ifdef BIG Xint first_time = 1; Xstatic char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec"; X#endif X X#ifndef TINY X{ X /* If no dot in name, add ".zoo" extension */ X char *p; X p = zoo_path; X while (*p != '\0' && *p != '.') X p++; X if (*p != '.') { /* no dot found */ X p = malloc (strlen (zoo_path) + 5); X if (p == (char *) 0) X memerr(); X strcpy (p, zoo_path); X strcat (p, ".zoo"); X zoo_path = p; X } X} X#endif X Xzoo_han = OPEN(zoo_path); X Xif (zoo_han == -1) X prterror ('f', "Could not open ", zoo_path, "\n"); X X/* read header */ Xrd_zooh (&zoo_header, zoo_han); Xlseek (zoo_han, zoo_header.zoo_start, 0); /* seek to where data begins */ X Xwhile (1) { X rd_dir (&direntry, zoo_han); X X if (direntry.lo_tag != LO_TAG || direntry.hi_tag != HI_TAG) X prterror ('f', "Bad entry in archive\n", X ((char *) 0), ((char *) 0)); X if (direntry.next == 0L) { /* END OF CHAIN */ X break; /* EXIT on end of chain */ X } X next_ptr = direntry.next; /* ptr to next dir entry */ X X#ifndef TINY X /* See if this file is wanted */ X if (!needed (direntry.fname, argc, argv)) { X goto loop_again; X } X#endif X X#ifdef BIG X /* If list needed, give information and loop again */ X if (*option == 'l') { X char outstr[80]; X char buf[20]; X int year, month, day, hours, min, sec; X int size_factor; X size_factor = cfactor (direntry.org_size, direntry.size_now); X X year = ((unsigned int) direntry.date >> 9) & 0x7f; X month = ((unsigned int) direntry.date >> 5) & 0x0f; X day = direntry.date & 0x1f; X X hours = ((unsigned int) direntry.time >> 11)& 0x1f; X min = ((unsigned int) direntry.time >> 5) & 0x3f; X sec = ((unsigned int) direntry.time & 0x1f) * 2; X X if (first_time) { X putstr ("Length CF Size Now Date Time\n"); X putstr ("-------- --- -------- --------- --------\n"); X first_time = 0; X } X strcpy (outstr, itoa(' ', direntry.org_size, buf, 9)); X strcat (outstr, itoa(' ',(long) size_factor, buf, 5)); X strcat (outstr, "% "); X strcat (outstr, itoa(' ',direntry.size_now, buf, 9)); X strcat (outstr, " "); X strcat (outstr, itoa(' ',(long) day, buf, 3)); X strcat (outstr, " "); X strncat (outstr, &month_list[month*3], 3); X strcat (outstr, " "); X if (day && month) X strcat (outstr, itoa(' ',(long) (year+80) % 100, buf, 3)); X else X strcat (outstr, itoa(' ',0L, buf, 3)); X strcat (outstr, " "); X strcat (outstr, itoa('0',(long) hours, buf, 3)); X strcat (outstr, ":"); X strcat (outstr, itoa('0',(long) min, buf, 3)); X strcat (outstr, ":"); X strcat (outstr, itoa('0',(long) sec, buf, 3)); X strcat (outstr, " "); X strcat (outstr, direntry.fname); X strcat (outstr, "\n"); X putstr (outstr); X X#ifdef COMMENT X printf ("%8lu %3u%% %8lu %2d %-.3s %02d %02d:%02d:%02d ", X direntry.org_size, X size_factor, direntry.size_now, X day, &month_list[month*3], X (day && month) ? (year+80) % 100 : 0, X hours, min, sec); X printf ("%s\n", direntry.fname); X#endif X X goto loop_again; X } X#endif /* SMALL */ X X X if (direntry.major_ver > 1 || X (direntry.major_ver == 1 && direntry.minor_ver > 0)) { X prterror ('e', vermsg, direntry.fname, "\n"); X goto loop_again; X } X X#ifdef FIXFNAME X /* Make the filename syntax acceptable to the host system */ X fixfname (direntry.fname); X#endif X X X#ifndef TINY X /* See if this file already exists */ X X#ifdef BIG X if (*option != 't' && !all) X#else X if (!all) X#endif X { X X this_han = OPEN(direntry.fname); X if (this_han != -1) { X char ans[2]; X char ans2[2]; X close (this_han); X X do { X prterror ('m', "Overwrite ", direntry.fname, " (Yes/No/All)? "); X read (0, ans, 1); X do { X read (0, ans2, 1); X } while (*ans2 != '\n'); X } while (*ans != 'y' && *ans != 'Y' && X *ans != 'n' && *ans != 'N' && X *ans != 'a' && *ans != 'A'); X X if (*ans == 'a' || *ans == 'A') X all++; X if (*ans == 'n' || *ans == 'N') { X prterror ('m', "Skipping ", direntry.fname, "\n"); X goto loop_again; X } X } X } X#endif /* ndef TINY */ X X X#ifdef BIG X if (*option == 't') X this_han = -2; X else X#endif X this_han = CREATE(direntry.fname); X X if (this_han == -1) { X prterror ('e', "Could not open ", direntry.fname, " for output.\n"); X } else { X lseek (zoo_han, direntry.offset, 0); X crccode = 0; /* Initialize CRC before extraction */ X prterror ('m', direntry.fname, " ", ((char *) 0)); X X if (direntry.packing_method == 0) X status = getfile (zoo_han, this_han, direntry.size_now); X else if (direntry.packing_method == 1) X status = lzd (zoo_han, this_han); /* uncompress */ X else X prterror ('e', vermsg, direntry.fname, "\n"); X if (status != 0) { X unlink(direntry.fname); X if (status == 1) { X memerr(); X } else X prterror ('e', "I/O error writing ", direntry.fname, "\n"); X } else { X if (direntry.file_crc != crccode) { X putstr ("<--\007WARNING: Bad CRC.\n"); X exitstat = 1; X } else X putstr ("\n"); X } /* end if */ X } /* end if */ X X#ifdef BIG X if (*option != 't') X#endif X close (this_han); X Xloop_again: X lseek (zoo_han, next_ptr, 0); /* ..seek to next dir entry */ X} /* end while */ Xclose (zoo_han); Xexit (exitstat); X} /* end oozext */ X X/* XFunction fixfname() fixes the syntax of the supplied filename so it is Xacceptable to the host system. We call the standard string function Xstrchr(s, c) which searches a string s for a character c and returns Xa pointer to it or returns NULL if not found. The scheme below Xstrips the 8th bit and changes control characters to corresponding Xprintable characters (e.g. ^A becomes A). X XAs supplied, fixfname() is activated only if the symbol FIXFNAME Xis defined. X*/ X X X#ifdef FIXFNAME X/* set of all characters legal for our system */ Xchar legal[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz."; X Xchar *strchr (); X Xint fixfname (fname) Xchar *fname; X{ X char *p; X for (p = fname; *p != '\0'; p++) { X *p &= 0x7f; X if (strchr (legal, *p) == (char *) 0) { X *p = legal[(*p) % 26]; X } X } X} X#endif /* FIXFNAME */ SHAR_EOF if test 8196 -ne "`wc -c < 'oozext.c'`" then echo shar: "error transmitting 'oozext.c'" '(should have been 8196 characters)' fi fi echo shar: "extracting 'oozio.h'" '(1325 characters)' if test -f 'oozio.h' then echo shar: "will not over-write existing file 'oozio.h'" else sed 's/^X//' << \SHAR_EOF > 'oozio.h' X/* oozio.h */ X/* Definitions for portable I/O. X XDefinitions are: X XOPEN(x) open file x for read XCREATE(x) create file x for read/write X XNote that files opened by OPEN() and CREATE() must be opened in Xbinary mode (not involving any LF <-> CR/LF translation). X XThe contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1987/02/08 X*/ X X/* MIX C compiler for CP/M. */ X#ifdef MIXC X#define CREATE(x) (iofilter(0,0), creat (x, 0)) X#define OPEN(x) (iofilter (0,0), open (x, 0)) X#endif X X/* Microsoft C 3.0 under MS-DOS */ X#ifdef MSC X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <io.h> X#define CREATE(x) \ X open (x, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE) X#define OPEN(x) open (x, O_RDONLY|O_BINARY) X#endif X X/* Turbo C 1.0 under MS-DOS */ X#ifdef TURBOC X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <io.h> X#define CREATE(x) \ X open (x, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE) X#define OPEN(x) open (x, O_RDONLY|O_BINARY) X#endif X X/* **IX family I/O */ X#ifdef NIX_IO X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X#define CREATE(x) \ X open (x, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE) X#define OPEN(x) open (x, O_RDONLY) X#endif SHAR_EOF if test 1325 -ne "`wc -c < 'oozio.h'`" then echo shar: "error transmitting 'oozio.h'" '(should have been 1325 characters)' fi fi echo shar: "extracting 'options.h'" '(1559 characters)' if test -f 'options.h' then echo shar: "will not over-write existing file 'options.h'" else sed 's/^X//' << \SHAR_EOF > 'options.h' X/* Compile-time options for Booz to allow custom versions to be built */ X X/* XUse buffer sizes of at least 1024, larger if enough memory is Xavailable. Buffer sizes of over 8192 have not been confirmed to work. X*/ X#define IN_BUF_SIZE 1024 X#define OUT_BUF_SIZE 1024 X X/* XDecompression stack. Except in pathological cases, 2000 bytes should Xbe enough. Rare files may need a bigger stack to decompress. XMay be decreased to 1000 bytes if memory is tight. X*/ X#define STACKSIZE 2000 /* adjust to conserve memory */ X X/* XDefine one of the symbols TINY, SMALL, and BIG. Do not define more than Xone of these symbols. The effects are: X X Symbol Effect X X TINY A very tiny barebones version that always extracts an entire X archive at a time. Should compile and run under CP/M. X X SMALL A slightly bigger version that will let the user specify X which files are to be extracted from the archive. Wildcards X "?" and "*" are accepted in any combination. Still quite X small. Will probably compile and run under CP/M. X X BIG Does everything that the SMALL version does. In addition, X it will list and test archives. May or may not compile X and run under CP/M. X*/ X X/* Only one of the three following symbols should be defined */ X#define TINY X/* #define SMALL */ X/* #define BIG */ X X/* Define FIXFNAME to activate the fixfname() function that converts Xfilename syntax to be acceptable to the host system */ X/* #define FIXFNAME */ SHAR_EOF if test 1559 -ne "`wc -c < 'options.h'`" then echo shar: "error transmitting 'options.h'" '(should have been 1559 characters)' fi fi echo shar: "extracting 'portable.c'" '(3351 characters)' if test -f 'portable.c' then echo shar: "will not over-write existing file 'portable.c'" else sed 's/^X//' << \SHAR_EOF > 'portable.c' X/* XThe contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1987/02/08 X*/ X Xtypedef char BYTE; /* MUST be an 8-bit value */ X X#include "func.h" X#include "zoo.h" X Xlong to_long (); Xint to_int (); Xint b_to_zooh(); Xint b_to_dir(); Xint splitlong(); Xint splitint(); X X/********************** Xto_long() converts four consecutive bytes, in order of increasing Xsignificance, to a long integer. It is used to make Zoo independent of the Xbyte order of the system. X*/ Xlong to_long(data) XBYTE data[]; X{ X int i; X long retval; X retval = ((unsigned) data[2] & 0xff) | X (((unsigned) data[3] & 0xff) << 8); X retval <<= 16; X retval |= (((unsigned) data[0] & 0xff) | X (((unsigned) data[1] & 0xff) << 8)); X return (retval); X} X X/********************** Xto_int() converts two consecutive bytes, in order of increasing Xsignificance, to an integer, in a machine-independent manner X*/ Xint to_int(data) XBYTE data[]; X{ X return (int) (((unsigned) data[0] & 0xff) | X ((unsigned) (data[1] & 0xff) << 8)); X} X X/********************** XFunction rd_zooh() reads a Zoo archive header in a machine-dependent manner, Xfrom a file handle. X*/ Xint rd_zooh (header, zoo_han) Xstruct zoo_header *header; Xint zoo_han; X{ X int status; X BYTE bytes[SIZ_ZOOH]; X status = read (zoo_han, (char *) bytes, SIZ_ZOOH); X b_to_zooh (header, bytes); X return (status); X} X X/********************** XFunction rd_dir() reads a directory entry in a machine-independent manner Xfrom a handle. X*/ Xint rd_dir(direntry, zoo_han) Xstruct direntry *direntry; Xint zoo_han; X{ X int status; X BYTE bytes[SIZ_DIR]; X status = read (zoo_han, (char *) bytes, SIZ_DIR); X b_to_dir (direntry, bytes); X return (status); X} X X/*********************** Xb_to_zooh() converts an array of BYTE to a zoo_header structure. X*/ Xint b_to_zooh (zoo_header, bytes) Xstruct zoo_header *zoo_header; XBYTE bytes[]; X{ X int i; X for (i = 0; i < SIZ_TEXT; i++) X zoo_header->text[i] = bytes[TEXT_I + i]; X zoo_header->lo_tag = to_int(&bytes[ZTAG_I]); X zoo_header->hi_tag = to_int(&bytes[ZTAG_I+2]); X /* zoo_header->zoo_tag = to_long(&bytes[ZTAG_I]); */ X zoo_header->zoo_start = to_long(&bytes[ZST_I]); X zoo_header->zoo_minus = to_long(&bytes[ZSTM_I]); X zoo_header->major_ver = bytes[MAJV_I]; X zoo_header->minor_ver = bytes[MINV_I]; X} X X/* b_to_dir() converts bytes to directory entry structure */ Xint b_to_dir(direntry, bytes) Xstruct direntry *direntry; XBYTE bytes[]; X{ X int i; X direntry->lo_tag = to_int(&bytes[DTAG_I]); X direntry->hi_tag = to_int(&bytes[DTAG_I+2]); X /* direntry->zoo_tag = to_long(&bytes[DTAG_I]); */ X direntry->type = bytes[DTYP_I]; X direntry->packing_method = bytes[PKM_I]; X direntry->next = to_long(&bytes[NXT_I]); X direntry->offset = to_long(&bytes[OFS_I]); X direntry->date = to_int(&bytes[DAT_I]); X direntry->time = to_int(&bytes[TIM_I]); X direntry->file_crc = to_int(&bytes[CRC_I]); X direntry->org_size = to_long(&bytes[ORGS_I]); X direntry->size_now = to_long(&bytes[SIZNOW_I]); X direntry->major_ver = bytes[DMAJ_I]; X direntry->minor_ver = bytes[DMIN_I]; X direntry->deleted = bytes[DEL_I]; X direntry->comment = to_long(&bytes[CMT_I]); X direntry->cmt_size = to_int(&bytes[CMTSIZ_I]); X for (i = 0; i < FNM_SIZ; i++) X direntry->fname[i] = bytes[FNAME_I + i]; X} SHAR_EOF if test 3351 -ne "`wc -c < 'portable.c'`" then echo shar: "error transmitting 'portable.c'" '(should have been 3351 characters)' fi fi echo shar: "extracting 'zoo.h'" '(1900 characters)' if test -f 'zoo.h' then echo shar: "will not over-write existing file 'zoo.h'" else sed 's/^X//' << \SHAR_EOF > 'zoo.h' X/* zoo.h */ X X/* XThe contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1987/02/08 X*/ X X#define SIZ_TEXT 20 X#define FNAMESIZE 13 X#define MAX_PACK 1 X#define LO_TAG (0xa7dc) X#define HI_TAG (0xfdc4) X Xstruct zoo_header { X char text[SIZ_TEXT]; X unsigned lo_tag; X unsigned hi_tag; X long zoo_start; X long zoo_minus; X char major_ver; X char minor_ver; X}; X Xstruct direntry { X unsigned lo_tag; X unsigned hi_tag; X char type; X char packing_method; /* 0 = no packing, 1 = normal LZW */ X long next; /* pos'n of next directory entry */ X long offset; /* position of this file */ X unsigned int date; /* DOS format date */ X unsigned int time; /* DOS format time */ X unsigned int file_crc; /* CRC of this file */ X long org_size; X long size_now; X char major_ver; X char minor_ver; /* minimum version needed to extract */ X char deleted; /* will be 1 if deleted, 0 if not */ X long comment; /* points to comment; zero if none */ X unsigned int cmt_size; /* length of comment, 0 if none */ X char fname[FNAMESIZE]; /* filename */ X}; X X/* offsets of items within the canonical zoo archive header */ X#define SIZ_ZOOH 34 X#define TEXT_I 0 X#define ZTAG_I 20 X#define ZST_I 24 X#define ZSTM_I 28 X#define MAJV_I 32 X#define MINV_I 33 X X/* offsets of items within the canonical directory entry structure */ X#define SIZ_DIR 51 X#define DTAG_I 0 X#define DTYP_I 4 X#define PKM_I 5 X#define NXT_I 6 X#define OFS_I 10 X#define DAT_I 14 X#define TIM_I 16 X#define CRC_I 18 X#define ORGS_I 20 X#define SIZNOW_I 24 X#define DMAJ_I 28 X#define DMIN_I 29 X#define DEL_I 30 X#define SPARE_I 31 X#define CMT_I 32 X#define CMTSIZ_I 36 X#define FNAME_I 38 X X#define FNM_SIZ 13 SHAR_EOF if test 1900 -ne "`wc -c < 'zoo.h'`" then echo shar: "error transmitting 'zoo.h'" '(should have been 1900 characters)' fi fi exit 0 # End of shell archive