home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / unzip50 / part09 < prev    next >
Encoding:
Text File  |  1992-08-22  |  58.3 KB  |  1,526 lines

  1. Newsgroups: comp.sources.misc
  2. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  3. Subject:  v31i112:  unzip50 - Info-ZIP portable UnZip, version 5.0, Part09/14
  4. Message-ID: <1992Aug24.025659.25051@sparky.imd.sterling.com>
  5. X-Md4-Signature: 6a5e93b9b352571481748a7a0fb1ea7c
  6. Date: Mon, 24 Aug 1992 02:56:59 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
  10. Posting-number: Volume 31, Issue 112
  11. Archive-name: unzip50/part09
  12. Supersedes: unzip: Volume 29, Issue 31-42
  13. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT AMIGA?, !ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  MAC/macstat.h VMS/VMS.notes explode.c zipinfo.1
  22. # Wrapped by kent@sparky on Sun Aug 23 21:09:34 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 9 (of 14)."'
  26. if test -f 'MAC/macstat.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'MAC/macstat.h'\"
  28. else
  29.   echo shar: Extracting \"'MAC/macstat.h'\" \(974 characters\)
  30.   sed "s/^X//" >'MAC/macstat.h' <<'END_OF_FILE'
  31. X/*****************************************************************
  32. X *
  33. X *                stat.h
  34. X *
  35. X *****************************************************************/
  36. X
  37. X#include <time.h>
  38. Xextern int macstat(char *path, struct stat *buf, short nVRefNum, long lDirID );
  39. Xtypedef long dev_t;
  40. Xtypedef long ino_t;
  41. Xtypedef long off_t;
  42. X
  43. Xstruct stat {
  44. X    dev_t    st_dev;
  45. X    ino_t    st_ino;
  46. X    unsigned short    st_mode;
  47. X    short    st_nlink;
  48. X    short    st_uid;
  49. X    short    st_gid;
  50. X    dev_t    st_rdev;
  51. X    off_t    st_size;
  52. X    time_t   st_atime, st_mtime, st_ctime;
  53. X    long     st_blksize;
  54. X    long     st_blocks;
  55. X};
  56. X
  57. X#define S_IFMT     0xF000
  58. X#define S_IFIFO    0x1000
  59. X#define S_IFCHR    0x2000
  60. X#define S_IFDIR    0x4000
  61. X#define S_IFBLK    0x6000
  62. X#define S_IFREG    0x8000
  63. X#define S_IFLNK    0xA000
  64. X#define S_IFSOCK   0xC000
  65. X#define S_ISUID    0x800
  66. X#define S_ISGID    0x400
  67. X#define S_ISVTX    0x200
  68. X#define S_IREAD    0x100
  69. X#define S_IWRITE   0x80
  70. X#define S_IEXEC    0x40
  71. END_OF_FILE
  72.   if test 974 -ne `wc -c <'MAC/macstat.h'`; then
  73.     echo shar: \"'MAC/macstat.h'\" unpacked with wrong size!
  74.   fi
  75.   # end of 'MAC/macstat.h'
  76. fi
  77. if test -f 'VMS/VMS.notes' -a "${1}" != "-c" ; then 
  78.   echo shar: Will not clobber existing file \"'VMS/VMS.notes'\"
  79. else
  80.   echo shar: Extracting \"'VMS/VMS.notes'\" \(13719 characters\)
  81.   sed "s/^X//" >'VMS/VMS.notes' <<'END_OF_FILE'
  82. X                     VMS Notes for UnZip 5.0
  83. X                           24 May 1992
  84. X
  85. X
  86. XThe various VMS tweaks to UnZip 5.0 and ZipInfo 0.97 were tested on a 
  87. XVAX 8600 running VMS 5.2 (and, later, VMS 5.4) and VAX C 3.0.  Older 
  88. Xversions were also tested on a VAX 11/785.
  89. X
  90. XTo build UnZip (and its trusty sidekick, ZipInfo), just run one of the 
  91. Xincluded command files MAKE_UNZIP_VAXC.COM or MAKE_UNZIP_GCC.COM, either
  92. Xdecryption or non-decryption versions, depending on whether you have the
  93. Xseparate crypt.c module and whether you use VAX C or GNU C (for example, 
  94. X"@make_unzip_vaxc").  By default, this creates shareable-image executables,
  95. Xwhich are smaller and (supposedly) load faster than the normal type.  They 
  96. Xalso (supposedly) will be better able to take advantage of any bug fixes 
  97. Xor new capabilities that DEC might introduce, since the library code isn't 
  98. Xbuilt into the executable.  The shared executable is about a quarter the 
  99. Xsize of the ordinary type in the case of UnZip.
  100. X
  101. X[Btw, the VMS make utility "MMS" is not compatible enough with Unix make 
  102. Xto use the same makefile.  Antonio Querubin, Jr., sent along an MMS makefile,
  103. Xsubsequently modified by Igor Mandrichenko.  Read the comments at the top 
  104. Xof DESCRIP.MMS for more info.  An alternate Unix-like makefile designed for 
  105. Xuse with Todd Aven's MAKE/VMS is included, as well.  Comments on where to
  106. Xget MAKE/VMS are at the bottom of VMS Contents.]
  107. X
  108. XUnZip is written to return the standard PK-type return codes (or error
  109. Xcodes, or exit codes, or whatever you want to call them).  Unfortunately,
  110. XVMS insists on interpreting the codes in its own lovable way, and this
  111. Xresults in endearing commentary such as "access violation, error mask =
  112. X0005, PC = 00003afc" (or something like that) when you run UnZip with no
  113. Xarguments.  To avoid this I've added a special VMS_return() function which
  114. Xeither ignores the error codes (and exits with normal status) or interprets
  115. Xthem, prints a semi-informative message (enclosed in square [] brackets), 
  116. Xand then exits with a normal error status.  I personally can't stand the 
  117. Xlatter behavior, so by default the error codes are simply ignored.  Tastes
  118. Xvary, however, and some people may actually like semi-informative messages.
  119. XIf you happen to be one of those people, you may enable the messages by 
  120. Xrecompiling misc.c with RETURN_CODES defined.  (This adds a block or two
  121. Xto the executable size, though.)  The syntax is as follows:
  122. X    cc /def=(RETURN_CODES) misc
  123. X
  124. XTo use UnZip in the normal way, define a symbol "unzip" as follows:
  125. X    unzip :== "$diskname:[directory]unzip.exe"
  126. X(substitute for "diskname" and "directory" as appropriate, and DON'T FORGET
  127. XTHE `$'!  It won't work if you omit that.)  In general it's wise to stick 
  128. Xsuch assignments in your LOGIN.COM file and THEN forget about them.  It is 
  129. Xno longer necessary to worry about the record type of the zipfile...er, 
  130. Xwell, most of the time, anyway (see the Kermit section below).
  131. X
  132. XHaving done all this you are ready to roll.  Use the unzip command in
  133. Xthe usual way; as with the Unix, OS/2 and MS-DOS versions, this one uses 
  134. X'-' as a switch character.  If nothing much happens when you do a directory
  135. Xlisting, for example, you're probably trying to specify a filename which
  136. Xhas uppercase letters in it...VMS thoughtfully converts everything on the
  137. Xcommand line to lowercase, so even if you type:
  138. X    unzip -v zipfile Makefile
  139. Xwhat you get is:
  140. X    unzip -v zipfile makefile
  141. Xwhich, in my example here, doesn't match the contents of the zipfile.
  142. XThis is relatively easy to circumvent by enclosing the filespec(s) in 
  143. Xquotes:
  144. X    unzip -tq unzip401 "Makefile" "VMS*" *.c *.h
  145. X[This example also demonstrates the use of wildcards, which act like Unix
  146. Xwildcards, not VMS ones.   In other words, "VMS*" matches files VMSNOTES,
  147. XVMS_MAKE.COM, and VMSSHARE.OPT, whereas the normal VMS behavior would be
  148. Xto match only the first file (since the others have extensions--ordinarily,
  149. Xyou would be required to specify "VMS*.*").]
  150. X
  151. XNote that created files get whatever default permissions you've set, but 
  152. Xcreated directories additionally inherit the (possibly more restrictive) 
  153. Xpermissions of the parent directory.  And, of course, things probably won't 
  154. Xwork too well if you don't have permission to write to whatever directory 
  155. Xinto which you're trying to extract things.  (That made sense; read it 
  156. Xagain if you don't believe me.)
  157. X
  158. XZipInfo, by the way, is an amusing little utility which tells you all sorts
  159. Xof amazingly useless information about zipfiles.  Occasionally it's useful
  160. Xto debug a problem with a corrupted zipfile (for example, we used it to 
  161. Xfind a bug in PAK-created zipfiles, versions 2.5 and earlier).  Feel free
  162. Xto blow it away if you don't need it.  It's about 30 blocks on my system,
  163. Xand I find I actually prefer its listing format to that of UnZip now (hardly
  164. Xsurprising, since I wrote it :-) ).  I also find it useful to use "ii" 
  165. Xrather than "zipinfo" as the symbol for zipinfo, since it's easier to type 
  166. Xthan either "zipinfo" or "unzip -v", and it echoes the common Unix alias 
  167. X"ll" for the similar style of directory listings.  Oh, and the reason it's 
  168. Xstill got a beta version number is that I haven't finished it yet--it would 
  169. Xbe better with an automatic paging function, for example.  Oh well.
  170. X
  171. XRANDOM OTHER NOTES:  (1) Igor Mandrichenko (leader of our fearless Russian 
  172. Xcontingent) rewrote major portions of the VMS file-handling code, with
  173. Xthe result that UnZip is much smarter now about VMS file formats.  For
  174. Xfull VMS compatibility (file attributes, ownership info, etc.), be sure
  175. Xto use the -X option of Zip 1.6 and later.  There are also some notes
  176. Xat the end of this file from Hugh Schmidt and Mike Freeman which give 
  177. Xhints on how to save VMS attributes using Zip 1.0 and UnZip 4.1.  Most of
  178. Xthe information is still valid, but the -X option is much easier if you
  179. Xdon't have to transfer the zipfiles to a Unix or PC system.  (2) Zip 1.0 
  180. Xcannot handle any zipfile that isn't in stream-LF format, so you may need 
  181. Xto use Rahul Dhesi's BILF utility which is included with UnZip.  It will
  182. Xalso be necessary for certain other special occasions, like when you've 
  183. Xforgotten to set the correct Kermit parameters while uploading a zipfile 
  184. X(see Hugh Schmidt's note below for comments about Kermit, too).
  185. X
  186. XGreg Roelofs
  187. X
  188. X====================
  189. X
  190. XFrom INFO-ZIP Digest (Wed, 6 Nov 1991), Volume 91, Issue 290
  191. X
  192. X                VMS attributes and PKZIP compatibility
  193. X                  VMS attributes restored! (2 msgs)
  194. X
  195. X------------------------------
  196. X
  197. XDate: Tue, 5 Nov 91 15:31 CDT
  198. XFrom: Hugh Schmidt <HUGH@macc.wisc.edu>
  199. XSubject: VMS attributes and PKZIP compatibility
  200. XMessage-ID: <21110515313938@vms.macc.wisc.edu>
  201. X
  202. X           ******************************************************
  203. X(1)        *** Retaining VMS attributes - a proposed strategy ***
  204. X           ******************************************************
  205. X
  206. XThis is a proposed strategy for recovering VMS file attributes after
  207. Xzip/unzip:
  208. X
  209. Xa) capture VMS file attributes: VMS ANALYZE/RMS/FDL/OUTPUT=fdlfile vmsfile.ext
  210. Xb) compress files on VMS......: ZIP zipfile vmsfile.ext, fdlfile.fdl
  211. Xc) uncompress files on VMS....: UNZIP zipfile vmsfile.ext, fdlfile.fdl
  212. Xd) recover VMS file attributes: CONVERT/FDL=fdlfile.fdl vmsfile.ext vmsfile.ext
  213. X
  214. XThe wrinkle is that UNZIP creates files which are unreadable by CONVERT
  215. Xdespite a concerted effort to accomodate VMS file management system:
  216. X
  217. Xfile_io.c, line 178: ...creat(filename,0, "rat=cr", "rfm=streamlf")
  218. X
  219. XThese files are unCONVERTABLE because they appear to VMS to contain
  220. Xrecords with 512+ bytes.  Poring over VMS manuals (Programming V-6A, VAX
  221. XC RTL Reference Manual) doesn't readily suggest better alternatives.
  222. XExperimentation with "rat=fix", etc. may help suppress the spurious
  223. Xblock-end delimeters.
  224. X
  225. X          ****************************************************
  226. X(2)       *** VMS ZIP and PKZIP compatibility using KERMIT ***
  227. X          ****************************************************
  228. X
  229. XMany use Procomm's kermit to transfer zipped files between PC and VMS
  230. XVAX.  The following VMS kermit settings make VMS-ZIP compatible with
  231. XPKZIP:
  232. X
  233. X                                             VMS kermit      Procomm kermit
  234. X                                           ---------------   --------------
  235. XUploading PKZIPped file to be UNZIPped:    set fi ty fixed    set fi ty bi
  236. XDownloading ZIPped file to be PKUNZIPped:  set fi ty block    set fi ty bi
  237. X
  238. X"Block I/O lets you bypass the VMS RMS record-processing capabilities
  239. Xentirely", (Guide to VMS file applications, Section 8.5).  The kermit
  240. Xguys must have known this!
  241. X
  242. X         ************************************************
  243. X(3)      *** Making ZIP files compatible with VMS RMS ***
  244. X         ************************************************
  245. X
  246. XIt looks like a crummy patch, but to make VMS RMS happy, I inserted the
  247. Xfollowing near line 570 in the putend() section of zipfile.c:
  248. X
  249. X#ifdef VMS
  250. X fprintf(f,"\n")
  251. X#endif
  252. X
  253. XIt's probably of no consequence, but it satisfies VMS ANALYZE.
  254. X
  255. X------------------------------
  256. X
  257. XDate: Tue, 5 Nov 91 19:40 CDT
  258. XFrom: Hugh Schmidt <HUGH@macc.wisc.edu>
  259. XSubject: VMS attributes restored!
  260. XMessage-ID: <21110519403912@vms.macc.wisc.edu>
  261. X
  262. X           ************************************************************
  263. X           ***   Aha!  It works!  VMS attributes can be restored! *****
  264. X           ***                                                      ***
  265. X           *** Change FAB$C_STMLF to FAB$C_FIX in file_io.c         ***
  266. X           *** ANALYZE => .FDL | CONVERT => original VMS attributes ***
  267. X           ************************************************************
  268. X
  269. X(1) Change line 147 in file_io.c and dropping lines 148-149:
  270. X
  271. X    fileblk.fab$b_rfm = FAB$C_STMLF;    /* stream-LF record format */
  272. X    fileblk.fab$b_rat = FAB$M_CR;       /* carriage-return carriage ctrl */
  273. X    /*                      ^^^^ *NOT* V_CR!!!     */
  274. X
  275. X=>
  276. X
  277. X    fileblk.fab$b_rfm = FAB$C_FIX;    /* fixed record format */
  278. X
  279. X(2) Use VMS ANALYZE to store the VMS attributes for the original file
  280. X    into a file descripion language file.  Save the .FDL file with the
  281. X    original file.
  282. X
  283. X(3) Apply the original attributes to the UNZIPped file using VMS CREATE
  284. X    and the description file (test.fdl).
  285. X
  286. XIn the following example, the original attributes of a SPSSX system
  287. Xformat file were restored.  Later, SPSSX successfully read the UNZIPped/
  288. XCONVERTed file.
  289. X
  290. X!******** Procedure (or method for you ai'ers)
  291. X!********
  292. X!******** Create an .FDL file using ANALYZE
  293. X
  294. X$ analyze/rms/fdl/out=test test.spssxsav;1
  295. X
  296. X!******** ZIP the file and its description file
  297. X
  298. X$ zip test test.spssxsav;1 test.fdl;1
  299. Xadding test.spssxsav (imploded 62%)
  300. Xadding test.fdl (imploded 90%)
  301. X
  302. X!******** When the ZIPPED file is needed, UNZIP it and its description file
  303. X
  304. X$ unzip test
  305. X  Exploding: test.spssxsav
  306. X  Exploding: test.fdl
  307. X
  308. X!******** To restore the original attributes, apply the description file to
  309. X!********  the UNZIPped file using VMS CONVERT
  310. X
  311. X$ convert/fdl=test  test.spssxsav;2 test.spssxsav;3
  312. X
  313. X! ******* The following show that the VMS attributes are restored.
  314. X
  315. X$ analyze/rms/check test.spssxsav;1
  316. X
  317. X    File Spec: PROJDISK5:[322042.CORE]TEST.SPSSXSAV;1
  318. X    File Organization: sequential
  319. X    Record Format: fixed
  320. X    Record Attributes:
  321. X    Maximum Record Size: 4
  322. X    Longest Record: 4
  323. X
  324. XThe analysis uncovered NO errors.
  325. X
  326. X$ analyze/rms/check test.spssxsav;2
  327. X    File Spec: PROJDISK5:[322042.CORE]TEST.SPSSXSAV;2
  328. X    File Organization: sequential
  329. X    Record Format: undefined
  330. X    Record Attributes:
  331. X    Maximum Record Size: 0
  332. X    Longest Record: 512
  333. XThe analysis uncovered NO errors.
  334. X
  335. X$ analyze/rms/check test.spssxsav;3
  336. X    File Spec: PROJDISK5:[322042.CORE]TEST.SPSSXSAV;3
  337. X    File Organization: sequential
  338. X    Record Format: fixed
  339. X    Record Attributes:
  340. X    Maximum Record Size: 4
  341. X    Longest Record: 4
  342. X
  343. XThank you all for your help and comments.  It was very reasurring to
  344. Xknow that I was on the right track.  This is a humble contribution
  345. Xcompared to the great efforts of others in the ZIP project.
  346. X
  347. X------------------------------
  348. X
  349. XDate: Wed, 6 Nov 91 12:49:33 EST
  350. XFrom: Mike Freeman <freeman@watsun.cc.columbia.edu>
  351. XSubject: Re: VMS attributes restored!
  352. XMessage-ID: <CMM.0.90.0.689449773.freeman@watsun.cc.columbia.edu>
  353. X
  354. XHello, all.
  355. X
  356. XHUGH@macc.wisc.edu has come up with a commendable method for saving/
  357. Xrestoring record attributes in Vax/VMS files when ZIPping/UNZIPping.
  358. XThere are a couple of potential problems in his specific implementation,
  359. Xhowever:
  360. X
  361. X(a) It would be better to leave the output file(s) in STREAM_LF format
  362. X    and use Joe Meadows' FILE utility to put them in fixed-record
  363. X    format if CONVERT has trouble reading them.
  364. X
  365. X    Outputting a text file as fixed-record format could be a pain, and
  366. X    one would have to use FILE anyway.
  367. X
  368. X    (Incidentally, I ZIPped up a text file, UNZIPped it and used Hugh's
  369. X    method to restore the attributes.  CONVERT had no trouble with the
  370. X    STREAM_LF format -- it's only a problem with binary files and, as I
  371. X    say, Joe Meadows' FILE will fix this.)
  372. X
  373. X(b) Even if ANALYZE/RMS complains, I do not think one ought to put the
  374. X    "\n" in as Hugh advocates.  This contradicts the ZIP philosophy of
  375. X    byte-for-byte storage/retrieval.
  376. X
  377. X    As Mr. Roelofs has said, there is nothing wrong with the ZIP file;
  378. X    it's just that ANALYZE/RMS expects STREAM_LF files to end in an
  379. X    <LF>.
  380. X
  381. XAnyway, I was able to use Hugh's method without modifying ZIP 1.0.  We
  382. Xreally ought to get the word out about FILE, though -- it's very handy.
  383. X
  384. XMike Freeman, K7UIJ     |       Internet: freeman@watsun.cc.columbia.edu
  385. X301 N.E. 107th Street   |       GEnie: M.FREEMAN11
  386. XVancouvEr, WA 98685 USA |       Confidence is the feeling you have
  387. XTelephone (206)574-8221 |       before you understand the situation.
  388. X
  389. X------------------------------
  390. X
  391. END_OF_FILE
  392.   if test 13719 -ne `wc -c <'VMS/VMS.notes'`; then
  393.     echo shar: \"'VMS/VMS.notes'\" unpacked with wrong size!
  394.   fi
  395.   # end of 'VMS/VMS.notes'
  396. fi
  397. if test -f 'explode.c' -a "${1}" != "-c" ; then 
  398.   echo shar: Will not clobber existing file \"'explode.c'\"
  399. else
  400.   echo shar: Extracting \"'explode.c'\" \(26874 characters\)
  401.   sed "s/^X//" >'explode.c' <<'END_OF_FILE'
  402. X/* explode.c -- Not copyrighted 1992 by Mark Adler
  403. X   version c7, 27 June 1992 */
  404. X
  405. X
  406. X/* You can do whatever you like with this source file, though I would
  407. X   prefer that if you modify it and redistribute it that you include
  408. X   comments to that effect with your name and the date.  Thank you.
  409. X
  410. X   History:
  411. X   vers    date          who           what
  412. X   ----  ---------  --------------  ------------------------------------
  413. X    c1   30 Mar 92  M. Adler        explode that uses huft_build from inflate
  414. X                                    (this gives over a 70% speed improvement
  415. X                                    over the original unimplode.c, which
  416. X                                    decoded a bit at a time)
  417. X    c2    4 Apr 92  M. Adler        fixed bug for file sizes a multiple of 32k.
  418. X    c3   10 Apr 92  M. Adler        added a little memory tracking if DEBUG
  419. X    c4   11 Apr 92  M. Adler        added NOMEMCPY do kill use of memcpy()
  420. X    c5   21 Apr 92  M. Adler        added the WSIZE #define to allow reducing
  421. X                                    the 32K window size for specialized
  422. X                                    applications.
  423. X    c6   31 May 92  M. Adler        added typecasts to eliminate some warnings
  424. X    c7   27 Jun 92  G. Roelofs      added more typecasts
  425. X */
  426. X
  427. X
  428. X/*
  429. X   Explode imploded (PKZIP method 6 compressed) data.  This compression
  430. X   method searches for as much of the current string of bytes (up to a length
  431. X   of ~320) in the previous 4K or 8K bytes.  If it doesn't find any matches
  432. X   (of at least length 2 or 3), it codes the next byte.  Otherwise, it codes
  433. X   the length of the matched string and its distance backwards from the
  434. X   current position.  Single bytes ("literals") are preceded by a one (a
  435. X   single bit) and are either uncoded (the eight bits go directly into the
  436. X   compressed stream for a total of nine bits) or Huffman coded with a
  437. X   supplied literal code tree.  If literals are coded, then the minimum match
  438. X   length is three, otherwise it is two.
  439. X   
  440. X   There are therefore four kinds of imploded streams: 8K search with coded
  441. X   literals (min match = 3), 4K search with coded literals (min match = 3),
  442. X   8K with uncoded literals (min match = 2), and 4K with uncoded literals
  443. X   (min match = 2).  The kind of stream is identified in two bits of a
  444. X   general purpose bit flag that is outside of the compressed stream.
  445. X   
  446. X   Distance-length pairs are always coded.  Distance-length pairs for matched
  447. X   strings are preceded by a zero bit (to distinguish them from literals) and
  448. X   are always coded.  The distance comes first and is either the low six (4K)
  449. X   or low seven (8K) bits of the distance (uncoded), followed by the high six
  450. X   bits of the distance coded.  Then the length is six bits coded (0..63 +
  451. X   min match length), and if the maximum such length is coded, then it's
  452. X   followed by another eight bits (uncoded) to be added to the coded length.
  453. X   This gives a match length range of 2..320 or 3..321 bytes.
  454. X
  455. X   The literal, length, and distance codes are all represented in a slightly
  456. X   compressed form themselves.  What is sent are the lengths of the codes for
  457. X   each value, which is sufficient to construct the codes.  Each byte of the
  458. X   code representation is the code length (the low four bits representing
  459. X   1..16), and the number of values sequentially with that length (the high
  460. X   four bits also representing 1..16).  There are 256 literal code values (if
  461. X   literals are coded), 64 length code values, and 64 distance code values,
  462. X   in that order at the beginning of the compressed stream.  Each set of code
  463. X   values is preceded (redundantly) with a byte indicating how many bytes are
  464. X   in the code description that follows, in the range 1..256.
  465. X
  466. X   The codes themselves are decoded using tables made by huft_build() from
  467. X   the bit lengths.  That routine and its comments are in the inflate.c
  468. X   module.
  469. X */
  470. X
  471. X#include "unzip.h"      /* this must supply the slide[] (byte) array */
  472. X
  473. X#ifndef WSIZE
  474. X#  define WSIZE 0x8000  /* window size--must be a power of two, and at least
  475. X                           8K for zip's implode method */
  476. X#endif /* !WSIZE */
  477. X
  478. X
  479. Xstruct huft {
  480. X  byte e;               /* number of extra bits or operation */
  481. X  byte b;               /* number of bits in this code or subcode */
  482. X  union {
  483. X    UWORD n;            /* literal, length base, or distance base */
  484. X    struct huft *t;     /* pointer to next level of table */
  485. X  } v;
  486. X};
  487. X
  488. X/* Function prototypes */
  489. X/* routines from inflate.c */
  490. Xextern unsigned hufts;
  491. Xint huft_build OF((unsigned *, unsigned, unsigned, UWORD *, UWORD *,
  492. X                   struct huft **, int *));
  493. Xint huft_free OF((struct huft *));
  494. Xvoid flush OF((unsigned));
  495. X
  496. X/* routines here */
  497. Xint get_tree OF((unsigned *, unsigned));
  498. Xint explode_lit8 OF((struct huft *, struct huft *, struct huft *,
  499. X                     int, int, int));
  500. Xint explode_lit4 OF((struct huft *, struct huft *, struct huft *,
  501. X                     int, int, int));
  502. Xint explode_nolit8 OF((struct huft *, struct huft *, int, int));
  503. Xint explode_nolit4 OF((struct huft *, struct huft *, int, int));
  504. Xint explode OF((void));
  505. X
  506. X
  507. X/* The implode algorithm uses a sliding 4K or 8K byte window on the
  508. X   uncompressed stream to find repeated byte strings.  This is implemented
  509. X   here as a circular buffer.  The index is updated simply by incrementing
  510. X   and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1).  Here, the 32K
  511. X   buffer of inflate is used, and it works just as well to always have
  512. X   a 32K circular buffer, so the index is anded with 0x7fff.  This is
  513. X   done to allow the window to also be used as the output buffer. */
  514. X/* This must be supplied in an external module useable like "byte slide[8192];"
  515. X   or "byte *slide;", where the latter would be malloc'ed.  In unzip, slide[]
  516. X   is actually a 32K area for use by inflate, which uses a 32K sliding window.
  517. X */
  518. X
  519. X
  520. X/* Tables for length and distance */
  521. XUWORD cplen2[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  522. X        18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
  523. X        35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  524. X        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65};
  525. XUWORD cplen3[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
  526. X        19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  527. X        36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  528. X        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66};
  529. XUWORD extra[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  530. X        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  531. X        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  532. X        8};
  533. XUWORD cpdist4[] = {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705,
  534. X        769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473,
  535. X        1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177,
  536. X        2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881,
  537. X        2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585,
  538. X        3649, 3713, 3777, 3841, 3905, 3969, 4033};
  539. XUWORD cpdist8[] = {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281,
  540. X        1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689,
  541. X        2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097,
  542. X        4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505,
  543. X        5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913,
  544. X        7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065};
  545. X
  546. X
  547. X/* Macros for inflate() bit peeking and grabbing.
  548. X   The usage is:
  549. X   
  550. X        NEEDBITS(j)
  551. X        x = b & mask_bits[j];
  552. X        DUMPBITS(j)
  553. X
  554. X   where NEEDBITS makes sure that b has at least j bits in it, and
  555. X   DUMPBITS removes the bits from b.  The macros use the variable k
  556. X   for the number of bits in b.  Normally, b and k are register
  557. X   variables for speed.
  558. X */
  559. X
  560. Xextern UWORD bytebuf;           /* (use the one in inflate.c) */
  561. X#define NEXTBYTE    (ReadByte(&bytebuf), bytebuf)
  562. X#define NEEDBITS(n) {while(k<(n)){b|=((ULONG)NEXTBYTE)<<k;k+=8;}}
  563. X#define DUMPBITS(n) {b>>=(n);k-=(n);}
  564. X
  565. X
  566. X
  567. Xint get_tree(l, n)
  568. Xunsigned *l;            /* bit lengths */
  569. Xunsigned n;             /* number expected */
  570. X/* Get the bit lengths for a code representation from the compressed
  571. X   stream.  If get_tree() returns 4, then there is an error in the data.
  572. X   Otherwise zero is returned. */
  573. X{
  574. X  unsigned i;           /* bytes remaining in list */
  575. X  unsigned k;           /* lengths entered */
  576. X  unsigned j;           /* number of codes */
  577. X  unsigned b;           /* bit length for those codes */ 
  578. X
  579. X
  580. X  /* get bit lengths */
  581. X  ReadByte(&bytebuf);
  582. X  i = bytebuf + 1;                      /* length/count pairs to read */
  583. X  k = 0;                                /* next code */
  584. X  do {
  585. X    ReadByte(&bytebuf);
  586. X    b = ((j = bytebuf) & 0xf) + 1;      /* bits in code (1..16) */
  587. X    j = ((j & 0xf0) >> 4) + 1;          /* codes with those bits (1..16) */
  588. X    if (k + j > n)
  589. X      return 4;                         /* don't overflow l[] */
  590. X    do {
  591. X      l[k++] = b;
  592. X    } while (--j);
  593. X  } while (--i);
  594. X  return k != n ? 4 : 0;                /* should have read n of them */
  595. X}
  596. X
  597. X
  598. X
  599. Xint explode_lit8(tb, tl, td, bb, bl, bd)
  600. Xstruct huft *tb, *tl, *td;      /* literal, length, and distance tables */
  601. Xint bb, bl, bd;                 /* number of bits decoded by those */
  602. X/* Decompress the imploded data using coded literals and an 8K sliding
  603. X   window. */
  604. X{
  605. X  longint s;            /* bytes to decompress */
  606. X  register unsigned e;  /* table entry flag/number of extra bits */
  607. X  unsigned n, d;        /* length and index for copy */
  608. X  unsigned w;           /* current window position */
  609. X  struct huft *t;       /* pointer to table entry */
  610. X  unsigned mb, ml, md;  /* masks for bb, bl, and bd bits */
  611. X  register ULONG b;     /* bit buffer */
  612. X  register unsigned k;  /* number of bits in bit buffer */
  613. X  unsigned u;           /* true if unflushed */
  614. X
  615. X
  616. X  /* explode the coded data */
  617. X  b = k = w = 0;                /* initialize bit buffer, window */
  618. X  u = 1;                        /* buffer unflushed */
  619. X  mb = mask_bits[bb];           /* precompute masks for speed */
  620. X  ml = mask_bits[bl];
  621. X  md = mask_bits[bd];
  622. X  s = ucsize;
  623. X  while (s > 0)                 /* do until ucsize bytes uncompressed */
  624. X  {
  625. X    NEEDBITS(1)
  626. X    if (b & 1)                  /* then literal--decode it */
  627. X    {
  628. X      DUMPBITS(1)
  629. X      s--;
  630. X      NEEDBITS((unsigned)bb)    /* get coded literal */
  631. X      if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
  632. X        do {
  633. X          if (e == 99)
  634. X            return 1;
  635. X          DUMPBITS(t->b)
  636. X          e -= 16;
  637. X          NEEDBITS(e)
  638. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  639. X      DUMPBITS(t->b)
  640. X      slide[w++] = (byte)t->v.n;
  641. X      if (w == WSIZE)
  642. X      {
  643. X        flush(w);
  644. X        w = u = 0;
  645. X      }
  646. X    }
  647. X    else                        /* else distance/length */
  648. X    {
  649. X      DUMPBITS(1)
  650. X      NEEDBITS(7)               /* get distance low bits */
  651. X      d = (unsigned)b & 0x7f;
  652. X      DUMPBITS(7)
  653. X      NEEDBITS((unsigned)bd)    /* get coded distance high bits */
  654. X      if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
  655. X        do {
  656. X          if (e == 99)
  657. X            return 1;
  658. X          DUMPBITS(t->b)
  659. X          e -= 16;
  660. X          NEEDBITS(e)
  661. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  662. X      DUMPBITS(t->b)
  663. X      d = w - d - t->v.n;       /* construct offset */
  664. X      NEEDBITS((unsigned)bl)    /* get coded length */
  665. X      if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
  666. X        do {
  667. X          if (e == 99)
  668. X            return 1;
  669. X          DUMPBITS(t->b)
  670. X          e -= 16;
  671. X          NEEDBITS(e)
  672. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  673. X      DUMPBITS(t->b)
  674. X      n = t->v.n;
  675. X      if (e)                    /* get length extra bits */
  676. X      {
  677. X        NEEDBITS(8)
  678. X        n += (unsigned)b & 0xff;
  679. X        DUMPBITS(8)
  680. X      }
  681. X
  682. X      /* do the copy */
  683. X      s -= n;
  684. X      do {
  685. X        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
  686. X        if (u && w <= d)
  687. X        {
  688. X          memset(slide + w, 0, e);
  689. X          w += e;
  690. X          d += e;
  691. X        }
  692. X        else
  693. X#ifndef NOMEMCPY
  694. X          if (w - d >= e)       /* (this test assumes unsigned comparison) */
  695. X          {
  696. X            memcpy(slide + w, slide + d, e);
  697. X            w += e;
  698. X            d += e;
  699. X          }
  700. X          else                  /* do it slow to avoid memcpy() overlap */
  701. X#endif /* !NOMEMCPY */
  702. X            do {
  703. X              slide[w++] = slide[d++];
  704. X            } while (--e);
  705. X        if (w == WSIZE)
  706. X        {
  707. X          flush(w);
  708. X          w = u = 0;
  709. X        }
  710. X      } while (n);
  711. X    }
  712. X  }
  713. X
  714. X  /* flush out slide */
  715. X  flush(w);
  716. X  return csize ? 5 : 0;         /* should have read csize bytes */
  717. X}
  718. X
  719. X
  720. X
  721. Xint explode_lit4(tb, tl, td, bb, bl, bd)
  722. Xstruct huft *tb, *tl, *td;      /* literal, length, and distance tables */
  723. Xint bb, bl, bd;                 /* number of bits decoded by those */
  724. X/* Decompress the imploded data using coded literals and a 4K sliding
  725. X   window. */
  726. X{
  727. X  longint s;            /* bytes to decompress */
  728. X  register unsigned e;  /* table entry flag/number of extra bits */
  729. X  unsigned n, d;        /* length and index for copy */
  730. X  unsigned w;           /* current window position */
  731. X  struct huft *t;       /* pointer to table entry */
  732. X  unsigned mb, ml, md;  /* masks for bb, bl, and bd bits */
  733. X  register ULONG b;     /* bit buffer */
  734. X  register unsigned k;  /* number of bits in bit buffer */
  735. X  unsigned u;           /* true if unflushed */
  736. X
  737. X
  738. X  /* explode the coded data */
  739. X  b = k = w = 0;                /* initialize bit buffer, window */
  740. X  u = 1;                        /* buffer unflushed */
  741. X  mb = mask_bits[bb];           /* precompute masks for speed */
  742. X  ml = mask_bits[bl];
  743. X  md = mask_bits[bd];
  744. X  s = ucsize;
  745. X  while (s > 0)                 /* do until ucsize bytes uncompressed */
  746. X  {
  747. X    NEEDBITS(1)
  748. X    if (b & 1)                  /* then literal--decode it */
  749. X    {
  750. X      DUMPBITS(1)
  751. X      s--;
  752. X      NEEDBITS((unsigned)bb)    /* get coded literal */
  753. X      if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
  754. X        do {
  755. X          if (e == 99)
  756. X            return 1;
  757. X          DUMPBITS(t->b)
  758. X          e -= 16;
  759. X          NEEDBITS(e)
  760. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  761. X      DUMPBITS(t->b)
  762. X      slide[w++] = (byte)t->v.n;
  763. X      if (w == WSIZE)
  764. X      {
  765. X        flush(w);
  766. X        w = u = 0;
  767. X      }
  768. X    }
  769. X    else                        /* else distance/length */
  770. X    {
  771. X      DUMPBITS(1)
  772. X      NEEDBITS(6)               /* get distance low bits */
  773. X      d = (unsigned)b & 0x3f;
  774. X      DUMPBITS(6)
  775. X      NEEDBITS((unsigned)bd)    /* get coded distance high bits */
  776. X      if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
  777. X        do {
  778. X          if (e == 99)
  779. X            return 1;
  780. X          DUMPBITS(t->b)
  781. X          e -= 16;
  782. X          NEEDBITS(e)
  783. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  784. X      DUMPBITS(t->b)
  785. X      d = w - d - t->v.n;       /* construct offset */
  786. X      NEEDBITS((unsigned)bl)    /* get coded length */
  787. X      if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
  788. X        do {
  789. X          if (e == 99)
  790. X            return 1;
  791. X          DUMPBITS(t->b)
  792. X          e -= 16;
  793. X          NEEDBITS(e)
  794. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  795. X      DUMPBITS(t->b)
  796. X      n = t->v.n;
  797. X      if (e)                    /* get length extra bits */
  798. X      {
  799. X        NEEDBITS(8)
  800. X        n += (unsigned)b & 0xff;
  801. X        DUMPBITS(8)
  802. X      }
  803. X
  804. X      /* do the copy */
  805. X      s -= n;
  806. X      do {
  807. X        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
  808. X        if (u && w <= d)
  809. X        {
  810. X          memset(slide + w, 0, e);
  811. X          w += e;
  812. X          d += e;
  813. X        }
  814. X        else
  815. X#ifndef NOMEMCPY
  816. X          if (w - d >= e)       /* (this test assumes unsigned comparison) */
  817. X          {
  818. X            memcpy(slide + w, slide + d, e);
  819. X            w += e;
  820. X            d += e;
  821. X          }
  822. X          else                  /* do it slow to avoid memcpy() overlap */
  823. X#endif /* !NOMEMCPY */
  824. X            do {
  825. X              slide[w++] = slide[d++];
  826. X            } while (--e);
  827. X        if (w == WSIZE)
  828. X        {
  829. X          flush(w);
  830. X          w = u = 0;
  831. X        }
  832. X      } while (n);
  833. X    }
  834. X  }
  835. X
  836. X  /* flush out slide */
  837. X  flush(w);
  838. X  return csize ? 5 : 0;         /* should have read csize bytes */
  839. X}
  840. X
  841. X
  842. X
  843. Xint explode_nolit8(tl, td, bl, bd)
  844. Xstruct huft *tl, *td;   /* length and distance decoder tables */
  845. Xint bl, bd;             /* number of bits decoded by tl[] and td[] */
  846. X/* Decompress the imploded data using uncoded literals and an 8K sliding
  847. X   window. */
  848. X{
  849. X  longint s;            /* bytes to decompress */
  850. X  register unsigned e;  /* table entry flag/number of extra bits */
  851. X  unsigned n, d;        /* length and index for copy */
  852. X  unsigned w;           /* current window position */
  853. X  struct huft *t;       /* pointer to table entry */
  854. X  unsigned ml, md;      /* masks for bl and bd bits */
  855. X  register ULONG b;     /* bit buffer */
  856. X  register unsigned k;  /* number of bits in bit buffer */
  857. X  unsigned u;           /* true if unflushed */
  858. X
  859. X
  860. X  /* explode the coded data */
  861. X  b = k = w = 0;                /* initialize bit buffer, window */
  862. X  u = 1;                        /* buffer unflushed */
  863. X  ml = mask_bits[bl];           /* precompute masks for speed */
  864. X  md = mask_bits[bd];
  865. X  s = ucsize;
  866. X  while (s > 0)                 /* do until ucsize bytes uncompressed */
  867. X  {
  868. X    NEEDBITS(1)
  869. X    if (b & 1)                  /* then literal--get eight bits */
  870. X    {
  871. X      DUMPBITS(1)
  872. X      s--;
  873. X      NEEDBITS(8)
  874. X      slide[w++] = (byte)b;
  875. X      if (w == WSIZE)
  876. X      {
  877. X        flush(w);
  878. X        w = u = 0;
  879. X      }
  880. X      DUMPBITS(8)
  881. X    }
  882. X    else                        /* else distance/length */
  883. X    {
  884. X      DUMPBITS(1)
  885. X      NEEDBITS(7)               /* get distance low bits */
  886. X      d = (unsigned)b & 0x7f;
  887. X      DUMPBITS(7)
  888. X      NEEDBITS((unsigned)bd)    /* get coded distance high bits */
  889. X      if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
  890. X        do {
  891. X          if (e == 99)
  892. X            return 1;
  893. X          DUMPBITS(t->b)
  894. X          e -= 16;
  895. X          NEEDBITS(e)
  896. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  897. X      DUMPBITS(t->b)
  898. X      d = w - d - t->v.n;       /* construct offset */
  899. X      NEEDBITS((unsigned)bl)    /* get coded length */
  900. X      if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
  901. X        do {
  902. X          if (e == 99)
  903. X            return 1;
  904. X          DUMPBITS(t->b)
  905. X          e -= 16;
  906. X          NEEDBITS(e)
  907. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  908. X      DUMPBITS(t->b)
  909. X      n = t->v.n;
  910. X      if (e)                    /* get length extra bits */
  911. X      {
  912. X        NEEDBITS(8)
  913. X        n += (unsigned)b & 0xff;
  914. X        DUMPBITS(8)
  915. X      }
  916. X
  917. X      /* do the copy */
  918. X      s -= n;
  919. X      do {
  920. X        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
  921. X        if (u && w <= d)
  922. X        {
  923. X          memset(slide + w, 0, e);
  924. X          w += e;
  925. X          d += e;
  926. X        }
  927. X        else
  928. X#ifndef NOMEMCPY
  929. X          if (w - d >= e)       /* (this test assumes unsigned comparison) */
  930. X          {
  931. X            memcpy(slide + w, slide + d, e);
  932. X            w += e;
  933. X            d += e;
  934. X          }
  935. X          else                  /* do it slow to avoid memcpy() overlap */
  936. X#endif /* !NOMEMCPY */
  937. X            do {
  938. X              slide[w++] = slide[d++];
  939. X            } while (--e);
  940. X        if (w == WSIZE)
  941. X        {
  942. X          flush(w);
  943. X          w = u = 0;
  944. X        }
  945. X      } while (n);
  946. X    }
  947. X  }
  948. X
  949. X  /* flush out slide */
  950. X  flush(w);
  951. X  return csize ? 5 : 0;         /* should have read csize bytes */
  952. X}
  953. X
  954. X
  955. X
  956. Xint explode_nolit4(tl, td, bl, bd)
  957. Xstruct huft *tl, *td;   /* length and distance decoder tables */
  958. Xint bl, bd;             /* number of bits decoded by tl[] and td[] */
  959. X/* Decompress the imploded data using uncoded literals and a 4K sliding
  960. X   window. */
  961. X{
  962. X  longint s;            /* bytes to decompress */
  963. X  register unsigned e;  /* table entry flag/number of extra bits */
  964. X  unsigned n, d;        /* length and index for copy */
  965. X  unsigned w;           /* current window position */
  966. X  struct huft *t;       /* pointer to table entry */
  967. X  unsigned ml, md;      /* masks for bl and bd bits */
  968. X  register ULONG b;     /* bit buffer */
  969. X  register unsigned k;  /* number of bits in bit buffer */
  970. X  unsigned u;           /* true if unflushed */
  971. X
  972. X
  973. X  /* explode the coded data */
  974. X  b = k = w = 0;                /* initialize bit buffer, window */
  975. X  u = 1;                        /* buffer unflushed */
  976. X  ml = mask_bits[bl];           /* precompute masks for speed */
  977. X  md = mask_bits[bd];
  978. X  s = ucsize;
  979. X  while (s > 0)                 /* do until ucsize bytes uncompressed */
  980. X  {
  981. X    NEEDBITS(1)
  982. X    if (b & 1)                  /* then literal--get eight bits */
  983. X    {
  984. X      DUMPBITS(1)
  985. X      s--;
  986. X      NEEDBITS(8)
  987. X      slide[w++] = (byte)b;
  988. X      if (w == WSIZE)
  989. X      {
  990. X        flush(w);
  991. X        w = u = 0;
  992. X      }
  993. X      DUMPBITS(8)
  994. X    }
  995. X    else                        /* else distance/length */
  996. X    {
  997. X      DUMPBITS(1)
  998. X      NEEDBITS(6)               /* get distance low bits */
  999. X      d = (unsigned)b & 0x3f;
  1000. X      DUMPBITS(6)
  1001. X      NEEDBITS((unsigned)bd)    /* get coded distance high bits */
  1002. X      if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
  1003. X        do {
  1004. X          if (e == 99)
  1005. X            return 1;
  1006. X          DUMPBITS(t->b)
  1007. X          e -= 16;
  1008. X          NEEDBITS(e)
  1009. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  1010. X      DUMPBITS(t->b)
  1011. X      d = w - d - t->v.n;       /* construct offset */
  1012. X      NEEDBITS((unsigned)bl)    /* get coded length */
  1013. X      if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
  1014. X        do {
  1015. X          if (e == 99)
  1016. X            return 1;
  1017. X          DUMPBITS(t->b)
  1018. X          e -= 16;
  1019. X          NEEDBITS(e)
  1020. X        } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
  1021. X      DUMPBITS(t->b)
  1022. X      n = t->v.n;
  1023. X      if (e)                    /* get length extra bits */
  1024. X      {
  1025. X        NEEDBITS(8)
  1026. X        n += (unsigned)b & 0xff;
  1027. X        DUMPBITS(8)
  1028. X      }
  1029. X
  1030. X      /* do the copy */
  1031. X      s -= n;
  1032. X      do {
  1033. X        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
  1034. X        if (u && w <= d)
  1035. X        {
  1036. X          memset(slide + w, 0, e);
  1037. X          w += e;
  1038. X          d += e;
  1039. X        }
  1040. X        else
  1041. X#ifndef NOMEMCPY
  1042. X          if (w - d >= e)       /* (this test assumes unsigned comparison) */
  1043. X          {
  1044. X            memcpy(slide + w, slide + d, e);
  1045. X            w += e;
  1046. X            d += e;
  1047. X          }
  1048. X          else                  /* do it slow to avoid memcpy() overlap */
  1049. X#endif /* !NOMEMCPY */
  1050. X            do {
  1051. X              slide[w++] = slide[d++];
  1052. X            } while (--e);
  1053. X        if (w == WSIZE)
  1054. X        {
  1055. X          flush(w);
  1056. X          w = u = 0;
  1057. X        }
  1058. X      } while (n);
  1059. X    }
  1060. X  }
  1061. X
  1062. X  /* flush out slide */
  1063. X  flush(w);
  1064. X  return csize ? 5 : 0;         /* should have read csize bytes */
  1065. X}
  1066. X
  1067. X
  1068. X
  1069. Xint explode()
  1070. X/* Explode an imploded compressed stream.  Based on the general purpose
  1071. X   bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding
  1072. X   window.  Construct the literal (if any), length, and distance codes and
  1073. X   the tables needed to decode them (using huft_build() from inflate.c),
  1074. X   and call the appropriate routine for the type of data in the remainder
  1075. X   of the stream.  The four routines are nearly identical, differing only
  1076. X   in whether the literal is decoded or simply read in, and in how many
  1077. X   bits are read in, uncoded, for the low distance bits. */
  1078. X{
  1079. X  unsigned r;           /* return codes */
  1080. X  struct huft *tb;      /* literal code table */
  1081. X  struct huft *tl;      /* length code table */
  1082. X  struct huft *td;      /* distance code table */
  1083. X  int bb;               /* bits for tb */
  1084. X  int bl;               /* bits for tl */
  1085. X  int bd;               /* bits for td */
  1086. X  unsigned l[256];      /* bit lengths for codes */
  1087. X
  1088. X
  1089. X  /* Tune base table sizes.  Note: I thought that to truly optimize speed,
  1090. X     I would have to select different bl, bd, and bb values for different
  1091. X     compressed file sizes.  I was suprised to find out the the values of
  1092. X     7, 7, and 9 worked best over a very wide range of sizes, except that
  1093. X     bd = 8 worked marginally better for large compressed sizes. */
  1094. X  bl = 7;
  1095. X  bd = csize > 200000L ? 8 : 7;
  1096. X
  1097. X
  1098. X  /* With literal tree--minimum match length is 3 */
  1099. X  hufts = 0;                    /* initialze huft's malloc'ed */
  1100. X  if (lrec.general_purpose_bit_flag & 4)
  1101. X  {
  1102. X    bb = 9;                     /* base table size for literals */
  1103. X    if ((r = get_tree(l, 256)) != 0)
  1104. X      return r;
  1105. X    if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb)) != 0)
  1106. X    {
  1107. X      if (r == 1)
  1108. X        huft_free(tb);
  1109. X      return r;
  1110. X    }
  1111. X    if ((r = get_tree(l, 64)) != 0)
  1112. X      return r;
  1113. X    if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl)) != 0)
  1114. X    {
  1115. X      if (r == 1)
  1116. X        huft_free(tl);
  1117. X      huft_free(tb);
  1118. X      return r;
  1119. X    }
  1120. X    if ((r = get_tree(l, 64)) != 0)
  1121. X      return r;
  1122. X    if (lrec.general_purpose_bit_flag & 2)      /* true if 8K */
  1123. X    {
  1124. X      if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
  1125. X      {
  1126. X        if (r == 1)
  1127. X          huft_free(td);
  1128. X        huft_free(tl);
  1129. X        huft_free(tb);
  1130. X        return r;
  1131. X      }
  1132. X      r = explode_lit8(tb, tl, td, bb, bl, bd);
  1133. X    }
  1134. X    else                                        /* else 4K */
  1135. X    {
  1136. X      if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
  1137. X      {
  1138. X        if (r == 1)
  1139. X          huft_free(td);
  1140. X        huft_free(tl);
  1141. X        huft_free(tb);
  1142. X        return r;
  1143. X      }
  1144. X      r = explode_lit4(tb, tl, td, bb, bl, bd);
  1145. X    }
  1146. X    huft_free(td);
  1147. X    huft_free(tl);
  1148. X    huft_free(tb);
  1149. X  }
  1150. X  else
  1151. X
  1152. X
  1153. X  /* No literal tree--minimum match length is 2 */
  1154. X  {
  1155. X    if ((r = get_tree(l, 64)) != 0)
  1156. X      return r;
  1157. X    if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl)) != 0)
  1158. X    {
  1159. X      if (r == 1)
  1160. X        huft_free(tl);
  1161. X      return r;
  1162. X    }
  1163. X    if ((r = get_tree(l, 64)) != 0)
  1164. X      return r;
  1165. X    if (lrec.general_purpose_bit_flag & 2)      /* true if 8K */
  1166. X    {
  1167. X      if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
  1168. X      {
  1169. X        if (r == 1)
  1170. X          huft_free(td);
  1171. X        huft_free(tl);
  1172. X        return r;
  1173. X      }
  1174. X      r = explode_nolit8(tl, td, bl, bd);
  1175. X    }
  1176. X    else                                        /* else 4K */
  1177. X    {
  1178. X      if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
  1179. X      {
  1180. X        if (r == 1)
  1181. X          huft_free(td);
  1182. X        huft_free(tl);
  1183. X        return r;
  1184. X      }
  1185. X      r = explode_nolit4(tl, td, bl, bd);
  1186. X    }
  1187. X    huft_free(td);
  1188. X    huft_free(tl);
  1189. X  }
  1190. X#ifdef DEBUG
  1191. X  fprintf(stderr, "<%u > ", hufts);
  1192. X#endif /* DEBUG */
  1193. X  return r;
  1194. X}
  1195. END_OF_FILE
  1196.   if test 26874 -ne `wc -c <'explode.c'`; then
  1197.     echo shar: \"'explode.c'\" unpacked with wrong size!
  1198.   fi
  1199.   # end of 'explode.c'
  1200. fi
  1201. if test -f 'zipinfo.1' -a "${1}" != "-c" ; then 
  1202.   echo shar: Will not clobber existing file \"'zipinfo.1'\"
  1203. else
  1204.   echo shar: Extracting \"'zipinfo.1'\" \(13533 characters\)
  1205.   sed "s/^X//" >'zipinfo.1' <<'END_OF_FILE'
  1206. X.de X
  1207. X.nf
  1208. X.ien .ti -5
  1209. X.el \{ .ti +2m
  1210. X.ps -1 \}
  1211. X\&\\$1
  1212. X.ien .ti +5
  1213. X.el \{ .ti -2m
  1214. X.ps +1 \}
  1215. X.fi
  1216. X..
  1217. X.TH ZIPINFO 1 "19 Aug 92 (v1.0)"
  1218. X.SH NAME
  1219. Xzipinfo \- list detailed information about a ZIP archive file
  1220. X.SH SYNOPSIS
  1221. X\fBzipinfo\fP [\-\fB1smlvht\fP] \fRfile\fP[\fR.zip\fP] [\fRfilespec\fP\ ...]
  1222. X.SH ARGUMENTS
  1223. X.IP \fIfile\fP[\fI.zip\fP] \w'[\fIfilespec\fP]'u+2m
  1224. XPath of the ZIP archive.  The suffix ``\fR.zip\fP'' is applied
  1225. Xif the \fRfile\fP specified does not exist.  Note that
  1226. Xself-extracting ZIP files are supported; just specify
  1227. Xthe ``\fR.exe\fP'' suffix yourself.
  1228. X.IP [\fIfilespec\fP]
  1229. XAn optional list of archive members to be processed.
  1230. XExpressions may be used to match multiple members; be sure to quote
  1231. Xexpressions that contain characters interpreted by the Unix shell. See
  1232. XPATTERN MATCHING (below) for more details.
  1233. X.SH OPTIONS
  1234. X.PD 0
  1235. X.IP \-1 \w'\-1'u+2m
  1236. Xlist filenames only, one per line (useful for pipes)
  1237. X.IP \-s
  1238. Xlist zipfile info in short Unix ``ls \-l'' format:  default
  1239. X.IP \-m
  1240. Xlist zipfile info in medium Unix ``ls \-l'' format
  1241. X.IP \-l
  1242. Xlist zipfile info in long Unix ``ls \-l'' format
  1243. X.IP \-v
  1244. Xlist zipfile information in verbose, multi-page format
  1245. X.IP \-h
  1246. Xlist header line
  1247. X.IP \-t
  1248. Xlist totals for files listed or for all files
  1249. X.PD
  1250. X.SH PATTERN MATCHING
  1251. XAll archive members are listed unless a \fIfilespec\fP is provided to 
  1252. Xspecify a subset of the archive members.  The \fIfilespec\fP is similar 
  1253. Xto an \fRegrep\fP expression, and may contain:
  1254. X.PP
  1255. X.ta \w'[...]'u+2m
  1256. X*    matches a sequence of 0 or more characters
  1257. X.br
  1258. X?    matches exactly 1 character
  1259. X.br
  1260. X\\nnn    matches the character having octal code nnn
  1261. X.PD 0
  1262. X.IP [...] \w'[...]'u+2m
  1263. Xmatches any single character found inside the brackets; ranges
  1264. Xare specified by a beginning character, a hyphen, and an ending
  1265. Xcharacter.  If an exclamation point or a carat (`!' or `^') follows
  1266. Xthe left bracket, then the range of characters matched is complemented
  1267. Xwith respect to the ASCII character set (that is, anything except the
  1268. Xcharacters inside the brackets is considered a match).
  1269. X.PD
  1270. X.SH DESCRIPTION
  1271. X.I ZipInfo
  1272. Xlists technical information about a ZIP archive, including information
  1273. Xfile access permissions, encryption status, type of compression, version
  1274. Xand operating system of compressing program, and the like.  The default
  1275. Xoption is to list files in the following format:
  1276. X.PP
  1277. X.X "-rw-rwl---  1.5 unx    2802 t- defX 11-Aug-91 13:48 perms.2660"
  1278. X.PP
  1279. XThe last three fields are clearly the modification date and time of
  1280. Xthe file, and its name.  The case of the filename is respected; thus
  1281. Xfiles which come from MS-DOS PKZIP are always capitalized.  If the file
  1282. Xwas zipped with a stored directory name, that is also displayed as part
  1283. Xof the filename.
  1284. X.PP
  1285. XThe second and third fields indicate that the file was zipped under
  1286. XUnix with version 1.5 of \fRZip\fP (a beta version).  Since it comes
  1287. Xfrom Unix, the file
  1288. Xpermissions at the beginning of the line are printed in Unix format.
  1289. XThe uncompressed file-size (2802 in this example) is the fourth field.
  1290. X.PP
  1291. XThe fifth field consists of two characters, either of which may take
  1292. Xon several values.  The first character may be either `t' or `b', indicating
  1293. Xthat \fRZip\fP believes the file to be text or binary, respectively;
  1294. Xbut if the file is encrypted, \fIZipInfo\fP
  1295. Xnotes this fact by capitalizing the character (`T' or `B').  The second
  1296. Xcharacter may also take on four values, depending on whether there is
  1297. Xan extended local header and/or an ``extra field'' associated with the
  1298. Xfile (explained in PKWare's APPNOTE.TXT).  If neither exists, the character
  1299. Xwill be a hyphen (`\-'); if there is an extended local header but no extra
  1300. Xfield, `l'; if the reverse, `x'; and if both exist, `X'.  Thus the
  1301. Xfile in this example is (apparently) a text file, is not encrypted, and
  1302. Xhas neither an extra field nor an extended local header associated with it.
  1303. XThe example below, on the other hand, is an encrypted binary file with an 
  1304. Xextra field:
  1305. X.PP
  1306. X.X "RWD,R,R     0.9 vms     168 Bx shrk  9-Aug-91 19:15 perms.0644"
  1307. X.PP
  1308. XExtra fields are used by PKWare for authenticity verification(?) and
  1309. Xpossibly other purposes, and by Info-ZIP's \fRZip\fP
  1310. X1.6 and later to store OS/2, Macintosh and VMS file attributes.
  1311. XThis example presumably falls into
  1312. Xthe latter class, then.  Note that the file attributes are listed in
  1313. XVMS format.  Other possibilities for the host operating system include
  1314. XOS/2 with High Performance File System (HPFS), DOS or OS/2 with File 
  1315. XAllocation Table (FAT) file system, and Macintosh, denoted
  1316. Xas follows:
  1317. X.PP
  1318. X.X "arc,,rw,    1.0 os2    5358 Tl i4:3  4-Dec-91 11:33 longfilename.hpfs"
  1319. X.X "arc,hid,rdo,sys dos    4096 b- i4:2 14-Jul-91 12:58 EA DATA. SF"
  1320. X.X "--w-------  1.0 mac   17357 bx i8:2  4-May-92 04:02 unzip.macr"
  1321. X.PP
  1322. XFile attributes in the first two cases are indicated in a DOS-like format,
  1323. Xwhere the file may or may not have its archive bit set; may be hidden or not;
  1324. Xmay be read-write or read-only; and may be a system file or not.  If the
  1325. Xattributes are too long, the version number of the encoding software is
  1326. Xomitted.  (The information is still available in the verbose listing, 
  1327. Xhowever.)  Interpretation of Macintosh file attributes needs some work yet.
  1328. X.PP
  1329. XFinally, the sixth field indicates
  1330. Xthe compression method and possible sub-method used.  There are six methods
  1331. Xknown at present:  storing (no compression), reducing, shrinking, imploding,
  1332. Xtokenizing, and deflating.  In addition, there are four levels of reducing
  1333. X(1 through 4); four types of imploding (4K or 8K sliding dictionary, and
  1334. X2 or 3 Shannon-Fano trees); and three levels of deflating (fast, normal,
  1335. Xmaximum compression).  \fIZipInfo\fP represents these methods and their
  1336. Xsub-methods as follows:  ``stor''; ``re:1,'' ``re:2,'' etc.; ``shrk'';
  1337. X``i4:2,'' ``i8:3,'' etc.; ``tokn''; and ``defF,'' ``defN,'' and ``defX.''
  1338. X.PP
  1339. XThe medium and long listings are almost identical to the
  1340. Xshort format except that they add information on the file's
  1341. Xcompression.  The medium format indicates the file's
  1342. Xcompression factor as a percentage:
  1343. X.PP
  1344. X.X "-rw-rwl---  1.5 unx    2802 t- 81% defX 11-Aug-91 13:48 perms.2660"
  1345. X.PP
  1346. XIn this example, the file has been compressed by more than a factor of
  1347. Xfive; the compressed data are only 19% of the original size.  The long
  1348. Xformat gives the compressed file's size in bytes, instead:
  1349. X.PP
  1350. X.X "-rw-rwl---  1.5 unx    2802 t-     538 defX 11-Aug-91 13:48 perms.2660"
  1351. X.PP
  1352. XIn addition to individual file information, a default zipfile listing
  1353. Xalso includes header and trailer lines:
  1354. X.PP
  1355. X.X "Archive:  OS2.zip   5453 bytes   5 files"
  1356. X.X ",,rw,       1.0 os2     730 b- i4:3 26-Jun-92 23:40 Contents"
  1357. X.X ",,rw,       1.0 os2    3710 b- i4:3 26-Jun-92 23:33 makefile.os2"
  1358. X.X ",,rw,       1.0 os2    8753 b- i8:3 26-Jun-92 15:29 os2unzip.c"
  1359. X.X ",,rw,       1.0 os2      98 b- stor 21-Aug-91 15:34 unzip.def"
  1360. X.X ",,rw,       1.0 os2      95 b- stor 21-Aug-91 17:51 zipinfo.def"
  1361. X.X "5 files, 13386 bytes uncompressed, 4951 bytes compressed:  63%"
  1362. X.PP
  1363. XThe header line gives the name of the archive, its total size, and the
  1364. Xtotal number of files; the trailer gives the number of files listed,
  1365. Xtheir total uncompressed size, and their total compressed size (not
  1366. Xincluding any of \fRZip\fP's internal overhead).  If, however, one or 
  1367. Xmore \fIfilespec\fPs are provided, the header and trailer lines are
  1368. Xnot listed.  This behavior is also similar to that of Unix's ``ls \-l'';
  1369. Xit may be overridden by specifying the \-h and \-t options explicitly.
  1370. XIn such a case the listing format must also be specified explicitly,
  1371. Xsince \-h or \-t (or both) in the absence of other options implies
  1372. Xthat ONLY the header or trailer line (or both) is listed.  See the
  1373. XEXAMPLES section below for a semi-intelligible translation of this
  1374. Xnonsense.
  1375. X.PP
  1376. XThe verbose listing is self-explanatory.  It also lists file
  1377. Xcomments and the zipfile comment, if any, and the number of
  1378. Xbytes of OS/2 extended attributes stored.  Note that the
  1379. Xlatter number will in general NOT match the number given by
  1380. XOS/2's ``dir'' command; OS/2 always reports the number of
  1381. Xbytes required in 16-bit format, whereas \fIZipInfo\fP
  1382. Xalways reports the 32-bit storage.
  1383. X.PD
  1384. X.SH ENVIRONMENT OPTIONS
  1385. XModifying \fIZipInfo\fP's default behavior via options placed in
  1386. Xan environment variable can be a bit complicated to explain, due to
  1387. X\fIZipInfo\fP's attempts to handle various defaults in an intuitive,
  1388. Xyet Unix-like, manner.  Nevertheless, there is some underlying logic.
  1389. XIn brief, 
  1390. Xthere are three ``priority levels'' of options:  the default options;
  1391. Xenvironment options, which can override or add to the defaults; and 
  1392. Xexplicit options given by the user, which can override or add to 
  1393. Xeither of the above.
  1394. X.PP
  1395. XThe default listing format, as noted above, corresponds roughly
  1396. Xto the "zipinfo \-hst" command (except when individual zipfile members
  1397. Xare specified).
  1398. XA user who prefers the long-listing format (\-l) can make use of the
  1399. X\fIZIPINFO\fP environment variable to change this default:
  1400. X.ta \w'tabset'u +\w'ZIPINFO=\-l; export ZIPINFO'u+3m
  1401. X.PP
  1402. X.IP "\tsetenv ZIPINFO \-l\tUnix C shell"
  1403. X.br
  1404. X.IP "\tZIPINFO=\-l; export ZIPINFO\tUnix Bourne shell"
  1405. X.PP
  1406. X.IP "\tset ZIPINFO=\-l\tOS/2 or MS-DOS"
  1407. X.PP
  1408. X.IP "\tdefine ZIPINFO_OPTS ""\-l""\tVMS (quotes for LOWERCASE)"
  1409. X.PP
  1410. XIf, in addition, the user dislikes the trailer line, \fIZipInfo\fP's
  1411. Xconcept of ``negative options'' may be used to override the default
  1412. Xinclusion of the line.  This is accomplished by preceding the undesired
  1413. Xoption with one or more minuses:  e.g., ``\-l\-t'' or ``\-\-tl'', in this
  1414. Xexample.  The first hyphen is the regular switch character, but the one
  1415. Xbefore the `t' is a minus sign.  The dual use of hyphens may seem a little
  1416. Xawkward, but it's reasonably intuitive nonetheless:  simply ignore the
  1417. Xfirst hyphen and go from there.  It is also consistent with the behavior
  1418. Xof the Unix command \fRnice\fP(1).
  1419. X.PD
  1420. X.SH EXAMPLES
  1421. XTo get a basic, short-format listing of the complete contents of a ZIP 
  1422. Xarchive ``storage.zip,'' with both header and totals lines, use only
  1423. Xthe archive name as an argument to zipinfo:
  1424. X.PP
  1425. X.IP "\t\fIzipinfo\fP storage"
  1426. X.PP
  1427. XTo produce a basic, long-format listing (not verbose), including header and
  1428. Xtotals lines, use \-l:
  1429. X.PP
  1430. X.IP "\t\fIzipinfo\fP \-l storage"
  1431. X.PP
  1432. XTo list the complete contents of the archive without header and totals
  1433. Xlines, either negate the \-h and \-t options or else specify the contents
  1434. Xexplicitly:
  1435. X.PP
  1436. X.IP "\t\fIzipinfo\fP \-\-h\-t storage"
  1437. X.IP "\t\fIzipinfo\fP storage \e*"
  1438. X.PP
  1439. X(where the backslash is required only if the shell would otherwise expand
  1440. Xthe `*' wildcard, as in Unix when globbing is turned on--double quotes around
  1441. Xthe asterisk would have worked as well).  To turn off the totals line by
  1442. Xdefault, use the environment variable (C shell is assumed here):
  1443. X.PP
  1444. X.IP "\tsetenv ZIPINFO \-\-t"
  1445. X.IP "\t\fIzipinfo\fP storage"
  1446. X.PP
  1447. XTo get the full, short-format listing of the first example again, given
  1448. Xthat the environment variable is set as in the previous example, it is
  1449. Xnecessary to specify the \-s option explicitly, since the \-t
  1450. Xoption by itself implies that ONLY the footer line is to be printed:
  1451. X.PP
  1452. X.IP "\tsetenv ZIPINFO \-\-t"
  1453. X.IP "\t\fIzipinfo\fP \-t storage\t[only totals line]"
  1454. X.IP "\t\fIzipinfo\fP \-st storage\t[full listing]"
  1455. X.PP
  1456. XThe \-s option, like \-m and \-l, includes headers and footers by default,
  1457. Xunless otherwise specified.  Since the environment variable specified no
  1458. Xfooters and that has a higher precedence than the default behavior of \-s,
  1459. Xan explicit \-t option was necessary to produce the full listing.  Nothing 
  1460. Xwas indicated about the header, however, so the \-s option was sufficient.
  1461. XNote that both the \-h and \-t options, when used by themselves or with
  1462. Xeach other, override any default listing of member files; only the header
  1463. Xand/or footer are printed.  This behavior will be more 
  1464. Xuseful when \fIZipInfo\fP accepts wildcards for the zipfile name; one
  1465. Xmay then summarize the contents of all zipfiles with a single command.
  1466. X.PP
  1467. XTo list information on a single file within the archive, in medium format,
  1468. Xspecify the filename explicitly:
  1469. X.PP
  1470. X.IP "\t\fIzipinfo\fP \-m storage unshrink.c"
  1471. X.PP
  1472. XThe specification of any member file, as in this example, will override
  1473. Xthe default header and totals lines; only the single line of information
  1474. Xabout the requested file will be printed.  This is intuitively what one
  1475. Xwould expect when requesting information about a single file.  For multiple
  1476. Xfiles, it is often useful to know the total compressed and uncompressed
  1477. Xsize; in such cases \-t may be specified explicitly:
  1478. X.PP
  1479. X.IP "\t\fIzipinfo\fP \-mt storage ""*.[ch] Mak\e*"
  1480. X.PP
  1481. XFinally, to get maximal information about the ZIP archive, use the verbose 
  1482. Xoption.  It is usually wise to pipe the output into a filter such as 
  1483. X\fRmore\fP(1):
  1484. X.PP
  1485. X.IP "\t\fIzipinfo\fP \-v storage | more"
  1486. X.PD
  1487. X.SH TIPS
  1488. XThe author finds it convenient to set up an alias ``ii'' for \fIZipInfo\fP
  1489. Xon systems which allow aliases, or else to set up a batch file ``ii.bat''
  1490. Xor to rename the executable to ``ii.exe'' on systems such as MS-DOS which
  1491. Xhave no provision for aliases.  The ``ii'' usage parallels the common
  1492. X``ll'' alias for long listings in Unix, and the similarity between the
  1493. Xoutputs of the two commands was intentional.
  1494. X.PD
  1495. X.SH SEE ALSO
  1496. Xfunzip(1), unzip(1), zip(1), zipcloak(1), zipnote(1), zipsplit(1)
  1497. X.PD
  1498. X.SH AUTHOR
  1499. XGreg Roelofs (also known as Cave Newt).  \fIZipInfo\fP is partly based on
  1500. XS. H. Smith's \fRunzip\fP and contains pattern-matching code by J. Kercheval,
  1501. Xbut mostly it was written from scratch.  The OS/2 extra-field code is by
  1502. XKai Uwe Rommel.
  1503. END_OF_FILE
  1504.   if test 13533 -ne `wc -c <'zipinfo.1'`; then
  1505.     echo shar: \"'zipinfo.1'\" unpacked with wrong size!
  1506.   fi
  1507.   # end of 'zipinfo.1'
  1508. fi
  1509. echo shar: End of archive 9 \(of 14\).
  1510. cp /dev/null ark9isdone
  1511. MISSING=""
  1512. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1513.     if test ! -f ark${I}isdone ; then
  1514.     MISSING="${MISSING} ${I}"
  1515.     fi
  1516. done
  1517. if test "${MISSING}" = "" ; then
  1518.     echo You have unpacked all 14 archives.
  1519.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1520. else
  1521.     echo You still must unpack the following archives:
  1522.     echo "        " ${MISSING}
  1523. fi
  1524. exit 0
  1525. exit 0 # Just in case...
  1526.