home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / sources / misc / 3861 < prev    next >
Encoding:
Text File  |  1992-08-23  |  59.1 KB  |  1,533 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  4. Subject:  v31i111:  unzip50 - Info-ZIP portable UnZip, version 5.0, Part08/14
  5. Message-ID: <1992Aug24.025609.24832@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 9b7db4696753d88ac9695a11405b9708
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v31i104=unzip50.215137@sparky.IMD.Sterling.COM>
  11. Date: Mon, 24 Aug 1992 02:56:09 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 1518
  14.  
  15. Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
  16. Posting-number: Volume 31, Issue 111
  17. Archive-name: unzip50/part08
  18. Supersedes: unzip: Volume 29, Issue 31-42
  19. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT AMIGA?, !ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then feed it
  23. # into a shell via "sh file" or similar.  To overwrite existing files,
  24. # type "sh file -c".
  25. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  26. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  27. # Contents:  funzip.c unzip.c.A zipinfo.doc
  28. # Wrapped by kent@sparky on Sun Aug 23 21:09:34 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. echo If this archive is complete, you will see the following message:
  31. echo '          "shar: End of archive 8 (of 14)."'
  32. if test -f 'funzip.c' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'funzip.c'\"
  34. else
  35.   echo shar: Extracting \"'funzip.c'\" \(11324 characters\)
  36.   sed "s/^X//" >'funzip.c' <<'END_OF_FILE'
  37. X/* funzip.c -- Not copyrighted 1992 by Mark Adler
  38. X   version 1.3, 16 August 1992 */
  39. X
  40. X
  41. X/* You can do whatever you like with this source file, though I would
  42. X   prefer that if you modify it and redistribute it that you include
  43. X   comments to that effect with your name and the date.  Thank you.
  44. X
  45. X   History:
  46. X   vers    date          who           what
  47. X   ----  ---------  --------------  ------------------------------------
  48. X    1.0  13 Aug 92  M. Adler        really simple unzip filter.
  49. X    1.1  13 Aug 92  M. Adler        cleaned up somewhat, give help if
  50. X                                    stdin not redirected, warn if more
  51. X                                    zip file entries after the first.
  52. X    1.2  15 Aug 92  M. Adler        added check of lengths for stored
  53. X                                    entries, added more help.
  54. X    1.3  16 Aug 92  M. Adler        removed redundant #define's, added
  55. X                                    decryption.
  56. X
  57. X */
  58. X
  59. X
  60. X/*
  61. X
  62. X   All funzip does is take a zip file from stdin and decompress the
  63. X   first entry to stdout.  The entry has to be either deflated or
  64. X   stored.  If the entry is encrypted, then the decryption password
  65. X   must be supplied on the command line as the first argument.
  66. X
  67. X   funzip needs to be linked with inflate.o compiled from the unzip
  68. X   source.  If decryption is desired, then it needs to be compiled
  69. X   with -DCRYPT and linked also with crypt.o.
  70. X
  71. X */
  72. X
  73. X#include "unzip.h"
  74. X
  75. X/* enforce binary i/o if recognized */
  76. X#ifdef __STDC__
  77. X#  define FOPR "rb"
  78. X#  define FOPW "w+b"
  79. X#else
  80. X#  define FOPR "r"
  81. X#  define FOPW "w+"
  82. X#endif
  83. X
  84. X/* PKZIP header definitions */
  85. X#define LOCSIG 0x04034b50L      /* four byte lead-in (lsb first) */
  86. X#define LOCFLG 6                /* offset of bit flag */
  87. X#define  CRPFLG 1               /*  bit for encrypted entry */
  88. X#define  EXTFLG 8               /*  bit for extended local header */
  89. X#define LOCHOW 8                /* offset of compression method */
  90. X#define LOCTIM 10               /* file mod time (for decryption) */
  91. X#define LOCCRC 14               /* offset of crc */
  92. X#define LOCSIZ 18               /* offset of compressed size */
  93. X#define LOCLEN 22               /* offset of uncompressed length */
  94. X#define LOCFIL 26               /* offset of file name field length */
  95. X#define LOCEXT 28               /* offset of extra field length */
  96. X#define LOCHDR 30               /* size of local header, including sig */
  97. X#define EXTHDR 16               /* size of extended local header, inc sig */
  98. X
  99. X/* Macros for getting two byte and four byte header values */
  100. X#define SH(p) ((UWORD)(byte)((p)[0]) | ((UWORD)(byte)((p)[1]) << 8))
  101. X#define LG(p) ((ULONG)(SH(p)) | ((ULONG)(SH((p)+2)) << 16))
  102. X
  103. X/* Function prototypes */
  104. XULONG updcrc OF((byte *, int));
  105. Xint inflate_entry OF((void));
  106. Xvoid err OF((int, char *));
  107. Xvoid main OF((int, char **));
  108. X
  109. X/* Globals */
  110. XFILE *in, *out;                 /* input and output files */
  111. Xunion work area;                /* inflate sliding window */
  112. Xbyte *outbuf;                   /* malloc'ed output buffer */
  113. Xbyte *outptr;                   /* points to next byte in output buffer */
  114. Xint outcnt;                     /* bytes in output buffer */
  115. XULONG outsiz;                   /* total bytes written to out */
  116. Xint decrypt;                    /* flag to turn on decryption */
  117. Xchar *key;                      /* not used--needed to link crypt.c */
  118. X
  119. X/* Masks for inflate.c */
  120. XUWORD mask_bits[] = {
  121. X    0x0000,
  122. X    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
  123. X    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
  124. X};
  125. X
  126. X
  127. X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
  128. XULONG crc_32_tab[] = {
  129. X  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  130. X  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  131. X  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  132. X  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  133. X  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  134. X  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  135. X  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  136. X  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  137. X  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  138. X  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  139. X  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  140. X  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  141. X  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  142. X  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  143. X  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  144. X  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  145. X  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  146. X  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  147. X  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  148. X  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  149. X  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  150. X  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  151. X  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  152. X  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  153. X  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  154. X  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  155. X  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  156. X  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  157. X  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  158. X  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  159. X  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  160. X  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  161. X  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  162. X  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  163. X  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  164. X  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  165. X  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  166. X  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  167. X  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  168. X  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  169. X  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  170. X  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  171. X  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  172. X  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  173. X  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  174. X  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  175. X  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  176. X  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  177. X  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  178. X  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  179. X  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  180. X  0x2d02ef8dL
  181. X};
  182. X
  183. X
  184. XULONG updcrc(s, n)
  185. Xbyte *s;                /* pointer to bytes to pump through */
  186. Xint n;                  /* number of bytes in s[] */
  187. X/* Run a set of bytes through the crc shift register.  If s is a NULL
  188. X   pointer, then initialize the crc shift register contents instead.
  189. X   Return the current crc in either case. */
  190. X{
  191. X  register ULONG c;       /* temporary variable */
  192. X
  193. X  static ULONG crc = 0xffffffffL; /* shift register contents */
  194. X
  195. X  if (s == NULL)
  196. X    c = 0xffffffffL;
  197. X  else
  198. X  {
  199. X    c = crc;
  200. X    while (n--)
  201. X      c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
  202. X  }
  203. X  crc = c;
  204. X  return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
  205. X}
  206. X
  207. X
  208. Xvoid err(n, m)
  209. Xint n;
  210. Xchar *m;
  211. X/* Exit on error with a message and a code */
  212. X{
  213. X  fprintf(stderr, "funzip error: %s\n", m);
  214. X  exit(n);
  215. X}
  216. X
  217. X
  218. Xint ReadByte(b)
  219. XUWORD *b;
  220. X/* Used by inflate.c to get a byte (archaism from unzip) */
  221. X{
  222. X  register int c = getc(in);
  223. X
  224. X  if (c == EOF)
  225. X    return 0;
  226. X#ifdef CRYPT
  227. X  if (decrypt)
  228. X    update_keys(c ^= decrypt_byte());
  229. X#endif /* CRYPT */
  230. X  *b = (UWORD)c;
  231. X  return 8;
  232. X}
  233. X
  234. X
  235. Xint FlushOutput()
  236. X/* Empty output buffer */
  237. X{
  238. X  if (outcnt)
  239. X  {
  240. X    updcrc(outbuf, outcnt);
  241. X    if (fwrite(outbuf, 1, outcnt, out) != outcnt)
  242. X      err(9, "out of space on stdout");
  243. X    outsiz += outcnt;
  244. X    outptr = outbuf;
  245. X    outcnt = 0;
  246. X  }
  247. X  return 0;
  248. X}
  249. X
  250. X
  251. Xvoid main(argc, argv)
  252. Xint argc;
  253. Xchar **argv;
  254. X/* Given a zip file on stdin, decompress the first entry to stdout. */
  255. X{
  256. X  byte h[LOCHDR];               /* first local header */
  257. X
  258. X  /* if stdin not redirected, give the user help */
  259. X  if (isatty(0))
  260. X  {
  261. X    fprintf(stderr,
  262. X#ifdef CRYPT
  263. X      "usage: funzip [password] < infile.zip > outfile\n");
  264. X#else /* !CRYPT */
  265. X      "usage: funzip < infile.zip > outfile\n");
  266. X#endif /* ?CRYPT */
  267. X    fprintf(stderr,
  268. X      "       extracts to stdout the first zip entry of stdin.\n");
  269. X    exit(3);
  270. X  }
  271. X
  272. X  /* prepare to be a binary filter */
  273. X  if ((outbuf = (byte *)malloc(OUTBUFSIZ)) == NULL)
  274. X    err(1, "out of memory");
  275. X  if ((in = fdopen(0, FOPR)) == NULL)
  276. X    err(2, "cannot find stdin");
  277. X  if ((out = fdopen(1, FOPW)) == NULL)
  278. X    err(2, "cannot write to stdout");
  279. X
  280. X  /* read local header, check validity, and skip name and extra fields */
  281. X  if (fread((char *)h, 1, LOCHDR, in) != LOCHDR || LG(h) != LOCSIG)
  282. X    err(3, "input not a zip file or empty");
  283. X  if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
  284. X    err(3, "first entry not deflated or stored--can't funzip");
  285. X  fseek(in, (long)(SH(h + LOCFIL)) + (long)(SH(h + LOCEXT)), 1);
  286. X
  287. X  /* if entry encrypted, decrypt and validate encryption header */
  288. X  if ((decrypt = h[LOCFLG] & CRPFLG) != 0)
  289. X#ifdef CRYPT
  290. X  {
  291. X    UWORD i, e;
  292. X
  293. X    if (argc < 2)
  294. X      err(3, "need password on command line for encrypted entry");
  295. X    init_keys(argv[1]);
  296. X    for (i = 0; i < 10; i++)
  297. X      ReadByte(&e);
  298. X    ReadByte(&e);
  299. X    ReadByte(&i);
  300. X    e += i << 8;
  301. X    if (e != (h[LOCFLG] & EXTFLG ? SH(h + LOCTIM) : SH(h + LOCCRC + 2)))
  302. X      err(3, "incorrect password for first entry");
  303. X  }
  304. X#else /* !CRYPT */
  305. X    err(3, "cannot decrypt entry (need to recompile funzip with crypt.c)");
  306. X#endif /* ?CRYPT */
  307. X
  308. X  /* prepare output buffer and crc */
  309. X  outptr = outbuf;
  310. X  outcnt = 0;
  311. X  outsiz = 0L;
  312. X  updcrc(NULL, 0);
  313. X
  314. X  /* decompress */
  315. X  if (h[LOCHOW])
  316. X  {                             /* deflated entry */
  317. X    if (inflate_entry())
  318. X      err(4, "invalid compressed data or out of memory");
  319. X  }
  320. X  else
  321. X  {                             /* stored entry */
  322. X    register ULONG n;
  323. X
  324. X    n = LG(h + LOCLEN);
  325. X    if (n != LG(h + LOCSIZ))
  326. X      err(4, "invalid compressed data--length mismatch");
  327. X    while (n--)
  328. X      OUTB(getc(in));
  329. X  }
  330. X  FlushOutput();
  331. X  fflush(out);
  332. X
  333. X  /* if extended header, get it */
  334. X  if ((h[LOCFLG] & EXTFLG) &&
  335. X      fread((char *)h + LOCCRC - 4, 1, EXTHDR, in) != EXTHDR)
  336. X    err(3, "zip file ended prematurely");
  337. X
  338. X  /* validate decompression */
  339. X  if (LG(h + LOCCRC) != updcrc(outbuf, 0))
  340. X    err(4, "invalid compressed data--crc error");
  341. X  if (LG(h + LOCLEN) != outsiz)
  342. X    err(4, "invalid compressed data--length error");
  343. X
  344. X  /* check if there are more entries */
  345. X  if (fread((char *)h, 1, 4, in) == 4 && LG(h) == LOCSIG)
  346. X    fprintf(stderr,
  347. X      "funzip warning: zip file has more than one entry--rest ignored\n");
  348. X}
  349. END_OF_FILE
  350.   if test 11324 -ne `wc -c <'funzip.c'`; then
  351.     echo shar: \"'funzip.c'\" unpacked with wrong size!
  352.   fi
  353.   # end of 'funzip.c'
  354. fi
  355. if test -f 'unzip.c.A' -a "${1}" != "-c" ; then 
  356.   echo shar: Will not clobber existing file \"'unzip.c.A'\"
  357. else
  358.   echo shar: Extracting \"'unzip.c.A'\" \(29228 characters\)
  359.   sed "s/^X//" >'unzip.c.A' <<'END_OF_FILE'
  360. X/*---------------------------------------------------------------------------
  361. X
  362. X  unzip.c
  363. X
  364. X  UnZip - a zipfile extraction utility.  See below for make instructions, or
  365. X  read the comments in Makefile and the various Contents files for more de-
  366. X  tailed explanations.  To report a bug, send a *complete* description to
  367. X  zip-bugs@cs.ucla.edu; include machine type, operating system and version,
  368. X  compiler and version, and reasonably detailed error messages or problem
  369. X  report.  To join Info-ZIP, send a message to info-zip-request@cs.ucla.edu.
  370. X
  371. X  UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
  372. X  which in turn was almost a complete rewrite of version 3.x.  For a detailed
  373. X  revision history, see UnzpHist.zip at Info-ZIP headquarters (below).  For a 
  374. X  (partial) list of the many (near infinite) contributors, see "CONTRIBS" in
  375. X  the UnZip source distribution.
  376. X
  377. X  ---------------------------------------------------------------------------
  378. X
  379. X  To compile (partial instructions):
  380. X
  381. X     under Unix (cc):  make <system name>
  382. X       (type "make list" for a list of valid names, or read Makefile for 
  383. X       details.  "make unzip" works for most systems.  If you have a NEW
  384. X       system, not covered by any of the existing targets, send FULL infor-
  385. X       mation--hardware, OS, versions, etc.--to zip-bugs@cs.ucla.edu)
  386. X
  387. X     under MS-DOS (MSC, Turbo C, or Borland C++):  use the makefiles or
  388. X       project files in the MSDOS sub-archive; edit or otherwise modify
  389. X       as appropriate.  For MSC, use NMAKE.
  390. X
  391. X     under MS Windows 3.x:  get wunz12sr.{zip | zoo | whatever} and use
  392. X       the included makefile
  393. X
  394. X     under OS/2 (MSC, gcc, IBM C Set/2, Watcom C):  make -f makefile.os2
  395. X       (from OS2 sub-archive; for MSC, use NMAKE)
  396. X
  397. X     under VMS (VAX C or GNU C):  @make_unzip_vaxc  or  @make_unzip_gcc
  398. X       (from VMS sub-archive; can also use MMS or MAKE/VMS; see VMS.notes)
  399. X
  400. X     under Macintosh OS:  Double click on unzip.make.  Press <Command>-M.
  401. X       (from MAC sub-archive)
  402. X
  403. X     under Windows NT:  use makefile.nt (from NT sub-archive)
  404. X
  405. X     under AmigaDOS:  try one of the makefiles in the AMIGA sub-archive;
  406. X       may need some work yet...
  407. X
  408. X     under Atari TOS:  needs considerable work yet...
  409. X
  410. X  ---------------------------------------------------------------------------
  411. X
  412. X  Version:  unzip50.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Windows,
  413. X              Windows NT, Macintosh and Amiga.  Decryption requires sources
  414. X              in zcrypt19.zip, and Windows (not NT) support requires sources
  415. X              in wunz12sr.zip.  See accompanying file "Where" in the main
  416. X              source distribution for ftp, uucp and mail-server sites.
  417. X  Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  418. X
  419. X  ---------------------------------------------------------------------------*/
  420. X
  421. X
  422. X
  423. X
  424. X
  425. X#include "unzip.h"               /* includes, defines, and macros */
  426. X#ifdef MSWIN
  427. X#  include "wizunzip.h"          /* see History.500 for version history */
  428. X#endif
  429. X
  430. X#define VERSION  "v5.0 of 21 August 1992"
  431. X/* #define VERSION  "v5.0p BETA of 8-21-92" */   /* internal beta level */
  432. X#define PAKFIX   /* temporary(?) solution to PAK-created zipfiles */
  433. X
  434. X
  435. X
  436. X
  437. X
  438. X/**********************/
  439. X/*  Global Variables  */
  440. X/**********************/
  441. X
  442. Xint aflag=0;          /* -a: do ASCII to EBCDIC translation, or CR-LF  */
  443. X                      /*     to CR or LF conversion of extracted files */
  444. X/* int bflag=0; RESERVED for -b: extract as binary */
  445. Xint cflag=0;          /* -c: output to stdout */
  446. Xint fflag=0;          /* -f: "freshen" (extract only newer files) */
  447. Xint jflag=0;          /* -j: junk pathnames */
  448. Xint overwrite_none=0; /* -n: never overwrite files (no prompting) */
  449. Xint overwrite_all=0;  /* -o: OK to overwrite files without prompting */
  450. Xint force_flag=0;     /* (shares -o for now): force to override errors, etc. */
  451. Xint quietflg=0;       /* -q: produce a lot less output */
  452. X#ifdef DOS_OS2
  453. X   int sflag=1;       /* -s: allow spaces (blanks) in filenames */
  454. X#endif /* DOS_OS2 */
  455. Xint tflag=0;          /* -t: test */
  456. Xint uflag=0;          /* -u: "update" (extract only newer & brand-new files) */
  457. Xstatic int U_flag=0;  /* -U: leave filenames in upper or mixed case */
  458. Xstatic int vflag=0;   /* -v: view directory (only used in unzip.c) */
  459. Xint V_flag=0;         /* -V: don't strip VMS version numbers */
  460. X#ifdef VMS
  461. X   int secinf=0;      /* -X: keep owner/protection */
  462. X#endif /* VMS */
  463. Xint zflag=0;          /* -z: display only the archive comment */
  464. Xint process_all_files=0;
  465. X
  466. Xlongint csize;        /* used by list_files(), ReadByte(): must be signed */
  467. Xlongint ucsize;       /* used by list_files(), unReduce(), explode() */
  468. X
  469. Xchar *fnames[2] = {"*", NULL};   /* default filenames vector */
  470. Xchar **fnv = fnames;
  471. Xchar sig[5];
  472. Xchar answerbuf[10];
  473. X
  474. Xmin_info info[DIR_BLKSIZ], *pInfo=info;
  475. X
  476. X#ifdef OS2
  477. X   int longname;              /* used in extract.c, mapname.c and file_io.c */
  478. X   char longfilename[FILNAMSIZ];
  479. X#endif /* OS2 */
  480. X
  481. X#ifdef CRYPT
  482. X   char *key = (char *)NULL;  /* password with which to decrypt data, or NULL */
  483. X#endif /* CRYPT */
  484. X
  485. X/*---------------------------------------------------------------------------
  486. X    unShrink/unReduce/explode/inflate working storage and globals:
  487. X  ---------------------------------------------------------------------------*/
  488. X
  489. Xunion work area;              /* see unzip.h for the definition of work */
  490. XULONG crc32val;
  491. X
  492. XUWORD mask_bits[] = {
  493. X    0x0000,
  494. X    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
  495. X    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
  496. X};
  497. X
  498. X/*---------------------------------------------------------------------------
  499. X    Input file variables:
  500. X  ---------------------------------------------------------------------------*/
  501. X
  502. Xbyte *inbuf, *inptr;     /* input buffer (any size is legal) and pointer */
  503. Xint incnt;
  504. X
  505. XULONG bitbuf;
  506. Xint bits_left;
  507. Xboolean zipeof;
  508. X
  509. Xint zipfd;               /* zipfile file handle */
  510. X#ifdef MSWIN
  511. X   char *zipfn;
  512. X#else
  513. X   char zipfn[FILNAMSIZ];
  514. X#endif
  515. X
  516. Xchar local_hdr_sig[5] = "\120";    /* remaining signature bytes come later   */
  517. Xchar central_hdr_sig[5] = "\120";  /*  (must initialize at runtime so unzip  */
  518. Xchar end_central_sig[5] = "\120";  /*  executable won't look like a zipfile) */
  519. X/* char extd_local_sig[5] = "\120";  NOT USED YET */
  520. X
  521. Xcdir_file_hdr crec;      /* used in unzip.c, extract.c, misc.c */
  522. Xlocal_file_hdr lrec;     /* used in unzip.c, extract.c */
  523. Xecdir_rec ecrec;         /* used in unzip.c, extract.c */
  524. Xstruct stat statbuf;     /* used by main(), mapped_name(), check_for_newer() */
  525. X
  526. Xlongint extra_bytes = 0;        /* used in unzip.c, misc.c */
  527. Xlongint cur_zipfile_bufstart;   /* extract_or_test_files, readbuf, ReadByte */
  528. X  
  529. X#ifdef MACOS
  530. X   short  gnVRefNum;
  531. X   long  glDirID;
  532. X   OSType  gostCreator;
  533. X   OSType  gostType;
  534. X   boolean  fMacZipped;
  535. X   boolean  macflag;
  536. X   CursHandle  rghCursor[4];    /* status cursors */
  537. X   short  giCursor = 0;
  538. X#endif
  539. X
  540. X/*---------------------------------------------------------------------------
  541. X    Output stream variables:
  542. X  ---------------------------------------------------------------------------*/
  543. X
  544. Xbyte *outbuf;                   /* buffer for rle look-back */
  545. Xbyte *outptr;
  546. X#ifdef MSWIN
  547. X   byte __far *outout;
  548. X   char *filename;
  549. X#else /* !MSWIN */
  550. X   byte *outout;                /* scratch pad for ASCII-native trans */
  551. X   char filename[FILNAMSIZ];
  552. X#endif /* ?MSWIN */
  553. Xbyte *extra_field = (byte *)NULL;  /* used by VMS, Mac and OS/2 versions */
  554. Xlongint outpos;                 /* absolute position in outfile */
  555. Xint outcnt;                     /* current position in outbuf */
  556. Xint outfd;
  557. Xint mem_mode = 0;
  558. Xint disk_full;
  559. X
  560. X/*---------------------------------------------------------------------------
  561. X    unzip.c static global variables (visible only within this file):
  562. X  ---------------------------------------------------------------------------*/
  563. X
  564. Xstatic byte *hold;
  565. Xstatic char unkn[10];
  566. Xstatic longint ziplen;
  567. Xstatic UWORD methnum;
  568. X
  569. X/*---------------------------------------------------------------------------
  570. X    unzip.c repeated error messages (we use all of these at least twice)
  571. X  ---------------------------------------------------------------------------*/
  572. X
  573. Xchar *EndSigMsg = "\nwarning:\
  574. X  didn't find end-of-central-dir signature at end of central dir.\n";
  575. Xchar *CentSigMsg =
  576. X  "error:  expected central file header signature not found (file #%u).\n";
  577. Xchar *SeekMsg =
  578. X  "error:  attempt to seek before beginning of zipfile\n%s";
  579. X
  580. X#ifdef VMS
  581. Xchar *ReportMsg = "\
  582. X  (please check that you have transferred or created the zipfile in the\n\
  583. X  appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
  584. X#else /* !VMS */
  585. Xchar *ReportMsg = "\
  586. X  (please check that you have transferred or created the zipfile in the\n\
  587. X  appropriate BINARY mode and that you have compiled unzip properly)\n";
  588. X#endif /* ?VMS */
  589. X
  590. X
  591. X#ifdef MSWIN
  592. X/* MS Windows Setup  and Take-Down functions bracket calls to 
  593. X * process_zipfile().
  594. X * These functions allocate and free the necessary buffers, set and clear
  595. X * any global variables so that  process_zipfile()  can be called multiple
  596. X * times in the same session of WizUnzip. You'll recognize some of the 
  597. X * code from main() in SetUpToProcessZipFile().
  598. X */
  599. XHANDLE hOutBuf;
  600. XHANDLE hOutOut;   /* added 04/03/92 for version 1.1 */
  601. XHANDLE hInBuf;
  602. XHANDLE hZipFN;
  603. XHANDLE hFileName;
  604. X
  605. XBOOL FSetUpToProcessZipFile(int ncflag, int ntflag, int nvflag, int nUflag, 
  606. X       int nzflag, int ndflag, int noflag, int naflag, int argc,
  607. X       LPSTR lpszZipFN, PSTR *FNV)
  608. X{
  609. X    /* clear all global flags -- need to or not. */
  610. X
  611. X    tflag = vflag=cflag=aflag=U_flag=quietflg=zflag = 0;
  612. X    overwrite_all=overwrite_none=0;
  613. X    fnv = &fnames[0];       /* assign default file name vector */
  614. X
  615. X    cflag = ncflag ; overwrite_all = noflag;
  616. X    tflag = ntflag ; vflag = nvflag; zflag = nzflag; U_flag = nUflag;
  617. X    aflag = naflag;
  618. X    sflag = 1;
  619. X
  620. X    local_hdr_sig[0] = central_hdr_sig[0] = end_central_sig[0] = '\120';
  621. X    local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
  622. X
  623. X    if (!(hZipFN = LocalAlloc(LMEM_MOVEABLE, FILNAMSIZ)))
  624. X        return FALSE;
  625. X
  626. X    zipfn = (char *)LocalLock(hZipFN);
  627. X    lstrcpy(zipfn, lpszZipFN);
  628. X    if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR)
  629. X        strcat(zipfn, ZSUFX);
  630. X
  631. X    if (stat(zipfn, &statbuf)) {  /* try again */
  632. X        fprintf(stderr, "error:  can't find zipfile [ %s ]\n", zipfn);
  633. X        return TRUE;              /* 9:  file not found */
  634. X    } else
  635. X        ziplen = statbuf.st_size;
  636. X
  637. X    if (argc != 0) {
  638. X        fnv = FNV;
  639. X        process_all_files = FALSE;
  640. X    } else
  641. X        process_all_files = TRUE;       /* for speed */
  642. X
  643. X/*---------------------------------------------------------------------------
  644. X    Okey dokey, we have everything we need to get started.  Let's roll.
  645. X  ---------------------------------------------------------------------------*/
  646. X
  647. X    if (hInBuf = LocalAlloc(LMEM_MOVEABLE, INBUFSIZ+4)) {  /* 4 extra: hold[] */
  648. X        inbuf = (byte *) LocalLock(hInBuf);
  649. X        WinAssert(inbuf);
  650. X    }
  651. X    if (hOutBuf = LocalAlloc(LMEM_MOVEABLE, OUTBUFSIZ+1)) {  /* extra: ASCIIZ */
  652. X        outbuf = (byte *)LocalLock(hOutBuf);
  653. X        WinAssert(outbuf);
  654. X        if (aflag) {   /* if LF => CR,LF translation */
  655. X            if (hOutOut = GlobalAlloc(GMEM_MOVEABLE,OUTBUFSIZ)) {
  656. X                outout = (byte _far *)GlobalLock(hOutOut);
  657. X                WinAssert(outout);
  658. X            }
  659. X        } else    /* no translation; just re-use output buffer */
  660. X            outout = (byte _far *)outbuf;  /*  point to outbuf */
  661. X    }
  662. X    if ( hFileName = LocalAlloc(LMEM_MOVEABLE, FILNAMSIZ)) {
  663. X        filename = (char *)LocalLock(hFileName);
  664. X        WinAssert(filename);
  665. X    }
  666. X
  667. X    if ((inbuf == NULL) || (outbuf == NULL) || (outout == NULL) ||
  668. X        (zipfn == NULL) || (filename == NULL))
  669. X        return FALSE;
  670. X
  671. X    hold = &inbuf[INBUFSIZ];   /* to check for boundary-spanning signatures */
  672. X
  673. X    return TRUE;    /* set up was OK */
  674. X}
  675. X
  676. Xvoid TakeDownFromProcessZipFile(void)
  677. X{
  678. X    if (inbuf) {
  679. X        LocalUnlock(hInBuf);
  680. X        inbuf = NULL;
  681. X    }
  682. X    if (hInBuf)
  683. X        hInBuf = LocalFree(hInBuf);
  684. X
  685. X    if (outbuf) {
  686. X        LocalUnlock(hOutBuf);
  687. X        outbuf = NULL;
  688. X    }
  689. X    if (hOutBuf)
  690. X        hOutBuf = LocalFree(hOutBuf);
  691. X
  692. X    if (aflag && outout)    /* if doing LF => CR,LF translation */
  693. X        GlobalUnlock(hOutOut);
  694. X    outout = NULL;          /* free now, translation or not     */
  695. X    if (hOutOut)
  696. X        hOutOut = GlobalFree(hOutOut);  /* mark buffer as freed */
  697. X
  698. X    if (zipfn) {
  699. X        LocalUnlock(hZipFN);
  700. X        zipfn = NULL;
  701. X    }
  702. X    if (hZipFN)
  703. X        hZipFN = LocalFree(hZipFN);
  704. X
  705. X    if (filename) {
  706. X        LocalUnlock(hFileName);
  707. X        filename = NULL;
  708. X    }
  709. X    if (hFileName)
  710. X        hFileName = LocalFree(hFileName);
  711. X}
  712. X
  713. X#else /* !MSWIN */
  714. X
  715. X/******************/
  716. X/*  Main program  */
  717. X/******************/
  718. X
  719. Xint main(argc, argv)   /* return PK-type error code (except under VMS) */
  720. X    int argc;
  721. X    char *argv[];
  722. X{
  723. X    char *s;
  724. X    int c, error=FALSE, negative=0;
  725. X
  726. X
  727. X/*---------------------------------------------------------------------------
  728. X    Macintosh initialization code.
  729. X  ---------------------------------------------------------------------------*/
  730. X
  731. X#ifdef MACOS
  732. X#ifdef THINK_C
  733. X#   include <console.h>
  734. X    static char *argstr[30], args[30*64];
  735. X    Point p;
  736. X    SFTypeList sfT;
  737. X    EventRecord theEvent;
  738. X    short eMask;
  739. X    SFReply fileRep;
  740. X#endif /* THINK_C */
  741. X    int a;
  742. X
  743. X    for (a = 0;  a < 4;  ++a)
  744. X        rghCursor[a] = GetCursor(a+128);
  745. X    giCursor = 0;
  746. X
  747. X    area.Slide = (byte *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
  748. X    area.shrink.Prefix_of = (short *)area.Slide;
  749. X    area.shrink.Suffix_of = area.Slide + (sizeof(short)*(HSIZE+1));
  750. X    area.shrink.Stack = area.Slide + (sizeof(short) + sizeof(char))*(HSIZE+1);
  751. X
  752. X#ifdef THINK_C   
  753. X    for (a = 0;  a < 30;  ++a)
  754. X        argstr[a] = &args[a*64];
  755. Xstart:
  756. X    tflag=vflag=cflag=aflag=jflag=U_flag=quietflg=fflag=uflag=zflag = 0;
  757. X    local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
  758. X/*  extd_local_sig[1] = '\0';  */
  759. X    error = FALSE;
  760. X
  761. X    argc = ccommand(&argv);
  762. X    SetPt(&p, 40, 40);
  763. X
  764. X    SFGetFile(p, "\pSpecify ZIP file:", 0L, -1, sfT, 0L, &fileRep);
  765. X    if (fileRep.good) {
  766. X        macfstest(fileRep.vRefNum);
  767. X        ResolveMacVol(fileRep.vRefNum, &gnVRefNum, &glDirID, NULL);
  768. X        for (a = 1;  a < argc;  ++a)
  769. X            if (argv[a][0] == '-')
  770. X                BlockMove(argv[a], argstr[a], (strlen(argv[a]) > 63) ? 64 :
  771. X                   strlen(argv[a])+1);
  772. X            else
  773. X                break;
  774. X        PtoCstr((char *)fileRep.fName);
  775. X        strcpy(argstr[a], (char *)fileRep.fName);
  776. X        for (;  a < argc;  ++a)
  777. X            BlockMove(argv[a], argstr[a+1], (strlen(argv[a]) > 63) ? 64 :
  778. X               strlen(argv[a])+1);
  779. X        ++argc;
  780. X        argv = argstr;
  781. X
  782. X        if (hfsflag == FALSE)  /* can't support directories:  junk pathnames */
  783. X            jflag = 1;
  784. X    }
  785. X#endif /* THINK_C */
  786. X#endif /* MACOS */
  787. X
  788. X/*---------------------------------------------------------------------------
  789. X    Set signal handler for restoring echo, warn of zipfile corruption, etc.
  790. X  ---------------------------------------------------------------------------*/
  791. X
  792. X    signal(SIGINT, handler);
  793. X    signal(SIGTERM, handler);
  794. X#ifdef SIGBUS
  795. X    signal(SIGBUS, handler);
  796. X#endif
  797. X#ifdef SIGSEGV
  798. X    signal(SIGSEGV, handler);
  799. X#endif
  800. X
  801. X/*---------------------------------------------------------------------------
  802. X    Debugging info for checking on structure padding:
  803. X  ---------------------------------------------------------------------------*/
  804. X
  805. X#ifdef DEBUG_STRUC
  806. X    printf("local_file_hdr size: %X\n",
  807. X           sizeof(local_file_hdr));
  808. X    printf("local_byte_hdr size: %X\n",
  809. X           sizeof(local_byte_hdr));
  810. X    printf("actual size of local headers: %X\n", LREC_SIZE);
  811. X
  812. X    printf("central directory header size: %X\n",
  813. X           sizeof(cdir_file_hdr));
  814. X    printf("central directory byte header size: %X\n",
  815. X           sizeof(cdir_byte_hdr));
  816. X    printf("actual size of central dir headers: %X\n", CREC_SIZE);
  817. X
  818. X    printf("end central dir record size: %X\n",
  819. X           sizeof(ecdir_rec));
  820. X    printf("end central dir byte record size: %X\n",
  821. X           sizeof(ec_byte_rec));
  822. X    printf("actual size of end-central-dir record: %X\n", ECREC_SIZE);
  823. X#endif /* DEBUG_STRUC */
  824. X
  825. X/*---------------------------------------------------------------------------
  826. X    Put environment-variable options into the queue, then rip through any
  827. X    command-line options lurking about...
  828. X  ---------------------------------------------------------------------------*/
  829. X
  830. X    envargs(&argc, &argv, ENV_UNZIP);
  831. X
  832. X    while (--argc > 0 && (*++argv)[0] == '-') {
  833. X        s = argv[0] + 1;
  834. X        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
  835. X            switch (c) {
  836. X                case ('-'):
  837. X                    ++negative;
  838. X                    break;
  839. X                case ('a'):
  840. X                    if (negative)
  841. X                        aflag = FALSE, negative = 0;
  842. X                    else
  843. X                        aflag = TRUE;
  844. X                    break;
  845. X#if 0
  846. X                case ('b'):    /* force binary mode */
  847. X                    if (negative)
  848. X                        bflag = FALSE, negative = 0;
  849. X                    else
  850. X                        bflag = TRUE;
  851. X                    break;
  852. X#endif
  853. X                case ('c'):
  854. X                    if (negative) {
  855. X                        cflag = FALSE, negative = 0;
  856. X#ifdef NATIVE
  857. X                        aflag = FALSE;
  858. X#endif
  859. X                    } else {
  860. X                        cflag = TRUE;
  861. X#ifdef NATIVE
  862. X                        aflag = TRUE;  /* so you can read it on the screen */
  863. X#endif
  864. X                    }
  865. X                    break;
  866. X                case ('d'):    /* re-create directory structure (default) */
  867. X                    if (negative)
  868. X                        jflag = TRUE, negative = 0;
  869. X                    break;
  870. X                case ('e'):    /* just ignore -e, -x options (extract) */
  871. X                    break;
  872. X                case ('f'):    /* "freshen" (extract only newer files) */
  873. X                    if (negative)
  874. X                        fflag = uflag = FALSE, negative = 0;
  875. X                    else
  876. X                        fflag = uflag = TRUE;
  877. X                    break;
  878. X                case ('j'):    /* junk pathnames/directory structure */
  879. X                    if (negative)
  880. X                        jflag = FALSE, negative = 0;
  881. X                    else
  882. X                        jflag = TRUE;
  883. X                    break;
  884. X                case ('l'):
  885. X                    if (negative) {
  886. X                        vflag = MAX(vflag-negative,0);
  887. X                        negative = 0;
  888. X                    } else
  889. X                        ++vflag;
  890. X                    break;
  891. X                case ('n'):    /* don't overwrite any files */
  892. X                    if (negative)
  893. X                        overwrite_none = FALSE, negative = 0;
  894. X                    else
  895. X                        overwrite_none = TRUE;
  896. X                    break;
  897. X                case ('o'):    /* OK to overwrite files without prompting */
  898. X                    if (negative) {
  899. X                        overwrite_all = MAX(overwrite_all-negative,0);
  900. X                        force_flag = MAX(force_flag-negative,0);
  901. X                        negative = 0;
  902. X                    } else {
  903. X                        ++overwrite_all;
  904. X                        ++force_flag;  /* (share -o for now) force to cont. */
  905. X                    }
  906. X                    break;
  907. X                case ('p'):    /* pipes:  stdout, no tranlation, no messages */
  908. X                    if (negative) {
  909. X                        cflag = FALSE;
  910. X                        quietflg = MAX(quietflg-999,0);
  911. X                        negative = 0;
  912. X                    } else {
  913. X                        cflag = TRUE;
  914. X                        quietflg += 999;
  915. X                    }
  916. X                    break;
  917. X                case ('q'):    /* quiet:  fewer comments/messages */
  918. X                    if (negative) {
  919. X                        quietflg = MAX(quietflg-negative,0);
  920. X                        negative = 0;
  921. X                    } else
  922. X                        ++quietflg;
  923. X                    break;
  924. X#ifdef DOS_OS2
  925. X                case ('s'):    /* spaces in filenames:  allow by default */
  926. X                    if (negative)
  927. X                        sflag = TRUE, negative = 0;
  928. X                    else
  929. X                        sflag = FALSE;
  930. X                    break;
  931. X#endif
  932. X                case ('t'):
  933. X                    if (negative)
  934. X                        tflag = FALSE, negative = 0;
  935. X                    else
  936. X                        tflag = TRUE;
  937. X                    break;
  938. X                case ('U'):    /* Uppercase (don't convert to all-lower) */
  939. X                    if (negative)
  940. X                        U_flag = FALSE, negative = 0;
  941. X                    else
  942. X                        U_flag = TRUE;
  943. X                    break;
  944. X                case ('u'):    /* update (extract only new and newer files) */
  945. X                    if (negative)
  946. X                        uflag = FALSE, negative = 0;
  947. X                    else
  948. X                        uflag = TRUE;
  949. X                    break;
  950. X                case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
  951. X                    if (negative)
  952. X                        V_flag = FALSE, negative = 0;
  953. X                    else
  954. X                        V_flag = TRUE;
  955. X                    break;
  956. X                case ('v'):    /* verbose */
  957. X                    if (negative) {
  958. X                        vflag = MAX(vflag-negative,0);
  959. X                        negative = 0;
  960. X                    } else if (vflag)
  961. X                        ++vflag;
  962. X                    else
  963. X                        vflag = 2;
  964. X                    break;
  965. X#ifdef VMS
  966. X                case ('X'):   /* restore owner/protection info (need privs?) */
  967. X                    if (negative)
  968. X                        secinf = FALSE, negative = 0;
  969. X                    else
  970. X                        secinf = TRUE;
  971. X                    break;
  972. X#endif /* VMS */
  973. X                case ('x'):    /* extract:  default */
  974. X                    break;
  975. X                case ('z'):    /* display only the archive comment */
  976. X                    if (negative) {
  977. X                        zflag = MAX(zflag-negative,0);
  978. X                        negative = 0;
  979. X                    } else
  980. X                        ++zflag;
  981. X                    break;
  982. X                default:
  983. X                    error = TRUE;
  984. X                    break;
  985. X
  986. X            } /* end switch */
  987. X        } /* end while (not end of argument string) */
  988. X    } /* end while (not done with switches) */
  989. X
  990. X/*---------------------------------------------------------------------------
  991. X    Make sure we aren't trying to do too many things here.  [This seems like
  992. X    kind of a brute-force way to do things; but aside from that, isn't the
  993. X    -a option useful when listing the directory (i.e., for reading zipfile
  994. X    comments)?  It's a modifier, not an action in and of itself, so perhaps
  995. X    it should not be included in the test--certainly, in the case of zipfile
  996. X    testing, it can just be ignored.]
  997. X  ---------------------------------------------------------------------------*/
  998. X
  999. X    if ((aflag && tflag) || (aflag && vflag) || (cflag && tflag) ||
  1000. X        (cflag && uflag) || (cflag && vflag) || (tflag && uflag) ||
  1001. X        (tflag && vflag) || (uflag && vflag) || (fflag && overwrite_none)) {
  1002. X        fprintf(stderr, "error:\
  1003. X  -at, -av, -ct, -cu, -cv, -fn, -tu, -tv, -uv combinations not allowed\n");
  1004. X        error = TRUE;
  1005. X    }
  1006. X    if (quietflg && zflag)
  1007. X        quietflg = 0;
  1008. X    if (overwrite_all && overwrite_none) {
  1009. X        fprintf(stderr, "caution:  both -n and -o specified; ignoring -o\n");
  1010. X        overwrite_all = FALSE;
  1011. X    }
  1012. X    if ((argc-- == 0) || error)
  1013. X        RETURN(usage(error));
  1014. X
  1015. X/*---------------------------------------------------------------------------
  1016. X    Now get the zipfile name from the command line and see if it exists as a
  1017. X    regular (non-directory) file.  If not, append the ".zip" suffix.  We don't
  1018. X    immediately check to see if this results in a good name, but we will do so
  1019. X    later.  In the meantime, see if there are any member filespecs on the com-
  1020. X    mand line, and if so, set the filename pointer to point at them.
  1021. X  ---------------------------------------------------------------------------*/
  1022. X
  1023. X    strcpy(zipfn, *argv++);
  1024. X    if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR)
  1025. X        strcat(zipfn, ZSUFX);
  1026. X#if (defined(UNIX) && !defined(VMS)) /* Unix executables have no extension-- */
  1027. X    else if (statbuf.st_mode & S_IXUSR)  /* might find zip, not zip.zip; etc */
  1028. X        fprintf(stderr, "\nnote:  file [ %s ] may be an executable\n\n", zipfn);
  1029. X#endif /* UNIX && !VMS */
  1030. X
  1031. X    if (stat(zipfn, &statbuf)) {/* try again */
  1032. X        fprintf(stderr, "error:  can't find zipfile [ %s ]\n", zipfn);
  1033. X        RETURN(9);              /* 9:  file not found */
  1034. X    } else
  1035. X        ziplen = statbuf.st_size;
  1036. X
  1037. X    if (argc != 0) {
  1038. X        fnv = argv;
  1039. X        process_all_files = FALSE;
  1040. X    } else
  1041. X        process_all_files = TRUE;       /* for speed */
  1042. X
  1043. X/*---------------------------------------------------------------------------
  1044. X    Okey dokey, we have everything we need to get started.  Let's roll.
  1045. X  ---------------------------------------------------------------------------*/
  1046. X
  1047. X    inbuf = (byte *) malloc(INBUFSIZ + 4);     /* 4 extra for hold[] (below) */
  1048. X    outbuf = (byte *) malloc(OUTBUFSIZ + 1);   /* 1 extra for string termin. */
  1049. X#ifndef DOS_OS2
  1050. X    if (aflag)                  /* if need an ascebc scratch, */
  1051. X        outout = (byte *) malloc(OUTBUFSIZ);
  1052. X    else                        /*  allocate it... */
  1053. X#endif /* !DOS_OS2 */
  1054. X        outout = outbuf;        /*  else just point to outbuf */
  1055. X
  1056. X    if ((inbuf == (byte *)NULL) || (outbuf == (byte *)NULL) ||
  1057. X        (outout == (byte *)NULL)) {
  1058. X        fprintf(stderr, "error:  can't allocate unzip buffers\n");
  1059. X        RETURN(4);              /* 4-8:  insufficient memory */
  1060. X    }
  1061. X    hold = &inbuf[INBUFSIZ];    /* to check for boundary-spanning signatures */
  1062. X
  1063. X    RETURN(process_zipfile());  /* keep passing errors back... */
  1064. X
  1065. X} /* end main() */
  1066. X
  1067. X
  1068. X
  1069. X
  1070. X
  1071. X/**********************/
  1072. X/*  Function usage()  */
  1073. X/**********************/
  1074. X
  1075. Xint usage(error)   /* return PK-type error code */
  1076. X    int error;
  1077. X{
  1078. X#ifdef NATIVE
  1079. X#ifdef EBCDIC
  1080. X    char *astring = "-a  convert ASCII to EBCDIC";
  1081. X#else /* !EBCDIC */
  1082. X    char *astring = "-a  convert ASCII to native chars";
  1083. X#endif /* ?EBCDIC */
  1084. X/*  char *astring = "-a  convert ASCII to " NATIVE;  (ANSI C concatenation)  */
  1085. X    char *loc_str = "";
  1086. X#else /* !NATIVE */
  1087. X#ifdef DOS_OS2
  1088. X    char *astring = "-a  convert text (LF => CR LF)";
  1089. X    char *loc_str = "-s  spaces in filenames => _";
  1090. X#else /* !DOS_OS2 */
  1091. X#ifdef MACOS
  1092. X    char *astring = "-a  convert text (CR LF => CR)";
  1093. X    char *loc_str = "";
  1094. X#else /* !MACOS:  UNIX, VMS */
  1095. X    char *astring = "-a  convert text (CR LF => LF)";
  1096. X#ifdef VMS
  1097. X    char *loc_str = "-X  restore owner/protection info";
  1098. X#else /* !VMS */
  1099. X    char *loc_str = "";
  1100. X#endif /* ?VMS */
  1101. X#endif /* ?MACOS */
  1102. X#endif /* ?DOS_OS2 */
  1103. X#endif /* ?NATIVE */
  1104. X    FILE *usagefp;
  1105. X
  1106. X
  1107. X/*---------------------------------------------------------------------------
  1108. X    If user requested usage, send it to stdout; else send to stderr.
  1109. X  ---------------------------------------------------------------------------*/
  1110. X
  1111. X    if (error)
  1112. X        usagefp = (FILE *) stderr;
  1113. X    else
  1114. X        usagefp = (FILE *) stdout;
  1115. X
  1116. X    fprintf(usagefp, "\
  1117. XUnZip:  Zipfile Extract %s;  (c) 1989 S.H.Smith and others\n\
  1118. XVersions 3.0 and later by Info-ZIP.  Bug reports ONLY to zip-bugs@cs.ucla.edu\
  1119. X\n\n", VERSION);
  1120. X
  1121. X    fprintf(usagefp, "\
  1122. XUsage: unzip [ -options[modifiers] ] file[.zip] [filespec...]\n\
  1123. X  -x  extract files (default)                -l  list files (short format)\n\
  1124. X  -c  extract files to stdout/screen (CRT)   -v  list files (verbose format)\n\
  1125. X  -f  freshen existing files, create none    -p  extract to pipe, no messages\n\
  1126. X  -u  update files, create if necessary      -t  test archive integrity\n\
  1127. X                                             -z  display archive comment\n\
  1128. Xmodifiers:\n\
  1129. X  -n  never overwrite existing files         %s\n", loc_str);
  1130. X    fprintf(usagefp, "\
  1131. X  -o  overwrite files WITHOUT prompting      %s\n\
  1132. X  -j  junk paths (don't make directories)    -U  don't make names lowercase\n\
  1133. X  -q  quiet mode (-qq => quieter)            -V  retain VMS version numbers\
  1134. X\n\n\
  1135. XExamples: (See manual for more information)\n\
  1136. X  unzip data1 Readme   => extracts file Readme from zipfile data1.zip\n\
  1137. X  unzip -p foo | more  => send contents of foo.zip via pipe into program more\n\
  1138. X  unzip -fo foo        => quietly replace existing files if archive files newer\
  1139. X\n", astring);
  1140. X
  1141. X#ifdef VMS
  1142. X    fprintf(usagefp, "\
  1143. X  unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\
  1144. X\n");
  1145. X#endif
  1146. X
  1147. X    if (error)
  1148. X        return 10;    /* 10:  bad or illegal parameters specified */
  1149. X    else
  1150. X        return 0;     /* just wanted usage screen: no error */
  1151. X
  1152. X} /* end function usage() */
  1153. X
  1154. X#endif /* ?MSWIN */
  1155. X
  1156. X
  1157. X
  1158. END_OF_FILE
  1159.  if test 29228 -ne `wc -c <'unzip.c.A'`; then
  1160.     echo shar: \"'unzip.c.A'\" unpacked with wrong size!
  1161.  elif test -f 'unzip.c.B'; then
  1162.     echo shar: Combining  \"'unzip.c'\" \(60418 characters\)
  1163.     cat 'unzip.c.A' 'unzip.c.B' > 'unzip.c'
  1164.     if test 60418 -ne `wc -c <'unzip.c'`; then
  1165.       echo shar: \"'unzip.c'\" combined with wrong size!
  1166.     else
  1167.       rm unzip.c.A unzip.c.B
  1168.     fi
  1169.   fi
  1170.   # end of 'unzip.c.A'
  1171. fi
  1172. if test -f 'zipinfo.doc' -a "${1}" != "-c" ; then 
  1173.   echo shar: Will not clobber existing file \"'zipinfo.doc'\"
  1174. else
  1175.   echo shar: Extracting \"'zipinfo.doc'\" \(15236 characters\)
  1176.   sed "s/^X//" >'zipinfo.doc' <<'END_OF_FILE'
  1177. X
  1178. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1179. X
  1180. XNAME
  1181. X     zipinfo - list detailed information about a ZIP archive file
  1182. X
  1183. XSYNOPSIS
  1184. X     zipinfo [-1smlvht] file[.zip] [filespec ...]
  1185. X
  1186. XARGUMENTS
  1187. X     file[.zip]  Path of the ZIP archive.  The suffix ``.zip'' is
  1188. X                 applied  if  the  file specified does not exist.
  1189. X                 Note that self-extracting  ZIP  files  are  sup-
  1190. X                 ported;  just  specify the ``.exe'' suffix your-
  1191. X                 self.
  1192. X
  1193. X     [filespec]  An optional list of archive members to  be  pro-
  1194. X                 cessed.  Expressions may be used to match multi-
  1195. X                 ple members; be sure to quote  expressions  that
  1196. X                 contain   characters  interpreted  by  the  Unix
  1197. X                 shell. See PATTERN  MATCHING  (below)  for  more
  1198. X                 details.
  1199. X
  1200. XOPTIONS
  1201. X     -1  list filenames only, one per line (useful for pipes)
  1202. X     -s  list zipfile  info  in  short  Unix  ``ls  -l''  format:
  1203. X         default
  1204. X     -m  list zipfile info in medium Unix ``ls -l'' format
  1205. X     -l  list zipfile info in long Unix ``ls -l'' format
  1206. X     -v  list zipfile information in verbose, multi-page format
  1207. X     -h  list header line
  1208. X     -t  list totals for files listed or for all files
  1209. X
  1210. XPATTERN MATCHING
  1211. X     All archive members are listed unless a filespec is provided
  1212. X     to specify a subset of the archive members.  The filespec is
  1213. X     similar to an egrep expression, and may contain:
  1214. X
  1215. X     *      matches a sequence of 0 or more characters
  1216. X     ?      matches exactly 1 character
  1217. X     \nnn   matches the character having octal code nnn
  1218. X     [...]  matches any single character found inside the  brack-
  1219. X            ets; ranges are specified by a beginning character, a
  1220. X            hyphen, and an ending character.  If  an  exclamation
  1221. X            point  or  a  carat  (`!'  or  `^')  follows the left
  1222. X            bracket, then the range of characters matched is com-
  1223. X            plemented  with  respect  to  the ASCII character set
  1224. X            (that is, anything except the characters  inside  the
  1225. X            brackets is considered a match).
  1226. X
  1227. XDESCRIPTION
  1228. X     ZipInfo lists technical information  about  a  ZIP  archive,
  1229. X     including  information  file  access permissions, encryption
  1230. X     status, type of compression, version and operating system of
  1231. X     compressing program, and the like.  The default option is to
  1232. X
  1233. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 1
  1234. X
  1235. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1236. X
  1237. X     list files in the following format:
  1238. X
  1239. X-rw-rwl---  1.5 unx    2802 t- defX 11-Aug-91 13:48 perms.2660
  1240. X
  1241. X     The last three fields are clearly the modification date  and
  1242. X     time of the file, and its name.  The case of the filename is
  1243. X     respected; thus files  which  come  from  MS-DOS  PKZIP  are
  1244. X     always  capitalized.   If  the file was zipped with a stored
  1245. X     directory name, that  is  also  displayed  as  part  of  the
  1246. X     filename.
  1247. X
  1248. X     The second and third  fields  indicate  that  the  file  was
  1249. X     zipped  under Unix with version 1.5 of Zip (a beta version).
  1250. X     Since it comes from Unix, the file permissions at the begin-
  1251. X     ning   of   the  line  are  printed  in  Unix  format.   The
  1252. X     uncompressed file-size (2802 in this example) is the  fourth
  1253. X     field.
  1254. X
  1255. X     The fifth field consists of two characters, either of  which
  1256. X     may  take  on  several  values.   The first character may be
  1257. X     either `t' or `b', indicating that Zip believes the file  to
  1258. X     be  text  or  binary,  respectively;  but  if  the  file  is
  1259. X     encrypted, ZipInfo notes this fact by capitalizing the char-
  1260. X     acter  (`T'  or `B').  The second character may also take on
  1261. X     four values, depending on whether there is an extended local
  1262. X     header  and/or  an  ``extra field'' associated with the file
  1263. X     (explained in PKWare's APPNOTE.TXT).  If neither exists, the
  1264. X     character  will  be  a hyphen (`-'); if there is an extended
  1265. X     local header but no extra field, `l'; if the  reverse,  `x';
  1266. X     and  if  both  exist, `X'.  Thus the file in this example is
  1267. X     (apparently) a text file, is not encrypted, and has  neither
  1268. X     an  extra field nor an extended local header associated with
  1269. X     it.  The example below, on the other hand, is  an  encrypted
  1270. X     binary file with an extra field:
  1271. X
  1272. XRWD,R,R     0.9 vms     168 Bx shrk  9-Aug-91 19:15 perms.0644
  1273. X
  1274. X     Extra fields are used by PKWare for  authenticity  verifica-
  1275. X     tion(?)  and  possibly other purposes, and by Info-ZIP's Zip
  1276. X     1.6 and later to store OS/2, Macintosh and VMS  file  attri-
  1277. X     butes.  This example presumably falls into the latter class,
  1278. X     then.  Note that the file attributes are listed in VMS  for-
  1279. X     mat.   Other  possibilities  for  the  host operating system
  1280. X     include OS/2 with High Performance File System  (HPFS),  DOS
  1281. X     or  OS/2  with  File Allocation Table (FAT) file system, and
  1282. X     Macintosh, denoted as follows:
  1283. X
  1284. Xarc,,rw,    1.0 os2    5358 Tl i4:3  4-Dec-91 11:33 longfilename.hpfs
  1285. Xarc,hid,rdo,sys dos    4096 b- i4:2 14-Jul-91 12:58 EA DATA. SF
  1286. X--w-------  1.0 mac   17357 bx i8:2  4-May-92 04:02 unzip.macr
  1287. X
  1288. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 2
  1289. X
  1290. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1291. X
  1292. X     File attributes in the first two cases are  indicated  in  a
  1293. X     DOS-like  format,  where  the  file  may or may not have its
  1294. X     archive bit set; may be hidden or not; may be read-write  or
  1295. X     read-only;  and  may be a system file or not.  If the attri-
  1296. X     butes are too long,  the  version  number  of  the  encoding
  1297. X     software is omitted.  (The information is still available in
  1298. X     the verbose listing, however.)  Interpretation of  Macintosh
  1299. X     file attributes needs some work yet.
  1300. X
  1301. X     Finally, the sixth field indicates  the  compression  method
  1302. X     and  possible  sub-method used.  There are six methods known
  1303. X     at present:  storing (no compression), reducing,  shrinking,
  1304. X     imploding,  tokenizing,  and  deflating.  In addition, there
  1305. X     are four levels of reducing (1 through  4);  four  types  of
  1306. X     imploding  (4K or 8K sliding dictionary, and 2 or 3 Shannon-
  1307. X     Fano trees); and three levels of  deflating  (fast,  normal,
  1308. X     maximum  compression).  ZipInfo represents these methods and
  1309. X     their sub-methods as follows:  ``stor''; ``re:1,'' ``re:2,''
  1310. X     etc.;  ``shrk'';  ``i4:2,''  ``i8:3,''  etc.;  ``tokn''; and
  1311. X     ``defF,'' ``defN,'' and ``defX.''
  1312. X
  1313. X     The medium and long listings are  almost  identical  to  the
  1314. X     short  format except that they add information on the file's
  1315. X     compression.   The  medium  format  indicates   the   file's
  1316. X     compression factor as a percentage:
  1317. X
  1318. X-rw-rwl---  1.5 unx    2802 t- 81% defX 11-Aug-91 13:48 perms.2660
  1319. X
  1320. X     In this example, the file has been compressed by more than a
  1321. X     factor of five; the compressed data are only 19% of the ori-
  1322. X     ginal size.  The long format  gives  the  compressed  file's
  1323. X     size in bytes, instead:
  1324. X
  1325. X-rw-rwl---  1.5 unx    2802 t-     538 defX 11-Aug-91 13:48 perms.2660
  1326. X
  1327. X     In addition to individual file information, a  default  zip-
  1328. X     file listing also includes header and trailer lines:
  1329. X
  1330. XArchive:  OS2.zip   5453 bytes   5 files
  1331. X,,rw,       1.0 os2     730 b- i4:3 26-Jun-92 23:40 Contents
  1332. X,,rw,       1.0 os2    3710 b- i4:3 26-Jun-92 23:33 makefile.os2
  1333. X,,rw,       1.0 os2    8753 b- i8:3 26-Jun-92 15:29 os2unzip.c
  1334. X,,rw,       1.0 os2      98 b- stor 21-Aug-91 15:34 unzip.def
  1335. X,,rw,       1.0 os2      95 b- stor 21-Aug-91 17:51 zipinfo.def
  1336. X5 files, 13386 bytes uncompressed, 4951 bytes compressed:  63%
  1337. X
  1338. X     The header line gives the name of  the  archive,  its  total
  1339. X     size,  and  the total number of files; the trailer gives the
  1340. X     number of files listed, their total uncompressed  size,  and
  1341. X     their  total  compressed  size  (not  including any of Zip's
  1342. X     internal overhead).  If, however, one or more filespecs  are
  1343. X     provided, the header and trailer lines are not listed.  This
  1344. X
  1345. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 3
  1346. X
  1347. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1348. X
  1349. X     behavior is also similar to that of Unix's ``ls -l''; it may
  1350. X     be  overridden  by  specifying  the -h and -t options expli-
  1351. X     citly.  In such a case  the  listing  format  must  also  be
  1352. X     specified  explicitly,  since  -h  or  -t  (or  both) in the
  1353. X     absence of other options implies that  ONLY  the  header  or
  1354. X     trailer  line (or both) is listed.  See the EXAMPLES section
  1355. X     below for a semi-intelligible translation of this nonsense.
  1356. X
  1357. X     The verbose listing is self-explanatory.  It also lists file
  1358. X     comments  and the zipfile comment, if any, and the number of
  1359. X     bytes of OS/2 extended attributes  stored.   Note  that  the
  1360. X     latter  number will in general NOT match the number given by
  1361. X     OS/2's ``dir'' command; OS/2 always reports  the  number  of
  1362. X     bytes  required  in  16-bit  format,  whereas ZipInfo always
  1363. X     reports the 32-bit storage.
  1364. X
  1365. XENVIRONMENT OPTIONS
  1366. X     Modifying ZipInfo's default behavior via options  placed  in
  1367. X     an environment variable can be a bit complicated to explain,
  1368. X     due to ZipInfo's attempts to handle various defaults  in  an
  1369. X     intuitive,  yet  Unix-like,  manner.  Nevertheless, there is
  1370. X     some underlying logic.  In brief, there are three ``priority
  1371. X     levels''  of  options:   the  default  options;  environment
  1372. X     options, which can override or  add  to  the  defaults;  and
  1373. X     explicit  options  given  by the user, which can override or
  1374. X     add to either of the above.
  1375. X
  1376. X     The default listing  format,  as  noted  above,  corresponds
  1377. X     roughly  to  the "zipinfo -hst" command (except when indivi-
  1378. X     dual zipfile members are specified).  A user who prefers the
  1379. X     long-listing  format  (-l)  can  make  use  of  the  ZIPINFO
  1380. X     environment variable to change this default:
  1381. X
  1382. X           setenv ZIPINFO -l            Unix C shell
  1383. X
  1384. X           ZIPINFO=-l; export ZIPINFO   Unix Bourne shell
  1385. X
  1386. X           set ZIPINFO=-l               OS/2 or MS-DOS
  1387. X
  1388. X           define ZIPINFO_OPTS "-l"     VMS (quotes for LOWERCASE)
  1389. X
  1390. X     If,  in  addition,  the  user  dislikes  the  trailer  line,
  1391. X     ZipInfo's concept of ``negative options''  may  be  used  to
  1392. X     override  the default inclusion of the line.  This is accom-
  1393. X     plished by preceding the undesired option with one  or  more
  1394. X     minuses:   e.g., ``-l-t'' or ``--tl'', in this example.  The
  1395. X     first hyphen is the regular switch character,  but  the  one
  1396. X     before the `t' is a minus sign.  The dual use of hyphens may
  1397. X     seem  a  little  awkward,  but  it's  reasonably   intuitive
  1398. X     nonetheless:   simply  ignore  the  first hyphen and go from
  1399. X     there.  It is also consistent with the behavior of the  Unix
  1400. X     command nice(1).
  1401. X
  1402. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 4
  1403. X
  1404. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1405. X
  1406. XEXAMPLES
  1407. X     To get a basic, short-format listing of  the  complete  con-
  1408. X     tents of a ZIP archive ``storage.zip,'' with both header and
  1409. X     totals lines, use only the archive name as  an  argument  to
  1410. X     zipinfo:
  1411. X
  1412. X           zipinfo storage
  1413. X
  1414. X     To produce  a  basic,  long-format  listing  (not  verbose),
  1415. X     including header and totals lines, use -l:
  1416. X
  1417. X           zipinfo -l storage
  1418. X
  1419. X     To list the complete contents of the archive without  header
  1420. X     and  totals  lines,  either  negate the -h and -t options or
  1421. X     else specify the contents explicitly:
  1422. X
  1423. X           zipinfo --h-t storage
  1424. X
  1425. X           zipinfo storage \*
  1426. X
  1427. X     (where the backslash is required only  if  the  shell  would
  1428. X     otherwise  expand the `*' wildcard, as in Unix when globbing
  1429. X     is turned on--double quotes around the asterisk  would  have
  1430. X     worked  as  well).   To turn off the totals line by default,
  1431. X     use the environment variable (C shell is assumed here):
  1432. X
  1433. X           setenv ZIPINFO --t
  1434. X
  1435. X           zipinfo storage
  1436. X
  1437. X     To get the full, short-format listing of the  first  example
  1438. X     again,  given that the environment variable is set as in the
  1439. X     previous example, it is necessary to specify the  -s  option
  1440. X     explicitly,  since the -t option by itself implies that ONLY
  1441. X     the footer line is to be printed:
  1442. X
  1443. X           setenv ZIPINFO --t
  1444. X
  1445. X           zipinfo -t storage           [only totals line]
  1446. X
  1447. X           zipinfo -st storage          [full listing]
  1448. X
  1449. X     The -s option, like -m and -l, includes headers and  footers
  1450. X     by  default, unless otherwise specified.  Since the environ-
  1451. X     ment variable specified no footers and  that  has  a  higher
  1452. X     precedence  than  the default behavior of -s, an explicit -t
  1453. X     option was necessary to produce the full  listing.   Nothing
  1454. X     was  indicated  about  the header, however, so the -s option
  1455. X     was sufficient.  Note that both the -h and -t options,  when
  1456. X     used  by themselves or with each other, override any default
  1457. X     listing of member files; only the header and/or  footer  are
  1458. X
  1459. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 5
  1460. X
  1461. XZIPINFO(1)               USER COMMANDS                 ZIPINFO(1)
  1462. X
  1463. X     printed.   This  behavior  will  be more useful when ZipInfo
  1464. X     accepts wildcards for the zipfile name; one may then summar-
  1465. X     ize the contents of all zipfiles with a single command.
  1466. X
  1467. X     To list information on a single file within the archive,  in
  1468. X     medium format, specify the filename explicitly:
  1469. X
  1470. X           zipinfo -m storage unshrink.c
  1471. X
  1472. X     The specification of any member file, as  in  this  example,
  1473. X     will  override the default header and totals lines; only the
  1474. X     single line of information about the requested file will  be
  1475. X     printed.   This  is  intuitively  what one would expect when
  1476. X     requesting information about a single  file.   For  multiple
  1477. X     files,  it  is often useful to know the total compressed and
  1478. X     uncompressed size; in such cases -t may be specified  expli-
  1479. X     citly:
  1480. X
  1481. X           zipinfo -mt storage "*.[ch] Mak\*
  1482. X
  1483. X     Finally, to get maximal information about the  ZIP  archive,
  1484. X     use the verbose option.  It is usually wise to pipe the out-
  1485. X     put into a filter such as more(1):
  1486. X
  1487. X           zipinfo -v storage | more
  1488. X
  1489. XTIPS
  1490. X     The author finds it convenient to set up an alias ``ii'' for
  1491. X     ZipInfo  on systems which allow aliases, or else to set up a
  1492. X     batch  file  ``ii.bat''  or  to  rename  the  executable  to
  1493. X     ``ii.exe'' on systems such as MS-DOS which have no provision
  1494. X     for aliases.  The ``ii'' usage parallels the  common  ``ll''
  1495. X     alias  for long listings in Unix, and the similarity between
  1496. X     the outputs of the two commands was intentional.
  1497. X
  1498. XSEE ALSO
  1499. X     funzip(1),  unzip(1),   zip(1),   zipcloak(1),   zipnote(1),
  1500. X     zipsplit(1)
  1501. X
  1502. XAUTHOR
  1503. X     Greg Roelofs (also known as Cave Newt).  ZipInfo  is  partly
  1504. X     based  on  S. H. Smith's unzip and contains pattern-matching
  1505. X     code by  J.  Kercheval,  but  mostly  it  was  written  from
  1506. X     scratch.  The OS/2 extra-field code is by Kai Uwe Rommel.
  1507. X
  1508. XInfo-ZIP          Last change: 19 Aug 92 (v1.0)                 6
  1509. X
  1510. END_OF_FILE
  1511.   if test 15236 -ne `wc -c <'zipinfo.doc'`; then
  1512.     echo shar: \"'zipinfo.doc'\" unpacked with wrong size!
  1513.   fi
  1514.   # end of 'zipinfo.doc'
  1515. fi
  1516. echo shar: End of archive 8 \(of 14\).
  1517. cp /dev/null ark8isdone
  1518. MISSING=""
  1519. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1520.     if test ! -f ark${I}isdone ; then
  1521.     MISSING="${MISSING} ${I}"
  1522.     fi
  1523. done
  1524. if test "${MISSING}" = "" ; then
  1525.     echo You have unpacked all 14 archives.
  1526.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1527. else
  1528.     echo You still must unpack the following archives:
  1529.     echo "        " ${MISSING}
  1530. fi
  1531. exit 0
  1532. exit 0 # Just in case...
  1533.