home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume23 / zip / part05 < prev    next >
Encoding:
Text File  |  1991-10-21  |  53.9 KB  |  1,408 lines

  1. Newsgroups: comp.sources.misc
  2. From: kirsch@usasoc.soc.mil (David Kirschbaum)
  3. Subject:  v23i092:  zip - Portable zip v1.0, Part05/09
  4. Message-ID: <1991Oct21.042139.8052@sparky.imd.sterling.com>
  5. X-Md4-Signature: ef2d0ebf66ab2291a46cb1396abe9840
  6. Date: Mon, 21 Oct 1991 04:21:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
  10. Posting-number: Volume 23, Issue 92
  11. Archive-name: zip/part05
  12. Environment: UNIX, Minix, MSDOS, OS/2, VMS
  13.  
  14. #! /bin/sh
  15. # into a shell via "sh file" or similar.  To overwrite existing files,
  16. # type "sh file -c".
  17. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  18. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  19. # Contents:  doturboc.bat im_lmat.c zip.doc
  20. # Wrapped by kent@sparky on Sun Oct 20 22:58:54 1991
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 5 (of 9)."'
  24. if test -f 'doturboc.bat' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'doturboc.bat'\"
  26. else
  27.   echo shar: Extracting \"'doturboc.bat'\" \(574 characters\)
  28.   sed "s/^X//" >'doturboc.bat' <<'END_OF_FILE'
  29. X: This file is a complement to zip.prj for Turbo C 2.0 users.
  30. X: Use it to assemble im_lm.asm then enter TC, change the compilation
  31. X: model from small to compact if you wish (thus removing a limitation on
  32. X: the number of files but getting slower code), and press F9...
  33. X: Note: currently, im_lm.asm does not work in the compact model with Turbo C.
  34. X: If you wish to use the compact model, #define NO_ASM in im_lmat.c and
  35. X: remove im_lm.obj from zip.prj.
  36. Xtasm -t -ml -DDYN_ALLOC im_lm;
  37. X: Let's do ship while we're here
  38. Xtcc -w -a -d -G -O -Z -ms -Ic:\tc\include -Lc:\tc\lib ship
  39. END_OF_FILE
  40.   if test 574 -ne `wc -c <'doturboc.bat'`; then
  41.     echo shar: \"'doturboc.bat'\" unpacked with wrong size!
  42.   fi
  43.   # end of 'doturboc.bat'
  44. fi
  45. if test -f 'im_lmat.c' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'im_lmat.c'\"
  47. else
  48.   echo shar: Extracting \"'im_lmat.c'\" \(27597 characters\)
  49.   sed "s/^X//" >'im_lmat.c' <<'END_OF_FILE'
  50. X/*
  51. X
  52. X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  53. X Permission is granted to any individual or institution to use, copy, or
  54. X redistribute this software so long as all of the original files are included
  55. X unmodified, that it is not sold for profit, and that this copyright notice
  56. X is retained.
  57. X
  58. X*/
  59. X
  60. X/*
  61. X *  im_lmat.c by Jean-loup Gailly.
  62. X *
  63. X *  PURPOSE
  64. X *
  65. X *      Identify new text as repetitions of old text within a fixed-
  66. X *      length sliding window trailing behind the new text.
  67. X *
  68. X *  DISCUSSION
  69. X *
  70. X *      The "implosion" process depends on being able to identify portions
  71. X *      of the input text which are identical to earlier input (within a
  72. X *      sliding window trailing behind the input currently being processed).
  73. X *
  74. X *      The most straightforward technique turns out to be the fastest for
  75. X *      most input files: try all possible matches and select the longest.
  76. X *      The key feature is of this algorithm is that insertion and deletions
  77. X *      from the string dictionary are very simple and thus fast. Insertions
  78. X *      and deletions are performed at each input character, whereas string
  79. X *      matches are performed only when the previous match ends. So it is
  80. X *      preferable to spend more time in matches to allow very fast string
  81. X *      insertions and deletions. The matching algorithm for small strings
  82. X *      is inspired from that of Rabin & Karp. A brute force approach is
  83. X *      used to find longer strings when a small match has been found.
  84. X *      A similar algorithm is used in freeze (by Leonid Broukhis) but the
  85. X *      algorithm used here is faster.
  86. X *         A previous version of this file used a more sophisticated algorithm
  87. X *      (by Fiala and Greene) which is guaranteed to run in linear amortized
  88. X *      time, but has a larger average cost and uses more memory. However
  89. X *      the F&G algorithm may be faster for some highly redundant files if
  90. X *      the parameter max_chain_length (described below) is too large.
  91. X *
  92. X *  ACKNOWLEDGEMENTS
  93. X *
  94. X *      Rich Wales defined the interface, provided the necessary information
  95. X *      to ensure compatibility with pkunzip 1.0 (not an easy job) and
  96. X *      suggested the solution (n == 1 + n-1) adopted here.
  97. X *      The idea of lazy evaluation of matches is due to Jan Mark Wams, and
  98. X *      I found it in 'freeze' written by Leonid Broukhis.
  99. X *      Special thanks to Kai-Uwe Rommel for the OS/2 port, to Glenn J.
  100. X *      Andrews for the VMS port, and to many other info-zippers for testing.
  101. X *
  102. X *  REFERENCES
  103. X *
  104. X *      A description of the Rabin and Karp algorithm is given in the book
  105. X *          "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
  106. X *
  107. X *      Fiala,E.R., and Greene,D.H.
  108. X *          Data Compression with Finite Windows, CACM, 32,4 (1989) 490-595.
  109. X *
  110. X *  INTERFACE
  111. X *
  112. X *      ImpErr lm_init (int pack_level)
  113. X *          Initialize the "longest match" routines for a new file.
  114. X *          The global variable fd is an implicit parameter.
  115. X *
  116. X *      ImpErr lm_input (U_CHAR *block, U_INT count)
  117. X *          Process a block of input characters.
  118. X *
  119. X *      ImpErr lm_windup (void)
  120. X *          Flush out the remaining unprocessed input.
  121. X */
  122. X
  123. X#include "implode.h"
  124. X
  125. X/***********************************************************************
  126. X *
  127. X * Configuration parameters
  128. X */
  129. X
  130. X#define MAX_MATCH_LENGTH  320
  131. X/* The maximum match length. 320 = 64 + 256. (If the length is greater than
  132. X * 63, pkzip uses an extra byte.)
  133. X */
  134. X
  135. X#define MAX_WBITS  13
  136. X#define WSIZE (1 << MAX_WBITS)
  137. X/* Maximum window size = 8K */
  138. X
  139. X/* Constants used to dimension the hash table: */
  140. X#define HASH_BITS  14
  141. X/* HASH_BITS must be >= 13, see longest_match() */
  142. X
  143. X#define HASH_SIZE (1<<HASH_BITS)
  144. X#define HASH_MASK (HASH_SIZE-1)
  145. X
  146. X#if defined(MSDOS) || defined(i386) || defined(mc68020) || defined(vax)
  147. X#   define UNALIGNED_OK
  148. X    /* Define this symbol if your target allows access to unaligned data.
  149. X     * This is not mandatory, just a speed optimization. The compressed
  150. X     * output is strictly identical.
  151. X     */
  152. X#endif
  153. X#ifdef __TURBOC__
  154. X#   define DYN_ALLOC
  155. X    /* Turbo C 2.0 does not accept far static allocations in small model */
  156. X#endif
  157. X
  158. X/***********************************************************************
  159. X *
  160. X * Local data used by the "longest match" routines.
  161. X */
  162. X
  163. X#if HASH_BITS <= 14
  164. X   typedef unsigned short Hash;
  165. X#else
  166. X   /* Defined just for safety, since values > 14 do not speed up implosion */
  167. X   typedef unsigned long Hash;
  168. X#endif
  169. X
  170. Xtypedef unsigned short Pos;
  171. Xtypedef unsigned int  IPos;
  172. X/* A Pos is an index in the character window. We use short instead of int to
  173. X * save space in the various tables. IPos is used only for parameter passing.
  174. X */
  175. X
  176. Xint near min_match_length;
  177. X/* Minimum match length, 2 for binary files, 3 for ascii files.
  178. X * (bad luck for ebcdic users; not because they may not get optimal
  179. X * compression, but because they have to use ebcdic machines :-)
  180. X * A zero value means that the min_match_length is not yet determined.
  181. X */
  182. X
  183. XU_CHAR near window[MAX_MATCH_LENGTH + WSIZE + BSZ];
  184. X/* MAX_MATCH_LENGTH bytes are duplicated at both ends of the window,
  185. X * to speed up string comparisons. The BSZ extra bytes allow a block copy
  186. X * of the input buffer into the window instead of a copy one byte at a time.
  187. X */
  188. X
  189. X#define MAX_DIST (WSIZE + BSZ)
  190. X/* Maximum theoretical distance between two distinct bytes in the window.
  191. X * Actual distances are limited to bufsize.
  192. X */
  193. X
  194. X#define NIL  MAX_DIST
  195. X/* Tail of hash chains */
  196. X
  197. X#ifdef DYN_ALLOC
  198. X   Hash far *next = NULL;
  199. X   Pos  far *prev = NULL;
  200. X#else
  201. X   Hash far next[MAX_DIST+1];
  202. X   Pos  far prev[MAX_DIST+HASH_SIZE+1];
  203. X#endif
  204. X/* next is a link to a more recent string with same hash index, or to the head
  205. X * of a hash table chain if there is no such string. next[NIL] is used to
  206. X * avoid extra checks. next[s] is NIL if string s is not yet in the dictionary
  207. X *
  208. X * prev is a link to an older string with same hash index (first MAX_DIST
  209. X * values) or head of hash chain (last HASH_SIZE values). prev[NIL] is used
  210. X * to avoid extra checks.
  211. X */
  212. X#define match_head (prev+(MAX_DIST+1))
  213. X
  214. XHash near ins_h;  /* hash index of string to be inserted. */
  215. X
  216. Xint near h_shift;
  217. X/* Number of bits by which ins_h must be shifted at each
  218. X * input step. It must be such that after min_match_length steps, the oldest
  219. X * byte no longer takes part in the hash key, that is:
  220. X *   h_shift * min_match_length >= HASH_BITS
  221. X */
  222. X
  223. XMATCH *ma_buf = NULL;
  224. X/* Buffer used to speed up reading/writing to/from temp file */
  225. X#define MA_BUFEND (ma_buf+MA_BUFSIZE)
  226. X
  227. XMATCH *ma;
  228. X/* Pointer to the most recent match. */
  229. X
  230. Xint near start_length;
  231. X/* Matches not greater than this are discarded. This is used in the lazy match
  232. X * evaluation. If start_length > 1, ma is a valid guess of length start_length
  233. X * and ct_tally has not yet been called.
  234. X */
  235. X
  236. X        int near strstart;      /* start of string to insert */
  237. X        int near strsize;       /* length of string to insert */
  238. X        int near match_length;  /* length of current best match */
  239. X        int near bufsize;       /* # of slots in window */
  240. X        int near checkpoint;    /* look for new match at this point */
  241. Xstatic  int      insert_point;  /* position of next input buffer */
  242. X
  243. Xstatic  int      max_lazy_match;
  244. X/* We try lazy evaluation only for matches of length 2..max_lazy_match, to
  245. X * speed up the implosion. We use 0 for maximum speed, 0.9*MAX_MATCH_LENGTH
  246. X * for maximum compression.
  247. X */
  248. X
  249. X        int near max_chain_length;
  250. X/* To speed up implosion, hash chains are truncated to this length.
  251. X * A higher limit improves compression ratio but degrades the speed.
  252. X * We use 40 for maximum speed, 960 for maximum compression. Values
  253. X * below 20 are not recommended.
  254. X */
  255. X
  256. X/* Values for max_lazy_match and max_chain_length, depending on the desired
  257. X * pack level (0..9). The values given below have been tuned to exclude
  258. X * worst case performance for pathological files. Better values may be
  259. X * found for specific files. Note that the current algorithm requires 
  260. X * max_lazy >= 2.
  261. X */
  262. Xtypedef struct config {
  263. X   int max_lazy;
  264. X   int max_chain;
  265. X} config;
  266. X
  267. Xstatic config configuration_table[10] = {
  268. X/* 0 */ {2,                     MAX_MATCH_LENGTH/8}, /* maximum speed */
  269. X/* 1 */ {4,                     MAX_MATCH_LENGTH/4},
  270. X/* 2 */ {5,                     MAX_MATCH_LENGTH/2},
  271. X/* 3 */ {MAX_MATCH_LENGTH/16,   MAX_MATCH_LENGTH/2},
  272. X/* 4 */ {MAX_MATCH_LENGTH/16,   3*MAX_MATCH_LENGTH/4},
  273. X/* 5 */ {MAX_MATCH_LENGTH/16,   MAX_MATCH_LENGTH},
  274. X/* 6 */ {MAX_MATCH_LENGTH/16,   3*MAX_MATCH_LENGTH/2},
  275. X/* 7 */ {MAX_MATCH_LENGTH/16,   2*MAX_MATCH_LENGTH},
  276. X/* 8 */ {9*MAX_MATCH_LENGTH/10, 2*MAX_MATCH_LENGTH},
  277. X/* 9 */ {9*MAX_MATCH_LENGTH/10, 3*MAX_MATCH_LENGTH}}; /* maximum compression */
  278. X
  279. X
  280. X#define MIN(a,b) ((a) <= (b) ? (a) : (b))
  281. X/* The arguments must not have side effects. */
  282. X
  283. X#define EQUAL 0
  284. X/* result of strncmp for equal strings */
  285. X
  286. X/*  Prototypes for local functions */
  287. X
  288. Xstatic void   set_min_match_length OF ((U_CHAR *block, U_INT count));
  289. X       ImpErr write_match OF ((IPos ma_start, int ma_length));
  290. X       IPos   longest_match OF ((IPos cur_match));
  291. X       ImpErr lm_process OF ((U_INT count));
  292. X
  293. X/***********************************************************************
  294. X *
  295. X * Initialize the "longest match" routines for a new file.
  296. X * The global variable fd is an implicit parameter.
  297. X */
  298. XImpErr lm_init (pack_level)
  299. X    int pack_level; /* 0: best speed, 9: best compression, other: default */
  300. X{
  301. X    register int i;
  302. X
  303. X    /* Validate the arguments */
  304. X    bufsize = fd.fd_bufsize;
  305. X    strsize = MIN (fd.fd_strsize, MAX_MATCH_LENGTH);
  306. X    if (bufsize > WSIZE)          return IM_BADARG;
  307. X    if (bufsize < 2 * strsize)    return IM_BADARG;
  308. X    if (pack_level < 0 || pack_level > 9) return IM_BADARG;
  309. X
  310. X    /* Make sure "bufsize" is a power of 2 */
  311. X    if ((bufsize & (bufsize - 1)) != 0) return IM_BADARG;
  312. X
  313. X    /* Use dynamic allocation if compiler does not like big static arrays: */
  314. X#ifdef DYN_ALLOC
  315. X    if (prev == NULL) {
  316. X       next = (Hash far*)farmalloc((U_INT)(MAX_DIST+9)*sizeof(Hash));
  317. X       prev = (Pos far*) farmalloc((U_INT)(MAX_DIST+HASH_SIZE+9)*sizeof(Pos));
  318. X       /* We allocate 16 extra bytes for the normalization under MSDOS */
  319. X       if (prev == NULL || next == NULL) return IM_NOMEM;
  320. X
  321. X#   if defined(MSDOS) && !defined(OS2)
  322. X       /* Normalize to pointers with offset 0 (required by asm version).
  323. X        * For OS/2, we can't of course play such nasty games.
  324. X        */
  325. X#define NORMALIZE(ptr) { \
  326. X   *((int*)&ptr+1) += ((unsigned)(ptr-0) + 15) >> 4; \
  327. X   *(int*)&ptr = 0; \
  328. X}
  329. X       NORMALIZE(prev); NORMALIZE(next);
  330. X#   endif
  331. X    }
  332. X#endif /* DYN_ALLOC */
  333. X
  334. X    /* Initialize the hash tables. */
  335. X    for (i = 0;  i < HASH_SIZE; i++) match_head[i] = NIL;
  336. X    for (i = 0;  i <= MAX_DIST; i++) next[i] = NIL;
  337. X    /* prev[0..MAX_DIST] will be initialized on the fly */
  338. X    ins_h = 0;
  339. X
  340. X    /* Assume strsize zeros before the input (bytes beyond strsize
  341. X     * can be garbage):
  342. X     */
  343. X    memset((char*)window, 0, MAX_MATCH_LENGTH);
  344. X    /* It is not necessary to duplicate this at the end of the window.
  345. X     * Duplication will start only after the first wrap around.
  346. X     */
  347. X    insert_point = MAX_MATCH_LENGTH;
  348. X
  349. X    /* Force a check for the file type (ascii/binary) and set the default
  350. X     * configuration parameters:
  351. X     */
  352. X    min_match_length = 0;
  353. X    max_lazy_match   = configuration_table[pack_level].max_lazy;
  354. X    max_chain_length = configuration_table[pack_level].max_chain;
  355. X
  356. X    /* Do not report matches before the first strsize strings have been
  357. X     * inserted in the suffix tree:
  358. X     */
  359. X    strstart = 0;
  360. X    checkpoint = strsize;
  361. X    if (ma_buf == NULL) {
  362. X        ma_buf = (MATCH *) malloc ((unsigned) (MA_BUFSIZE * sizeof (MATCH)));
  363. X        if (ma_buf == NULL) return IM_NOMEM;
  364. X    }
  365. X    ma = ma_buf - 1;
  366. X    start_length = 1;
  367. X
  368. X    /* All done. */
  369. X    return IM_OK;
  370. X}
  371. X
  372. X/***********************************************************************
  373. X *
  374. X * Output the match info.
  375. X * IN assertions: The matching strings start at strstart and ma_start
  376. X *    and have a length of ma_length bytes.
  377. X *    If ma_length is not greater than start_length, ma_start is garbage.
  378. X *    strstat == checkpoint. If start_length > 1, ma is the
  379. X *    previous match which has not yet been output.
  380. X * OUT assertion: checkpoint is reset according to the match length
  381. X *    actually chosen.
  382. X *    ma is set to the current match, with start_length set appropriately.
  383. X */
  384. XImpErr write_match(ma_start, ma_length)
  385. X    IPos ma_start;           /* start of matched string */
  386. X    int ma_length;           /* length of complete match */
  387. X{
  388. X    int ma_dist = 0;         /* distance of current match */
  389. X
  390. X    /* ma_length can be too large towards the end of the input: */
  391. X    if (ma_length > strsize) ma_length = strsize;
  392. X
  393. X#ifdef DEBUG
  394. X    /* check that the match is indeed a match */
  395. X    if (ma_length > start_length &&
  396. X        strncmp(window + ma_start, window + strstart, ma_length) != EQUAL) {
  397. X        fprintf(stderr,
  398. X            "write_match: ma_start %d, strstart %d, ma_length %d\n",
  399. X            ma_start, strstart, ma_length);
  400. X        exit(1);
  401. X    }
  402. X#endif
  403. X    /* PKUNZIP accepts most overlapping matches.  However, when the
  404. X     * distance has the value 1, versions of PKUNZIP prior to 1.10 don't
  405. X     * handle the overlap properly -- and version 1.10 handles the
  406. X     * overlap correctly only if the length is limited to 62 plus the
  407. X     * minimum match length; i.e., only if there is no supplementary
  408. X     * length byte.  (From phone conversation with Phil Katz, 23 January
  409. X     * 1991.) The compression ratio is generally better when we do not
  410. X     * limit the match length to 64, so we remove distance-one matches
  411. X     * completely. (But PKUNZIP 1.01 also rejects some distance-two matches.
  412. X     * This could be fixed but would degrade compression.)
  413. X     */
  414. X    if (ma_length > 1) {
  415. X        ma_dist = strstart - ma_start;
  416. X        if (ma_dist < 0) ma_dist += MAX_DIST;
  417. X        if (ma_dist == 1) {
  418. X            /* keep the previous match if it was delayed */
  419. X            if (start_length > 1) {
  420. X                ma_length = 1;
  421. X            } else {
  422. X                /* Truncate the match to 1 */
  423. X                ImpErr retcode = write_match(ma_start, 1);
  424. X                if (retcode != IM_OK) return retcode;
  425. X
  426. X                /* Emit a match with a distance of two and a length reduced by
  427. X                 * one. This reduced match may be delayed.
  428. X                 */
  429. X                checkpoint = ++strstart;
  430. X                retcode = write_match(ma_start, ma_length-1);
  431. X                strstart--;
  432. X                return retcode; /* Leave checkpoint unchanged */
  433. X            } /* start_length > 1 */
  434. X        } /* ma_dist == 1 */
  435. X    } /* ma_length > 1 */
  436. X
  437. X    /* If the previous match has been delayed, keep it or prefer the
  438. X     * current match:
  439. X     */
  440. X    if (start_length > 1) {
  441. X        /* Keep the previous match if it is not shorter than the current one.
  442. X         * Otherwise, emit only the first byte of the previous match,
  443. X         * followed by the current match. If we have a delayed match for
  444. X         * the last bytes of the input file, the next match will necessarily
  445. X         * be smaller, so ct_tally will correctly be called for the delayed
  446. X         * match.
  447. X         */
  448. X        if (start_length >= ma_length) {
  449. X            /* Keep the previous match */
  450. X            if (start_length == 2) {
  451. X                ma->ma_dist = - ma->ma_dist;
  452. X                ma->l.ma_litc[1] = window[strstart]; /* litc[0] already set */
  453. X            } else {
  454. X                ma->l.ma_length = start_length; /* overwrite ma->l.ma_litc */
  455. X            }
  456. X            checkpoint = strstart + start_length - 1;
  457. X            start_length = 1;
  458. X            return ct_tally (ma);
  459. X        }
  460. X        /* Shorten the previous match to zero */
  461. X        ma->ma_dist = 0; /* keep ma->l.ma_litc */
  462. X        start_length = 1;
  463. X        (void) ct_tally (ma); /* ignore result, ct_tally cannot fail */
  464. X    }
  465. X
  466. X    if (++ma == MA_BUFEND) {
  467. X        ma = ma_buf;
  468. X        if (twrite ((char *) ma, sizeof(MATCH), MA_BUFSIZE, fd.fd_temp)
  469. X            != MA_BUFSIZE) return IM_IOERR;
  470. X    }
  471. X
  472. X    /* Keep the current match as guess only if its length is small,
  473. X     * trying to find a better match at the next step. If speed is not
  474. X     * critical, we use this lazy mechanism for all lengths.
  475. X     */
  476. X    if (ma_length > 1) {
  477. X        ma->ma_dist = ma_dist;
  478. X        if (ma_length <= max_lazy_match) {
  479. X           /* Set ma_litc[0]: this is the only way to identify the unmatched
  480. X            * data if the delayed match will be truncated to 1. It is also
  481. X            * useful if ma_length == 2: it may be more efficient in this case
  482. X            * to encode the individual characters rather than the match info.
  483. X            */
  484. X            ma->l.ma_litc[0] = window[strstart];
  485. X            start_length = ma_length;
  486. X            checkpoint = strstart + 1;
  487. X            return IM_OK;
  488. X        }
  489. X        /* At this point, ma_length >= 3, no need for ma_litc */
  490. X        ma->l.ma_length = ma_length;
  491. X        checkpoint = strstart + ma_length;
  492. X    } else {
  493. X        ma->ma_dist = 0;
  494. X        ma->l.ma_litc[0] = window[strstart]; /* ma_litc[1] is not required */
  495. X        checkpoint = strstart + 1;
  496. X    }
  497. X    return ct_tally (ma);
  498. X    /* Keep start_length == 1 */
  499. X}
  500. X
  501. X/***********************************************************************
  502. X *
  503. X * Determine the minimum match length, based on the type of data
  504. X * in the given input buffer: 2 for binary data, 3 otherwise. Set also
  505. X * h_shift according to the chosen min_match_length, and reduce
  506. X * max_chain_length for binary files.
  507. X *    If the guess about data type is wrong, this only affects the
  508. X * compression ratio and speed but not the correctness of the algorithms.
  509. X * If there are more than 20% bytes which seem non ascii in the first
  510. X * 500 bytes, we assume that the data is binary. (We accept data
  511. X * with a few high bits set as ascii to take into account special
  512. X * word processor formats.)
  513. X */
  514. Xstatic void set_min_match_length (block, count)
  515. X    U_CHAR *block;          /* input data */
  516. X    U_INT  count;           /* # of input char's */
  517. X{
  518. X    int non_ascii = 0;
  519. X    min_match_length = 3;  /* Default ascii */
  520. X    if (count >= 500) {
  521. X        count = 500;
  522. X        while (--count != 0) {
  523. X            if (*block <= 6 || *block >= 0x80) non_ascii++;
  524. X            block++;
  525. X        }
  526. X        if (non_ascii > 100) {
  527. X            min_match_length = 2;
  528. X            max_chain_length >>= 2;
  529. X        }
  530. X    }
  531. X    h_shift = (HASH_BITS+min_match_length-1)/min_match_length;
  532. X#ifdef DEBUG
  533. X    fprintf(stderr," (min_match_length %d) ", min_match_length);
  534. X#endif
  535. X}
  536. X
  537. X/***********************************************************************
  538. X *
  539. X * Insert string s in the dictionary and set last_match to the previous head
  540. X * of the hash chain (the most recent string with same hash key).
  541. X * IN  assertion: all calls to to INSERT_STRING are made with consecutive
  542. X *    input characters, so that a running hash key can be computed from the
  543. X *    previous key instead of complete recalculation each time.
  544. X */
  545. X#define INSERT_STRING(s, last_match) \
  546. X{ \
  547. X    ins_h = ((ins_h<<h_shift) ^ window[s + min_match_length-1]) & HASH_MASK; \
  548. X    prev[s] = last_match = match_head[ins_h]; \
  549. X    next[last_match] = prev[next[s] = ins_h + MAX_DIST+1] = s; \
  550. X}
  551. X    /* next[NIL] is garbage, we can overwrite it if s is a tail */
  552. X
  553. X/***********************************************************************
  554. X *
  555. X * Remove string s from the dictionary, or do nothing if s is not yet
  556. X * in the dictionary.
  557. X * IN assertion: s is the tail of its hash chain (the oldest string).
  558. X */
  559. X#define DELETE_STRING(s)  {prev[next[s]] = NIL;}
  560. X/* No effect if next[s] == NIL (s not in dictionary) */
  561. X
  562. X/***********************************************************************
  563. X *
  564. X * Find the longest match starting at the given string. Return its position
  565. X * and set its length in match_length. Matches shorter or equal to
  566. X * start_length are discarded, in which case match_length is unchanged
  567. X * and the result position is NIL.
  568. X * IN assertions: cur_match is the head of the hash chain for the current
  569. X *   string (strstart) and is not NIL, and start_length >= 1
  570. X */
  571. X#if !defined(MSDOS) || defined(NO_ASM)
  572. X/* For MSDOS, a version of this routine written in assembler is in im_lm.asm.
  573. X * The algorithms are strictly equivalent, so the C version can be used
  574. X * instead if you do not have masm or tasm. (Update the makefile in this case.)
  575. X */
  576. XIPos longest_match(cur_match)
  577. X    IPos cur_match;
  578. X{
  579. X    register U_CHAR *match;                   /* pointer in matched string */
  580. X    register U_CHAR *scan = window + strstart;/* pointer in current string */
  581. X    register int len;                         /* length of current match */
  582. X    IPos cur_best = NIL;                      /* best match so far */
  583. X    register int ma_length = start_length;    /* best match length so far */
  584. X    int chain_count = max_chain_length;       /* used to limit hash chains */
  585. X    typedef unsigned short US;
  586. X    typedef unsigned long  UL;
  587. X#ifdef UNALIGNED_OK
  588. X    register US scan_start = *(US*)scan;
  589. X    register US scan_end   = *(US*)(scan+ma_length-1);
  590. X#else
  591. X    register U_CHAR scan_start = *scan;
  592. X    register U_CHAR scan_end1  = scan[ma_length-1];
  593. X    register U_CHAR scan_end   = scan[ma_length];
  594. X#endif
  595. X    do {
  596. X        match = window + cur_match;
  597. X        /* Skip to next match if the match length cannot increase
  598. X         * or if the match length is less than 2:
  599. X         */
  600. X#ifdef UNALIGNED_OK
  601. X        /* This code assumes sizeof(unsigned short) == 2 and
  602. X         * sizeof(unsigned long) == 4. Do not use UNALIGNED_OK if your
  603. X         * compiler uses different sizes.
  604. X         */
  605. X        if (*(US*)(match+ma_length-1) != scan_end ||
  606. X            *(US*)match != scan_start) continue;
  607. X
  608. X        len = min_match_length - 4;
  609. X        /* If min_match_length == 3, it is not necessary to compare
  610. X         * scan[2] and match[2] since they are always equal when the other
  611. X         * bytes match, given that the hash keys are equal and that
  612. X         * HASH_BITS >= 8.
  613. X         */
  614. X#       define ML MAX_MATCH_LENGTH
  615. X        do {} while ((len+=4) < ML && *(UL*)(scan+len) == *(UL*)(match+len));
  616. X
  617. X        if (*(US*)(scan+len) == *(US*)(match+len)) len += 2;
  618. X        if (scan[len] == match[len]) len++;
  619. X
  620. X#else /* UNALIGNED_OK */
  621. X        if (match[ma_length] != scan_end ||
  622. X            match[ma_length-1] != scan_end1 || *match != scan_start)
  623. X           continue;
  624. X        /* It is not necessary to compare scan[1] and match[1] since they
  625. X         * are always equal when the other bytes match, given that
  626. X         * the hash keys are equal and that h_shift+8 <= HASH_BITS,
  627. X         * that is, when the last byte is entirely included in the hash key.
  628. X         * The condition is equivalent to
  629. X         *       (HASH_BITS+2)/3 + 8 <= HASH_BITS
  630. X         * or: HASH_BITS >= 13 (see set_min_match_length()).
  631. X         * Also, we check for a match at ma_length-1 to get rid quickly of
  632. X         * the match with the suffix of the match made at the previous step,
  633. X         * which is known to fail.
  634. X         */
  635. X        len = 1;
  636. X        do {} while (++len < MAX_MATCH_LENGTH && scan[len] == match[len]);
  637. X
  638. X#endif /* UNALIGNED_OK */
  639. X
  640. X        if (len > ma_length) {
  641. X            cur_best = cur_match, ma_length = len;
  642. X            if (len >= strsize) break;
  643. X#ifdef UNALIGNED_OK
  644. X            scan_end = *(US*)(scan+ma_length-1);
  645. X#else
  646. X            scan_end1  = scan[ma_length-1];
  647. X            scan_end   = scan[ma_length];
  648. X#endif
  649. X        }
  650. X    } while (--chain_count != 0 && (cur_match = prev[cur_match]) != NIL);
  651. X
  652. X    if (ma_length > start_length) match_length = ma_length;
  653. X    return cur_best;
  654. X}
  655. X#endif /* MSDOS */
  656. X
  657. X/***********************************************************************
  658. X *
  659. X * Process a block of input characters, generating zero or more match
  660. X * info records as appropriate.
  661. X * IN assertion: count <= BSZ
  662. X */
  663. XImpErr lm_input (block, count)
  664. X    U_CHAR *block;          /* input data */
  665. X    U_INT  count;           /* # of input char's */
  666. X{
  667. X    if (count == 0) return IM_OK;
  668. X
  669. X    /* Determine the input file type if this is the first call */
  670. X    if (min_match_length == 0) set_min_match_length (block, count);
  671. X
  672. X    if (insert_point + count <= sizeof(window)) {
  673. X        memcpy((char*)window + insert_point, (char*)block, count);
  674. X
  675. X    } else {
  676. X        int remain = sizeof(window)-insert_point;
  677. X        memcpy((char*)window + insert_point, (char*)block, remain);
  678. X
  679. X        memcpy((char*)window + MAX_MATCH_LENGTH,
  680. X               (char*)block + remain, count - remain);
  681. X    }
  682. X    insert_point += count;
  683. X    if (insert_point > MAX_DIST) {
  684. X        /* Duplicate the end of the window */
  685. X        memcpy((char*)window,
  686. X               (char*)window + MAX_DIST,
  687. X               MIN (insert_point - MAX_DIST, MAX_MATCH_LENGTH));
  688. X    }
  689. X    if (insert_point >= sizeof(window)) insert_point -= MAX_DIST;
  690. X
  691. X    return lm_process(count);
  692. X}
  693. X
  694. X/***********************************************************************
  695. X *
  696. X * Process a block of characters already inserted in the window
  697. X * IN assertion: count > 0
  698. X */
  699. X#if !defined(MSDOS) || defined(NO_ASM)
  700. XImpErr lm_process (count)
  701. X    U_INT  count;           /* number of bytes to process */
  702. X{
  703. X    ImpErr retcode;         /* as usual */
  704. X    IPos cur_match;         /* starting point for longest match search */
  705. X    IPos best_match = NIL;  /* longest match found */
  706. X    int delete_point;       /* position of next string to remove */
  707. X    
  708. X    delete_point = strstart - bufsize + MAX_MATCH_LENGTH - 1;
  709. X    if (delete_point < 0) delete_point += MAX_DIST;
  710. X
  711. X    /* Process the input block. */
  712. X    do {
  713. X        /* Insert the string window[strstart .. strstart+strsize-1] in the
  714. X         * dictionary, and set cur_match to the head of the hash chain:
  715. X         */
  716. X        INSERT_STRING(strstart, cur_match);
  717. X
  718. X        if (strstart == checkpoint) {
  719. X            /* Find the longest match, discarding those <= start_length */
  720. X            match_length = 0;
  721. X            if (cur_match != NIL) {
  722. X                best_match = longest_match (cur_match);
  723. X                /* longest_match updates match_length if longer match found */
  724. X            }
  725. X            retcode = write_match (best_match, match_length);
  726. X            if (retcode != IM_OK) return retcode;
  727. X        }
  728. X
  729. X        /* Remove the oldest string from the dictionary, except if we have not
  730. X         * yet created bufsize dictionary entries. We could avoid this
  731. X         * deletion and check instead for obsolete pointers in
  732. X         * longest_match(), but this would be slower.
  733. X         */
  734. X#if (MAX_DIST & (MAX_DIST-1)) != 0
  735. X        if (++delete_point == MAX_DIST) delete_point = 0;
  736. X#else
  737. X        delete_point = (delete_point + 1) & (MAX_DIST-1);
  738. X#endif
  739. X        DELETE_STRING (delete_point);
  740. X
  741. X        if (++strstart == MAX_DIST) {
  742. X            strstart = 0, checkpoint -= MAX_DIST;
  743. X        }
  744. X    } while (--count != 0);
  745. X    return IM_OK;
  746. X}
  747. X#endif /* MSDOS */
  748. X
  749. X/***********************************************************************
  750. X *
  751. X * Wind up processing by flushing unprocessed input. For normal processing,
  752. X * this routine is called twice (by imp_size then imp_clear) and the
  753. X * second call does nothing. In case of error, this routine is called only
  754. X * by imp_clear().
  755. X */
  756. XImpErr lm_windup()
  757. X{
  758. X    ImpErr retcode;
  759. X    int matches;
  760. X
  761. X    /* Process the remaining input. */
  762. X    while (strsize > 0) {
  763. X       retcode = lm_process (1);
  764. X       if (retcode != IM_OK) return retcode;
  765. X       --strsize;
  766. X    }
  767. X    /* Flush the match buffer. */
  768. X    if ((matches = ma-ma_buf+1) != 0 && matches != 
  769. X        twrite ((char *) ma_buf, sizeof(MATCH), matches, fd.fd_temp)) {
  770. X        return IM_IOERR;
  771. X    }
  772. X    ma = ma_buf - 1;
  773. X    return IM_OK;
  774. X}
  775. END_OF_FILE
  776.   if test 27597 -ne `wc -c <'im_lmat.c'`; then
  777.     echo shar: \"'im_lmat.c'\" unpacked with wrong size!
  778.   fi
  779.   # end of 'im_lmat.c'
  780. fi
  781. if test -f 'zip.doc' -a "${1}" != "-c" ; then 
  782.   echo shar: Will not clobber existing file \"'zip.doc'\"
  783. else
  784.   echo shar: Extracting \"'zip.doc'\" \(22906 characters\)
  785.   sed "s/^X//" >'zip.doc' <<'END_OF_FILE'
  786. X
  787. X
  788. X
  789. XZIP(1)              UNIX Programmer's Manual               ZIP(1)
  790. X
  791. X
  792. X
  793. XNAME
  794. X     zip - package and compress (archive) files
  795. X
  796. XSYNOPSIS
  797. X     zip [ -cdefghijklmnoqrsuwyz ] [ -b path ] [ -t mmddyy ] zip-
  798. X     file list [ -x list ]
  799. X
  800. XDESCRIPTION
  801. X     Zip is a compression and file packaging utility for Unix,
  802. X     MSDOS, OS/2, and VMS.  It is analogous to a combination of
  803. X     tar and compress and is compatible with PKZIP (Phil Katz
  804. X     ZIP) for MSDOS systems.
  805. X
  806. X     There is a companion to Zip called UnZip (of course) which
  807. X     you should be able to find the same place you got Zip. Zip
  808. X     and UnZip can work with files produced by PKZIP under MSDOS,
  809. X     and PKZIP and PKUNZIP can work with files produced by Zip.
  810. X
  811. X     Zip puts one or more compressed files into a single "zip
  812. X     file" along with information about the files, including the
  813. X     name, path if requested, date and time last modified, pro-
  814. X     tection, and check information to verify the fidelity of
  815. X     each entry.  Zip can pack an entire directory structure in a
  816. X     zip file with a single command.  Compression ratios of 2:1
  817. X     to 3:1 are common for text files.  Zip has two compression
  818. X     methods, implosion and shrinking, and automatically chooses
  819. X     the better of the two for each file to be compressed.
  820. X
  821. X     Zip is useful for packaging a set of files to send to some-
  822. X     one or for distribution; for archiving or backing up files;
  823. X     and for saving disk space by temporarily compressing unused
  824. X     files or directories.
  825. X
  826. XHOW TO INSTALL ZIP
  827. X     Zip is distributed as C source code that can be compiled on
  828. X     a wide range of Unix machines, VAXes running VMS, and MSDOS
  829. X     machines using Microsoft or Borland C++, and OS/2 machines
  830. X     using Microsoft C.  You will need Unzip (under Unix, MSDOS,
  831. X     or VMS) or PKUNZIP (under MSDOS) to unpack the distribution
  832. X     file, zip10.zip.
  833. X
  834. X     First, unpack the source as follows, assuming that you have
  835. X     zip10.zip in the current directory:
  836. X
  837. X          mkdir zipsrc
  838. X          cd zipsrc
  839. X          unzip ../zip10
  840. X
  841. X     This extracts all source files and documentation in the
  842. X     directory called "zipsrc". You then do:
  843. X
  844. X
  845. X          make system
  846. X
  847. X     where "system" is one of: bsd, bsdold, sysv, next, next10,
  848. X     sun, hpux, dnix, cray, 3b1, zilog, aux, convex, aix, or
  849. X     minix.  If you are using a NeXT running version 2.0 or
  850. X     greater, then make next.  If you are using 1.0, then make
  851. X     next10.  If you are using Sun OS 4.x, then make sun.  If you
  852. X     are using HPUX, then make hpux.  The other special systems
  853. X     are DNIX 5.2 or 5.3, Cray Unicos, AT&T 3B1 (also known as
  854. X     Unix PC or PC 7300), Zilog Zeus, A/UX, Convex, AIX, and
  855. X     MINIX.  Otherwise, if you are using BSD Unix, try bsd.  If
  856. X     the linker cannot find _memset or _memcpy, try bsdold.  If
  857. X     you are using System V Unix or SCO Unix, try sysv.  Also use
  858. X     sysv on a Silicon Graphics (SGI) machine.  You can also
  859. X     cross-compile Zip for MSDOS under SCO 386 Unix using "make
  860. X     scodos".
  861. X
  862. X     If none of these compiles, links, and functions properly on
  863. X     your Unix system, see the section BUGS below for how to get
  864. X     help.
  865. X
  866. X     If the appropriate system was selected, then the executable
  867. X     "zip" will be created.  You can move the executable "zip" to
  868. X     an appropriate directory in the search path using a command
  869. X     like:
  870. X
  871. X          mv zip ~/bin
  872. X
  873. X     or
  874. X
  875. X          mv zip /usr/local/bin
  876. X
  877. X     You can use the command "set" to see the current search
  878. X     path.  If you are using the C-Shell (csh), enter the com-
  879. X     mand:
  880. X
  881. X          rehash
  882. X
  883. X     so csh can find the new command in the path.  You are now
  884. X     ready to use Zip.
  885. X
  886. X     You can also move the manual page (the raw form of what
  887. X     you're reading) to where the Unix man command can find it
  888. X     (assuming you have the necessary privileges):
  889. X
  890. X          mv zip.1 /usr/man/man1
  891. X
  892. X     You can get rid of the now unnecessary source and object
  893. X     files with:
  894. X
  895. X          cd ..
  896. X          rm -r zipsrc
  897. X
  898. X     This will remove the directory zip and its contents created
  899. X     by unzip.  You should keep the zip10.zip file around though,
  900. X     in case you need to build it again or want to give it to a
  901. X     colleague.
  902. X
  903. X     The steps for installation under MSDOS, OS/2, and VMS are
  904. X     similar to the above: first unzip the distribution files
  905. X     into their own directory.  Then under MSDOS do one of:
  906. X
  907. X          make makefile.msc
  908. X          make -fmakefile.bor
  909. X
  910. X
  911. X     for Microsoft or Borland C++, respectively.  Under OS/2:
  912. X
  913. X          nmake -f makefile.os2
  914. X
  915. X     for Microsoft C 6.00.  Under VAX VMS:
  916. X
  917. X
  918. X          @makevms
  919. X
  920. X     The installation process will also compile and link several
  921. X     other utilities.  They are zipcloak for encrypting and
  922. X     decrypting zip files, zipnote for editing zip file comments,
  923. X     zipsplit for splitting a zip file into several zip files,
  924. X     and ship for sending zip files or any other binary file via
  925. X     electronic mail.  For command help on any of the zip* utili-
  926. X     ties, simply enter the name with no arguments.  For help
  927. X     with ship, enter "ship -h".
  928. X
  929. XHOW TO USE ZIP
  930. X     The simplest use of Zip is as follows:
  931. X
  932. X          zip stuff *
  933. X
  934. X     This will create the file "stuff.zip" (assuming it does not
  935. X     exist) and put all the files in the current directory in
  936. X     stuff.zip in a compressed form.  The .zip suffix is added
  937. X     automatically, unless that file name given contains a dot
  938. X     already.  This allows specifying suffixes other than ".zip".
  939. X
  940. X     Because of the way the shell does filename substitution,
  941. X     files that start with a "." are not included.  To include
  942. X     those as well, you can:
  943. X
  944. X          zip stuff .* *
  945. X
  946. X     Even this will not include any subdirectories that are in
  947. X     the current directory.  To zip up an entire directory, the
  948. X     command:
  949. X
  950. X          zip -r foo foo
  951. X
  952. X     will create the file "foo.zip" containing all the files and
  953. X     directories in the directory "foo" that is in the current
  954. X     directory.  The "r" option means recurse through the direc-
  955. X     tory structure.  In this case, all the files and directories
  956. X     in foo are zipped, including the ones that start with a ".",
  957. X     since the recursion does not use the shell's file-name sub-
  958. X     stitution.  You should not use -r with the name ".*", since
  959. X     that matches ".." which will attempt to zip up the parent
  960. X     directory--probably not what was intended.
  961. X
  962. X     You may want to make a zip file that contains the files in
  963. X     foo, but not record the directory name, foo.  You can use
  964. X     the -j (junk path) option to leave off the path:
  965. X
  966. X          zip -j foo foo/*
  967. X
  968. X     The -y option (only under Unix) will store symbolic links as
  969. X     such in the zip file, instead of compressing and storing the
  970. X     file referred to in the link.
  971. X
  972. X     You might be zipping to save disk space, in which case you
  973. X     could:
  974. X
  975. X          zip -rm foo foo
  976. X
  977. X     where the "m" option means "move".  This will delete foo and
  978. X     its contents after making foo.zip.  No deletions will be
  979. X     done until the zip has completed with no errors.  This
  980. X     option is obviously more dangerous and should be used with
  981. X     care.
  982. X
  983. X
  984. X     If the zip file already exists, these commands will replace
  985. X     existing or add new entries to the zip file.  For example,
  986. X     if you were really short on disk space, you might not have
  987. X     enough room simultaneously to hold the directory foo and the
  988. X     compressed foo.zip.  In this case, you could do it in steps.
  989. X     If foo contained the subdirectories tom, dick, and harry,
  990. X     then you could:
  991. X
  992. X          zip -rm foo foo/tom
  993. X          zip -rm foo foo/dick
  994. X          zip -rm foo foo/harry
  995. X
  996. X     where the first command would create foo.zip, and the next
  997. X     two would add to it.  At the completion of each zip command,
  998. X     the directory just zipped would be deleted, making room in
  999. X     which the next Zip command could work.
  1000. X
  1001. XMODIFYING EXISTING ZIP FILES
  1002. X     When given the name of an existing zip file with the above
  1003. X     commands, Zip will replace identically named entries in the
  1004. X     Zip file or add entries for new names.  For example, if
  1005. X     foo.zip exists and contains foo/file1 and foo/file2, and the
  1006. X     directory foo contains the files foo/file1 and foo/file3,
  1007. X     then:
  1008. X
  1009. X          zip -r foo foo
  1010. X
  1011. X     will replace foo/file1 in foo.zip and add foo/file3 to
  1012. X     foo.zip.  After this, foo.zip contains foo/file1, foo/file2,
  1013. X     and foo/file3, with foo/file2 unchanged from before.
  1014. X
  1015. X     When changing an existing zip file, Zip will write a tem-
  1016. X     porary file with the new contents, and only replace the old
  1017. X     one when the zip has completed with no errors.  Also, the
  1018. X     two methods, shrink and implode, create temporary files that
  1019. X     are deleted after each file is zipped.  You can use the -b
  1020. X     option to specify a different path (usually a different dev-
  1021. X     ice) to put the temporary files in.  For example:
  1022. X
  1023. X          zip -b /tmp stuff *
  1024. X
  1025. X     will put the temporary zip file and the temporary compres-
  1026. X     sion files in the directory "/tmp", copying over stuff.zip
  1027. X     in the current directory when done.
  1028. X
  1029. X     If you are only adding entries to a zip file, not replacing,
  1030. X     and the -g option is given, then Zip grows (appends to) the
  1031. X     file instead of copying it.  The danger of this is that if
  1032. X     the operation fails, the original zip file is corrupted and
  1033. X     lost.
  1034. X
  1035. X     There are two other ways to change or add entries in a zip
  1036. X     file that are restrictions of simple addition or replace-
  1037. X     ment.  The first is -u (update) which will add new entries
  1038. X     to the zip file as before but will replace existing entries
  1039. X     only if the modified date of the file is more recent than
  1040. X     the date recorded for that name in the zip file.  For exam-
  1041. X     ple:
  1042. X
  1043. X          zip -u stuff *
  1044. X
  1045. X     will add any new files in the current directory, and update
  1046. X     any changed files in the zip file stuff.zip.  Note that Zip
  1047. X     will not try to pack stuff.zip into itself when you do this.
  1048. X     Zip will always exclude the zip file from the files on which
  1049. X     to be operated.
  1050. X
  1051. X     The second restriction is -f (freshen) which, like update,
  1052. X     will only replace entries with newer files; unlike update,
  1053. X     will not add files that are not already in the zip file.
  1054. X     For this option, you may want to simply freshen all of the
  1055. X     files that are in the specified zip file.  To do this you
  1056. X     would simply:
  1057. X
  1058. X          zip -f foo
  1059. X
  1060. X     Note that the -f option with no arguments freshens all the
  1061. X     entries in the zip file.  The same is true of -u, and hence
  1062. X     "zip -u foo" and "zip -f foo" both do the same thing.
  1063. X
  1064. X     This command should be run from the same directory from
  1065. X     which the original zip command was run, since paths stored
  1066. X     in zip files are always relative.
  1067. X
  1068. X     Another restriction that can be used with adding, updating,
  1069. X     or freshening is -t (time), which will not operate on files
  1070. X     modified earlier than the specified date.  For example:
  1071. X
  1072. X          zip -rt 120791 infamy foo
  1073. X
  1074. X     will add all the files in foo and its subdirectories that
  1075. X     were last modified on December 7, 1991, or later to the zip
  1076. X     file infamy.zip.
  1077. X
  1078. X     Also, files can be explicitly excluded using the -x option:
  1079. X
  1080. X          zip -r foo foo -x \*.o
  1081. X
  1082. X     which will zip up the contents of foo into foo.zip but
  1083. X     exclude all the files that end in ".o".  Here the backslash
  1084. X     causes Zip to match file names that were found when foo was
  1085. X     searched.
  1086. X
  1087. X     The last operation is -d (delete) which will remove entries
  1088. X     from a zip file.  An example might be:
  1089. X
  1090. X          zip -d foo foo/tom/junk foo/harry/\* \*.o
  1091. X
  1092. X     which will remove the entry foo/tom/junk, all of the files
  1093. X     that start with "foo/harry/", and all of the files that end
  1094. X     with ".o" (in any path).  Note that once again, the shell
  1095. X     expansion has been inhibited with backslashes, so that Zip
  1096. X     can see the asterisks. Zip can then match on the contents of
  1097. X     the zip file instead of the contents of the current direc-
  1098. X     tory.
  1099. X
  1100. X     Under MSDOS, -d is case sensitive when it matches names in
  1101. X     the zip file.  This allows deleting names that were zipped
  1102. X     on other systems, but requires that the names be entered in
  1103. X     upper case if they were zipped on an MSDOS system, so that
  1104. X     the names can be found in the zip file and deleted.
  1105. X
  1106. XMORE OPTIONS
  1107. X     As mentioned before, Zip will use the best of two methods:
  1108. X     shrink or implode.  Usually implode is better, but sometimes
  1109. X     shrink is better, especially for smaller files.  Sometimes
  1110. X     neither method produces a packed version smaller than the
  1111. X     original file, in which case it is stored in the zip file
  1112. X     with no compression (called the "store" method).
  1113. X
  1114. X     The option -s (shrink) will force Zip always to use shrink
  1115. X     or store, and the -i (implode) option forces Zip to use
  1116. X     implode or store.  Shrinking is faster than imploding, and
  1117. X     so -s might be used when speed is more important than
  1118. X     optimal compression.  Implode only (-i) might be used when
  1119. X     the unzipper for which the zip file is destined can only
  1120. X     handle implosion.  An example of this is the PKSFXjr program
  1121. X     that comes with PKZIP.  Also, -i is slightly faster than
  1122. X     imploding and shrinking at the same time.  For example:
  1123. X
  1124. X          zip -rs foo foo
  1125. X
  1126. X     will zip up the directory foo into foo.zip using only shrink
  1127. X     or store.  The speed of implosion can also be controlled
  1128. X     with options -0 (fastest method but less compression) to -9
  1129. X     (best compression but slower). The default value is -5. For
  1130. X     example:
  1131. X
  1132. X          zip -r0 foo foo
  1133. X
  1134. X     In nearly all cases, a file that is already compressed can-
  1135. X     not be compressed further by Zip, or if it can, the effect
  1136. X     is minimal.  The -n option prevents Zip from trying to
  1137. X     compress files that have the suffixes: .Z, .zip, .zoo, or
  1138. X     .arc.  Such files are simply stored (0% compression) in the
  1139. X     output zip file, so that Zip doesn't waste its time trying
  1140. X     to compress them.  If the environment variable NOZIP is set,
  1141. X     then the suffixes listed there are used instead of the
  1142. X     default list.  The suffixes are separated by either colons
  1143. X     or semicolons.  For example, in Unix csh:
  1144. X
  1145. X          setenv NOZIP .Z:.zip:.tiff:.gif:.snd
  1146. X          zip -rn foo foo
  1147. X
  1148. X     will put everything in foo into foo.zip, but will store any
  1149. X     files that end in .Z, .zip, .tiff, .gif, or .snd without
  1150. X     trying to compress them.  (Image and sound files often have
  1151. X     their own specialized compression methods.)  If the environ-
  1152. X     ment variable NOZIP exists but is empty or contains just a
  1153. X     colon or semicolon, then zip -n will store all the entries
  1154. X     and do no compression.
  1155. X
  1156. X     Under Unix and under OS/2 (if files from a HPFS are stored),
  1157. X     Zip will store the full path (relative to the current path)
  1158. X     and name of the file (or just the name if -j is specified)
  1159. X     in the zip file along with the Unix attributes, and it will
  1160. X     mark the entry as made under Unix.  If the zip file is
  1161. X     intended for PKUNZIP under MSDOS, then the -k (Katz) option
  1162. X     should be used to attempt to convert the names and paths to
  1163. X     conform to MSDOS, store only the MSDOS attribute (just the
  1164. X     user write attribute from Unix), and mark the entry as made
  1165. X     under MSDOS (even though it wasn't).
  1166. X
  1167. X     The -o (older) option will set the "last modified" time of
  1168. X     the zip file to the latest "last modified" time of the
  1169. X     entries in the zip file.  This can be used without any other
  1170. X     operations, if desired.  For example:
  1171. X
  1172. X          zip -o foo
  1173. X
  1174. X
  1175. X     will change the last modified time of foo.zip to the latest
  1176. X     time of the entries in foo.zip.
  1177. X
  1178. X     The -e and -c options operate on all files updated or added
  1179. X     to the zip file.  Encryption (-e) will prompt for a password
  1180. X     on the terminal and will not echo the password as it is
  1181. X     typed (if stderr is not a TTY, Zip will exit with an error).
  1182. X     New zip entries will be encrypted using that password.  For
  1183. X     added peace of mind, you can use -ee, which will prompt for
  1184. X     the password twice, checking that the two are the same
  1185. X     before using it.
  1186. X
  1187. X     One-line comments can be added for each file with the -c
  1188. X     option.  The zip file operations (adding or updating) will
  1189. X     be done first, and you will then be prompted for a one-line
  1190. X     comment for each file.  You can then enter the comment fol-
  1191. X     lowed by return, or just return for no comment.
  1192. X
  1193. X     The -z option will prompt you for a multi-line comment for
  1194. X     the entire zip file.  This option can be used by itself, or
  1195. X     in combination with other options.  The comment is ended by
  1196. X     a line containing just a period, or an end of file condition
  1197. X     (^D on Unix, ^Z on MSDOS, OS/2, and VAX/VMS).  Since -z
  1198. X     reads the lines from stdin, you can simply take the comment
  1199. X     from a file:
  1200. X
  1201. X          zip -z foo < foowhat
  1202. X
  1203. X     The -q (quiet) option eliminates the informational messages
  1204. X     and comment prompts while Zip is operating.  This might be
  1205. X     used in shell scripts, for example, or if the zip operation
  1206. X     is being performed as a background task ("zip -q foo *.c
  1207. X     &").
  1208. X
  1209. X     Zip can take a list of file names to operate on from stdin
  1210. X     using the - option.  In Unix, this option can be used with
  1211. X     the find command to extend greatly the functionality of Zip.
  1212. X     For example, to zip up all the C source files in the current
  1213. X     directory and its subdirectories, you can:
  1214. X
  1215. X          find . -type f -name "*.[ch]" -print | zip source -
  1216. X
  1217. X     Note that the pattern must be quoted to keep the shell from
  1218. X     expanding it.
  1219. X
  1220. X     Under VMS only, the -w option will append the version number
  1221. X     of the files to the name and zip up multiple versions of
  1222. X     files.  Without -w, Zip will only use the most recent ver-
  1223. X     sion of the specified file(s).
  1224. X
  1225. X     If Zip is run with no arguments or with the -h option, the
  1226. X     license and the command-argument and option help is shown.
  1227. X     The -l option just shows the license.
  1228. X
  1229. XABOUT PATTERN MATCHING
  1230. X     (Note: this section applies to Unix.  Watch this space for
  1231. X     details on MSDOS and VMS operation.)
  1232. X
  1233. X     The Unix shell (sh or csh) does filename substitution on
  1234. X     command arguments.  The special characters are ?, which
  1235. X     matches any single character; * which matches any number of
  1236. X     characters (including none); and [] which matches any char-
  1237. X     acter in the range inside the brackets (like [a-f] or
  1238. X     [0-9]).  When these characters are encountered (and not
  1239. X     escaped with a backslash or quotes), the shell will look for
  1240. X     files relative to the current path that match the pattern,
  1241. X     and replace the argument with a list of the names that
  1242. X     matched.
  1243. X
  1244. X     Zip can do the same matching on names that are in the zip
  1245. X     file being modified or, in the case of the -x (exclude)
  1246. X     option, on the list of files to be operated on, by using
  1247. X     backslashes or quotes to tell the shell not to do the name
  1248. X     expansion.  In general, when Zip encounters a name in the
  1249. X     list of files to do, it first looks for the name in the file
  1250. X     system.  If it finds it, it then adds it to the list of
  1251. X     files to do.  If it does not find it, it will look for the
  1252. X     name in the zip file being modified (if it exists), using
  1253. X     the pattern matching characters above, if any.  For each
  1254. X     match, it will add that name to the list of files to do.
  1255. X     After -x (exclude), the names are removed from the to-do
  1256. X     list instead of added.
  1257. X
  1258. X     The pattern matching includes the path, and so patterns like
  1259. X     \*.o match names that end in ".o", no matter what the path
  1260. X     prefix is.  Note that the backslash must precede every spe-
  1261. X     cial character (i.e. ?*[]), or the entire argument must be
  1262. X     enclosed in double quotes ("").
  1263. X
  1264. X     In general, using backslash to make Zip do the pattern
  1265. X     matching is used with the -f (freshen) and -d (delete)
  1266. X     options, and sometimes after the -x (exclude) option when
  1267. X     used with any operation (add, -u, -f, or -d).  Zip will
  1268. X     never use pattern matching to search the file system.  If
  1269. X     Zip has recursed into a directory, all files (and all direc-
  1270. X     tories) in there are fair game.
  1271. X
  1272. XCOPYRIGHT
  1273. X     Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and
  1274. X     Jean-loup Gailly.  Permission is granted to any individual
  1275. X     or institution to use, copy, or redistribute this software
  1276. X     so long as all of the original files are included unmodi-
  1277. X     fied, that it is not sold for profit, and that this copy-
  1278. X     right notice is retained.
  1279. X
  1280. XACKNOWLEDGEMENTS
  1281. X     Thanks to R. P. Byrne for his Shrink.Pas program which
  1282. X     inspired this project, and from which the shrink algorithm
  1283. X     was stolen; to Phil Katz for making the zip file format,
  1284. X     compression format, and .ZIP filename extension all public
  1285. X     domain; to Keith Petersen for providing a mailing list and
  1286. X     ftp site for the INFO-ZIP group to use; and most impor-
  1287. X     tantly, to the INFO-ZIP group itself (listed in the file
  1288. X     infozip.who) without whose tireless testing and bug-fixing
  1289. X     efforts a portable Zip would not have been possible.
  1290. X     Finally we should thank (blame) the INFO-ZIP moderator,
  1291. X     David Kirschbaum for getting us into this mess in the first
  1292. X     place.
  1293. X
  1294. XSEE ALSO
  1295. X     unzip(1), tar(1), compress(1)
  1296. X
  1297. XBUGS
  1298. X     Versions of PKUNZIP before 1.1 have a bug that on rare occa-
  1299. X     sions will prevent it from unzipping files produced by Zip
  1300. X     or PKZIP 1.1.  If you experience such problems, we recommend
  1301. X     that you get PKUNZIP 1.1 or the portable Unzip, neither of
  1302. X     which have this problem.
  1303. X
  1304. X     Under MSDOS, Zip will find hidden and system files, but not
  1305. X     set the attributes appropriately in the zip file so that
  1306. X     Unzip can restore them.  This will be fixed in the next
  1307. X     version.
  1308. X
  1309. X     Under VMS, not all of the odd file formats are treated prop-
  1310. X     erly.  Only stream-LF format zip files are expected to work
  1311. X     with Zip.  Others can be converted using Rahul Dhesi's BILF
  1312. X     program.  The next version of Zip will handle some of the
  1313. X     conversion internally.
  1314. X
  1315. X     LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTIL-
  1316. X     ITIES ARE PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY
  1317. X     KIND, EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE
  1318. X     COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES RESULTING FROM
  1319. X     THE USE OF THIS SOFTWARE.
  1320. X
  1321. X     That having been said, please send any problems or comments
  1322. X     via email to the Internet address zip-bugs@cs.ucla.edu.  For
  1323. X     bug reports, please include the version of Zip, the make
  1324. X     options you used to compile it, the machine and operating
  1325. X     system you are using, and as much additional information as
  1326. X     possible.  Thank you for your support.
  1327. X
  1328. X
  1329. X
  1330. X
  1331. X
  1332. X
  1333. X
  1334. X
  1335. X
  1336. X
  1337. X
  1338. X
  1339. X
  1340. X
  1341. X
  1342. X
  1343. X
  1344. X
  1345. X
  1346. X
  1347. X
  1348. X
  1349. X
  1350. X
  1351. X
  1352. X
  1353. X
  1354. X
  1355. X
  1356. X
  1357. X
  1358. X
  1359. X
  1360. X
  1361. X
  1362. X
  1363. X
  1364. X
  1365. X
  1366. X
  1367. X
  1368. X
  1369. X
  1370. X
  1371. X
  1372. X
  1373. X
  1374. X
  1375. X
  1376. X
  1377. X
  1378. X
  1379. X
  1380. END_OF_FILE
  1381.   if test 22906 -ne `wc -c <'zip.doc'`; then
  1382.     echo shar: \"'zip.doc'\" unpacked with wrong size!
  1383.   fi
  1384.   # end of 'zip.doc'
  1385. fi
  1386. echo shar: End of archive 5 \(of 9\).
  1387. cp /dev/null ark5isdone
  1388. MISSING=""
  1389. for I in 1 2 3 4 5 6 7 8 9 ; do
  1390.     if test ! -f ark${I}isdone ; then
  1391.     MISSING="${MISSING} ${I}"
  1392.     fi
  1393. done
  1394. if test "${MISSING}" = "" ; then
  1395.     echo You have unpacked all 9 archives.
  1396.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1397. else
  1398.     echo You still must unpack the following archives:
  1399.     echo "        " ${MISSING}
  1400. fi
  1401. exit 0
  1402. exit 0 # Just in case...
  1403. -- 
  1404. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1405. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1406. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1407. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1408.