home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3615 < prev    next >
Internet Message Format  |  1991-07-10  |  32KB

  1. From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
  2. Newsgroups: alt.sources
  3. Subject: zoo 2.1 source part 14/15
  4. Message-ID: <12781@bsu-cs.bsu.edu>
  5. Date: 10 Jul 91 11:50:18 GMT
  6.  
  7. Checksum: 4111504653 (verify with "brik -cv")
  8. Submitted-by: dhesi@bsu-cs.bsu.edu
  9. Archive-name: zoo210/part14
  10.  
  11. ---- Cut Here and feed the following to sh ----
  12. #!/bin/sh
  13. # This is part 14 of zoo210
  14. # ============= zooext.c ==============
  15. if test -f 'zooext.c' -a X"$1" != X"-c"; then
  16.     echo 'x - skipping zooext.c (File already exists)'
  17. else
  18. echo 'x - extracting zooext.c (Text)'
  19. sed 's/^X//' << 'SHAR_EOF' > 'zooext.c' &&
  20. #ifndef LINT
  21. /* derived from: zooext.c 2.21 88/08/24 02:39:04 */
  22. /*$Source: /usr/home/dhesi/zoo/RCS/zooext.c,v $*/
  23. /*$Id: zooext.c,v 1.9 91/07/09 01:54:13 dhesi Exp $*/
  24. static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zooext.c,v $\n\
  25. $Id: zooext.c,v 1.9 91/07/09 01:54:13 dhesi Exp $";
  26. #endif /* LINT */
  27. X
  28. /*
  29. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  30. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  31. (C) Copyright 1991 Rahul Dhesi -- All rights reserved
  32. */
  33. /* Extract file from archive.  Extracts files specified in parameter-list
  34. X   from archive zoo_path.  If none specified, extracts all files from
  35. X   archive. */
  36. X
  37. #include "options.h"
  38. #include "zoo.h"
  39. #include "parse.h"      /* defines struct for parse() */
  40. X
  41. #include "portable.h"   /* portable I/O definitions */
  42. #include "machine.h"    /* machine-specific declarations */
  43. X
  44. #include "zooio.h"
  45. #include "various.h"
  46. X
  47. #ifndef NOSIGNAL
  48. #include <signal.h>
  49. #endif
  50. X
  51. #include "zoofns.h"
  52. X
  53. #ifdef MODE_BIN        /* will need fileno() from stdio.h */
  54. # include <stdio.h>
  55. #endif
  56. X
  57. void makepath PARMS((char *));
  58. int needed PARMS((char *, struct direntry *, struct zoo_header *));
  59. void putstr PARMS((char *));
  60. X
  61. #ifdef FATTR
  62. int setfattr PARMS ((char *, unsigned long));
  63. #endif /* FATTR */
  64. X
  65. extern int quiet;
  66. X
  67. #include "errors.i"
  68. X
  69. /* Following two are used by ctrl_c() also, hence declared here */
  70. char extfname[LFNAMESIZE];             /* filename of extracted file */
  71. char prtfname[LFNAMESIZE];             /* name of extracted file on screen */
  72. static ZOOFILE this_file;              /* file to extract */
  73. X
  74. static int tofile;                     /* true if not pipe or null device */
  75. extern unsigned int crccode;
  76. extern char *out_buf_adr;              /* address of output buffer */
  77. X
  78. void zooext(zoo_path, option)
  79. char *zoo_path, *option;
  80. {
  81. char *whichname;                          /* which name to extract */
  82. char matchname[PATHSIZE];                 /* for pattern matching only */
  83. #ifndef NOSIGNAL
  84. T_SIGNAL (*oldsignal)();        /* to save previous SIGINT handler */
  85. #endif
  86. ZOOFILE zoo_file;                         /* open archive */
  87. long next_ptr;                            /* pointer to within archive */
  88. struct zoo_header zoo_header;             /* header for archive */
  89. int status;                               /* error status */
  90. int exit_status = 0;                                /* exit status */
  91. int error_message;                                /* Whether to give error message */
  92. unsigned long disk_space;                 /* disk space left */
  93. int matched = 0;                          /* Any files matched? */
  94. int overwrite = 0;                        /* force overwrite of files? */
  95. int supersede = 0;                                /* supersede newer files? */
  96. int needdel = 0;                          /* extract deleted files too */
  97. int usepath = 2;                          /* use path for extraction */
  98. int todot = 0;                            /* extract relative to . */
  99. int badcrc_count = 0;                     /* how many files with bad CRC */
  100. int bad_header = 0;                       /* to avoid spurious messages later */
  101. long fiz_ofs = 0;                         /* offset where to start */
  102. long dat_ofs = 0;                                    /* .. and offset of file data */
  103. int pipe = 0;                             /* are we piping output? */
  104. int null_device = 0;                      /* are we sending to null device? */
  105. #ifndef PORTABLE
  106. int fast_ext = 0;                         /* fast extract as *.?Z? */
  107. int alloc_size;                           /* disk allocation unit size */
  108. #endif
  109. struct direntry direntry;                 /* directory entry */
  110. int first_dir = 1;                                /* first dir entry seen? */
  111. X
  112. static char extract_ver[] = "Zoo %d.%d is needed to extract %s.\n";
  113. static char no_space[] = "Insufficient disk space to extract %s.\n";
  114. X
  115. while (*option) {
  116. X   switch (*option) {
  117. #ifndef PORTABLE
  118. X      case 'z': fast_ext++; break;
  119. #endif
  120. X      case 'x':
  121. X      case 'e': break;
  122. X      case 'N': null_device++; break;
  123. X      case 'O': overwrite += 2; break;
  124. X      case 'o': overwrite++; break;
  125. X      case 'p': pipe++; break;
  126. X        case 'S': supersede++; break;
  127. X      case 'd': needdel++; break;
  128. X      case 'q': quiet++; break;
  129. X        case ':': usepath = 0; break;
  130. X      case '/': usepath++; break;
  131. X      case '.': todot++; break;
  132. X      case '@':     /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
  133. X            {
  134. X                char *comma_pos;
  135. X                ++option;
  136. X                comma_pos = strchr(option, ',');
  137. X                if (comma_pos != NULL) {
  138. X                    dat_ofs = calc_ofs (comma_pos + 1);
  139. X                    *comma_pos = '\0';
  140. X                }
  141. X                fiz_ofs = calc_ofs(option); 
  142. X                goto no_more;
  143. X            }
  144. X      default:
  145. X         prterror ('f', inv_option, *option);
  146. X         /* break; */
  147. X   }
  148. X   option++;
  149. }
  150. X
  151. no_more: /* come from exit in while loop above */
  152. X
  153. X
  154. if (overwrite == 1)                 /* must be at least 2 to begin with */
  155. X   overwrite--;
  156. X
  157. if (null_device && pipe) {
  158. X   prterror ('f', inv_option, 'p');
  159. X   pipe = 0;
  160. }
  161. X
  162. if (overwrite && pipe)
  163. X   prterror ('w', option_ignored, 'O');
  164. X
  165. #ifndef PORTABLE
  166. if (null_device && fast_ext) {
  167. X   prterror ('w', inv_option, 'N');
  168. X   null_device = 0;
  169. }
  170. #endif
  171. X
  172. tofile = !pipe && !null_device;     /* sending to actual file */
  173. X
  174. zoo_file = zooopen(zoo_path, Z_READ);
  175. X
  176. if (zoo_file == NOFILE)
  177. X   prterror ('f', could_not_open, zoo_path);
  178. X
  179. if (fiz_ofs != 0L) {                /* if offset specified, start there */
  180. X    prterror ('m', start_ofs, fiz_ofs, dat_ofs);
  181. X   zooseek (zoo_file, fiz_ofs, 0);
  182. } else {
  183. X   /* read header */
  184. X   frd_zooh (&zoo_header, zoo_file);
  185. X   if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L) {
  186. X      prterror ('w', failed_consistency);
  187. X      bad_header++;
  188. X        exit_status = 1;
  189. X   }
  190. X   zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
  191. }
  192. X
  193. #ifndef PORTABLE
  194. disk_space = space (0, &alloc_size);         /* remember disk space left */
  195. #else
  196. disk_space = MAXLONG;              /* infinite disk space */
  197. #endif
  198. X
  199. /* if piping output we open the output device just once */
  200. if (null_device) {
  201. X   this_file = NULLFILE;
  202. } else if (pipe)
  203. X   this_file = STDOUT;    /* standard output */
  204. X
  205. while (1) {
  206. X   frd_dir (&direntry, zoo_file);
  207. X   if (direntry.zoo_tag != ZOO_TAG) {
  208. X      long currpos, zoolength;
  209. X        prterror ('F', invalid_header);
  210. X
  211. X        /* Note:  if header was bad, there's no point trying to find
  212. X            how many more bytes aren't processed -- our seek position is
  213. X            likely very wrong */
  214. X
  215. X        if (!bad_header)
  216. X            if ((currpos = zootell (zoo_file)) != -1L)
  217. X                if (zooseek (zoo_file, 0L, 2) != -1)
  218. X                    if ((zoolength = zootell (zoo_file)) != -1L)
  219. X                        printf (cant_process, zoolength - currpos);              
  220. X        zooexit (1);
  221. X   }
  222. X   if (direntry.next == 0L) {                /* END OF CHAIN */
  223. X      break;                                 /* EXIT on end of chain */
  224. X   }
  225. X    /* when first direntry read, change dat_ofs from abs. pos. to rel. offset */
  226. X    if (first_dir && dat_ofs != 0) {
  227. X        dat_ofs -= direntry.offset;
  228. X        first_dir = 0;
  229. X    }
  230. X   next_ptr = direntry.next + dat_ofs;       /* ptr to next dir entry */
  231. X
  232. X   whichname = choosefname(&direntry);       /* which filename */
  233. X    whichname = str_dup(whichname);                /* bug fix */
  234. X   fixfname(whichname);                      /* fix syntax */
  235. X    strcpy (matchname, fullpath (&direntry));    /* get full pathname */
  236. X    if (zoo_header.vdata & VFL_ON)
  237. X        add_version (matchname, &direntry);        /* add version suffix */
  238. X
  239. /* if extraction to subtree rooted at curr dir, modify pathname */
  240. #if 0
  241. #ifdef DIR_LBRACK
  242. X   if (todot && direntry.dirname[0] == *DIR_LBRACK &&
  243. X                direntry.dirname[1] != *CUR_DIR)      {
  244. X      char tmpstr[PATHSIZE];
  245. X      strcpy (tmpstr, DIR_LBRACK);
  246. X      strcat (tmpstr, CUR_DIR);
  247. X      strcat (tmpstr, &direntry.dirname[1]);
  248. X      strcpy (direntry.dirname, tmpstr);
  249. X   }
  250. #endif
  251. #endif
  252. X
  253. X   /* hard-coded '/' should be eventually removed */
  254. X   if (todot && *direntry.dirname == '/') { 
  255. X      char tmpstr[PATHSIZE];
  256. X      strcpy(tmpstr, direntry.dirname);
  257. X      strcpy(direntry.dirname,CUR_DIR);
  258. X      strcat(direntry.dirname, tmpstr);
  259. X   }
  260. X
  261. X   /* matchname now holds the full pathname for pattern matching */
  262. X
  263. X   if ( ( (needdel && direntry.deleted) ||
  264. X            (needdel < 2 && !direntry.deleted)
  265. X        ) && needed(matchname, &direntry, &zoo_header)) {
  266. X      matched++;           /* update count of files extracted */
  267. X
  268. X      if (direntry.major_ver > MAJOR_LZH_VER ||
  269. X         (direntry.major_ver == MAJOR_LZH_VER && 
  270. X            direntry.minor_ver > MINOR_LZH_VER)) {
  271. X            prterror ('e', extract_ver, direntry.major_ver, 
  272. X                           direntry.minor_ver, whichname);
  273. X                exit_status = 1;
  274. X            goto loop_again;
  275. X      }
  276. X
  277. X      /* 
  278. X      If extracting to null device, or if user requested extraction
  279. X      of entire path, include any directory name in filename.
  280. X      If extraction to current directory requested, and if extfname
  281. X      begins with path separator, fix it */
  282. X
  283. X      strcpy (extfname, whichname);
  284. X      if ((usepath || null_device) && direntry.dirlen != 0) {
  285. X         combine(extfname, direntry.dirname, whichname);
  286. X         if (usepath > 1 && !null_device)
  287. X            makepath(direntry.dirname);         /* make dir prefix */
  288. X      }
  289. X
  290. X        strcpy(prtfname, extfname);
  291. X        if (zoo_header.vdata & VFL_ON)
  292. X            add_version (prtfname, &direntry);
  293. X
  294. X      if (tofile) {
  295. X         int present = 0;
  296. X
  297. #ifndef PORTABLE
  298. X         /* 
  299. X         if Z format (fast) extraction, extension is created as
  300. X         follows:  for no current extension, new extension is "zzz";
  301. X         for current extension "a", new extension is "azz";  for 
  302. X         current extension "ab", new extension is "azb";  and for
  303. X         current extension "abc", new extension is "azc".
  304. X         */
  305. X           
  306. X         if (fast_ext) {
  307. X            int length;
  308. X            struct path_st path_st;
  309. X            parse (&path_st, extfname);         /* split filename */
  310. X            strcpy (extfname, path_st.fname);   /* just root filename */
  311. X            length = strlen (path_st.ext);
  312. X            strcat (extfname, ".");
  313. X            if (length == 0)
  314. X               strcat (extfname, "zzz");        /* no ext -> .zzz */
  315. X            else if (length == 1) {
  316. X               strcat (extfname, path_st.ext);
  317. X               strcat (extfname, "zz");         /* *.?    -> *.?zz */
  318. X            } else { /* length is 2 or 3 */
  319. X               if (length == 2)                 /* allow .aa, .ab, etc. */
  320. X                  path_st.ext[2] = path_st.ext[1];
  321. X               path_st.ext[1] = 'z';
  322. X               strcat (extfname, path_st.ext);  /* *.??   -> *.?z? */
  323. X            }
  324. X                strcpy(prtfname, direntry.fname);
  325. X                add_version (prtfname, &direntry);
  326. X         }
  327. #endif   /* ifndef PORTABLE */
  328. X
  329. X            /* don't extract if archived file is older than disk copy */
  330. X            if (!supersede && exists(extfname)) {
  331. X                unsigned int ddate, dtime;
  332. #ifdef GETUTIME
  333. X                getutime (extfname, &ddate, &dtime);
  334. #else
  335. X                ZOOFILE tfile;
  336. X                ddate = dtime = 0xffff;                    /* assume maximum */
  337. X                tfile = zooopen(extfname, Z_READ);
  338. X                if (tfile == NOFILE)
  339. X                    goto loop_again;
  340. X                gettime (tfile, &ddate, &dtime);
  341. X                zooclose (tfile);
  342. #endif
  343. X                if (cmpnum (direntry.date, direntry.time, ddate, dtime) <= 0) {
  344. X                    prterror ('m', "%-14s -- skipped\n", prtfname);
  345. X                    goto loop_again;
  346. X                }
  347. X            }
  348. X
  349. X         if (overwrite) {
  350. X            this_file = zoocreate (extfname);
  351. #ifdef FATTR
  352. X                /* if can't open file, and OO option, make it writable first */
  353. X                if (this_file == NOFILE && overwrite >= 4 && 
  354. X                        (direntry.fattr >> 22) == 1 && exists(extfname)) {
  355. X                    setfattr (extfname, (unsigned long) (1L << 7) | direntry.fattr);
  356. X                    this_file = zoocreate (extfname);
  357. X                }
  358. #endif /* FATTR */
  359. X         } else {
  360. X            if (exists (extfname)) {
  361. X               present = 1;
  362. X               this_file = NOFILE;
  363. X            } else
  364. X               this_file = zoocreate (extfname);
  365. X         }
  366. X            error_message = 1;
  367. X         if (this_file == NOFILE) {
  368. X            if (present == 1) {      /* if file exists already */
  369. X                    char ans[20];          /* answer to "Overwrite?" */
  370. X               do {
  371. #ifdef EXT_ANYWAY
  372. X                  printf ("%s exists; extract anyway? [Yes/No/All] ",
  373. X                           extfname);
  374. #else
  375. X                  printf ("Overwrite %s (Yes/No/All)? ", extfname);
  376. #endif
  377. X                  fflush (stdin);
  378. X                  fgets (ans, sizeof(ans), stdin);
  379. X                  str_lwr (ans);
  380. X               } while (*ans != 'y' && *ans != 'n' && *ans != 'a');
  381. X   
  382. X               if (*ans == 'a')
  383. X                  overwrite++;
  384. X               if (*ans == 'y' || *ans == 'a') {
  385. X                  this_file = zoocreate(extfname);
  386. X                  error_message = 1; /* give error message if open fails */
  387. X               } else {
  388. X                  error_message = 0; /* user said 'n', so no error message */
  389. X               }
  390. X            } else {
  391. X               error_message = 1;   /* Real error -- give error message */
  392. X            }
  393. X         } /* end if */
  394. X      } /* end if */
  395. X
  396. X      if (this_file == NOFILE) {         /* file couldn't be opened */
  397. X         if (error_message == 1) {
  398. X            prterror ('e', "Can't open %s for output.\n", extfname);
  399. X                exit_status = 1;
  400. X
  401. #ifndef PORTABLE
  402. X            /* if error was due to full disk, abort */
  403. X            if (space(0, &alloc_size) < alloc_size)
  404. X               prterror ('f', disk_full);
  405. #endif
  406. X
  407. X         }
  408. X      } else if (zooseek (zoo_file, (direntry.offset + dat_ofs), 0) == -1L) {
  409. X         prterror ('e', "Could not seek to file data.\n");
  410. X            exit_status = 1;
  411. X         close_file (this_file);
  412. X      } else {
  413. #ifndef PORTABLE
  414. X         /* check msdos's free disk space if we seem to be running low 
  415. X            (within 1 cluster of being full) */
  416. X         if (tofile && disk_space < direntry.org_size + alloc_size) {
  417. X            disk_space = space (0, &alloc_size);
  418. X            if (disk_space < alloc_size) {
  419. X               close_file (this_file);
  420. X               unlink (extfname);
  421. X               prterror ('f', disk_full);
  422. X            }              
  423. X         }
  424. #endif
  425. X         if (tofile && disk_space < direntry.org_size) {
  426. #ifdef PORTABLE
  427. X            ;
  428. #else
  429. X                prterror ('e', no_space, prtfname);
  430. X            unlink (extfname);               /* delete any created file */
  431. #endif   /* portable */
  432. X
  433. X         } else { 
  434. X
  435. #ifndef PORTABLE
  436. X            if (fast_ext) {            /* fast ext -> create header */
  437. X               void make_tnh PARMS((struct tiny_header *, struct direntry *));
  438. X               struct tiny_header tiny_header;
  439. X               make_tnh(&tiny_header, &direntry);
  440. X               zoowrite (this_file, (char *) &tiny_header, sizeof(tiny_header));
  441. X
  442. X               if (direntry.cmt_size != 0) { /* copy comment */
  443. X                  long save_pos;
  444. X                  save_pos = zootell (zoo_file);
  445. X                  zooseek (zoo_file, direntry.comment, 0);
  446. X                  getfile (zoo_file, this_file, 
  447. X                          (long) direntry.cmt_size, 0);
  448. X                  zooseek (zoo_file, save_pos, 0);
  449. X               }
  450. X            }
  451. #endif /* ifndef PORTABLE */
  452. X
  453. X            crccode = 0;      /* Initialize CRC before extraction */
  454. X               if (!pipe) {
  455. #ifdef PORTABLE
  456. X                  prterror ('m', "%-14s -- ", prtfname);
  457. #else
  458. X                  if (fast_ext)
  459. X                     prterror ('m', "%-12s ==> %-12s -- ", 
  460. X                        prtfname,  extfname);
  461. X                  else
  462. X                     prterror ('m', "%-12s -- ", prtfname);
  463. #endif /* PORTABLE */
  464. X
  465. X               } else {            /* must be pipe */
  466. X                  prterror ('M',"\n\n********\n%s\n********\n",prtfname);
  467. X
  468. #ifdef SETMODE
  469. X                  MODE_BIN(this_file);           /* make std output binary so
  470. X                                                   ^Z won't cause error */
  471. #endif
  472. X               }
  473. #ifndef NOSIGNAL
  474. X            if (tofile)
  475. X               {
  476. X                  oldsignal = signal (SIGINT, SIG_IGN);
  477. X                  if (oldsignal != SIG_IGN) 
  478. X                     signal (SIGINT, ctrl_c); /* Trap ^C & erase partial file */
  479. X               }
  480. #endif /* not NOSIGNAL */
  481. X
  482. X            if (direntry.packing_method == 0)
  483. X               /* 4th param 1 means CRC update */
  484. X               status = getfile (zoo_file, this_file, direntry.size_now, 1);
  485. X
  486. #ifndef PORTABLE
  487. X            else if (fast_ext)
  488. X               /* 4th param 0 means no CRC update */
  489. X               status = getfile (zoo_file, this_file, direntry.size_now, 0);
  490. #endif
  491. X
  492. X            else if (direntry.packing_method == 1) {
  493. #ifdef UNBUF_IO
  494. #include "ERROR"
  495. X                    /* NOT PORTABLE -- DO NOT TRY THIS AT HOME */
  496. X                    long lseek PARMS ((int, long, int));
  497. X                    long tell PARMS ((int));
  498. X                    int this_fd, zoo_fd;
  499. X            
  500. X                    /* get file descriptors */
  501. X                    this_fd = null_device ? -2 : fileno (this_file);
  502. X                    zoo_fd = fileno (zoo_file);
  503. X
  504. X                    zooseek (zoo_file, zootell (zoo_file), 0);    /* synch */
  505. X                    lseek (zoo_fd, zootell (zoo_file), 0);            /* ..again */
  506. X                    if (!null_device) {
  507. X                        zooseek (this_file, zootell (this_file), 0);    /* synch */
  508. X                        lseek (this_fd, zootell (this_file), 0);        /* ..again */
  509. X                    }
  510. X                  status = lzd(zoo_fd, this_fd);            /* uncompress */
  511. X                    zooseek (zoo_file, tell (zoo_fd), 0);    /* resynch    */
  512. X                    if (!null_device)
  513. X                        zooseek (this_file, tell (this_fd), 0);/* resynch    */
  514. #else
  515. X               status = lzd (zoo_file, this_file);     /* uncompress */
  516. #endif
  517. X                } else if (direntry.packing_method == 2) {
  518. X               status = lzh_decode (zoo_file, this_file);
  519. X            } else {
  520. X               prterror ('e', "File %s:  impossible packing method.\n",
  521. X                  whichname);
  522. X                  unlink(extfname);
  523. X                  goto loop_again;
  524. X            }
  525. X
  526. X
  527. #ifndef NOSIGNAL
  528. X            if (tofile)
  529. X               signal (SIGINT, oldsignal);
  530. #endif /* not NOSIGNAL */
  531. X
  532. #ifdef SETMODE
  533. X            if (pipe)
  534. X               MODE_TEXT(this_file);          /* restore text mode */
  535. #endif
  536. X   
  537. X            if (tofile) {
  538. X               /* set date/time of file being extracted */
  539. #ifdef GETTZ
  540. X                    void tzadj();
  541. X                    /* adjust for original timezone */
  542. X                    tzadj (&direntry);
  543. #endif
  544. #ifdef NIXTIME
  545. X               close_file (this_file);
  546. X               setutime (extfname, direntry.date, direntry.time);
  547. #else
  548. X               settime (this_file, direntry.date, direntry.time);
  549. X               close_file (this_file);
  550. #endif
  551. #ifdef FATTR
  552. /* Restore file attributes. Bit 23==1 means system-specific; we currently 
  553. don't recognize this.  Bit 23==0 means use portable format, in which case 
  554. bit 22==0 means ignore attributes.  Thus attributes are ignored if both 
  555. bits 23 and 22 are zero, which is the effect of a zero-filled file 
  556. attribute field.  Currently we restore file attributes if and only if
  557. bit 23==0 and bit 22==1. */
  558. X
  559. X                    if ((direntry.fattr >> 22) == 1) {
  560. X                        setfattr (extfname, direntry.fattr);
  561. X                    }
  562. #endif /* FATTR */
  563. X            } /* end of if (tofile) ... */
  564. X            if (status != 0) {
  565. X                    exit_status = 1;
  566. X               if (tofile)
  567. X                  unlink (extfname);
  568. X               if (status == 2) {    /* was 1 (wrong) */
  569. X                  memerr(0);
  570. X               /* To avoid spurious errors due to ^Z being sent to screen,
  571. X                  we don't check for I/O error if output was piped */
  572. X               } else if (!pipe && (status == 2 || status == 3)) {
  573. X                     prterror ('e', no_space, prtfname);
  574. X               }
  575. X            } else {
  576. X               /* file extracted, so update disk space.  */
  577. X               /* we subtract the original size of the file, rounded
  578. X                  UP to the nearest multiple of the disk allocation
  579. X                  size. */
  580. #ifndef PORTABLE
  581. X               {
  582. X                  unsigned long temp;
  583. X                  temp = (direntry.org_size + alloc_size) / alloc_size;
  584. X                  disk_space -= temp * alloc_size;
  585. X               }
  586. #endif
  587. X
  588. X               if (
  589. #ifndef PORTABLE
  590. X                          !fast_ext && 
  591. #endif
  592. X                            direntry.file_crc != crccode
  593. X                        ) {
  594. X                  badcrc_count++;
  595. X                        exit_status = 1;
  596. X                  if (!pipe) {
  597. X                     if (!null_device)
  598. X                        prterror ('M', "extracted   ");
  599. X                     prterror ('w', bad_crc, prtfname);
  600. X                  }
  601. X                  else {   /* duplicate to standard error */
  602. X                     static char stars[] = "\n******\n";
  603. X                     putstr (stars);
  604. X                     prterror ('w', bad_crc, prtfname);
  605. X                     putstr (stars);
  606. X                     fprintf (stderr, "WARNING:  ");
  607. X                     fprintf (stderr, bad_crc, prtfname);
  608. X                  }
  609. X               } else
  610. X                  if (!pipe)
  611. X                     prterror ('M', null_device ? "OK\n" : "extracted\n");
  612. X
  613. X            } /* end if */
  614. X         } /* end if */
  615. X      } /* end if */
  616. X   } /* end if */
  617. X
  618. loop_again:
  619. X   zooseek (zoo_file, next_ptr, 0); /* ..seek to next dir entry */
  620. } /* end while */
  621. X
  622. close_file (zoo_file);
  623. if (!matched)
  624. X   putstr (no_match);
  625. X
  626. if (badcrc_count) {
  627. X   prterror ('w', "%d File(s) with bad CRC.\n", badcrc_count);
  628. } else if (null_device)
  629. X   prterror ('m', "Archive seems OK.\n");
  630. X
  631. zooexit (exit_status);
  632. X
  633. } /* end zooext */
  634. X
  635. /* close_file() */
  636. /* closes a file if and only if we aren't sending output to 
  637. X   a pipe or to the null device */
  638. X
  639. void close_file (file)
  640. ZOOFILE file;
  641. {
  642. X   if (tofile)
  643. X      zooclose (file);
  644. }
  645. X
  646. /* Ctrl_c() is called if ^C is hit while a file is being extracted.
  647. X   It closes the files, deletes it, and exits. */
  648. T_SIGNAL ctrl_c()
  649. {
  650. #ifndef NOSIGNAL
  651. X   signal (SIGINT, SIG_IGN);     /* ignore any more */
  652. #endif
  653. X   zooclose (this_file);
  654. X   unlink (extfname);
  655. X   zooexit (1);
  656. }
  657. X
  658. #ifndef PORTABLE
  659. /* make_tnh copies creates a tiny_header */
  660. void make_tnh (tiny_header, direntry)
  661. struct tiny_header *tiny_header;
  662. struct direntry *direntry;
  663. {
  664. X   tiny_header->tinytag = TINYTAG;
  665. X   tiny_header->type = 1;
  666. X   tiny_header->packing_method = direntry->packing_method;
  667. X   tiny_header->date = direntry->date;
  668. X   tiny_header->time = direntry->time;
  669. X   tiny_header->file_crc = direntry->file_crc;
  670. X   tiny_header->org_size = direntry->org_size;
  671. X   tiny_header->size_now = direntry->size_now;
  672. X   tiny_header->major_ver = direntry->major_ver;
  673. X   tiny_header->minor_ver = direntry->minor_ver;
  674. X   tiny_header->cmt_size = direntry->cmt_size;
  675. X   strcpy (tiny_header->fname, direntry->fname);
  676. #endif /* ifndef PORTABLE */
  677. SHAR_EOF
  678. chmod 0644 zooext.c ||
  679. echo 'restore of zooext.c failed'
  680. Wc_c="`wc -c < 'zooext.c'`"
  681. test 22207 -eq "$Wc_c" ||
  682.     echo 'zooext.c: original size 22207, current size' "$Wc_c"
  683. fi
  684. # ============= zoofilt.c ==============
  685. if test -f 'zoofilt.c' -a X"$1" != X"-c"; then
  686.     echo 'x - skipping zoofilt.c (File already exists)'
  687. else
  688. echo 'x - extracting zoofilt.c (Text)'
  689. sed 's/^X//' << 'SHAR_EOF' > 'zoofilt.c' &&
  690. /* derived from: zoofilt.c 1.8 88/01/30 23:47:05 */
  691. X
  692. #ifndef LINT
  693. static char sccsid[]="@(#) $Id: zoofilt.c,v 1.5 91/07/09 01:54:15 dhesi Exp $";
  694. #endif
  695. X
  696. /*
  697. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  698. (C) Copyright 1991 Rahul Dhesi -- All rights reserved
  699. X
  700. Filter mode -- compress or decompress standard input and write
  701. to standard output.
  702. */
  703. X
  704. #include "options.h"
  705. X
  706. #ifdef FILTER
  707. X
  708. #include "zooio.h"
  709. #include "errors.i"
  710. #include "zoofns.h"
  711. X
  712. /* action */
  713. #define COMPRESS        0
  714. #define UNCOMPRESS    1
  715. X
  716. #define FTAG    ((unsigned int) 0x5a32)    /* magic number */
  717. X
  718. extern unsigned int crccode;
  719. X
  720. int rdint PARMS((unsigned int *));    /* read an unsigned int */
  721. int wrint PARMS((unsigned int));    /* write an unsigned int */
  722. X
  723. /* global variable used to pass two bytes (CRC value) back from lzd to here */
  724. unsigned int filt_lzd_word;
  725. X
  726. void zoofilt (option)
  727. char *option;
  728. {
  729. X    int choice;                                            /* what to do -- [de]compress */
  730. X    unsigned int filetag;                            /* tag stored in input */
  731. X    int stat1, stat2, stat3;                        /* status codes */
  732. X    int use_lzh = 0;                                    /* use lzh instead */
  733. X    extern lzc(), lzh_encode();                    /* possible encoders */
  734. X    extern lzd(), lzh_decode();                    /* and decoders */
  735. X
  736. X    while (*++option) {
  737. X        switch (*option) {
  738. X            case 'c':    choice = COMPRESS;    break;
  739. X            case 'u':    choice = UNCOMPRESS;  break;
  740. X            case 'h':    use_lzh = 1; break;
  741. X            default:
  742. X             prterror ('f', inv_option, *option);    /* fatal error -- abort */
  743. X      }
  744. X    }
  745. X
  746. X    crccode = 0;    /* needed whether compressing or uncompressing */
  747. X
  748. X    switch (choice) {
  749. X        case COMPRESS:
  750. X            stat1 = wrint (FTAG);
  751. X            stat2 = (use_lzh ? lzh_encode : lzc) (STDIN, STDOUT);
  752. X            stat3 = wrint (crccode);
  753. X            if (stat1 == 0 && stat2 == 0 && stat3 == 0)
  754. X                zooexit (0);
  755. X            else {
  756. X                fprintf (stderr, "Zoo: FATAL: Compression error.\n");
  757. X                zooexit (1);
  758. X            }
  759. X            break;
  760. X        case UNCOMPRESS:
  761. X            stat1 = rdint (&filetag);
  762. X            if (stat1 != 0 || filetag != FTAG)
  763. X                zooexit (1);
  764. X            stat2 = (use_lzh ? lzh_decode : lzd) (STDIN, STDOUT);
  765. X            if (stat2 == 0 && filt_lzd_word == crccode)
  766. X                zooexit (0);
  767. X            else {
  768. X                fprintf (stderr, "Zoo: FATAL: Uncompression error.\n");
  769. X                zooexit (1);
  770. X            }
  771. X            break;
  772. X    }
  773. } /* zoofilt */
  774. X
  775. #endif /* FILTER */
  776. SHAR_EOF
  777. chmod 0644 zoofilt.c ||
  778. echo 'restore of zoofilt.c failed'
  779. Wc_c="`wc -c < 'zoofilt.c'`"
  780. test 2179 -eq "$Wc_c" ||
  781.     echo 'zoofilt.c: original size 2179, current size' "$Wc_c"
  782. fi
  783. # ============= zoofns.h ==============
  784. if test -f 'zoofns.h' -a X"$1" != X"-c"; then
  785.     echo 'x - skipping zoofns.h (File already exists)'
  786. else
  787. echo 'x - extracting zoofns.h (Text)'
  788. sed 's/^X//' << 'SHAR_EOF' > 'zoofns.h' &&
  789. /* @(#) zoofns.h 2.5 88/01/16 19:03:13 */
  790. /* @(#) zoofns.h 2.7 88/01/27 19:39:18 */
  791. X
  792. /*
  793. The contents of this file are hereby released to the public domain.
  794. X
  795. X                           -- Rahul Dhesi 1986/11/14
  796. */
  797. X
  798. /* Defines function declarations for all Zoo functions */
  799. X
  800. #ifndef PARMS
  801. #ifdef LINT_ARGS
  802. #define    PARMS(x)        x
  803. #else
  804. #define    PARMS(x)        ()
  805. #endif
  806. #endif
  807. X
  808. /* 
  809. :.,$s/(PARMS\(.*\));/PARMS\1;/
  810. */
  811. #ifdef ANSI_HDRS
  812. #include <stdlib.h>
  813. #else
  814. char *memset PARMS ((char *, int, unsigned));
  815. #endif /* ANSI_HDRS */
  816. X
  817. long calc_ofs PARMS ((char *));
  818. char *addext PARMS ((char *, char *));
  819. char *combine PARMS ((char[], char *, char *));
  820. VOIDPTR emalloc PARMS ((unsigned int));
  821. VOIDPTR ealloc PARMS ((unsigned int));
  822. VOIDPTR erealloc PARMS ((VOIDPTR, unsigned int));
  823. char *findlast PARMS ((char *, char *));
  824. char *fixfname PARMS ((char *));
  825. char *getstdin PARMS ((void));
  826. char *lastptr PARMS ((char *));
  827. char *nameptr PARMS ((char *));
  828. char *newcat PARMS ((char *, char *));
  829. char *nextfile PARMS ((int, char *, int));
  830. int cfactor PARMS ((long, long));
  831. int chname PARMS ((char *, char *));
  832. int cmpnum PARMS ((unsigned int, unsigned int, unsigned int, unsigned int));
  833. T_SIGNAL ctrl_c PARMS ((void));
  834. int exists PARMS ((char *));
  835. int getfile PARMS ((ZOOFILE, ZOOFILE, long, int));
  836. int getutime PARMS ((char *, unsigned *, unsigned *));
  837. int gettime PARMS ((ZOOFILE, unsigned *, unsigned *));
  838. T_SIGNAL handle_break PARMS ((void));
  839. X
  840. #ifdef USE_ASCII
  841. int isupper PARMS ((int));
  842. int isdigit PARMS ((int));
  843. #endif /* USE_ASCII */
  844. X
  845. int kill_files PARMS ((char *[], int));
  846. #ifdef UNBUF_IO
  847. int lzc PARMS ((int, int));
  848. int lzd PARMS ((int, int));
  849. #else
  850. int lzc PARMS ((ZOOFILE, ZOOFILE));
  851. int lzd PARMS ((ZOOFILE, ZOOFILE));
  852. #endif
  853. X
  854. int lzh_encode PARMS((FILE *infile, FILE *outfile));
  855. int lzh_decode PARMS((FILE *infile, FILE *outfile));
  856. X
  857. int match_half PARMS ((char *, char *));
  858. int samefile PARMS ((char *, char *));
  859. int settime PARMS ((ZOOFILE, unsigned, unsigned));
  860. int setutime PARMS ((char *, unsigned, unsigned));
  861. int str_icmp PARMS ((char *, char *));
  862. X
  863. #ifdef USE_ASCII
  864. int tolower PARMS ((int));
  865. int toascii PARMS ((int));
  866. #endif /* USE_ASCII */
  867. X
  868. void zooexit PARMS ((int));
  869. long inlist PARMS ((char *, unsigned int *, unsigned int *, unsigned *,
  870. X                    unsigned *, unsigned *, long *, int));
  871. unsigned long space PARMS ((int, int *));
  872. void addbfcrc PARMS ((char *, int));
  873. void addfname PARMS ((char *, long, unsigned int, unsigned int, 
  874. X                            unsigned, unsigned));
  875. void add_version PARMS ((char *, struct direntry *));
  876. void basename PARMS ((char *, char []));
  877. void break_off PARMS ((void));
  878. void close_file PARMS ((ZOOFILE));
  879. void comment PARMS ((char *, char *));
  880. void extension PARMS ((char *, char []));
  881. void exit PARMS ((int));
  882. void fixslash PARMS ((char *));
  883. void makelist PARMS ((int, char *[], char *[], int, char *, char *, char *, int *));
  884. void memerr PARMS ((unsigned int));
  885. void prterror PARMS ((int, char *, ...));
  886. void rootname PARMS ((char *, char *));
  887. void skip_files PARMS ((ZOOFILE, unsigned int *, unsigned int *, int *,
  888. X                  char [], long *));
  889. void writenull PARMS ((ZOOFILE, int));
  890. void zooadd PARMS ((char *, int, char **, char *));
  891. void zoodel PARMS ((char *, char *, int));
  892. void zoofilt PARMS ((char *));
  893. void zooext PARMS ((char *, char *));
  894. void zoolist PARMS ((char **, char *, int));
  895. void zoopack PARMS ((char *, char *));
  896. X
  897. char *str_dup PARMS ((char *));
  898. char *str_lwr PARMS ((char *));
  899. X
  900. SHAR_EOF
  901. chmod 0644 zoofns.h ||
  902. echo 'restore of zoofns.h failed'
  903. Wc_c="`wc -c < 'zoofns.h'`"
  904. test 3423 -eq "$Wc_c" ||
  905.     echo 'zoofns.h: original size 3423, current size' "$Wc_c"
  906. fi
  907. # ============= zooio.h ==============
  908. if test -f 'zooio.h' -a X"$1" != X"-c"; then
  909.     echo 'x - skipping zooio.h (File already exists)'
  910. else
  911. echo 'x - extracting zooio.h (Text)'
  912. sed 's/^X//' << 'SHAR_EOF' > 'zooio.h' &&
  913. /* @(#) zooio.h 2.7 88/01/27 19:39:24 */
  914. X
  915. /*
  916. Declarations for portable I/O
  917. X
  918. The contents of this file are hereby placed in the public domain.
  919. X
  920. X                                            -- Rahul Dhesi 1988/01/24
  921. */
  922. #ifndef    OK_STDIO
  923. #include <stdio.h>
  924. #define    OK_STDIO
  925. #endif
  926. X
  927. #ifndef PARMS
  928. #ifdef LINT_ARGS
  929. #define    PARMS(x)        x
  930. #else
  931. #define    PARMS(x)        ()
  932. #endif
  933. #endif
  934. X
  935. /*
  936. In theory, all I/O using buffered files could be replaced with unbuffered
  937. I/O simply by changing the following definitions.  This has not been tried
  938. out yet, and there may be some remaining holes in the scheme.  On systems
  939. with limited memory, it might prove necessary to use unbuffered I/O
  940. only.
  941. */
  942. typedef FILE *ZOOFILE;
  943. #define NOFILE        ((ZOOFILE) 0)
  944. #define NULLFILE    ((ZOOFILE) -1)        /* or any unique value */
  945. #define STDOUT        stdout
  946. X
  947. #ifdef FILTER
  948. #define STDIN        stdin
  949. #endif
  950. X
  951. #ifdef IO_MACROS
  952. #define zooread(file, buffer, count)        fread (buffer, 1, count, file)
  953. #define zoowrite(file, buffer, count) \
  954. X    (file == NULLFILE ? count : fwrite (buffer, 1, count, file))
  955. #define zooseek(file, offset, whence)        fseek (file, offset, whence)
  956. #define zootell(file)                            ftell (file)
  957. #else
  958. int zooread PARMS((ZOOFILE, char *, int));
  959. int zoowrite PARMS((ZOOFILE, char *, int));
  960. long zooseek PARMS((ZOOFILE, long, int));
  961. long zootell PARMS((ZOOFILE));
  962. #endif /* IO_MACROS */
  963. X
  964. ZOOFILE zooopen PARMS((char *, char *));
  965. ZOOFILE zoocreate PARMS((char *));
  966. int zooclose PARMS((ZOOFILE));
  967. int zootrunc PARMS((ZOOFILE));
  968. X
  969. char *choosefname PARMS((struct direntry *));
  970. char *fullpath PARMS((struct direntry *));
  971. int frd_zooh PARMS((struct zoo_header *, ZOOFILE));
  972. int frd_dir PARMS((struct direntry *, ZOOFILE));
  973. int fwr_dir PARMS((struct direntry *, ZOOFILE));
  974. int fwr_zooh PARMS((struct zoo_header *, ZOOFILE));
  975. int readdir PARMS((struct direntry *, ZOOFILE, int));
  976. void rwheader PARMS((struct zoo_header *, ZOOFILE, int));
  977. void newdir PARMS((struct direntry *));
  978. void writedir PARMS((struct direntry *, ZOOFILE));
  979. SHAR_EOF
  980. chmod 0644 zooio.h ||
  981. echo 'restore of zooio.h failed'
  982. Wc_c="`wc -c < 'zooio.h'`"
  983. test 1939 -eq "$Wc_c" ||
  984.     echo 'zooio.h: original size 1939, current size' "$Wc_c"
  985. fi
  986. true || echo 'restore of zoolist.c failed'
  987. echo End of part 14, continue with part 15
  988. exit 0
  989.