home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3609 < prev    next >
Text File  |  1991-07-10  |  49KB  |  1,619 lines

  1. Newsgroups: alt.sources
  2. Subject: zoo 2.1 source part 02/15
  3. Message-ID: <12768@bsu-cs.bsu.edu>
  4. From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
  5. Date: 10 Jul 91 08:48:26 GMT
  6.  
  7. Checksum:  837499929 (verify with "brik -cv")
  8. Submitted-by: dhesi@bsu-cs.bsu.edu
  9. Archive-name: zoo210/part02
  10.  
  11. ---- Cut Here and feed the following to sh ----
  12. #!/bin/sh
  13. # This is part 02 of zoo210
  14. # ============= comment.c ==============
  15. if test -f 'comment.c' -a X"$1" != X"-c"; then
  16.     echo 'x - skipping comment.c (File already exists)'
  17. else
  18. echo 'x - extracting comment.c (Text)'
  19. sed 's/^X//' << 'SHAR_EOF' > 'comment.c' &&
  20. #ifndef LINT
  21. static char sccsid[]="@(#) comment.c 2.14 88/01/24 12:42:13";
  22. #endif /* LINT */
  23. X
  24. /*
  25. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  26. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  27. */
  28. X
  29. #include "options.h"
  30. #include "portable.h"
  31. /* comment() */
  32. /* Updates comments */
  33. X
  34. /* buffer size for any one comment line */
  35. #define  COMMENT_LINE_SIZE 76
  36. X
  37. #define  MAX_COMMENT_SIZE  32767
  38. #include "zooio.h"
  39. #include "various.h"
  40. X
  41. #ifndef NOSIGNAL
  42. #include <signal.h>
  43. #endif
  44. X
  45. #include "zoo.h"
  46. #include "zoofns.h"
  47. #include "errors.i"
  48. X
  49. void show_comment PARMS ((struct direntry *, ZOOFILE, int, char *));
  50. void get_comment PARMS ((struct direntry *, ZOOFILE, char *));
  51. int needed PARMS ((char *, struct direntry *, struct zoo_header *));
  52. X
  53. void comment(zoo_path, option)
  54. char *zoo_path, *option;
  55. {
  56. #ifndef NOSIGNAL  
  57. T_SIGNAL (*oldsignal)();
  58. #endif
  59. ZOOFILE zoo_file;                         /* stream for open archive */
  60. long next_ptr;                            /* pointers to within archive */
  61. long this_dir_offset;                     /* pointers to within archive */
  62. struct direntry direntry;                 /* directory entry */
  63. struct zoo_header zoo_header;
  64. int matched = 0;                          /* any files matched? */
  65. unsigned int zoo_date, zoo_time;          /* for restoring archive timestamp */
  66. char whichname[PATHSIZE];                 /* which name to use */
  67. #ifdef ZOOCOMMENT
  68. int acmt = 0;                                        /* if changing archive comment */
  69. #endif
  70. X
  71. /* on entry option points to first letter */
  72. option++;                                            /* skip 'c' */
  73. #ifdef ZOOCOMMENT
  74. while (*option != '\0') {
  75. X    if (*option == 'A') {
  76. X        acmt++;                                        /* changing archive comment */
  77. X        option++;
  78. X    } else
  79. X       prterror ('f', inv_option, *option);
  80. }
  81. #else
  82. if (*option != '\0')
  83. X    prterror ('f', inv_option, *option);
  84. #endif /* ZOOCOMMENT */
  85. X
  86. if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE)
  87. X   prterror ('f', could_not_open, zoo_path);
  88. X
  89. /* save archive timestamp */
  90. #ifdef GETUTIME
  91. getutime (zoo_path, &zoo_date, &zoo_time);
  92. #else
  93. gettime (zoo_file, &zoo_date, &zoo_time);
  94. #endif
  95. X
  96. /* read header and rewrite with updated version numbers, but ask user to pack
  97. archive first if archive comment is to be added and header type is 0 */
  98. #ifdef ZOOCOMMENT
  99. if (acmt)
  100. X    rwheader (&zoo_header, zoo_file, 0);
  101. else
  102. X    rwheader (&zoo_header, zoo_file, 1);
  103. #else
  104. rwheader (&zoo_header, zoo_file, 1);
  105. #endif
  106. X
  107. #ifdef ZOOCOMMENT
  108. /* if archive comment being added, handle it and return */
  109. if (acmt) {
  110. X    void do_acmt PARMS ((struct zoo_header *, ZOOFILE, char *));
  111. X    do_acmt (&zoo_header, zoo_file, zoo_path);
  112. #ifdef NIXTIME
  113. X    zooclose (zoo_file);
  114. X    setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  115. #else
  116. X    settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  117. X    zooclose (zoo_file);
  118. #endif
  119. X    return;
  120. }
  121. #endif /* ZOOCOMMENT */
  122. X
  123. /* Loop through and add comments for matching files */
  124. while (1) {
  125. X   this_dir_offset = zootell (zoo_file);  /* save pos'n of this dir entry */
  126. X   readdir (&direntry, zoo_file, 1);      /* read directory entry */
  127. X   next_ptr = direntry.next;              /* ptr to next dir entry */
  128. X
  129. X   /* exit on end of directory chain or end of file */
  130. X   if (next_ptr == 0L || feof(stdin))
  131. X      break;
  132. X
  133. X    strcpy (whichname, fullpath (&direntry));        /* full pathname */
  134. X    add_version (whichname, &direntry);                /* add version suffix */
  135. X   /* add comments for matching non-deleted files */
  136. X   if (!direntry.deleted && needed (whichname, &direntry, &zoo_header)) {
  137. X      matched++;
  138. X      show_comment (&direntry, zoo_file, 1, whichname);
  139. X      get_comment (&direntry, zoo_file, whichname);
  140. X      zooseek (zoo_file, this_dir_offset, 0);
  141. #ifndef NOSIGNAL
  142. X      oldsignal = signal (SIGINT, SIG_IGN);
  143. #endif
  144. X      fwr_dir (&direntry, zoo_file);
  145. #ifndef NOSIGNAL
  146. X      signal (SIGINT, oldsignal);
  147. #endif
  148. X   }
  149. X   zooseek (zoo_file, next_ptr, 0);   /* ..seek to next dir entry */
  150. } /* end while */
  151. X
  152. #ifdef NIXTIME
  153. zooclose (zoo_file);
  154. setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  155. #else
  156. settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  157. zooclose (zoo_file);
  158. #endif
  159. X
  160. if (!matched)
  161. X   printf ("Zoo:  %s", no_match);
  162. } /* comment */
  163. X
  164. /* show_comment() */
  165. /* shows comment on screen.  If show=1, says "Current comment is..." */
  166. X
  167. void show_comment (direntry, zoo_file, show, name)
  168. struct direntry *direntry;
  169. ZOOFILE zoo_file;
  170. int show;
  171. char *name;       /* name of file for which comment is being added */
  172. {
  173. X   if (direntry->cmt_size != 0) {
  174. X      unsigned int i;
  175. X      char ch;
  176. X      int newline = 1;
  177. X      zooseek (zoo_file, direntry->comment, 0);   
  178. X      if (show)
  179. X         printf ("Current comment for %s is:\n", name);
  180. X      for (i = 0; i < direntry->cmt_size; i++) {/* show it */
  181. X         ch = zgetc (zoo_file) & 0x7f;          /* 7 bits only */
  182. X         if (newline)
  183. X            printf (" |");    /* indent and mark comment lines thus */
  184. X         zputchar (ch);
  185. X         if (ch == '\n')
  186. X            newline = 1;
  187. X         else
  188. X            newline = 0;
  189. X      }
  190. X      if (!newline)              /* always terminate with newline */
  191. X         zputchar ('\n');
  192. X   }
  193. } /* show_comment() */
  194. X
  195. X
  196. /* get_comment() */
  197. /* Shows user old comment and updates it */
  198. X
  199. /* INPUT:
  200. X   direntry points to current directory entry.
  201. X   zoo_file is archive file.
  202. X   this_path is full pathname of file being updated/added.
  203. X
  204. X   OUTPUT:
  205. X   Comment is added to file and supplied directory entry is updated
  206. X   with comment size and seek position but directory entry is
  207. X   not written to file.  Exceptions:  If RETURN is hit as first line,
  208. X   previous comment is left unchanged.  If /END is hit, previous
  209. X   comment is superseded, even if new comment is null.
  210. */
  211. X
  212. char cmt_prompt[]="[Enter %scomment for %s then type /END]\n";
  213. X
  214. void get_comment (direntry, zoo_file, this_path)  /* update comment */
  215. register struct direntry *direntry;
  216. ZOOFILE zoo_file;
  217. char *this_path;
  218. {
  219. X   unsigned int line_count = 0;        /* count of new comment lines */
  220. X
  221. X   zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  222. #if 0
  223. X   fprintf (stderr, "[Enter comment for %s then type /END]\n", this_path);
  224. #else
  225. X   fprintf (stderr, cmt_prompt, "", this_path);
  226. #endif
  227. X   while (1) {
  228. X      char cmt_line[COMMENT_LINE_SIZE];
  229. X      int cmt_size;
  230. X      if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  231. X         break;
  232. X      line_count++;
  233. X      if (line_count == 1) {                 /* first line typed */
  234. X         if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  235. X            break;
  236. X         direntry->comment = zootell (zoo_file);
  237. X         direntry->cmt_size = 0;
  238. X      }
  239. X      if (!str_icmp (cmt_line, "/end\n"))
  240. X         break;
  241. X      cmt_size = strlen (cmt_line);
  242. X      if (MAX_COMMENT_SIZE - direntry->cmt_size > cmt_size) {
  243. X         direntry->cmt_size += (unsigned int) cmt_size;
  244. X         if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
  245. X            prterror ('f', disk_full);
  246. X      }
  247. X   } /* end while */
  248. } /* get_comment() */
  249. X
  250. #ifdef ZOOCOMMENT
  251. /*
  252. do_acmt() updates archive comment by showing it to user and 
  253. requesting a new one.  Typed input terminates as with file comment,
  254. i.e., empty initial line leaves comment unchanged, case-insensitive
  255. "/end" terminates input comment.
  256. */
  257. void do_acmt (zoo_header, zoo_file, zoo_path)
  258. struct zoo_header *zoo_header;
  259. ZOOFILE zoo_file;
  260. char *zoo_path;
  261. {
  262. X   unsigned int line_count = 0;        /* count of new comment lines */
  263. X    void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
  264. X
  265. X    show_acmt (zoo_header, zoo_file, 1);    /* show current archive comment */
  266. X   zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  267. #if 0
  268. X   fprintf (stderr, "[Enter archive comment for %s then type /END]\n", 
  269. X                            zoo_path);
  270. #else
  271. X   fprintf (stderr, cmt_prompt, "archive ", zoo_path);
  272. #endif
  273. X
  274. X   while (1) {
  275. X      char cmt_line[COMMENT_LINE_SIZE];
  276. X      int cmt_size;
  277. X      if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  278. X         break;
  279. X      line_count++;
  280. X      if (line_count == 1) {                 /* first line typed */
  281. X         if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  282. X            break;
  283. X         zoo_header->acmt_pos = zootell (zoo_file);
  284. X         zoo_header->acmt_len = 0;
  285. X      }
  286. X      if (!str_icmp (cmt_line, "/end\n"))
  287. X         break;
  288. X      cmt_size = strlen (cmt_line);
  289. X      if (MAX_COMMENT_SIZE - zoo_header->acmt_len > cmt_size) {
  290. X         zoo_header->acmt_len += (unsigned int) cmt_size;
  291. X         if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
  292. X            prterror ('f', disk_full);
  293. X      }
  294. X   } /* end while */
  295. X    zooseek (zoo_file, 0L, 0);                    /* seek back to beginning */
  296. X    fwr_zooh (zoo_header, zoo_file);            /* write update zoo_header */
  297. } /* do_acmt() */
  298. #endif /* ZOOCOMMENT */
  299. X
  300. /* Prints archive comment.  If show==1, says "Current archive comment is:" */
  301. void show_acmt (zoo_header, zoo_file, show)
  302. struct zoo_header *zoo_header;
  303. ZOOFILE zoo_file;
  304. int show;
  305. {
  306. X   if (zoo_header->zoo_start != FIXED_OFFSET && zoo_header->acmt_len > 0) {
  307. X      unsigned int i;
  308. X      char ch;
  309. X      int newline = 1;
  310. X      zooseek (zoo_file, zoo_header->acmt_pos, 0);   
  311. X        if (show)
  312. X          printf ("Current archive comment is:\n");
  313. X      for (i = 0; i < zoo_header->acmt_len; i++) {/* show it */
  314. X         ch = zgetc (zoo_file) & 0x7f;          /* 7 bits only */
  315. X         if (newline)
  316. X            printf (">> ");        /* indent and mark comment lines thus */
  317. X         zputchar (ch);
  318. X         if (ch == '\n')
  319. X            newline = 1;
  320. X         else
  321. X            newline = 0;
  322. X      }
  323. X      if (!newline)              /* always terminate with newline */
  324. X         zputchar ('\n');
  325. X   }
  326. } /* show_acmt() */
  327. SHAR_EOF
  328. chmod 0644 comment.c ||
  329. echo 'restore of comment.c failed'
  330. Wc_c="`wc -c < 'comment.c'`"
  331. test 9595 -eq "$Wc_c" ||
  332.     echo 'comment.c: original size 9595, current size' "$Wc_c"
  333. fi
  334. # ============= crcdefs.c ==============
  335. if test -f 'crcdefs.c' -a X"$1" != X"-c"; then
  336.     echo 'x - skipping crcdefs.c (File already exists)'
  337. else
  338. echo 'x - extracting crcdefs.c (Text)'
  339. sed 's/^X//' << 'SHAR_EOF' > 'crcdefs.c' &&
  340. #ifndef LINT
  341. static char sccsid[]="@(#) crcdefs.c 2.1 87/12/25 12:21:58";
  342. #endif /* LINT */
  343. X
  344. #include "options.h"
  345. X
  346. /*
  347. Global definitions for CRC calculation.  I claim no copyright over
  348. the contents of this file.
  349. X
  350. X                                  -- Rahul Dhesi 1987/08/27
  351. */
  352. X
  353. unsigned int crccode;
  354. unsigned int crctab[] = {
  355. X   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
  356. X    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 
  357. X    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0F00, 0xcFc1, 0xce81, 0x0e40, 
  358. X    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 
  359. X    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 
  360. X    0x1e00, 0xdec1, 0xdF81, 0x1F40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 
  361. X    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 
  362. X    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 
  363. X    0xF001, 0x30c0, 0x3180, 0xF141, 0x3300, 0xF3c1, 0xF281, 0x3240, 
  364. X   0x3600, 0xF6c1, 0xF781, 0x3740, 0xF501, 0x35c0, 0x3480, 0xF441, 
  365. X    0x3c00, 0xFcc1, 0xFd81, 0x3d40, 0xFF01, 0x3Fc0, 0x3e80, 0xFe41, 
  366. X    0xFa01, 0x3ac0, 0x3b80, 0xFb41, 0x3900, 0xF9c1, 0xF881, 0x3840, 
  367. X    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 
  368. X    0xee01, 0x2ec0, 0x2F80, 0xeF41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 
  369. X    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 
  370. X    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 
  371. X    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 
  372. X    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 
  373. X   0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaF01, 0x6Fc0, 0x6e80, 0xae41, 
  374. X    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 
  375. X    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 
  376. X    0xbe01, 0x7ec0, 0x7F80, 0xbF41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 
  377. X    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 
  378. X    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 
  379. X    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 
  380. X    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 
  381. X    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5F00, 0x9Fc1, 0x9e81, 0x5e40, 
  382. X   0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 
  383. X    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 
  384. X    0x4e00, 0x8ec1, 0x8F81, 0x4F40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 
  385. X    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 
  386. X    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 
  387. };
  388. SHAR_EOF
  389. chmod 0644 crcdefs.c ||
  390. echo 'restore of crcdefs.c failed'
  391. Wc_c="`wc -c < 'crcdefs.c'`"
  392. test 2446 -eq "$Wc_c" ||
  393.     echo 'crcdefs.c: original size 2446, current size' "$Wc_c"
  394. fi
  395. # ============= debug.h ==============
  396. if test -f 'debug.h' -a X"$1" != X"-c"; then
  397.     echo 'x - skipping debug.h (File already exists)'
  398. else
  399. echo 'x - extracting debug.h (Text)'
  400. sed 's/^X//' << 'SHAR_EOF' > 'debug.h' &&
  401. /* @(#) debug.h 2.1 87/12/25 12:22:02 */
  402. X
  403. /* 
  404. The contents of this file are hereby released to the public domain.
  405. X
  406. X                           -- Rahul Dhesi 1986/11/14
  407. X
  408. defines conditional function calls 
  409. X
  410. Usage:  The statement
  411. X
  412. X   debug((printf("y = %d\n", y)))
  413. X
  414. may be placed anywhere where two or more statements could be used.  It will 
  415. print the value of y at that point.
  416. X
  417. Conditional compilation:
  418. X
  419. X   if DEBUG is defined
  420. X      define the macro debug(X) to execute statement X
  421. X   else
  422. X      define the macro debug(X) to be null
  423. X   endif
  424. */
  425. X
  426. #ifdef DEBUG
  427. #define  debug(x)    x;
  428. #else
  429. #define  debug(x)
  430. #endif
  431. X
  432. SHAR_EOF
  433. chmod 0644 debug.h ||
  434. echo 'restore of debug.h failed'
  435. Wc_c="`wc -c < 'debug.h'`"
  436. test 615 -eq "$Wc_c" ||
  437.     echo 'debug.h: original size 615, current size' "$Wc_c"
  438. fi
  439. # ============= decode.c ==============
  440. if test -f 'decode.c' -a X"$1" != X"-c"; then
  441.     echo 'x - skipping decode.c (File already exists)'
  442. else
  443. echo 'x - extracting decode.c (Text)'
  444. sed 's/^X//' << 'SHAR_EOF' > 'decode.c' &&
  445. /*$Source: /usr/home/dhesi/zoo/RCS/decode.c,v $*/
  446. /*$Id: decode.c,v 1.6 91/07/09 01:39:49 dhesi Exp $*/
  447. /***********************************************************
  448. X    decode.c
  449. X
  450. Adapted from "ar" archiver written by Haruhiko Okumura.
  451. ***********************************************************/
  452. X
  453. #include "options.h"
  454. #include "zoo.h"
  455. #include "ar.h"
  456. #include "lzh.h"
  457. X
  458. extern int decoded;        /* from huf.c */
  459. X
  460. static int j;  /* remaining bytes to copy */
  461. X
  462. void decode_start()
  463. {
  464. X    huf_decode_start();
  465. X    j = 0;
  466. X    decoded = 0;
  467. }
  468. X
  469. /*
  470. decodes; returns no. of chars decoded 
  471. */
  472. X
  473. int decode(count, buffer)
  474. uint count;
  475. uchar buffer[];
  476. X    /* The calling function must keep the number of
  477. X       bytes to be processed.  This function decodes
  478. X       either 'count' bytes or 'DICSIZ' bytes, whichever
  479. X       is smaller, into the array 'buffer[]' of size
  480. X       'DICSIZ' or more.
  481. X       Call decode_start() once for each new file
  482. X       before calling this function. */
  483. {
  484. X    static uint i;
  485. X    uint r, c;
  486. X
  487. X    r = 0;
  488. X    while (--j >= 0) {
  489. X        buffer[r] = buffer[i];
  490. X        i = (i + 1) & (DICSIZ - 1);
  491. X        if (++r == count)
  492. X            return r;
  493. X    }
  494. X    for ( ; ; ) {
  495. X        c = decode_c();
  496. X        if (decoded)
  497. X            return r;
  498. X        if (c <= UCHAR_MAX) {
  499. X            buffer[r] = c;
  500. X            if (++r == count) 
  501. X                return r;
  502. X        } else {
  503. X            j = c - (UCHAR_MAX + 1 - THRESHOLD);
  504. X            i = (r - decode_p() - 1) & (DICSIZ - 1);
  505. X            while (--j >= 0) {
  506. X                buffer[r] = buffer[i];
  507. X                i = (i + 1) & (DICSIZ - 1);
  508. X                if (++r == count)
  509. X                    return r;
  510. X            }
  511. X        }
  512. X    }
  513. }
  514. SHAR_EOF
  515. chmod 0644 decode.c ||
  516. echo 'restore of decode.c failed'
  517. Wc_c="`wc -c < 'decode.c'`"
  518. test 1444 -eq "$Wc_c" ||
  519.     echo 'decode.c: original size 1444, current size' "$Wc_c"
  520. fi
  521. # ============= descrip.mms ==============
  522. if test -f 'descrip.mms' -a X"$1" != X"-c"; then
  523.     echo 'x - skipping descrip.mms (File already exists)'
  524. else
  525. echo 'x - extracting descrip.mms (Text)'
  526. sed 's/^X//' << 'SHAR_EOF' > 'descrip.mms' &&
  527. # derived from: @(#) descrip.mms 2.2 88/01/09 12:10:49
  528. # $Source: /usr/home/dhesi/zoo/RCS/descrip.mms,v $
  529. # $Id: descrip.mms,v 1.9 91/07/07 14:58:21 dhesi Exp $
  530. #Make Zoo for VAX/VMS
  531. #
  532. #The contents of this makefile are hereby released to the public domain.
  533. #                                  -- Rahul Dhesi 1991/07/06
  534. X
  535. CC = cc
  536. CFLAGS =
  537. EXTRA = /define=(BIG_MEM,NDEBUG,VMS)
  538. ldswitch =
  539. X
  540. #List of all object files created for Zoo
  541. ZOOOBJS = addbfcrc.obj, addfname.obj, basename.obj, comment.obj,  -
  542. X crcdefs.obj, decode.obj, encode.obj, getfile.obj, huf.obj,  -
  543. X io.obj, lzc.obj, lzd.obj, lzh.obj, machine.obj, makelist.obj,  -
  544. X maketbl.obj, maketree.obj, misc.obj, misc2.obj, needed.obj,  -
  545. X nextfile.obj, options.obj, parse.obj, portable.obj, prterror.obj,  -
  546. X version.obj, vmstime.obj, zoo.obj, zooadd.obj, zooadd2.obj,  -
  547. X zoodel.obj, zooext.obj, zoolist.obj, zoopack.obj
  548. X
  549. FIZOBJS = fiz.obj, addbfcrc.obj, portable.obj, crcdefs.obj
  550. X
  551. BILFOBJS = bilf.obj
  552. X
  553. .c.obj :
  554. X    $(CC) $(CFLAGS) $(EXTRA) $*.c
  555. X
  556. zoo.exe : $(ZOOOBJS)
  557. X    link/executable=zoo.exe $(ldswitch) $(ZOOOBJS), options/opt
  558. X
  559. # bigger but perhaps more (less?) portable across machines -- 
  560. # no shared libraries
  561. zoobig.exe : $(ZOOOBJS)
  562. X    link/executable=zoobig.exe $(ldswitch) $(ZOOOBJS)
  563. X
  564. fiz : $(FIZOBJS)
  565. X    link/executable=fiz.exe $(ldswitch) $(FIZOBJS), options/opt
  566. X
  567. bilf : $(BILFOBJS)
  568. X    link/executable=bilf.exe $(ldswitch) $(BILFOBJS), options/opt
  569. X
  570. #######################################################################
  571. # DEPENDENCIES -- not guaranteed to be up-to-date
  572. #######################################################################
  573. X
  574. addbfcrc.obj : options.h
  575. addfname.obj : options.h various.h zoo.h zoofns.h zooio.h
  576. addfname.obj : zoomem.h
  577. basename.obj : assert.h debug.h options.h parse.h various.h
  578. basename.obj : zoo.h zoofns.h zooio.h
  579. comment.obj : errors.i options.h portable.h various.h
  580. comment.obj : zoo.h zoofns.h zooio.h
  581. crcdefs.obj : options.h
  582. decode.obj : ar.h lzh.h options.h zoo.h
  583. encode.obj : ar.h errors.i lzh.h
  584. encode.obj : options.h zoo.h
  585. fiz.obj : options.h portable.h various.h zoo.h zoofns.h
  586. fiz.obj : zooio.h
  587. getfile.obj : options.h various.h zoo.h zoofns.h zooio.h
  588. getfile.obj : zoomem.h
  589. huf.obj : ar.h errors.i lzh.h options.h zoo.h
  590. io.obj : ar.h errors.i lzh.h options.h portable.h zoo.h
  591. io.obj : zooio.h
  592. lzc.obj : assert.h debug.h lzconst.h options.h various.h
  593. lzc.obj : zoo.h zoofns.h zooio.h zoomem.h
  594. lzd.obj : assert.h debug.h lzconst.h options.h various.h
  595. lzd.obj : zoo.h zoofns.h zooio.h zoomem.h
  596. lzh.obj : ar.h errors.i options.h zoo.h
  597. machine.obj : options.h various.h zoo.h zoofns.h zooio.h
  598. makelist.obj : assert.h debug.h errors.i options.h
  599. makelist.obj : portable.h various.h zoo.h zoofns.h zooio.h
  600. maketbl.obj : ar.h lzh.h options.h zoo.h
  601. maketree.obj : ar.h lzh.h options.h zoo.h
  602. misc.obj : errors.i options.h portable.h various.h zoo.h zoofns.h zooio.h
  603. misc2.obj : errors.i options.h portable.h various.h zoo.h
  604. misc2.obj : zoofns.h zooio.h zoomem.h
  605. msdos.obj : errors.i options.h zoo.h zoofns.h zooio.h
  606. needed.obj : debug.h options.h portable.h various.h zoo.h
  607. needed.obj : zoofns.h zooio.h
  608. nextfile.obj : options.h various.h zoo.h
  609. options.obj : errors.i options.h various.h zoo.h zoofns.h
  610. options.obj : zooio.h
  611. parse.obj : assert.h options.h parse.h various.h zoo.h
  612. parse.obj : zoofns.h zooio.h
  613. portable.obj : assert.h debug.h machine.h options.h
  614. portable.obj : portable.h various.h zoo.h zoofns.h zooio.h
  615. prterror.obj : options.h various.h
  616. prterror.obj : zoofns.h zooio.h
  617. zoo.obj : errors.i options.h various.h zoo.h zoofns.h
  618. zoo.obj : zooio.h zoomem.h
  619. zooadd.obj : debug.h errors.i options.h parse.h portable.h
  620. zooadd.obj : various.h zoo.h zoofns.h zooio.h zoomem.h
  621. zooadd2.obj : assert.h debug.h errors.i options.h parse.h
  622. zooadd2.obj : various.h zoo.h zoofns.h zooio.h
  623. zoodel.obj : errors.i options.h portable.h various.h zoo.h zoofns.h zooio.h
  624. zooext.obj : errors.i machine.h options.h parse.h portable.h various.h zoo.h
  625. zooext.obj : zoofns.h zooio.h
  626. zoofilt.obj : options.h
  627. zoolist.obj : errors.i options.h portable.h various.h zoo.h
  628. zoolist.obj : zoofns.h zooio.h zoomem.h
  629. zoopack.obj : errors.i options.h portable.h various.h
  630. zoopack.obj : zoo.h zoofns.h zooio.h
  631. SHAR_EOF
  632. chmod 0644 descrip.mms ||
  633. echo 'restore of descrip.mms failed'
  634. Wc_c="`wc -c < 'descrip.mms'`"
  635. test 4173 -eq "$Wc_c" ||
  636.     echo 'descrip.mms: original size 4173, current size' "$Wc_c"
  637. fi
  638. # ============= encode.c ==============
  639. if test -f 'encode.c' -a X"$1" != X"-c"; then
  640.     echo 'x - skipping encode.c (File already exists)'
  641. else
  642. echo 'x - extracting encode.c (Text)'
  643. sed 's/^X//' << 'SHAR_EOF' > 'encode.c' &&
  644. /*$Source: /usr/home/dhesi/zoo/RCS/encode.c,v $*/
  645. /*$Id: encode.c,v 1.41 91/07/09 01:39:47 dhesi Exp $*/
  646. X
  647. /*
  648. Adapted from "ar" archiver written by Haruhiko Okumura.
  649. */
  650. X
  651. #include "options.h"
  652. #include "zoo.h"
  653. #include "ar.h"
  654. #include "lzh.h"
  655. X
  656. extern void prterror();
  657. extern char *out_buf_adr;
  658. X
  659. #include <assert.h>
  660. X
  661. #ifdef ANSI_HDRS
  662. # include <stdlib.h>
  663. # include <string.h>
  664. #endif
  665. X
  666. #include "errors.i"
  667. X
  668. FILE *lzh_infile;
  669. FILE *lzh_outfile;
  670. X
  671. /*
  672. sliding dictionary with percolating update
  673. */
  674. X
  675. #define PERCOLATE  1
  676. #define NIL        0
  677. #define MAX_HASH_VAL (3 * DICSIZ + (DICSIZ / 512 + 1) * UCHAR_MAX)
  678. X
  679. typedef short node;
  680. X
  681. static uchar *text, *childcount;
  682. static node pos, matchpos, avail,
  683. X    *position, *parent, *prev, *next = NULL;
  684. static int remainder, matchlen;
  685. X
  686. #if MAXMATCH <= (UCHAR_MAX + 1)
  687. X    static uchar *level;
  688. # define T_LEVEL  uchar *
  689. #else
  690. X    static ushort *level;
  691. # define T_LEVEL  ushort *
  692. #endif
  693. X
  694. static void allocate_memory()
  695. {
  696. X    if (next != NULL) return;
  697. X    /* text = (uchar *) malloc(DICSIZ * 2 + MAXMATCH); */
  698. X    text = (uchar *) out_buf_adr; /* reuse I/O buffer used elsewhere */
  699. X    level      = (T_LEVEL) malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*level));
  700. X    childcount = (uchar *)malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*childcount));
  701. #ifdef PERCOLATE
  702. X      position = (node *) malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*position));
  703. #else
  704. X      position = (node *) malloc(DICSIZ * sizeof(*position));
  705. #endif
  706. X    parent     = (node *) malloc(DICSIZ * 2 * sizeof(*parent));
  707. X    prev       = (node *) malloc(DICSIZ * 2 * sizeof(*prev));
  708. X    next       = (node *) malloc((MAX_HASH_VAL + 1) * sizeof(*next));
  709. X    if (next == NULL) prterror('f', no_memory);
  710. }
  711. X
  712. static void init_slide()
  713. {
  714. X    node i;
  715. X
  716. X    for (i = DICSIZ; i <= DICSIZ + UCHAR_MAX; i++) {
  717. X        level[i] = 1;
  718. #ifdef PERCOLATE
  719. X            position[i] = NIL;  /* sentinel */
  720. #endif
  721. X    }
  722. X    for (i = DICSIZ; i < DICSIZ * 2; i++) parent[i] = NIL;
  723. X    avail = 1;
  724. X    for (i = 1; i < DICSIZ - 1; i++) next[i] = i + 1;
  725. X    next[DICSIZ - 1] = NIL;
  726. X    for (i = DICSIZ * 2; i <= MAX_HASH_VAL; i++) next[i] = NIL;
  727. }
  728. X
  729. #define HASH(p, c) ((p) + ((c) << (DICBIT - 9)) + DICSIZ * 2)
  730. X
  731. static node child(q, c)
  732. node q;
  733. uchar c;
  734. X    /* q's child for character c (NIL if not found) */
  735. {
  736. X    node r;
  737. X
  738. X    r = next[HASH(q, c)];
  739. X    parent[NIL] = q;  /* sentinel */
  740. X    while (parent[r] != q) r = next[r];
  741. X    return r;
  742. }
  743. X
  744. static void makechild(q, c, r)
  745. node q;
  746. uchar c;
  747. node r;
  748. X    /* Let r be q's child for character c. */
  749. {
  750. X    node h, t;
  751. X
  752. X    h = HASH(q, c);
  753. X    t = next[h];  next[h] = r;  next[r] = t;
  754. X    prev[t] = r;  prev[r] = h;
  755. X    parent[r] = q;  childcount[q]++;
  756. }
  757. X
  758. void split(old)
  759. node old;
  760. {
  761. X    node new, t;
  762. X
  763. X    new = avail;  avail = next[new];  childcount[new] = 0;
  764. X    t = prev[old];  prev[new] = t;  next[t] = new;
  765. X    t = next[old];  next[new] = t;  prev[t] = new;
  766. X    parent[new] = parent[old];
  767. X    level[new] = matchlen;
  768. X    position[new] = pos;
  769. X    makechild(new, text[matchpos + matchlen], old);
  770. X    makechild(new, text[pos + matchlen], pos);
  771. }
  772. X
  773. static void insert_node()
  774. {
  775. X    node q, r, j, t;
  776. X    uchar c, *t1, *t2;
  777. X
  778. X    if (matchlen >= 4) {
  779. X        matchlen--;
  780. X        r = (matchpos + 1) | DICSIZ;
  781. X        while ((q = parent[r]) == NIL) r = next[r];
  782. X        while (level[q] >= matchlen) {
  783. X            r = q;  q = parent[q];
  784. X        }
  785. #ifdef PERCOLATE
  786. X            t = q;
  787. X            while (position[t] < 0) {
  788. X                position[t] = pos;  t = parent[t];
  789. X            }
  790. X            if (t < DICSIZ) position[t] = pos | PERC_FLAG;
  791. #else
  792. X            t = q;
  793. X            while (t < DICSIZ) {
  794. X                position[t] = pos;  t = parent[t];
  795. X            }
  796. #endif
  797. X    } else {
  798. X        q = text[pos] + DICSIZ;  c = text[pos + 1];
  799. X        if ((r = child(q, c)) == NIL) {
  800. X            makechild(q, c, pos);  matchlen = 1;
  801. X            return;
  802. X        }
  803. X        matchlen = 2;
  804. X    }
  805. X    for ( ; ; ) {
  806. X        if (r >= DICSIZ) {
  807. X            j = MAXMATCH;  matchpos = r;
  808. X        } else {
  809. X            j = level[r];
  810. X            matchpos = position[r] & ~PERC_FLAG;
  811. X        }
  812. X        if (matchpos >= pos) matchpos -= DICSIZ;
  813. X        t1 = &text[pos + matchlen];  t2 = &text[matchpos + matchlen];
  814. X        while (matchlen < j) {
  815. X            if (*t1 != *t2) {  split(r);  return;  }
  816. X            matchlen++;  t1++;  t2++;
  817. X        }
  818. X        if (matchlen >= MAXMATCH) break;
  819. X        position[r] = pos;
  820. X        q = r;
  821. X        if ((r = child(q, *t1)) == NIL) {
  822. X            makechild(q, *t1, pos);  return;
  823. X        }
  824. X        matchlen++;
  825. X    }
  826. X    t = prev[r];  prev[pos] = t;  next[t] = pos;
  827. X    t = next[r];  next[pos] = t;  prev[t] = pos;
  828. X    parent[pos] = q;  parent[r] = NIL;
  829. X    next[r] = pos;  /* special use of next[] */
  830. }
  831. X
  832. static void delete_node()
  833. {
  834. #ifdef PERCOLATE
  835. X        node q, r, s, t, u;
  836. #else
  837. X        node r, s, t, u;
  838. #endif
  839. X
  840. X    if (parent[pos] == NIL) return;
  841. X    r = prev[pos];  s = next[pos];
  842. X    next[r] = s;  prev[s] = r;
  843. X    r = parent[pos];  parent[pos] = NIL;
  844. X    if (r >= DICSIZ || --childcount[r] > 1) return;
  845. #ifdef PERCOLATE
  846. X        t = position[r] & ~PERC_FLAG;
  847. #else
  848. X        t = position[r];
  849. #endif
  850. X    if (t >= pos) t -= DICSIZ;
  851. #ifdef PERCOLATE
  852. X        s = t;  q = parent[r];
  853. X        while ((u = position[q]) & PERC_FLAG) {
  854. X            u &= ~PERC_FLAG;  if (u >= pos) u -= DICSIZ;
  855. X            if (u > s) s = u;
  856. X            position[q] = (s | DICSIZ);  q = parent[q];
  857. X        }
  858. X        if (q < DICSIZ) {
  859. X            if (u >= pos) u -= DICSIZ;
  860. X            if (u > s) s = u;
  861. X            position[q] = s | DICSIZ | PERC_FLAG;
  862. X        }
  863. #endif
  864. X    s = child(r, text[t + level[r]]);
  865. X    t = prev[s];  u = next[s];
  866. X    next[t] = u;  prev[u] = t;
  867. X    t = prev[r];  next[t] = s;  prev[s] = t;
  868. X    t = next[r];  prev[t] = s;  next[s] = t;
  869. X    parent[s] = parent[r];  parent[r] = NIL;
  870. X    next[r] = avail;  avail = r;
  871. }
  872. X
  873. static void get_next_match()
  874. {
  875. X    int n;
  876. X
  877. X    remainder--;
  878. X    if (++pos == DICSIZ * 2) {
  879. #ifdef CHECK_BREAK
  880. X        check_break();
  881. #endif
  882. X        (void) MOVE_LEFT((char *) &text[0], (char *) &text[DICSIZ], DICSIZ + MAXMATCH);
  883. X        n = fread_crc(&text[DICSIZ + MAXMATCH], DICSIZ, lzh_infile);
  884. X        remainder += n;  pos = DICSIZ;  
  885. #ifdef SHOW_DOTS
  886. X        (void) putc('.', stderr);
  887. X        (void) fflush(stderr);
  888. #endif
  889. X    }
  890. X    delete_node();  insert_node();
  891. }
  892. X
  893. /* read from infile, compress, write to outfile */
  894. void encode(infile, outfile)
  895. FILE *infile;
  896. FILE *outfile;
  897. {
  898. X    int lastmatchlen;
  899. X    node lastmatchpos;
  900. X
  901. X    /* make input/output files visible to other functions */
  902. X    lzh_infile = infile;
  903. X    lzh_outfile = outfile;
  904. X
  905. X    allocate_memory();  init_slide();  huf_encode_start();
  906. X    remainder = fread_crc(&text[DICSIZ], DICSIZ + MAXMATCH, lzh_infile);
  907. #ifdef SHOW_DOTS
  908. X    (void) putc('.', stderr);
  909. X    (void) fflush(stderr);
  910. #endif
  911. X    matchlen = 0;
  912. X    pos = DICSIZ;  insert_node();
  913. X    if (matchlen > remainder) matchlen = remainder;
  914. X    while (remainder > 0 && ! unpackable) {
  915. X        lastmatchlen = matchlen;  lastmatchpos = matchpos;
  916. X        get_next_match();
  917. X        if (matchlen > remainder) matchlen = remainder;
  918. X        if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
  919. #if 0
  920. X            d1log("%c", text[pos-1]);
  921. #endif
  922. X            output(text[pos - 1], 0);
  923. X        } else {
  924. #if 0
  925. X        (void) putc('.', stderr); (void) fflush(stderr);
  926. #endif
  927. X
  928. #if 0
  929. X            {
  930. X                int i; 
  931. X                d1log("\nlastmatchlen=%d, pos=%d, lastmatchpos=%d",
  932. X                            lastmatchlen, pos, lastmatchpos);
  933. X                d1log("\n[%d: ", (int) lastmatchlen);
  934. X                for (i = 0;  i < lastmatchlen;  i++)
  935. X                    d1log("%c", text[lastmatchpos + i]);
  936. X                d1log("]\n");
  937. X            }
  938. #endif
  939. X
  940. X            output((uint) (lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD)),
  941. X                   (uint) ((pos - lastmatchpos - 2) & (DICSIZ - 1)));
  942. X            while (--lastmatchlen > 0) get_next_match();
  943. X            if (matchlen > remainder) matchlen = remainder;
  944. X        }
  945. X    }
  946. X    huf_encode_end();
  947. }
  948. X
  949. #ifdef NEED_MEMMOVE
  950. /* like memmove, but for moving stuff LEFT (downwards in memory) only!! */
  951. void move_left(dest, src, len)
  952. char *dest;
  953. char *src;
  954. int len;
  955. {
  956. X    while (len-- > 0)
  957. X        *dest++ = *src++;
  958. }
  959. #endif /* NEED_MEMMOVE */
  960. SHAR_EOF
  961. chmod 0644 encode.c ||
  962. echo 'restore of encode.c failed'
  963. Wc_c="`wc -c < 'encode.c'`"
  964. test 7292 -eq "$Wc_c" ||
  965.     echo 'encode.c: original size 7292, current size' "$Wc_c"
  966. fi
  967. # ============= errors.i ==============
  968. if test -f 'errors.i' -a X"$1" != X"-c"; then
  969.     echo 'x - skipping errors.i (File already exists)'
  970. else
  971. echo 'x - extracting errors.i (Text)'
  972. sed 's/^X//' << 'SHAR_EOF' > 'errors.i' &&
  973. /* @(#) errors.i 2.4 88/01/31 12:32:46 */
  974. X
  975. /*
  976. The contents of this file are hereby released to the public domain.
  977. X
  978. X                           -- Rahul Dhesi 1986/11/14
  979. */
  980. X
  981. /* defines all the errors as externs.  Declarations must be
  982. equivalent to those in prterror.c */
  983. X
  984. /* These declarations must be equivalent to those in prterror.c */
  985. extern char no_match[];
  986. extern char failed_consistency[];
  987. extern char invalid_header[];
  988. extern char internal_error[];
  989. extern char disk_full[];
  990. extern char bad_directory[];
  991. extern char no_memory[];
  992. extern char too_many_files[];
  993. extern char packfirst[];
  994. extern char garbled[];
  995. extern char start_ofs[];
  996. X
  997. #ifndef OOZ
  998. extern char wrong_version[];
  999. extern char cant_process[];
  1000. extern char option_ignored[];
  1001. extern char inv_option[];
  1002. extern char bad_crc[];
  1003. #endif
  1004. X
  1005. extern char could_not_open[];
  1006. X
  1007. SHAR_EOF
  1008. chmod 0644 errors.i ||
  1009. echo 'restore of errors.i failed'
  1010. Wc_c="`wc -c < 'errors.i'`"
  1011. test 825 -eq "$Wc_c" ||
  1012.     echo 'errors.i: original size 825, current size' "$Wc_c"
  1013. fi
  1014. # ============= file.fix ==============
  1015. if test -f 'file.fix' -a X"$1" != X"-c"; then
  1016.     echo 'x - skipping file.fix (File already exists)'
  1017. else
  1018. echo 'x - extracting file.fix (Text)'
  1019. sed 's/^X//' << 'SHAR_EOF' > 'file.fix' &&
  1020. X          Making the "file" command recognize zoo archives
  1021. X
  1022. Zoo archives have the following magic number:  Beginning at offset 20
  1023. decimal, there are four bytes with the values 0xdc, 0xa7, 0xc4, and
  1024. 0xfd.  (But if you call the first byte of a zoo archive byte 1, then
  1025. the magic bytes will be bytes 21 through 24.)
  1026. X
  1027. To make the "file" command identify zoo archives, changes can be made
  1028. as follows.
  1029. X
  1030. 4.3BSD:  See the context diff near the end of this document, suitable
  1031. for application with the "patch" utility, that works with the 4.3BSD 
  1032. "file" command on a VAX-11/785.  I don't know if this will also work 
  1033. under 4.2BSD or with any other implementation of the "file" command 
  1034. or on any other CPU.
  1035. X
  1036. System V Release 2 (as exemplified by Microport System V/AT):  At the
  1037. end of the file "/etc/magic", add the following line:
  1038. X
  1039. 20    long        0xfdc4a7dc    zoo archive
  1040. X
  1041. This should work on a little-endian machine, in which the long value
  1042. 0xfdc4a7dc is stored with the least-significant byte first.  For a big-
  1043. endian machine, you will probably need to replace it with 0xdca7c4fd.
  1044. This assumes that long occupies 4 bytes.  If not, use a data type name
  1045. that is exactly 4 bytes.
  1046. X
  1047. =====
  1048. Changes needed to make the 4.3BSD "file" command recognize zoo
  1049. archives.  Known to work on a VAX-11/785.
  1050. X
  1051. *** file.c.old    Thu Mar  6 19:34:29 1986
  1052. --- file.c    Sat Feb 21 19:28:52 1987
  1053. ***************
  1054. *** 172,181 ****
  1055. --- 172,187 ----
  1056. X      case 070707:
  1057. X          printf("cpio data\n");
  1058. X          return;
  1059. X      }
  1060. X  
  1061. +     if (buf[20] == (char) 0xdc && buf[21] == (char) 0xa7 && 
  1062. +                     buf[22] == (char) 0xc4 && buf[23] == (char) 0xfd) {
  1063. +         printf ("zoo archive\n");
  1064. +         return;
  1065. +     }
  1066. X      if (buf[0] == '#' && buf[1] == '!' && shellscript(buf+2, &mbuf))
  1067. X          return;
  1068. X      if (buf[0] == '\037' && buf[1] == '\235') {
  1069. X          if (buf[2]&0x80)
  1070. X              printf("block ");
  1071. SHAR_EOF
  1072. chmod 0644 file.fix ||
  1073. echo 'restore of file.fix failed'
  1074. Wc_c="`wc -c < 'file.fix'`"
  1075. test 1814 -eq "$Wc_c" ||
  1076.     echo 'file.fix: original size 1814, current size' "$Wc_c"
  1077. fi
  1078. # ============= fiz.1 ==============
  1079. if test -f 'fiz.1' -a X"$1" != X"-c"; then
  1080.     echo 'x - skipping fiz.1 (File already exists)'
  1081. else
  1082. echo 'x - extracting fiz.1 (Text)'
  1083. sed 's/^X//' << 'SHAR_EOF' > 'fiz.1' &&
  1084. .\" @(#) fiz.1 1.2 88/01/31 23:22:04
  1085. .\"
  1086. .\" For formatting with nroff:
  1087. .\"   nroff -man fiz.1
  1088. .\"
  1089. .TH FIZ 1 "Jan 31, 1988"
  1090. .SH NAME
  1091. fiz \- analyze damaged zoo archive for data revovery
  1092. .SH SYNOPSIS
  1093. .I fiz
  1094. .RB archive[ .zoo ]
  1095. .SH DESCRIPTION
  1096. .I Fiz
  1097. is used to analyze damaged
  1098. .I zoo
  1099. archives and locate directory entries and file data in them.
  1100. The current version of 
  1101. .I fiz
  1102. is 2.0 and it is meant to be used in conjunction with
  1103. .I zoo
  1104. version 2.0.
  1105. .I Fiz
  1106. makes no assumptions about archive structure.  Instead, it simply
  1107. searches the entire subject archive for tag values
  1108. that mark the locations of directory entries and file data.
  1109. In a 
  1110. .I zoo
  1111. archive, a
  1112. .I directory entry
  1113. contains information about a stored file such as its name, whether 
  1114. compressed or not, and its timestamp.  The
  1115. .I file data
  1116. are the actual data for the archived file, and may be
  1117. either the original data, or the result of compressing the file.
  1118. .PP
  1119. For each directory entry found,
  1120. .I fiz
  1121. prints where in the archive it is located, the directory path and
  1122. filename(s) found in it, whether the directory entry appears
  1123. to be corrupted (indicated by [*CRC Error*]), and the value of
  1124. the pointer to the file data that is found in the directory entry.
  1125. For each block of file data found in the archive,
  1126. .I fiz
  1127. prints where in the archive the block begins.  In the case of
  1128. an undamaged archive, the pointer to file data found in
  1129. a directory entry will correspond to where
  1130. .I fiz
  1131. actually locates the data.  Here is some sample output from 
  1132. .I fiz:
  1133. .PP
  1134. .nf
  1135. ****************
  1136. X    2526: DIR  [changes] ==>   95
  1137. X    2587: DATA
  1138. ****************
  1139. X    3909: DIR  [copyrite] ==> 1478
  1140. X    3970: DATA
  1141. X    4769: DATA
  1142. ****************
  1143. .fi
  1144. .sp 1
  1145. In such output, 
  1146. .B DIR
  1147. indicates where 
  1148. .I fiz
  1149. found a directory entry in the archive, and
  1150. .B DATA
  1151. indicates where 
  1152. .I fiz
  1153. found file data in the archive.  Filenames located by
  1154. .I fiz
  1155. are enclosed in square brackets, and the notation
  1156. "==>   95" indicates that the directory entry found by
  1157. .I fiz
  1158. at position 2526 has a file data pointer to
  1159. position 95.  In actuality,
  1160. .I fiz
  1161. found file data at positions 2587, 3970, and
  1162. 4769.  Since 
  1163. .I fiz
  1164. found only two directory entries, and each directory entry corresponds
  1165. to one file, one of the file data positions is an artifact.
  1166. .PP
  1167. Once the locations of directory entries and file data are found, the
  1168. .B @
  1169. modifier to
  1170. .I "zoo's"
  1171. archive list and extract commands can be used and
  1172. the archive contents selectively listed or extracted,
  1173. skipping the damaged portion.  This is further described
  1174. in the documentation for
  1175. .I zoo(1).
  1176. .PP
  1177. In the above case, commands to try giving to 
  1178. .I zoo
  1179. might be
  1180. .B x@2526,2587
  1181. (extract beginning at position 2526, and get file data
  1182. from position 2587),
  1183. .B x@3090,3970
  1184. (extract at 3090, get data from 3970)
  1185. and
  1186. .B x@3909,4769
  1187. (extract at 3909, get data from 4769).  Once a correctly-matched
  1188. directory entry/file data pair is found,
  1189. .I zoo
  1190. will in most cases synchronize with and correctly extract all files
  1191. subsequently found in the archive.  Trial and error should allow
  1192. all undamaged files to be extracted.
  1193. Also note that self-extracting archives created using
  1194. .I sez
  1195. (the Self-Extracting
  1196. .I Zoo
  1197. utility for MS-DOS), which are normally executed on an MS-DOS
  1198. system for extraction, can
  1199. be extracted on non-MSDOS systems in a similar way.
  1200. .PP
  1201. .SH "SEE ALSO"
  1202. zoo(1)
  1203. .SH BUGS
  1204. Random byte patterns can occasionally be incorrectly recognized
  1205. as tag values.  This occurs very rarely, however, and trial
  1206. and error will usually permit all undamaged data to be
  1207. extracted.
  1208. .SH DIAGNOSTICS
  1209. .I Fiz
  1210. always exits with a status code of 0.
  1211. .SH "FUTURE DIRECTIONS"
  1212. Automation of data recovery from a damaged archive is potentially
  1213. achievable.  However, since damaged archives occur only rarely,
  1214. .I fiz
  1215. as it currently stands is unlikely to change much in the
  1216. near future.
  1217. .SH AUTHOR
  1218. Rahul Dhesi
  1219. SHAR_EOF
  1220. chmod 0644 fiz.1 ||
  1221. echo 'restore of fiz.1 failed'
  1222. Wc_c="`wc -c < 'fiz.1'`"
  1223. test 3849 -eq "$Wc_c" ||
  1224.     echo 'fiz.1: original size 3849, current size' "$Wc_c"
  1225. fi
  1226. # ============= fiz.c ==============
  1227. if test -f 'fiz.c' -a X"$1" != X"-c"; then
  1228.     echo 'x - skipping fiz.c (File already exists)'
  1229. else
  1230. echo 'x - extracting fiz.c (Text)'
  1231. sed 's/^X//' << 'SHAR_EOF' > 'fiz.c' &&
  1232. #ifndef LINT
  1233. static char sccsid[]="@(#) fiz.c 2.6 88/01/31 23:23:50";
  1234. #endif /* LINT */
  1235. X
  1236. /*
  1237. The contents of this file are hereby released to the public domain.
  1238. X
  1239. X                                   -- Rahul Dhesi 1987/02/06
  1240. */
  1241. X
  1242. /*
  1243. Searches for all directory entries in an archive and prints their
  1244. offsets.  Zoo 1.41 and later may then be asked to extract a specific
  1245. file by supplying the offset of the file.
  1246. */
  1247. X
  1248. #include "options.h"
  1249. #include "zooio.h"
  1250. #include "various.h"
  1251. #include "zoofns.h"
  1252. #include "portable.h"         /* I/O definitions */
  1253. #include "zoo.h"
  1254. X
  1255. void prtctrl ();
  1256. void prtch ();
  1257. X
  1258. main(argc,argv)
  1259. register int argc;
  1260. register char **argv;
  1261. {
  1262. X   char *zooname;          /* name of archive to be read */
  1263. X   ZOOFILE zoo_file;       /* the archive being examined opened for read */
  1264. X   int state;              /* to keep track of how much of tag seen */
  1265. X   int inch;               /* char just read from archive */
  1266. X
  1267. X   static char usage1[] = "Fiz 2.0 (1987/02/01) public domain Zoo archive repair utility by Rahul Dhesi\n";
  1268. X   static char usage2[] = "Usage:  fiz archive[.zoo]  (\"fiz -h\" for help)\n";
  1269. X
  1270. #ifdef SETBUF
  1271. /* set stdout to unbuffered */
  1272. setbuf (stdout, (char *) NULL);
  1273. #endif
  1274. X
  1275. X   if (argc < 2) {
  1276. X      printf("%s%s", usage1, usage2);
  1277. X      exit (1);
  1278. X   }
  1279. X
  1280. X   if (strcmp(argv[1],"-h") == 0)
  1281. X      goto givehelp;
  1282. X
  1283. X   zooname = argv[1];
  1284. X
  1285. X   /* Add default extension if none supplied */
  1286. X   {
  1287. X      char *p, *q;
  1288. X      p = zooname + strlen(zooname);         /* point to last char */
  1289. X      while (p != zooname && *p != EXT_CH)
  1290. X         --p;
  1291. X      /* either found EXT_CH or reached beginning of zooname */
  1292. X      if (*p != EXT_CH) {
  1293. X         q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
  1294. X         if (q == NULL) {
  1295. X            printf("Fiz:  Ran out of memory.\n");
  1296. X            exit(1);
  1297. X         }
  1298. X         strcpy(q, zooname);
  1299. X         strcat(q, EXT_DFLT);
  1300. X         zooname = q;
  1301. X      }
  1302. X   }
  1303. X
  1304. X   zoo_file = zooopen (zooname, Z_READ);
  1305. X   if (zoo_file == NOFILE) {
  1306. X      printf("Fiz:  FATAL:  Could not open %s.\n", zooname);
  1307. X      exit(1);
  1308. X   }
  1309. X
  1310. #ifdef DOUBLE_SECRET
  1311. X    { void oh_well(void); oh_well(); }
  1312. #endif
  1313. X
  1314. #define  NOSTATE  1
  1315. #define  HDR_1   0xdc
  1316. #define  HDR_2   0xa7
  1317. #define  HDR_3   0xc4
  1318. #define  HDR_4   0xfd
  1319. X
  1320. #define    DAT_1   '@'
  1321. #define    DAT_2   ')'
  1322. #define    DAT_3   '#'
  1323. #define    DAT_4   '('
  1324. X
  1325. /* finite state machine implemented here by hand */
  1326. X
  1327. X   state = NOSTATE;
  1328. X   while ((inch = zgetc(zoo_file)) != EOF) {
  1329. X      inch = inch & 0xff;
  1330. X      if (state == NOSTATE) {
  1331. X            if (inch == HDR_1)
  1332. X                state = HDR_1;
  1333. X            else if (inch == DAT_1)
  1334. X                state = DAT_1;
  1335. X        } else if (state == HDR_1 && inch == HDR_2)
  1336. X         state = HDR_2;
  1337. X      else if (state == HDR_2 && inch == HDR_3)
  1338. X         state = HDR_3;
  1339. X      else if (state == HDR_3 && inch == HDR_4)
  1340. X         state = HDR_4;
  1341. X        else if (state == DAT_1 && inch == DAT_2)
  1342. X            state = DAT_2;
  1343. X        else if (state == DAT_2 && inch == DAT_3)
  1344. X            state = DAT_3;
  1345. X        else if (state == DAT_3 && inch == DAT_4)
  1346. X            state = DAT_4;
  1347. X      else
  1348. X         state = NOSTATE;
  1349. X
  1350. X      if (state == HDR_4) {                                   /* found archive tag */
  1351. X         long save_pos;
  1352. X         struct direntry direntry;
  1353. X         save_pos = zootell(zoo_file);
  1354. X         zooseek(zoo_file, save_pos-4L, 0);                /* back to tag pos */
  1355. X         frd_dir(&direntry, zoo_file);                        /* read dir entry */
  1356. X         printf("****************\n");
  1357. X
  1358. X         printf ("%8lu: DIR ", save_pos-4L);
  1359. X
  1360. X         if (direntry.dirlen > 0) {
  1361. X            printf ("[");
  1362. X            prtctrl (direntry.dirname);
  1363. X            printf ("]");
  1364. X         }
  1365. X
  1366. X         printf(" [");
  1367. X         prtctrl (direntry.fname);
  1368. X         printf ("]");
  1369. X
  1370. X         if (direntry.namlen > 0) {
  1371. X            printf (" [");
  1372. X            prtctrl (direntry.lfname);
  1373. X            printf ("]");
  1374. X         }
  1375. X            printf (" ==> %4lu", direntry.offset);
  1376. X         if (direntry.dir_crc != 0)
  1377. X            printf (" [*bad CRC*]");
  1378. X         printf ("\n");
  1379. X         fseek (zoo_file, save_pos, 0);         /* try again from there */
  1380. X      } else if (state == DAT_4) {                /* file data */
  1381. X         printf ("%8lu: DATA\n", zootell(zoo_file) + 1);
  1382. X        }
  1383. X   }
  1384. exit (0);      /* don't fall through */
  1385. X
  1386. givehelp:
  1387. X
  1388. /*
  1389. vi macros:
  1390. to add printf:
  1391. :s/^.*$/printf("&\\n");/
  1392. To remove printf:
  1393. :s/^printf("\(.*\)\\n");/\1/
  1394. */
  1395. printf("Fiz is used to help you recover data from a damaged archive.  Fiz searches\n");
  1396. printf("the specified archive for directory entries and stored files, and prints the\n");
  1397. printf("position of each one found.  Each directory entry contains a number that\n");
  1398. printf("represents the location in the archive where the file is stored;  fiz also\n");
  1399. printf("prints this position.  All numbers printed are decimal numbers.\n\n");
  1400. X
  1401. printf("Use Zoo version 2.00 or higher to list or extract files in the damaged\n");
  1402. printf("archive starting at a position identified by fiz.  For example, you can\n");
  1403. printf("start extracting files from archive \"badarc.zoo\" at position 1098 with the\n");
  1404. printf("command:\n\n");
  1405. X
  1406. printf("     zoo x@1098 badarc\n\n");
  1407. X
  1408. printf("Zoo will ignore the first 1098 bytes of the damaged archive and you should be\n");
  1409. printf("able to recover the undamaged files from the rest of the archive.  You can\n");
  1410. printf("also manually specify where to look for the file data with a command like\n\n");
  1411. X
  1412. printf("     zoo x@1098,1153\n\n");
  1413. X
  1414. printf("which tells zoo to use the directory entry at position 1098, but to get the\n");
  1415. printf("actual file data from position 1153 (and not from where the directory entry\n");
  1416. printf("says the data ought to be).  See the manuals for fiz and zoo for more details.\n");
  1417. X
  1418. exit (0);
  1419. }
  1420. X
  1421. /*
  1422. prtctrl() prints a string with all unprintable characters converted
  1423. to printable form.  To avoid the program running astray trying to
  1424. print damaged data, no more than MAXPRT characters are printed.
  1425. Characters with the 8th bit set are printed preceded with ~.  Control
  1426. characters are printed preceded with ^.  Both ~ and ^ may preced
  1427. the character if a control character has the 8th bit set.
  1428. */
  1429. #define  MAXPRT      50
  1430. X
  1431. void prtctrl (str)
  1432. char *str;
  1433. {
  1434. X   unsigned int ch;
  1435. X   int count;
  1436. X   count = 0;
  1437. X
  1438. X   while (count < MAXPRT && *str != '\0') {
  1439. X      ch = (unsigned) *str;
  1440. X      prtch(ch);
  1441. X      str++;
  1442. X      count++;
  1443. X   }
  1444. }
  1445. X
  1446. /*
  1447. Does the actual character printing for prtctrl()
  1448. */
  1449. void prtch(ch)
  1450. unsigned int ch;
  1451. {
  1452. X   /* assumes ASCII character set */
  1453. X   if (ch < ' ') {                        /* ^@ through ^_ */
  1454. X      printf("^%c", ch + 0x40);
  1455. X   } else if (ch == 0x7f) {               /* DEL */
  1456. X      printf("^?");
  1457. X   } else if (ch > 0x7f) {                /* 8th bit set */
  1458. X      printf("~");                        /* .. so precede with ~ */
  1459. X      prtch(ch & 0x7f);                   /* slick recursive call */
  1460. X   } else
  1461. X      printf("%c", ch);                   /* plain char */
  1462. }
  1463. SHAR_EOF
  1464. chmod 0644 fiz.c ||
  1465. echo 'restore of fiz.c failed'
  1466. Wc_c="`wc -c < 'fiz.c'`"
  1467. test 6784 -eq "$Wc_c" ||
  1468.     echo 'fiz.c: original size 6784, current size' "$Wc_c"
  1469. fi
  1470. # ============= fiz.man ==============
  1471. if test -f 'fiz.man' -a X"$1" != X"-c"; then
  1472.     echo 'x - skipping fiz.man (File already exists)'
  1473. else
  1474. echo 'x - extracting fiz.man (Text)'
  1475. sed 's/^X//' << 'SHAR_EOF' > 'fiz.man' &&
  1476. X
  1477. X
  1478. X
  1479. FIZ(1)              **IX Programmer's Manual               FIZ(1)
  1480. X
  1481. X
  1482. X
  1483. NAME
  1484. X     fiz - analyze damaged zoo archive for data revovery
  1485. X
  1486. SYNOPSIS
  1487. X     fiz archive[.zoo]
  1488. X
  1489. DESCRIPTION
  1490. X     Fiz is used to analyze damaged zoo archives and locate
  1491. X     directory entries and file data in them.  The current ver-
  1492. X     sion of fiz is 2.0 and it is meant to be used in conjunction
  1493. X     with zoo version 2.0.  Fiz makes no assumptions about
  1494. X     archive structure.  Instead, it simply searches the entire
  1495. X     subject archive for tag values that mark the locations of
  1496. X     directory entries and file data.  In a zoo archive, a direc-
  1497. X     tory entry contains information about a stored file such as
  1498. X     its name, whether compressed or not, and its timestamp.  The
  1499. X     file data are the actual data for the archived file, and may
  1500. X     be either the original data, or the result of compressing
  1501. X     the file.
  1502. X
  1503. X     For each directory entry found, fiz prints where in the
  1504. X     archive it is located, the directory path and filename(s)
  1505. X     found in it, whether the directory entry appears to be cor-
  1506. X     rupted (indicated by [*CRC Error*]), and the value of the
  1507. X     pointer to the file data that is found in the directory
  1508. X     entry.  For each block of file data found in the archive,
  1509. X     fiz prints where in the archive the block begins.  In the
  1510. X     case of an undamaged archive, the pointer to file data found
  1511. X     in a directory entry will correspond to where fiz actually
  1512. X     locates the data.  Here is some sample output from fiz:
  1513. X
  1514. X     ****************
  1515. X         2526: DIR  [changes] ==>   95
  1516. X         2587: DATA
  1517. X     ****************
  1518. X         3909: DIR  [copyrite] ==> 1478
  1519. X         3970: DATA
  1520. X         4769: DATA
  1521. X     ****************
  1522. X
  1523. X     In such output, DIR indicates where fiz found a directory
  1524. X     entry in the archive, and DATA indicates where fiz found
  1525. X     file data in the archive.  Filenames located by fiz are
  1526. X     enclosed in square brackets, and the notation "==>   95"
  1527. X     indicates that the directory entry found by fiz at position
  1528. X     2526 has a file data pointer to position 95.  In actuality,
  1529. X     fiz found file data at positions 2587, 3970, and 4769.
  1530. X     Since fiz found only two directory entries, and each direc-
  1531. X     tory entry corresponds to one file, one of the file data
  1532. X     positions is an artifact.
  1533. X
  1534. X
  1535. X
  1536. X
  1537. X
  1538. Printed 2/7/88            Jan 31, 1988                          1
  1539. X
  1540. X
  1541. X
  1542. X
  1543. X
  1544. X
  1545. FIZ(1)              **IX Programmer's Manual               FIZ(1)
  1546. X
  1547. X
  1548. X
  1549. X     Once the locations of directory entries and file data are
  1550. X     found, the @ modifier to zoo's archive list and extract com-
  1551. X     mands can be used and the archive contents selectively
  1552. X     listed or extracted, skipping the damaged portion.  This is
  1553. X     further described in the documentation for zoo(1).
  1554. X
  1555. X     In the above case, commands to try giving to zoo might be
  1556. X     x@2526,2587 (extract beginning at position 2526, and get
  1557. X     file data from position 2587), x@3090,3970 (extract at 3090,
  1558. X     get data from 3970) and x@3909,4769 (extract at 3909, get
  1559. X     data from 4769).  Once a correctly-matched directory
  1560. X     entry/file data pair is found, zoo will in most cases syn-
  1561. X     chronize with and correctly extract all files subsequently
  1562. X     found in the archive.  Trial and error should allow all
  1563. X     undamaged files to be extracted.  Also note that self-
  1564. X     extracting archives created using sez (the Self-Extracting
  1565. X     Zoo utility for MS-DOS), which are normally executed on an
  1566. X     MS-DOS system for extraction, can be extracted on non-MSDOS
  1567. X     systems in a similar way.
  1568. X
  1569. SEE ALSO
  1570. X     zoo(1)
  1571. X
  1572. BUGS
  1573. X     Random byte patterns can occasionally be incorrectly recog-
  1574. X     nized as tag values.  This occurs very rarely, however, and
  1575. X     trial and error will usually permit all undamaged data to be
  1576. X     extracted.
  1577. X
  1578. DIAGNOSTICS
  1579. X     Fiz always exits with a status code of 0.
  1580. X
  1581. FUTURE DIRECTIONS
  1582. X     Automation of data recovery from a damaged archive is poten-
  1583. X     tially achievable.  However, since damaged archives occur
  1584. X     only rarely, fiz as it currently stands is unlikely to
  1585. X     change much in the near future.
  1586. X
  1587. AUTHOR
  1588. X     Rahul Dhesi
  1589. X
  1590. X
  1591. X
  1592. X
  1593. X
  1594. X
  1595. X
  1596. X
  1597. X
  1598. X
  1599. X
  1600. X
  1601. X
  1602. X
  1603. X
  1604. Printed 2/7/88            Jan 31, 1988                          2
  1605. X
  1606. X
  1607. X
  1608. SHAR_EOF
  1609. chmod 0644 fiz.man ||
  1610. echo 'restore of fiz.man failed'
  1611. Wc_c="`wc -c < 'fiz.man'`"
  1612. test 4227 -eq "$Wc_c" ||
  1613.     echo 'fiz.man: original size 4227, current size' "$Wc_c"
  1614. fi
  1615. true || echo 'restore of generic.c failed'
  1616. echo End of part 2, continue with part 3
  1617. exit 0
  1618.