home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume04 / booz < prev    next >
Encoding:
Text File  |  1991-08-27  |  47.3 KB  |  1,603 lines

  1. Path: uunet!lll-winken!lll-tis!helios.ee.lbl.gov!nosc!ucsd!rutgers!gatech!cwjcc!hal!ncoast!allbery
  2. From: dhesi@bsu-cs.UUCP (Rahul Dhesi)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i037: booz, a barebones zoo archive extractor
  5. Message-ID: <3765@bsu-cs.UUCP>
  6. Date: 26 Aug 88 08:08:32 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: dhesi@bsu-cs.UUCP (Rahul Dhesi)
  9. Organization: CS Dept, Ball St U, Muncie, Indiana
  10. Lines: 1589
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. Posting-number: Volume 4, Issue 37
  14. Submitted-by: "Rahul Dhesi" <dhesi@bsu-cs.UUCP>
  15. Archive-name: booz
  16.  
  17. #! /bin/sh
  18. # The zoo archive program is currently available for MS-DOS,
  19. # AmigaDOS, VAX/VMS, and various **IX flavors.  To extract
  20. # zoo archives on systems other than these, one possibilty
  21. # is to see if the small zoo archive extraction program
  22. # provided here will work.  It is written in portable C
  23. # though it requires read(), write(), and lseek() system
  24. # calls or their emulations to be available.
  25. #
  26. # This is a shell archive, meaning:
  27. # 1. Remove everything above the #! /bin/sh line.
  28. # 2. Save the resulting text in a file.
  29. # 3. Execute the file with /bin/sh (not csh) to create:
  30. #    addbfcrc.c
  31. #    booz.c
  32. #    booz.doc
  33. #    booz.prj
  34. #    func.h
  35. #    lzd.c
  36. #    makefile.msc
  37. #    makefile.nix
  38. #    oozext.c
  39. #    oozio.h
  40. #    options.h
  41. #    portable.c
  42. #    zoo.h
  43. # This archive created: Fri Aug 26 02:41:13 1988
  44. export PATH; PATH=/bin:/usr/bin:$PATH
  45. echo shar: "extracting 'addbfcrc.c'" '(2921 characters)'
  46. if test -f 'addbfcrc.c'
  47. then
  48.     echo shar: "will not over-write existing file 'addbfcrc.c'"
  49. else
  50. sed 's/^X//' << \SHAR_EOF > 'addbfcrc.c'
  51. X/* adbfcrc.c */
  52. X
  53. X/*
  54. Xaddbfcrc() accepts a buffer address and a count and adds the CRC for
  55. Xall bytes in the buffer to the global variable crccode using
  56. XCRC-16.
  57. X
  58. XCRC computation algorithm taken from source code for ARC 5.12, which
  59. Xin turn took it from an article by David Schwaderer in the April 1985
  60. Xissue of PC Tech Journal.
  61. X
  62. XI claim no copyright over the contents of this file.
  63. X
  64. X                                    -- Rahul Dhesi 1986/12/31
  65. X*/
  66. X
  67. Xunsigned int crccode;
  68. Xunsigned int crctab[] = {
  69. X   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 
  70. X   0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 
  71. X   0x0d80, 0xcd41, 0x0F00, 0xcFc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 
  72. X   0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 
  73. X   0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdF81, 0x1F40, 0xdd01, 
  74. X   0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 
  75. X   0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 
  76. X   0x1040, 0xF001, 0x30c0, 0x3180, 0xF141, 0x3300, 0xF3c1, 0xF281, 0x3240, 
  77. X   0x3600, 0xF6c1, 0xF781, 0x3740, 0xF501, 0x35c0, 0x3480, 0xF441, 0x3c00, 
  78. X   0xFcc1, 0xFd81, 0x3d40, 0xFF01, 0x3Fc0, 0x3e80, 0xFe41, 0xFa01, 0x3ac0, 
  79. X   0x3b80, 0xFb41, 0x3900, 0xF9c1, 0xF881, 0x3840, 0x2800, 0xe8c1, 0xe981, 
  80. X   0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2F80, 0xeF41, 
  81. X   0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 
  82. X   0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 
  83. X   0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 
  84. X   0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 
  85. X   0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaF01, 0x6Fc0, 0x6e80, 0xae41, 0xaa01, 
  86. X   0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 
  87. X   0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7F80, 
  88. X   0xbF41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 
  89. X   0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 
  90. X   0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 
  91. X   0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 
  92. X   0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5F00, 0x9Fc1, 0x9e81, 0x5e40, 
  93. X   0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 
  94. X   0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 
  95. X   0x8F81, 0x4F40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 
  96. X   0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 
  97. X   0x4100, 0x81c1, 0x8081, 0x4040 
  98. X};
  99. X
  100. Xint addbfcrc(buffer,count)
  101. Xchar *buffer;
  102. Xint count;
  103. X
  104. X{
  105. X   register unsigned int localcrc;
  106. X   register int i;
  107. X   localcrc = crccode;
  108. X
  109. X   for (i=0; i<count; i++)
  110. X      localcrc = (localcrc>>8) ^ crctab[(localcrc ^ (buffer[i])) & 0x00ff];
  111. X   crccode = localcrc;
  112. X}
  113. SHAR_EOF
  114. if test 2921 -ne "`wc -c < 'addbfcrc.c'`"
  115. then
  116.     echo shar: "error transmitting 'addbfcrc.c'" '(should have been 2921 characters)'
  117. fi
  118. fi
  119. echo shar: "extracting 'booz.c'" '(8123 characters)'
  120. if test -f 'booz.c'
  121. then
  122.     echo shar: "will not over-write existing file 'booz.c'"
  123. else
  124. sed 's/^X//' << \SHAR_EOF > 'booz.c'
  125. X#define  VERSION  "Version 1.02 (1988/08/25)\n"
  126. X
  127. X/* booz.c -- small, memory-efficient Barebones Ooz to extract Zoo archives.
  128. X
  129. XFor maximum portability, Booz does not use the data type `unsigned long'.
  130. X
  131. XThe functions and system calls required by Tiny Booz are:
  132. X   read()
  133. X   write()
  134. X   strlen()
  135. X   exit()
  136. X   malloc()
  137. X   lseek()
  138. X   open() and/or creat()
  139. X   close()
  140. X   unlink()                -- may be defined to be an empty function
  141. X
  142. X
  143. XSmall Booz additionally uses the following functions:
  144. X   strcat()
  145. X   strcpy()
  146. X
  147. XBig Booz additionally use the following function:
  148. X   strncat()
  149. X*/
  150. X
  151. X/* 
  152. XThe contents of this file are hereby released to the public domain.
  153. X
  154. X                                   -- Rahul Dhesi 1988/08/25
  155. X*/
  156. X
  157. X#include "options.h"
  158. X#include "func.h"
  159. X#include "zoo.h"
  160. X
  161. Xmain(argc,argv)
  162. Xregister int argc;
  163. Xregister char **argv;
  164. X{
  165. X#ifdef TINY
  166. X   static char usage[]=
  167. X      "Usage:  booz archive.zoo\n";
  168. X   if (argc < 2) {
  169. X      putstr ("Public domain Barebones Ooz\nZoo archive extractor (Tiny) by Rahul Dhesi\n");
  170. X      putstr (VERSION);
  171. X      putstr (usage);
  172. X      exit (1);
  173. X   }
  174. X#endif
  175. X
  176. X#ifdef SMALL
  177. X   static char usage[]=
  178. X      "Usage:  booz archive[.zoo] [ file ... ]\n";
  179. X   if (argc < 2) {
  180. X      putstr ("Public domain Barebones Ooz\nZoo archive extractor (Small) by Rahul Dhesi\n");
  181. X      putstr (VERSION);
  182. X      putstr (usage);
  183. X      exit (1);
  184. X   }
  185. X#endif
  186. X
  187. X#ifdef BIG
  188. X   static char usage[]=
  189. X      "Usage:  booz {lxt} archive[.zoo] [ file ... ]\n";
  190. X   if (argc < 3) {
  191. X      putstr ("Public domain Barebones Ooz\nZoo archive extractor/lister (Big) by Rahul Dhesi\n");
  192. X      putstr (VERSION);
  193. X      putstr (usage);
  194. X      putstr ("l = list, x = extract, t = test\n");
  195. X      exit (1);
  196. X   }
  197. X#endif
  198. X
  199. X#ifdef TINY
  200. X   oozext (argv[1]);
  201. X#endif
  202. X
  203. X#ifdef SMALL
  204. X   oozext (argv[1], argc - 2, &argv[2]);
  205. X#endif
  206. X
  207. X#ifdef BIG
  208. X   {
  209. X      char *p;
  210. X      p = argv[1];
  211. X      if (*p == 'L')
  212. X         *p = 'l';
  213. X      if (*p == 'X')
  214. X         *p = 'x';
  215. X      if (*p == 'T')
  216. X         *p = 't';
  217. X      if (*p != 'l' && *p != 'x' && *p != 't') {
  218. X         putstr (usage);
  219. X         exit (1);
  220. X      }
  221. X      oozext (argv[2], p, argc - 3, &argv[3]);
  222. X   }
  223. X#endif
  224. X
  225. X   exit (0);
  226. X}
  227. X
  228. X/**********************/
  229. X/* putstr()
  230. XThis function prints a string to the standard output handle without
  231. Xusing printf() or the standard I/O library.  If a null string, nothing 
  232. Xis printed (not even the null character).
  233. X*/
  234. Xint putstr (str)
  235. Xregister char *str;
  236. X{
  237. X   if (str != (char *) 0)
  238. X      write (1, str, strlen(str));
  239. X}
  240. X
  241. X/**********************/
  242. X/* prterror()
  243. XPrints an error message.  The first character controls the severity
  244. Xof the error and the result.
  245. X
  246. X   'm'   informative message
  247. X   'w'   warning     -- execution continues
  248. X   'e'   error       -- execution continues
  249. X   'f'   fatal error -- program exits
  250. X*/
  251. X
  252. Xint prterror (level, a, b, c)
  253. Xint level;
  254. Xchar *a, *b, *c;
  255. X
  256. X{
  257. X
  258. X#ifdef DEBUG
  259. X   {
  260. X      char tmp[2];
  261. X      tmp[0] = level & 0x7f;
  262. X      tmp[1] = '\0';
  263. X      putstr ("prterror:  level = ");
  264. X      putstr (tmp);
  265. X      putstr ("\n");
  266. X   }
  267. X#endif
  268. X
  269. X   switch (level & 0x7f) {
  270. X      case 'm': break;
  271. X      case 'w': putstr ("WARNING:  "); break;
  272. X      case 'e': putstr ("ERROR:  "); break;
  273. X      case 'f': putstr ("FATAL:  "); break;
  274. X      default: prterror ('f', "Internal error\n", ((char *) 0), ((char *) 0));
  275. X   }
  276. X   putstr (a);
  277. X   putstr (b);
  278. X   putstr (c);
  279. X
  280. X   if (level == 'f')       /* and abort on fatal error 'f' but not 'F' */
  281. X      exit (1);
  282. X}
  283. X
  284. X/*************
  285. XThis function copies count characters from the source file to the
  286. Xdestination Function return value is 0 if no error, 2 if write error,
  287. Xand 3 if read error.  
  288. X
  289. XThe global variable crccode is updated.
  290. X*/
  291. Xextern char out_buf_adr[];
  292. X
  293. Xint getfile(input_han, output_han, count)
  294. Xint input_han, output_han;
  295. Xlong count;
  296. X{
  297. X   register int how_much;
  298. X
  299. X   while (count > 0) {
  300. X      if (count > OUT_BUF_SIZE)
  301. X         how_much = OUT_BUF_SIZE;
  302. X      else
  303. X         how_much = count;
  304. X      count -= how_much;
  305. X      if (read (input_han, out_buf_adr, how_much) != how_much)
  306. X         return (3);
  307. X      addbfcrc (out_buf_adr, how_much);
  308. X      if (output_han != -2 &&
  309. X            write (output_han, out_buf_adr, how_much) != how_much)
  310. X         return (2);
  311. X   }
  312. X   return (0);
  313. X}
  314. X
  315. X#ifndef TINY
  316. X
  317. Xint needed (fname, argc, argv)
  318. Xchar *fname;
  319. Xint argc;
  320. Xchar *argv[];
  321. X{
  322. X   register int i;
  323. X   if (argc == 0)
  324. X      return (1);
  325. X   for (i = 0; i < argc; i++) {
  326. X      if (match (fname, argv[i]))
  327. X         return (1);
  328. X   }
  329. X   return (0);
  330. X}
  331. X
  332. X/***********************/
  333. X/*
  334. Xmatch() compares a pattern with a string.  Wildcards accepted in
  335. Xthe pattern are:  "*" for zero or more arbitrary characters;  "?"
  336. Xfor any one characters.  Unlike the MS-DOS wildcard match, "*" is
  337. Xcorrectly handled even if it isn't at the end of the pattern. ".'
  338. Xis not special.
  339. X
  340. XOriginally written by Jeff Damens of Columbia University Center for
  341. XComputing Activities.  Taken from the source code for C-Kermit version
  342. X4C.
  343. X*/
  344. X
  345. Xint match (string, pattern) 
  346. Xregister char *string, *pattern;
  347. X{
  348. X   char *psave,*ssave;        /* back up pointers for failure */
  349. X   psave = ssave = ((char *) 0);
  350. X   while (1) {
  351. X      for (; *pattern == *string; pattern++,string++)  /* skip first */
  352. X         if (*string == '\0') 
  353. X            return(1);                          /* end of strings, succeed */
  354. X      if (*string != '\0' && *pattern == '?') {
  355. X         pattern++;                             /* '?', let it match */
  356. X         string++;
  357. X      } else if (*pattern == '*') {             /* '*' ... */
  358. X         psave = ++pattern;                     /* remember where we saw it */
  359. X         ssave = string;                        /* let it match 0 chars */
  360. X      } else if (ssave != ((char *) 0) && *ssave != '\0') {   /* if not at end  */
  361. X         /* ...have seen a star */
  362. X         string = ++ssave;                      /* skip 1 char from string */
  363. X         pattern = psave;                       /* and back up pattern */
  364. X      } else 
  365. X         return(0);                             /* otherwise just fail */
  366. X   }
  367. X}
  368. X
  369. X#endif /* ndef TINY */
  370. X
  371. Xint memerr()
  372. X{
  373. X   prterror ('f', "Ran out of memory\n");
  374. X}
  375. X
  376. X#ifdef BIG
  377. X/* cfactor() calculates the compression factor given a directory entry */
  378. Xint cfactor (org_size, size_now)
  379. Xlong org_size, size_now;
  380. X{
  381. X   register int size_factor;
  382. X
  383. X   while (org_size > 10000) { /* avoid overflow below */
  384. X      org_size = org_size >> 4;
  385. X      size_now = size_now >> 4;
  386. X   }
  387. X   if (org_size == 0)         /* avoid division by zero */
  388. X      size_factor = 0;
  389. X   else {
  390. X      size_factor = 
  391. X         (
  392. X            (1000 * 
  393. X               (org_size - size_now)
  394. X            ) / org_size + 5
  395. X         ) / 10;
  396. X   }
  397. X   return (size_factor);
  398. X}
  399. X
  400. X/******
  401. XFunction itoa() converts a positive long integer into a text string of
  402. Xdigits.  The buffer pointer buf must point to a buffer to receive the
  403. Xdigit string.  The digit string is stored right justified in the
  404. Xbuffer with leading blanks.  If the supplied number is negative, or if
  405. Xoverflow occurs, a single '*' is returned.
  406. X*/
  407. X
  408. Xchar *itoa (pad_ch, n, buf, buflen)
  409. Xchar pad_ch;                  /* leading pad character */
  410. Xlong n;                       /* positive long int to convert */
  411. Xchar *buf;                    /* buffer to receive digit string */
  412. Xint buflen;                   /* length of buffer */
  413. X{
  414. X   char *p;
  415. X   int i;
  416. X   for (i = 0;  i < buflen;  i++)         /* fill buffer with pad char */
  417. X      buf[i] = pad_ch;
  418. X   p = buf + buflen - 1;
  419. X   *p-- = '\0';                           /* ensure null termination */
  420. X   i = buflen - 1;
  421. X   for (;;) {
  422. X      if (n < 0) {                        /* can't handle negative n */
  423. X         goto overflow;
  424. X      } else {
  425. X         *p-- = (int) (n % 10) + '0';     /* store a converted digit */
  426. X         n = n / 10;
  427. X         i--;
  428. X         if (n == 0 || i == 0)
  429. X            break;
  430. X      } /* end of else of if (n < 0) */
  431. X   } /* end while (buflen > 0) */
  432. X   if (n != 0)                            /* buffer overflow */
  433. X      goto overflow;
  434. X   return (buf);
  435. X
  436. Xoverflow:                                 /* bad value filled with stars */
  437. X   for (i = 0; i < buflen; i++)
  438. X      buf[i] = '*';
  439. X   buf[buflen-1] = '\0';
  440. X   return (buf);
  441. X}
  442. X
  443. X#endif /* BIG */
  444. SHAR_EOF
  445. if test 8123 -ne "`wc -c < 'booz.c'`"
  446. then
  447.     echo shar: "error transmitting 'booz.c'" '(should have been 8123 characters)'
  448. fi
  449. fi
  450. echo shar: "extracting 'booz.doc'" '(6645 characters)'
  451. if test -f 'booz.doc'
  452. then
  453.     echo shar: "will not over-write existing file 'booz.doc'"
  454. else
  455. sed 's/^X//' << \SHAR_EOF > 'booz.doc'
  456. X                      Booz 1.02 -- Barebones Ooz
  457. X                                  a
  458. X                         Zoo Extractor/Lister
  459. X                                  by
  460. X                             Rahul Dhesi
  461. X
  462. XBooz 1.02 is a small, memory-efficient Zoo archive extractor/lister. 
  463. XIt is not fancy.  It does not recognize the advanced features
  464. Xavailable in current versions of Zoo, such as long filenames,
  465. Xdirectory names, comments, and multiple file generations.  Extraction
  466. Xalways uses a short MS-DOS format filename and all extracted files go
  467. Xinto the current directory.
  468. X
  469. XBut Booz 1.02 is simple and portable and can be implemented in about
  470. Xfifteen minutes on any system with a reasonably good C compiler that
  471. Xprovides **IX-compatible read(), write(), and lseek() functions.
  472. XAnd Booz 1.02 can extract and list all archives created by all
  473. Xcurrently-existing versions of Zoo.
  474. X
  475. XAt compilation time, conditional compilation selects one of three
  476. Xlevels of sophistication for Booz 1.02.  The three options are as
  477. Xfollows.
  478. X
  479. XThe Tiny option:  Booz compiled with the Tiny option is very frugal
  480. Xand should compile and run under CP/M and other systems with limited
  481. Xmemory.  Tiny Booz always extracts an entire archive at a time and
  482. Xdoes not attempt to prevent an exctracted file from overwriting
  483. Xanother.  Tiny Booz requires you to type the entire filename of the
  484. Xarchive being extracted, including the ".zoo" extension.
  485. X
  486. XThe Small option:  Booz compiled with the Small option is a little
  487. Xmore sophisticated than Tiny Booz.  Small Booz assumes the default
  488. Xextension ".zoo" for an archive if it is not specified.  It will let
  489. Xyou specify which files should be extracted from an archive.  Small
  490. XBooz accepts these wildcard symbols in the names of files to be
  491. Xextracted:  "?" stands for any one character and "*" stands for any
  492. Xsequence of zero or more characters.  Combinations of these are
  493. Xpermitted so, for example, "*c?t*h" matches filenames ending with "h"
  494. Xand containing "c" and "t" separated by one character.  Small Booz is
  495. Xnearly as memory-efficient as Tiny Booz and it very likely that it
  496. Xwill compile and run under CP/M.
  497. X
  498. XThe Big option:  Booz compiled with the Big option does everything
  499. Xthat Small Booz does and in addition it can give the directory
  500. Xlisting of a Zoo archive or test its integrity.  Despite its name,
  501. XBig Booz is still quite frugal.  Under MS-DOS, when compiled with
  502. Xthe Microsoft C compiler version 3.00, it runs in about 50 kilobytes
  503. Xof free memory and occupies about 9.5 kilobytes on disk.
  504. X
  505. X
  506. X                         COMPILING BOOZ 1.02
  507. X
  508. X1.
  509. XMake sure that the two macros OPEN and CREATE are correctly defined
  510. Xfor your system in file `oozio.h'.  Some sample macros are provided. 
  511. XThe macros must be defined to open files in binary mode (i.e.,
  512. Xwithout newline conversions).
  513. X
  514. XThe macro OPEN is supplied a filename and it must open the file for
  515. Xreading and return an open file descriptor, or -1 if the open fails. 
  516. XIt is used to open the archive being extracted or listed, and to test
  517. Xthe existence of a file about to be extracted.
  518. X
  519. XThe macro CREATE is supplied a filename and it must create a new file
  520. Xfor writing and return an open file descriptor, or -1 if the create
  521. Xfails.  It is used for creating each file that is extracted.
  522. X
  523. X2.
  524. XIf your C library does not provide the unlink() function (which
  525. Xdeletes a file given its name), define an empty function by that
  526. Xname, or define a suitable (possibly empty) macro by that name in
  527. Xfile `oozio.h'.
  528. X
  529. X3.
  530. XDecide which of the three options, Tiny, Small, or Big, you will use.
  531. XIf memory is tight use the Tiny option first to get a Zoo extractor
  532. Xquickly running on your system.  Then experiment with the other
  533. Xoptions.  If memory is not tight, use the Big option.  Define any one
  534. Xof the symbols TINY, SMALL, or BIG in the file `options.h' (or
  535. Xalternatively define it on the command line that invokes your C
  536. Xcompiler).  Exactly one of these three symbols must be defined.
  537. X
  538. X4.
  539. XChoose appropriate sizes for the input/output buffers and for the
  540. Xsize of the decompression stack in file `options.h'.  If memory
  541. Xpermits, make the buffers 8192 each.   (Bigger sizes, perhaps up to
  542. X16384, could be used but they have not been tested and could
  543. Xconceivably cause overflow in certain bit-shift operations in file
  544. X`lzd.c').  A reasonable stack size is 2000, but in pathological cases
  545. Xextraction of a file could require a larger stack.
  546. X
  547. XIf memory is tight, decrease the input/output buffers to 1024 each
  548. Xeach and the stack to 1000.
  549. X
  550. X5.
  551. XCompile and link all the C files.  Two makefiles are supplied, one
  552. Xsuitable for **IX systems and the other for Microsoft C 3.0 under
  553. XMS-DOS.  Modify these as necessary for your system.  Also supplied is
  554. Xa project file booz.prj for use with Turbo C 1.0 on MS-DOS.
  555. X
  556. X
  557. X                          MACHINE DEPENDENCE
  558. X
  559. XBooz is relatively independent of machine architecture, except that
  560. X(a) the machine must be a 2's complement machine (all modern machines
  561. Xare) and (b) `char' must be exactly 8 bits, `int' must be 16 bits or
  562. Xlarger, and `long' must be 32 bits or larger (though a `long' of a
  563. Xlittle less than 32 bits may work).
  564. X
  565. XBooz makes no assumptions about the filename syntax of the host
  566. Xmachine, except that Small and Big Booz assume that dot "." is used to
  567. Xseparate the extension "zoo" from the rest of the name of the
  568. Xarchive.  They will append ".zoo" to the archive name if it contains
  569. Xno dot;  this fails if an archive name of the type "../junk" is
  570. Xspecified.  
  571. X
  572. XIf your system uses a different filename syntax, you may need to
  573. Xchange the code.  Also, if your system cannot accept some of the
  574. Xcharacters legal in MS-DOS filenames, you may need to add a function
  575. Xthat will fix the filename before extraction.  A sample function
  576. X`fixfname()' is included in the file `oozext.c'.  It becomes activated
  577. Xonly if the preprocessor symbol FIXFNAME is defined.
  578. X
  579. X                 NOTE
  580. X
  581. XThis program does not attempt to be case-insensitive.  Therefore you
  582. Xwill need to type names of files to be extracted in the correct
  583. Xcase.  Note, however, that some operating systems (possibly CP/M) may
  584. Xfold command line arguments to uppercase.  If this happens, your
  585. Xbest bet is to extract all files from an archive instead of
  586. Xspecifying specific names.
  587. X
  588. X               REVISION HISTORY
  589. X
  590. XVersion 1.00
  591. X     Corresponded to just the Tiny booz 1.02
  592. X
  593. XVersion 1.01
  594. X     Included TINY, SMALL, BIG compilation options.  Had a bug in
  595. X     function needed() that sometimes cause file extraction to fail.
  596. X
  597. XVersion 1.02
  598. X     Fixed bug in function needed().  Added support for Turbo C 1.0.
  599. X     Revised this documentation and some comments in the source code.
  600. X
  601. X                                -- Rahul Dhesi 1988/08/25
  602. SHAR_EOF
  603. if test 6645 -ne "`wc -c < 'booz.doc'`"
  604. then
  605.     echo shar: "error transmitting 'booz.doc'" '(should have been 6645 characters)'
  606. fi
  607. fi
  608. echo shar: "extracting 'booz.prj'" '(138 characters)'
  609. if test -f 'booz.prj'
  610. then
  611.     echo shar: "will not over-write existing file 'booz.prj'"
  612. else
  613. sed 's/^X//' << \SHAR_EOF > 'booz.prj'
  614. Xbooz.c        (options.h zoo.h func.h)
  615. Xaddbfcrc.c
  616. Xlzd.c        (options.h func.h)
  617. Xoozext.c    (options.h zoo.h oozio.h func.h)
  618. Xportable.c    (func.h zoo.h)
  619. SHAR_EOF
  620. if test 138 -ne "`wc -c < 'booz.prj'`"
  621. then
  622.     echo shar: "error transmitting 'booz.prj'" '(should have been 138 characters)'
  623. fi
  624. fi
  625. echo shar: "extracting 'func.h'" '(505 characters)'
  626. if test -f 'func.h'
  627. then
  628.     echo shar: "will not over-write existing file 'func.h'"
  629. else
  630. sed 's/^X//' << \SHAR_EOF > 'func.h'
  631. X/* 
  632. XThe contents of this file are hereby released to the public domain.
  633. X                                   -- Rahul Dhesi 1987/02/08
  634. X*/
  635. X
  636. X/* Functions defined by Booz */
  637. X
  638. Xint getfile ();
  639. Xint lzd ();
  640. Xint readdir ();
  641. Xint rd_zooh ();
  642. Xint rd_dir ();
  643. Xint addbfcrc();
  644. Xint prterror();
  645. Xint oozext ();
  646. Xint putstr ();
  647. Xchar *itoa ();
  648. Xint fixfname ();
  649. X
  650. X/* Standard functions */
  651. X
  652. Xchar *malloc ();
  653. Xint close ();
  654. Xint creat ();
  655. Xint open ();
  656. Xint read ();
  657. Xint unlink ();
  658. Xint write ();
  659. Xlong lseek ();
  660. Xunsigned int strlen ();
  661. SHAR_EOF
  662. if test 505 -ne "`wc -c < 'func.h'`"
  663. then
  664.     echo shar: "error transmitting 'func.h'" '(should have been 505 characters)'
  665. fi
  666. fi
  667. echo shar: "extracting 'lzd.c'" '(5823 characters)'
  668. if test -f 'lzd.c'
  669. then
  670.     echo shar: "will not over-write existing file 'lzd.c'"
  671. else
  672. sed 's/^X//' << \SHAR_EOF > 'lzd.c'
  673. X/*
  674. XLempel-Ziv decompression.  Mostly based on Tom Pfau's assembly language
  675. Xcode.  The contents of this file are hereby released to the public domain.
  676. X                                 -- Rahul Dhesi 1986/11/14, 1987/02/08
  677. X*/
  678. X
  679. X#include "func.h"
  680. X#include "options.h"
  681. X
  682. X#define  INBUFSIZ    (IN_BUF_SIZE - SPARE)
  683. X#define  OUTBUFSIZ   (OUT_BUF_SIZE - SPARE)
  684. X#define  MEMERR      2
  685. X#define  IOERR       1
  686. X#define  MAXBITS     13
  687. X#define  CLEAR       256         /* clear code */
  688. X#define  Z_EOF       257         /* end of file marker */
  689. X#define  FIRST_FREE  258         /* first free code */
  690. X#define  MAXMAX      8192        /* max code + 1 */
  691. X
  692. X#define  SPARE       5
  693. X
  694. Xstruct tabentry {
  695. X   unsigned next;
  696. X   char z_ch;
  697. X};
  698. X
  699. Xstruct tabentry *table;
  700. Xint   gotmem = 0;
  701. X
  702. Xint init_dtab();
  703. Xunsigned rd_dcode();
  704. Xint wr_dchar();
  705. Xint ad_dcode();
  706. X
  707. Xunsigned lzd_sp = 0;
  708. Xunsigned lzd_stack[STACKSIZE + SPARE];
  709. X
  710. Xint push(ch)
  711. Xint ch;
  712. X{
  713. X   lzd_stack[lzd_sp++] = ch;
  714. X   if (lzd_sp >= STACKSIZE)
  715. X      prterror ('f', "Stack overflow in lzd()\n", (char *) 0, (char *) 0);
  716. X}
  717. X   
  718. X#define  pop()    (lzd_stack[--lzd_sp])
  719. X
  720. Xchar out_buf_adr[IN_BUF_SIZE + SPARE];
  721. Xchar in_buf_adr[OUT_BUF_SIZE + SPARE];
  722. X
  723. Xchar memflag = 0;                /* memory allocated? flag */
  724. X
  725. Xunsigned cur_code;
  726. Xunsigned old_code;
  727. Xunsigned in_code;
  728. X
  729. Xunsigned free_code;
  730. Xint nbits;
  731. Xunsigned max_code;
  732. X
  733. Xchar fin_char;
  734. Xchar k;
  735. Xunsigned masks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
  736. X                        0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff };
  737. Xunsigned bit_offset;
  738. Xunsigned output_offset;
  739. Xint in_han, out_han; 
  740. X
  741. Xint lzd(input_handle, output_handle)
  742. Xint input_handle, output_handle;          /* input & output file handles */
  743. X{
  744. X   in_han = input_handle;                 /* make it avail to other fns */
  745. X   out_han = output_handle;               /* ditto */
  746. X   nbits = 9;
  747. X   max_code = 512;
  748. X   free_code = FIRST_FREE;
  749. X   lzd_sp = 0;
  750. X   bit_offset = 0;
  751. X   output_offset = 0;
  752. X
  753. X   if (gotmem == 0) {
  754. X      table = (struct tabentry *) 
  755. X         malloc (MAXMAX * sizeof (struct tabentry) + SPARE);
  756. X      gotmem++;
  757. X   }
  758. X   if (table == (struct tabentry *) 0)
  759. X      memerr();
  760. X
  761. X   if (read(in_han, in_buf_adr, INBUFSIZ) == -1)
  762. X      return(IOERR);
  763. X
  764. X   init_dtab();             /* initialize table */
  765. X
  766. Xloop:
  767. X   cur_code = rd_dcode();
  768. X   if (cur_code == Z_EOF) {
  769. X      if (output_offset != 0) {
  770. X         if (out_han != -2) {
  771. X            if (write(out_han, out_buf_adr, output_offset) != output_offset)
  772. X               prterror ('f', "Output error in lzd()\n", 
  773. X                        (char *) 0, (char *) 0);
  774. X         }
  775. X         addbfcrc(out_buf_adr, output_offset);
  776. X      }
  777. X      return (0);
  778. X   }
  779. X
  780. X   if (cur_code == CLEAR) {
  781. X      init_dtab();
  782. X      fin_char = k = old_code = cur_code = rd_dcode();
  783. X      wr_dchar(k);
  784. X      goto loop;
  785. X   }
  786. X
  787. X   in_code = cur_code;
  788. X   if (cur_code >= free_code) {        /* if code not in table (k<w>k<w>k) */
  789. X      cur_code = old_code;             /* previous code becomes current */
  790. X      push(fin_char);
  791. X   }
  792. X
  793. X   while (cur_code > 255) {               /* if code, not character */
  794. X      push(table[cur_code].z_ch);         /* push suffix char */
  795. X      cur_code = table[cur_code].next;    /* <w> := <w>.code */
  796. X   }
  797. X
  798. X   k = fin_char = cur_code;
  799. X   push(k);
  800. X   while (lzd_sp != 0) {
  801. X      wr_dchar(pop());
  802. X   }
  803. X   ad_dcode();
  804. X   old_code = in_code;
  805. X
  806. X   goto loop;
  807. X} /* lzd() */
  808. X
  809. X/* rd_dcode() reads a code from the input (compressed) file and returns
  810. Xits value. */
  811. Xunsigned rd_dcode()
  812. X{
  813. X   register char *ptra, *ptrb;    /* miscellaneous pointers */
  814. X   unsigned word;                     /* first 16 bits in buffer */
  815. X   unsigned byte_offset;
  816. X   char nextch;                           /* next 8 bits in buffer */
  817. X   unsigned ofs_inbyte;               /* offset within byte */
  818. X
  819. X   ofs_inbyte = bit_offset % 8;
  820. X   byte_offset = bit_offset / 8;
  821. X   bit_offset = bit_offset + nbits;
  822. X
  823. X   if (byte_offset >= INBUFSIZ - 5) {
  824. X      int space_left;
  825. X
  826. X      bit_offset = ofs_inbyte + nbits;
  827. X      space_left = INBUFSIZ - byte_offset;
  828. X      ptrb = byte_offset + in_buf_adr;          /* point to char */
  829. X      ptra = in_buf_adr;
  830. X      /* we now move the remaining characters down buffer beginning */
  831. X      while (space_left > 0) {
  832. X         *ptra++ = *ptrb++;
  833. X         space_left--;
  834. X      }
  835. X      if (read(in_han, ptra, byte_offset) == -1)
  836. X         prterror ('f', "I/O error in lzd:rd_dcode\n", 
  837. X                (char *) 0, (char *) 0);
  838. X      byte_offset = 0;
  839. X   }
  840. X   ptra = byte_offset + in_buf_adr;
  841. X   /* NOTE:  "word = *((int *) ptra)" would not be independent of byte order. */
  842. X   word = (unsigned char) *ptra; ptra++;
  843. X   word = word | ((unsigned char) *ptra) << 8; ptra++;
  844. X
  845. X   nextch = *ptra;
  846. X   if (ofs_inbyte != 0) {
  847. X      /* shift nextch right by ofs_inbyte bits */
  848. X      /* and shift those bits right into word; */
  849. X      word = (word >> ofs_inbyte) | (((unsigned)nextch) << (16-ofs_inbyte));
  850. X   }
  851. X   return (word & masks[nbits]); 
  852. X} /* rd_dcode() */
  853. X
  854. Xint init_dtab()
  855. X{
  856. X   nbits = 9;
  857. X   max_code = 512;
  858. X   free_code = FIRST_FREE;
  859. X}
  860. X
  861. Xint wr_dchar (ch)
  862. Xchar ch;
  863. X{
  864. X   if (output_offset >= OUTBUFSIZ) {      /* if buffer full */
  865. X      if (out_han != -2) {
  866. X         if (write(out_han, out_buf_adr, output_offset) != output_offset)
  867. X            prterror ('f', "Write error in lzd:wr_dchar\n", 
  868. X                    (char *) 0, (char *) 0);
  869. X      }
  870. X      addbfcrc(out_buf_adr, output_offset);     /* update CRC */
  871. X      output_offset = 0;                  /* restore empty buffer */
  872. X   }
  873. X   out_buf_adr[output_offset++] = ch;        /* store character */
  874. X} /* wr_dchar() */
  875. X
  876. X/* adds a code to table */
  877. Xint ad_dcode()
  878. X{
  879. X   table[free_code].z_ch = k;                /* save suffix char */
  880. X   table[free_code].next = old_code;         /* save prefix code */
  881. X   free_code++;
  882. X   if (free_code >= max_code) {
  883. X      if (nbits < MAXBITS) {
  884. X         nbits++;
  885. X         max_code = max_code << 1;        /* double max_code */
  886. X      }
  887. X   }
  888. X}
  889. SHAR_EOF
  890. if test 5823 -ne "`wc -c < 'lzd.c'`"
  891. then
  892.     echo shar: "error transmitting 'lzd.c'" '(should have been 5823 characters)'
  893. fi
  894. fi
  895. echo shar: "extracting 'makefile.msc'" '(414 characters)'
  896. if test -f 'makefile.msc'
  897. then
  898.     echo shar: "will not over-write existing file 'makefile.msc'"
  899. else
  900. sed 's/^X//' << \SHAR_EOF > 'makefile.msc'
  901. X#Make Booz -- makefile for Microsoft C 3.0.  Rename to `makefile' before use.
  902. X
  903. XOOZOBJS = addbfcrc.obj lzd.obj booz.obj oozext.obj portable.obj
  904. X
  905. Xcswitch = -c -Oas -DMSC
  906. X
  907. X.c.obj :
  908. X    cl $(cswitch) $*.c
  909. X
  910. Xbooz.exe : $(OOZOBJS)
  911. X    cl $(OOZOBJS) -o booz
  912. X
  913. Xbooz.obj : options.h zoo.h func.h booz.c
  914. X
  915. Xlzd.obj : options.h func.h lzd.c
  916. X
  917. Xoozext.obj : options.h zoo.h oozio.h func.h oozext.c
  918. X
  919. Xportable.obj : func.h zoo.h portable.c
  920. SHAR_EOF
  921. if test 414 -ne "`wc -c < 'makefile.msc'`"
  922. then
  923.     echo shar: "error transmitting 'makefile.msc'" '(should have been 414 characters)'
  924. fi
  925. fi
  926. echo shar: "extracting 'makefile.nix'" '(380 characters)'
  927. if test -f 'makefile.nix'
  928. then
  929.     echo shar: "will not over-write existing file 'makefile.nix'"
  930. else
  931. sed 's/^X//' << \SHAR_EOF > 'makefile.nix'
  932. X#Make Booz -- makefile for **IX.  Rename to `makefile' before use.
  933. X
  934. XOOZOBJS = addbfcrc.o lzd.o booz.o oozext.o portable.o
  935. X
  936. Xcswitch = -c -O -DNIX_IO
  937. X
  938. X.c.o :
  939. X    cc $(cswitch) $*.c
  940. X
  941. Xbooz : $(OOZOBJS)
  942. X    cc $(OOZOBJS) -o booz
  943. X
  944. Xbooz.o : options.h zoo.h func.h booz.c
  945. X
  946. Xlzd.o : options.h func.h lzd.c
  947. X
  948. Xoozext.o : options.h zoo.h oozio.h func.h oozext.c
  949. X
  950. Xportable.o : func.h zoo.h portable.c
  951. SHAR_EOF
  952. if test 380 -ne "`wc -c < 'makefile.nix'`"
  953. then
  954.     echo shar: "error transmitting 'makefile.nix'" '(should have been 380 characters)'
  955. fi
  956. fi
  957. echo shar: "extracting 'oozext.c'" '(8196 characters)'
  958. if test -f 'oozext.c'
  959. then
  960.     echo shar: "will not over-write existing file 'oozext.c'"
  961. else
  962. sed 's/^X//' << \SHAR_EOF > 'oozext.c'
  963. X/* oozext.c -- extracts files from archive */
  964. X
  965. X/* The contents of this file are hereby released to the public domain.
  966. X
  967. X                                   -- Rahul Dhesi 1987/02/08
  968. X
  969. XThe function fixfname() is currently defined to be empty but may be
  970. Xactivated if needed to fix filename syntax to be legal for your
  971. Xcomputer system.  Look near the end of this file for instructions and
  972. Xa sample implementation of fixfname().  Currently, fixfname() is used
  973. Xonly if the symbol FIXFNAME is defined.
  974. X*/
  975. X
  976. X#include "options.h"
  977. X#include "zoo.h"
  978. X#include "oozio.h"
  979. X#include "func.h"
  980. X
  981. Xextern unsigned int crccode;
  982. X
  983. X#ifndef TINY
  984. Xint needed ();
  985. X#endif
  986. X
  987. X#ifdef TINY
  988. Xint oozext (zoo_path)
  989. Xchar *zoo_path;
  990. X#endif
  991. X
  992. X#ifdef SMALL
  993. Xint oozext (zoo_path, argc, argv)
  994. Xchar *zoo_path;
  995. Xint argc;
  996. Xchar *argv[];
  997. X#endif
  998. X
  999. X#ifdef BIG
  1000. Xint oozext (zoo_path, option, argc, argv)
  1001. Xchar *zoo_path;
  1002. Xchar *option;
  1003. Xint argc;
  1004. Xchar *argv[];
  1005. X#endif
  1006. X
  1007. X{
  1008. Xint zoo_han;                              /* handle for open archive */
  1009. Xint this_han;                             /* handle of file to extract */
  1010. Xlong next_ptr;                            /* pointer to within archive */
  1011. Xstruct zoo_header zoo_header;             /* header for archive */
  1012. Xint status;                               /* error status */
  1013. Xstruct direntry direntry;                 /* directory entry */
  1014. Xint all = 0;                              /* overwrite all? */
  1015. Xstatic char vermsg[] = "A higher version of Ooz is needed to extract ";
  1016. Xint exitstat = 0;                         /* return code */
  1017. X
  1018. X#ifdef BIG
  1019. Xint first_time = 1;
  1020. Xstatic char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
  1021. X#endif
  1022. X
  1023. X#ifndef TINY
  1024. X{
  1025. X   /* If no dot in name, add ".zoo" extension */
  1026. X   char *p;
  1027. X   p = zoo_path;
  1028. X   while (*p != '\0' && *p != '.')
  1029. X      p++;
  1030. X   if (*p != '.') {  /* no dot found */
  1031. X      p = malloc (strlen (zoo_path) + 5);
  1032. X      if (p == (char *) 0)
  1033. X         memerr();
  1034. X      strcpy (p, zoo_path);
  1035. X      strcat (p, ".zoo");
  1036. X      zoo_path = p;
  1037. X   }
  1038. X}
  1039. X#endif
  1040. X
  1041. Xzoo_han = OPEN(zoo_path);
  1042. X
  1043. Xif (zoo_han == -1)
  1044. X   prterror ('f', "Could not open ", zoo_path, "\n");
  1045. X
  1046. X/* read header */
  1047. Xrd_zooh (&zoo_header, zoo_han);
  1048. Xlseek (zoo_han, zoo_header.zoo_start, 0); /* seek to where data begins */
  1049. X
  1050. Xwhile (1) {
  1051. X   rd_dir (&direntry, zoo_han);
  1052. X
  1053. X   if (direntry.lo_tag != LO_TAG || direntry.hi_tag != HI_TAG)
  1054. X         prterror ('f', "Bad entry in archive\n", 
  1055. X            ((char *) 0), ((char *) 0));
  1056. X   if (direntry.next == 0L) {                /* END OF CHAIN */
  1057. X      break;                                 /* EXIT on end of chain */
  1058. X   }
  1059. X   next_ptr = direntry.next;                 /* ptr to next dir entry */
  1060. X
  1061. X#ifndef TINY
  1062. X      /* See if this file is wanted */
  1063. X      if (!needed (direntry.fname, argc, argv)) {
  1064. X         goto loop_again;
  1065. X      }
  1066. X#endif
  1067. X
  1068. X#ifdef BIG
  1069. X  /* If list needed, give information and loop again */
  1070. X   if (*option == 'l') {
  1071. X      char outstr[80];
  1072. X      char buf[20];
  1073. X      int year, month, day, hours, min, sec;
  1074. X      int size_factor;
  1075. X      size_factor = cfactor (direntry.org_size, direntry.size_now);
  1076. X   
  1077. X      year  =  ((unsigned int) direntry.date >> 9) & 0x7f;
  1078. X      month =  ((unsigned int) direntry.date >> 5) & 0x0f;
  1079. X      day   =  direntry.date        & 0x1f;
  1080. X      
  1081. X      hours =  ((unsigned int) direntry.time >> 11)& 0x1f;
  1082. X      min   =  ((unsigned int) direntry.time >> 5) & 0x3f;
  1083. X      sec   =  ((unsigned int) direntry.time & 0x1f) * 2;
  1084. X
  1085. X      if (first_time) {
  1086. X         putstr ("Length    CF  Size Now  Date      Time\n");
  1087. X         putstr ("--------  --- --------  --------- --------\n");
  1088. X         first_time = 0;
  1089. X      }
  1090. X      strcpy (outstr, itoa(' ', direntry.org_size, buf, 9));
  1091. X      strcat (outstr, itoa(' ',(long) size_factor, buf, 5));
  1092. X      strcat (outstr, "% ");
  1093. X      strcat (outstr, itoa(' ',direntry.size_now, buf, 9));
  1094. X      strcat (outstr, "  ");
  1095. X      strcat (outstr, itoa(' ',(long) day, buf, 3));
  1096. X      strcat (outstr, " ");
  1097. X      strncat (outstr, &month_list[month*3], 3);
  1098. X      strcat (outstr, " ");
  1099. X      if (day && month)
  1100. X         strcat (outstr, itoa(' ',(long) (year+80) % 100, buf, 3));
  1101. X      else
  1102. X         strcat (outstr, itoa(' ',0L, buf, 3));
  1103. X      strcat (outstr, " ");
  1104. X      strcat (outstr, itoa('0',(long) hours, buf, 3));
  1105. X      strcat (outstr, ":");
  1106. X      strcat (outstr, itoa('0',(long) min, buf, 3));
  1107. X      strcat (outstr, ":");
  1108. X      strcat (outstr, itoa('0',(long) sec, buf, 3));
  1109. X      strcat (outstr, "  ");
  1110. X      strcat (outstr, direntry.fname);
  1111. X      strcat (outstr, "\n");
  1112. X      putstr (outstr);
  1113. X
  1114. X#ifdef COMMENT
  1115. X      printf ("%8lu %3u%% %8lu  %2d %-.3s %02d %02d:%02d:%02d  ",  
  1116. X               direntry.org_size, 
  1117. X               size_factor, direntry.size_now, 
  1118. X               day, &month_list[month*3], 
  1119. X               (day && month) ?  (year+80) % 100 : 0,
  1120. X               hours, min, sec);
  1121. X      printf ("%s\n", direntry.fname);
  1122. X#endif
  1123. X
  1124. X     goto loop_again;
  1125. X   }
  1126. X#endif /* SMALL */
  1127. X
  1128. X
  1129. X   if (direntry.major_ver > 1 ||
  1130. X         (direntry.major_ver == 1 && direntry.minor_ver > 0)) {
  1131. X      prterror ('e', vermsg, direntry.fname, "\n");
  1132. X      goto loop_again;
  1133. X   }
  1134. X
  1135. X#ifdef FIXFNAME
  1136. X   /* Make the filename syntax acceptable to the host system */
  1137. X   fixfname (direntry.fname);
  1138. X#endif
  1139. X
  1140. X
  1141. X#ifndef TINY
  1142. X   /* See if this file already exists */
  1143. X
  1144. X#ifdef BIG
  1145. X   if (*option != 't' && !all)
  1146. X#else
  1147. X   if (!all)
  1148. X#endif
  1149. X   {
  1150. X
  1151. X      this_han = OPEN(direntry.fname);
  1152. X      if (this_han != -1) {
  1153. X         char ans[2];
  1154. X         char ans2[2];
  1155. X         close (this_han);
  1156. X   
  1157. X         do {
  1158. X            prterror ('m', "Overwrite ", direntry.fname, " (Yes/No/All)? ");
  1159. X            read (0, ans, 1);
  1160. X            do {
  1161. X               read (0, ans2, 1);
  1162. X            } while (*ans2 != '\n');
  1163. X         }  while (*ans != 'y' && *ans != 'Y' && 
  1164. X                   *ans != 'n' && *ans != 'N' &&
  1165. X                   *ans != 'a' && *ans != 'A');    
  1166. X   
  1167. X         if (*ans == 'a' || *ans == 'A')
  1168. X            all++;
  1169. X         if (*ans == 'n' || *ans == 'N') {
  1170. X            prterror ('m', "Skipping ", direntry.fname, "\n");
  1171. X            goto loop_again;
  1172. X         }
  1173. X      }
  1174. X   }
  1175. X#endif /* ndef TINY */
  1176. X
  1177. X
  1178. X#ifdef BIG
  1179. X   if (*option == 't')
  1180. X      this_han = -2;
  1181. X   else
  1182. X#endif
  1183. X      this_han = CREATE(direntry.fname);
  1184. X
  1185. X   if (this_han == -1) {
  1186. X      prterror ('e', "Could not open ", direntry.fname, " for output.\n");
  1187. X   } else {
  1188. X      lseek (zoo_han, direntry.offset, 0);
  1189. X      crccode = 0;      /* Initialize CRC before extraction */
  1190. X      prterror ('m', direntry.fname, " ", ((char *) 0));
  1191. X
  1192. X      if (direntry.packing_method == 0)
  1193. X         status = getfile (zoo_han, this_han, direntry.size_now);
  1194. X      else if (direntry.packing_method == 1)
  1195. X         status = lzd (zoo_han, this_han); /* uncompress */
  1196. X      else
  1197. X         prterror ('e', vermsg, direntry.fname, "\n");
  1198. X      if (status != 0) {
  1199. X         unlink(direntry.fname);
  1200. X         if (status == 1) {
  1201. X            memerr();
  1202. X         } else 
  1203. X            prterror ('e', "I/O error writing ", direntry.fname, "\n");
  1204. X      } else {
  1205. X         if (direntry.file_crc != crccode) {
  1206. X            putstr ("<--\007WARNING:  Bad CRC.\n");
  1207. X            exitstat = 1;
  1208. X         } else
  1209. X            putstr ("\n");
  1210. X      } /* end if */
  1211. X   } /* end if */
  1212. X
  1213. X#ifdef BIG
  1214. X   if (*option != 't')
  1215. X#endif
  1216. X      close (this_han);
  1217. X
  1218. Xloop_again:
  1219. X   lseek (zoo_han, next_ptr, 0); /* ..seek to next dir entry */
  1220. X} /* end while */
  1221. Xclose (zoo_han);
  1222. Xexit (exitstat);
  1223. X} /* end oozext */
  1224. X
  1225. X/*
  1226. XFunction fixfname() fixes the syntax of the supplied filename so it is
  1227. Xacceptable to the host system.  We call the standard string function 
  1228. Xstrchr(s, c) which searches a string s for a character c and returns
  1229. Xa pointer to it or returns NULL if not found.  The scheme below
  1230. Xstrips the 8th bit and changes control characters to corresponding 
  1231. Xprintable characters (e.g.  ^A becomes A).
  1232. X
  1233. XAs supplied, fixfname() is activated only if the symbol FIXFNAME
  1234. Xis defined.
  1235. X*/
  1236. X
  1237. X
  1238. X#ifdef FIXFNAME
  1239. X/* set of all characters legal for our system */
  1240. Xchar legal[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.";
  1241. X
  1242. Xchar *strchr ();
  1243. X
  1244. Xint fixfname (fname)
  1245. Xchar *fname;
  1246. X{
  1247. X   char *p;
  1248. X   for (p = fname;  *p != '\0';  p++) {
  1249. X      *p &= 0x7f;
  1250. X      if (strchr (legal, *p) == (char *) 0) {
  1251. X         *p = legal[(*p) % 26];
  1252. X      }
  1253. X   }
  1254. X}
  1255. X#endif /* FIXFNAME */
  1256. SHAR_EOF
  1257. if test 8196 -ne "`wc -c < 'oozext.c'`"
  1258. then
  1259.     echo shar: "error transmitting 'oozext.c'" '(should have been 8196 characters)'
  1260. fi
  1261. fi
  1262. echo shar: "extracting 'oozio.h'" '(1325 characters)'
  1263. if test -f 'oozio.h'
  1264. then
  1265.     echo shar: "will not over-write existing file 'oozio.h'"
  1266. else
  1267. sed 's/^X//' << \SHAR_EOF > 'oozio.h'
  1268. X/* oozio.h */
  1269. X/* Definitions for portable I/O.
  1270. X
  1271. XDefinitions are:
  1272. X
  1273. XOPEN(x)     open file x for read
  1274. XCREATE(x)   create file x for read/write
  1275. X
  1276. XNote that files opened by OPEN() and CREATE() must be opened in
  1277. Xbinary mode (not involving any LF <-> CR/LF translation).
  1278. X
  1279. XThe contents of this file are hereby released to the public domain.
  1280. X                                   -- Rahul Dhesi 1987/02/08
  1281. X*/
  1282. X
  1283. X/* MIX C compiler for CP/M. */
  1284. X#ifdef   MIXC
  1285. X#define  CREATE(x)      (iofilter(0,0), creat (x, 0))
  1286. X#define  OPEN(x)        (iofilter (0,0), open (x, 0))
  1287. X#endif
  1288. X
  1289. X/* Microsoft C 3.0 under MS-DOS */
  1290. X#ifdef   MSC
  1291. X#include <fcntl.h>
  1292. X#include <sys/types.h>
  1293. X#include <sys/stat.h>
  1294. X#include <io.h>
  1295. X#define  CREATE(x) \
  1296. X   open (x, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE)
  1297. X#define  OPEN(x)     open (x, O_RDONLY|O_BINARY)
  1298. X#endif
  1299. X
  1300. X/* Turbo C 1.0 under MS-DOS */
  1301. X#ifdef   TURBOC
  1302. X#include <fcntl.h>
  1303. X#include <sys/types.h>
  1304. X#include <sys/stat.h>
  1305. X#include <io.h>
  1306. X#define  CREATE(x) \
  1307. X   open (x, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE)
  1308. X#define  OPEN(x)     open (x, O_RDONLY|O_BINARY)
  1309. X#endif
  1310. X
  1311. X/* **IX family I/O */
  1312. X#ifdef   NIX_IO
  1313. X#include <fcntl.h>
  1314. X#include <sys/types.h>
  1315. X#include <sys/stat.h>
  1316. X#define  CREATE(x) \
  1317. X   open (x, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE)
  1318. X#define  OPEN(x)     open (x, O_RDONLY)
  1319. X#endif
  1320. SHAR_EOF
  1321. if test 1325 -ne "`wc -c < 'oozio.h'`"
  1322. then
  1323.     echo shar: "error transmitting 'oozio.h'" '(should have been 1325 characters)'
  1324. fi
  1325. fi
  1326. echo shar: "extracting 'options.h'" '(1559 characters)'
  1327. if test -f 'options.h'
  1328. then
  1329.     echo shar: "will not over-write existing file 'options.h'"
  1330. else
  1331. sed 's/^X//' << \SHAR_EOF > 'options.h'
  1332. X/* Compile-time options for Booz to allow custom versions to be built */
  1333. X
  1334. X/* 
  1335. XUse buffer sizes of at least 1024, larger if enough memory is
  1336. Xavailable.  Buffer sizes of over 8192 have not been confirmed to work.
  1337. X*/
  1338. X#define  IN_BUF_SIZE       1024
  1339. X#define  OUT_BUF_SIZE      1024
  1340. X
  1341. X/* 
  1342. XDecompression stack.  Except in pathological cases, 2000 bytes should
  1343. Xbe enough.  Rare files may need a bigger stack to decompress.
  1344. XMay be decreased to 1000 bytes if memory is tight.
  1345. X*/
  1346. X#define  STACKSIZE   2000        /* adjust to conserve memory */
  1347. X
  1348. X/* 
  1349. XDefine one of the symbols TINY, SMALL, and BIG.  Do not define more than
  1350. Xone of these symbols.  The effects are:
  1351. X
  1352. X   Symbol      Effect
  1353. X
  1354. X   TINY        A very tiny barebones version that always extracts an entire
  1355. X               archive at a time.  Should compile and run under CP/M.
  1356. X
  1357. X   SMALL       A slightly bigger version that will let the user specify
  1358. X               which files are to be extracted from the archive.  Wildcards
  1359. X               "?" and "*" are accepted in any combination.  Still quite
  1360. X               small.  Will probably compile and run under CP/M.
  1361. X
  1362. X   BIG         Does everything that the SMALL version does.  In addition, 
  1363. X               it will list and test archives.  May or may not compile 
  1364. X               and run under CP/M.
  1365. X*/
  1366. X
  1367. X/* Only one of the three following symbols should be defined */
  1368. X#define TINY
  1369. X/* #define SMALL */
  1370. X/* #define BIG */
  1371. X
  1372. X/* Define FIXFNAME to activate the fixfname() function that converts
  1373. Xfilename syntax to be acceptable to the host system */
  1374. X/* #define FIXFNAME */
  1375. SHAR_EOF
  1376. if test 1559 -ne "`wc -c < 'options.h'`"
  1377. then
  1378.     echo shar: "error transmitting 'options.h'" '(should have been 1559 characters)'
  1379. fi
  1380. fi
  1381. echo shar: "extracting 'portable.c'" '(3351 characters)'
  1382. if test -f 'portable.c'
  1383. then
  1384.     echo shar: "will not over-write existing file 'portable.c'"
  1385. else
  1386. sed 's/^X//' << \SHAR_EOF > 'portable.c'
  1387. X/* 
  1388. XThe contents of this file are hereby released to the public domain.
  1389. X                                   -- Rahul Dhesi 1987/02/08
  1390. X*/
  1391. X
  1392. Xtypedef char BYTE;      /* MUST be an 8-bit value */
  1393. X
  1394. X#include "func.h"
  1395. X#include "zoo.h"
  1396. X
  1397. Xlong to_long ();
  1398. Xint to_int ();
  1399. Xint b_to_zooh();
  1400. Xint b_to_dir();
  1401. Xint splitlong();
  1402. Xint splitint();
  1403. X
  1404. X/**********************
  1405. Xto_long() converts four consecutive bytes, in order of increasing
  1406. Xsignificance, to a long integer.  It is used to make Zoo independent of the
  1407. Xbyte order of the system.  
  1408. X*/
  1409. Xlong to_long(data)
  1410. XBYTE data[];
  1411. X{
  1412. X   int i;
  1413. X   long retval;
  1414. X   retval = ((unsigned) data[2] & 0xff) | 
  1415. X      (((unsigned) data[3] & 0xff) << 8);
  1416. X   retval <<= 16;
  1417. X   retval |= (((unsigned) data[0] & 0xff) | 
  1418. X      (((unsigned) data[1] & 0xff) << 8));
  1419. X   return (retval);
  1420. X}
  1421. X
  1422. X/**********************
  1423. Xto_int() converts two consecutive bytes, in order of increasing
  1424. Xsignificance, to an integer, in a machine-independent manner
  1425. X*/
  1426. Xint to_int(data)
  1427. XBYTE data[];
  1428. X{
  1429. X   return (int) (((unsigned) data[0] & 0xff) | 
  1430. X      ((unsigned) (data[1] & 0xff) << 8));
  1431. X}
  1432. X
  1433. X/**********************
  1434. XFunction rd_zooh() reads a Zoo archive header in a machine-dependent manner,
  1435. Xfrom a file handle.
  1436. X*/
  1437. Xint rd_zooh (header, zoo_han)
  1438. Xstruct zoo_header *header;
  1439. Xint zoo_han;
  1440. X{
  1441. X   int status;
  1442. X   BYTE bytes[SIZ_ZOOH];
  1443. X   status = read (zoo_han, (char *) bytes, SIZ_ZOOH);
  1444. X   b_to_zooh (header, bytes);
  1445. X   return (status);
  1446. X}
  1447. X
  1448. X/**********************
  1449. XFunction rd_dir() reads a directory entry in a machine-independent manner
  1450. Xfrom a handle.
  1451. X*/
  1452. Xint rd_dir(direntry, zoo_han)
  1453. Xstruct direntry *direntry;
  1454. Xint zoo_han;
  1455. X{
  1456. X   int status;
  1457. X   BYTE bytes[SIZ_DIR];
  1458. X   status = read (zoo_han, (char *) bytes, SIZ_DIR);
  1459. X   b_to_dir (direntry, bytes);
  1460. X   return (status);
  1461. X}
  1462. X
  1463. X/***********************
  1464. Xb_to_zooh() converts an array of BYTE to a zoo_header structure.
  1465. X*/
  1466. Xint b_to_zooh (zoo_header, bytes)
  1467. Xstruct zoo_header *zoo_header;
  1468. XBYTE bytes[];
  1469. X{
  1470. X   int i;
  1471. X   for (i = 0; i < SIZ_TEXT; i++)
  1472. X      zoo_header->text[i] = bytes[TEXT_I + i];
  1473. X   zoo_header->lo_tag = to_int(&bytes[ZTAG_I]);
  1474. X   zoo_header->hi_tag = to_int(&bytes[ZTAG_I+2]);
  1475. X   /* zoo_header->zoo_tag = to_long(&bytes[ZTAG_I]); */
  1476. X   zoo_header->zoo_start = to_long(&bytes[ZST_I]);
  1477. X   zoo_header->zoo_minus = to_long(&bytes[ZSTM_I]);
  1478. X   zoo_header->major_ver = bytes[MAJV_I];
  1479. X   zoo_header->minor_ver = bytes[MINV_I];
  1480. X}
  1481. X
  1482. X/* b_to_dir() converts bytes to directory entry structure */
  1483. Xint b_to_dir(direntry, bytes)
  1484. Xstruct direntry *direntry;
  1485. XBYTE bytes[];
  1486. X{
  1487. X   int i;
  1488. X   direntry->lo_tag = to_int(&bytes[DTAG_I]);
  1489. X   direntry->hi_tag = to_int(&bytes[DTAG_I+2]);
  1490. X   /* direntry->zoo_tag = to_long(&bytes[DTAG_I]); */
  1491. X   direntry->type = bytes[DTYP_I];
  1492. X   direntry->packing_method = bytes[PKM_I];
  1493. X   direntry->next = to_long(&bytes[NXT_I]);
  1494. X   direntry->offset = to_long(&bytes[OFS_I]);
  1495. X   direntry->date = to_int(&bytes[DAT_I]);
  1496. X   direntry->time = to_int(&bytes[TIM_I]);
  1497. X   direntry->file_crc = to_int(&bytes[CRC_I]);
  1498. X   direntry->org_size = to_long(&bytes[ORGS_I]);
  1499. X   direntry->size_now = to_long(&bytes[SIZNOW_I]);
  1500. X   direntry->major_ver = bytes[DMAJ_I];
  1501. X   direntry->minor_ver = bytes[DMIN_I];
  1502. X   direntry->deleted = bytes[DEL_I];
  1503. X   direntry->comment = to_long(&bytes[CMT_I]);
  1504. X   direntry->cmt_size = to_int(&bytes[CMTSIZ_I]);
  1505. X   for (i = 0; i < FNM_SIZ; i++)
  1506. X      direntry->fname[i] = bytes[FNAME_I + i];
  1507. X}
  1508. SHAR_EOF
  1509. if test 3351 -ne "`wc -c < 'portable.c'`"
  1510. then
  1511.     echo shar: "error transmitting 'portable.c'" '(should have been 3351 characters)'
  1512. fi
  1513. fi
  1514. echo shar: "extracting 'zoo.h'" '(1900 characters)'
  1515. if test -f 'zoo.h'
  1516. then
  1517.     echo shar: "will not over-write existing file 'zoo.h'"
  1518. else
  1519. sed 's/^X//' << \SHAR_EOF > 'zoo.h'
  1520. X/* zoo.h */
  1521. X
  1522. X/* 
  1523. XThe contents of this file are hereby released to the public domain.
  1524. X                                   -- Rahul Dhesi 1987/02/08
  1525. X*/
  1526. X
  1527. X#define SIZ_TEXT  20
  1528. X#define FNAMESIZE 13
  1529. X#define MAX_PACK 1
  1530. X#define LO_TAG (0xa7dc)
  1531. X#define HI_TAG (0xfdc4)
  1532. X
  1533. Xstruct zoo_header {
  1534. X   char text[SIZ_TEXT];
  1535. X   unsigned lo_tag;
  1536. X   unsigned hi_tag;
  1537. X   long zoo_start;
  1538. X   long zoo_minus;
  1539. X   char major_ver;
  1540. X   char minor_ver;
  1541. X};
  1542. X
  1543. Xstruct direntry {
  1544. X   unsigned lo_tag;
  1545. X   unsigned hi_tag;
  1546. X   char type;
  1547. X   char packing_method;       /* 0 = no packing, 1 = normal LZW */
  1548. X   long next;                 /* pos'n of next directory entry */
  1549. X   long offset;               /* position of this file */
  1550. X   unsigned int date;         /* DOS format date */
  1551. X   unsigned int time;         /* DOS format time */
  1552. X   unsigned int file_crc;     /* CRC of this file */
  1553. X   long org_size;
  1554. X   long size_now;
  1555. X   char major_ver;
  1556. X   char minor_ver;            /* minimum version needed to extract */
  1557. X   char deleted;              /* will be 1 if deleted, 0 if not */
  1558. X   long comment;              /* points to comment;  zero if none */
  1559. X   unsigned int cmt_size; /* length of comment, 0 if none */
  1560. X   char fname[FNAMESIZE]; /* filename */
  1561. X};
  1562. X
  1563. X/* offsets of items within the canonical zoo archive header */
  1564. X#define  SIZ_ZOOH 34
  1565. X#define  TEXT_I   0
  1566. X#define  ZTAG_I   20
  1567. X#define  ZST_I    24
  1568. X#define  ZSTM_I   28
  1569. X#define  MAJV_I   32
  1570. X#define  MINV_I   33
  1571. X
  1572. X/* offsets of items within the canonical directory entry structure */
  1573. X#define  SIZ_DIR  51
  1574. X#define  DTAG_I   0
  1575. X#define  DTYP_I   4
  1576. X#define  PKM_I    5
  1577. X#define  NXT_I    6
  1578. X#define  OFS_I    10 
  1579. X#define  DAT_I    14 
  1580. X#define  TIM_I    16 
  1581. X#define  CRC_I    18 
  1582. X#define  ORGS_I   20 
  1583. X#define  SIZNOW_I 24 
  1584. X#define  DMAJ_I   28 
  1585. X#define  DMIN_I   29 
  1586. X#define  DEL_I    30 
  1587. X#define  SPARE_I  31 
  1588. X#define  CMT_I    32 
  1589. X#define  CMTSIZ_I 36 
  1590. X#define  FNAME_I  38 
  1591. X
  1592. X#define  FNM_SIZ  13
  1593. SHAR_EOF
  1594. if test 1900 -ne "`wc -c < 'zoo.h'`"
  1595. then
  1596.     echo shar: "error transmitting 'zoo.h'" '(should have been 1900 characters)'
  1597. fi
  1598. fi
  1599. exit 0
  1600. #    End of shell archive
  1601. -- 
  1602. Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
  1603.