home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / misc / 3846 < prev    next >
Encoding:
Text File  |  1992-08-22  |  60.5 KB  |  1,734 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  4. Subject:  v31i096:  zip19 - Info-ZIP portable Zip, version 1.9, Part04/11
  5. Message-ID: <1992Aug23.064628.29121@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: fb99faa1e8171758728591c8da715b75
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v31i093=zip19.014410@sparky.IMD.Sterling.COM>
  11. Date: Sun, 23 Aug 1992 06:46:28 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 1719
  14.  
  15. Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
  16. Posting-number: Volume 31, Issue 96
  17. Archive-name: zip19/part04
  18. Supersedes: zip: Volume 23, Issue 88-96
  19. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, XOS, !AMIGA, ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun, PC
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then feed it
  23. # into a shell via "sh file" or similar.  To overwrite existing files,
  24. # type "sh file -c".
  25. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  26. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  27. # Contents:  mac/macstat.h zip.c zip.doc
  28. # Wrapped by kent@sparky on Sun Aug 23 01:00:44 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. echo If this archive is complete, you will see the following message:
  31. echo '          "shar: End of archive 4 (of 11)."'
  32. if test -f 'mac/macstat.h' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'mac/macstat.h'\"
  34. else
  35.   echo shar: Extracting \"'mac/macstat.h'\" \(974 characters\)
  36.   sed "s/^X//" >'mac/macstat.h' <<'END_OF_FILE'
  37. X/*****************************************************************
  38. X *
  39. X *                stat.h
  40. X *
  41. X *****************************************************************/
  42. X
  43. X#include <time.h>
  44. Xextern int macstat(char *path, struct stat *buf, short nVRefNum, long lDirID );
  45. Xtypedef long dev_t;
  46. Xtypedef long ino_t;
  47. Xtypedef long off_t;
  48. X
  49. Xstruct stat {
  50. X    dev_t    st_dev;
  51. X    ino_t    st_ino;
  52. X    unsigned short    st_mode;
  53. X    short    st_nlink;
  54. X    short    st_uid;
  55. X    short    st_gid;
  56. X    dev_t    st_rdev;
  57. X    off_t    st_size;
  58. X    time_t   st_atime, st_mtime, st_ctime;
  59. X    long     st_blksize;
  60. X    long     st_blocks;
  61. X};
  62. X
  63. X#define S_IFMT     0xF000
  64. X#define S_IFIFO    0x1000
  65. X#define S_IFCHR    0x2000
  66. X#define S_IFDIR    0x4000
  67. X#define S_IFBLK    0x6000
  68. X#define S_IFREG    0x8000
  69. X#define S_IFLNK    0xA000
  70. X#define S_IFSOCK   0xC000
  71. X#define S_ISUID    0x800
  72. X#define S_ISGID    0x400
  73. X#define S_ISVTX    0x200
  74. X#define S_IREAD    0x100
  75. X#define S_IWRITE   0x80
  76. X#define S_IEXEC    0x40
  77. END_OF_FILE
  78.   if test 974 -ne `wc -c <'mac/macstat.h'`; then
  79.     echo shar: \"'mac/macstat.h'\" unpacked with wrong size!
  80.   fi
  81.   # end of 'mac/macstat.h'
  82. fi
  83. if test -f 'zip.c' -a "${1}" != "-c" ; then 
  84.   echo shar: Will not clobber existing file \"'zip.c'\"
  85. else
  86.   echo shar: Extracting \"'zip.c'\" \(32880 characters\)
  87.   sed "s/^X//" >'zip.c' <<'END_OF_FILE'
  88. X/*
  89. X
  90. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  91. X Kai Uwe Rommel and Igor Mandrichenko.
  92. X Permission is granted to any individual or institution to use, copy, or
  93. X redistribute this software so long as all of the original files are included
  94. X unmodified, that it is not sold for profit, and that this copyright notice
  95. X is retained.
  96. X
  97. X*/
  98. X
  99. X/*
  100. X *  zip.c by Mark Adler.
  101. X */
  102. X
  103. X#include "revision.h"
  104. X#include "zip.h"
  105. X#ifdef VMS
  106. X#  include "VMSmunch.h"
  107. X#  define echon() echo(1)
  108. X#endif
  109. X#include <signal.h>
  110. X
  111. X#ifdef MACOS
  112. X#  include <console.h>
  113. X#endif
  114. X
  115. X#define PWLEN 80        /* Input buffer size for reading encryption key */
  116. X#define MAXCOM 256      /* Maximum one-line comment size */
  117. X
  118. X
  119. X/* Local option flags */
  120. X#define DELETE  0
  121. X#define ADD     1
  122. X#define UPDATE  2
  123. X#define FRESHEN 3
  124. Xlocal int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
  125. Xlocal int comadd = 0;   /* 1=add comments for new files */
  126. Xlocal int zipedit = 0;  /* 1=edit zip comment and all file comments */
  127. Xlocal int dispose = 0;  /* 1=remove files after put in zip file */
  128. Xlocal int latest = 0;   /* 1=set zip file time to time of latest file */
  129. Xlocal ulg before = 0;   /* 0=ignore, else exclude files before this time */
  130. X
  131. X
  132. X/* Temporary zip file name and file pointer */
  133. Xlocal char *tempzip;
  134. Xlocal FILE *tempzf;
  135. X
  136. X
  137. X/* Local functions */
  138. X#ifdef PROTO
  139. X   local void freeup(void);
  140. X   local void leave(int);
  141. X   local void handler(int);
  142. X   local void license(void);
  143. X   local void help(void);
  144. X   local void zipstdout(void);
  145. X   void main(int, char **);
  146. X   local int count_args(char *s);
  147. X   local void envargs(int *Pargc, char ***Pargv, char *envstr);
  148. X#endif /* PROTO */
  149. X
  150. X
  151. X
  152. Xlocal void freeup()
  153. X/* Free all allocations in the found list and the zfiles list */
  154. X{
  155. X  struct flist far *f;  /* steps through found list */
  156. X  struct zlist far *z;  /* pointer to next entry in zfiles list */
  157. X
  158. X  for (f = found; f != NULL; f = fexpel(f))
  159. X    ;
  160. X  while (zfiles != NULL)
  161. X  {
  162. X    z = zfiles->nxt;
  163. X    free((voidp *)(zfiles->name));
  164. X    free((voidp *)(zfiles->zname));
  165. X    if (zfiles->ext)
  166. X      free((voidp *)(zfiles->extra));
  167. X    if (zfiles->cext && zfiles->cextra != zfiles->extra)
  168. X      free((voidp *)(zfiles->cextra));
  169. X    if (zfiles->com)
  170. X      free((voidp *)(zfiles->comment));
  171. X    farfree((voidp far *)zfiles);
  172. X    zfiles = z;
  173. X    zcount--;
  174. X  }
  175. X}
  176. X
  177. X
  178. Xlocal void leave(e)
  179. Xint e;                  /* exit code */
  180. X/* Process -o and -m options (if specified), free up malloc'ed stuff, and
  181. X   exit with the code e. */
  182. X{
  183. X  int r;                /* return value from trash() */
  184. X  ulg t;                /* latest time in zip file */
  185. X  struct zlist far *z;  /* pointer into zfile list */
  186. X
  187. X  /* If latest, set time to zip file to latest file in zip file */
  188. X  if (latest && strcmp(zipfile, "-"))
  189. X  {
  190. X    diag("changing time of zip file to time of latest file in it");
  191. X    /* find latest time in zip file */
  192. X    if (zfiles == NULL)
  193. X       warn("zip file is empty, can't make it as old as latest entry", "");
  194. X    else {
  195. X      t = zfiles->tim;
  196. X      for (z = zfiles->nxt; z != NULL; z = z->nxt)
  197. X        if (t < z->tim)
  198. X          t = z->tim;
  199. X      /* set modified time of zip file to that time */
  200. X      stamp(zipfile, t);
  201. X    }
  202. X  }
  203. X  if (tempath != NULL)
  204. X  {
  205. X    free((voidp *)tempath);
  206. X    tempath = NULL;
  207. X  }
  208. X  if (zipfile != NULL)
  209. X  {
  210. X    free((voidp *)zipfile);
  211. X    zipfile = NULL;
  212. X  }
  213. X
  214. X
  215. X  /* If dispose, delete all files in the zfiles list that are marked */
  216. X  if (dispose)
  217. X  {
  218. X    diag("deleting files that were added to zip file");
  219. X    if ((r = trash()) != ZE_OK)
  220. X      err(r, "was deleting moved files and directories");
  221. X  }
  222. X
  223. X
  224. X  /* Done! */
  225. X  freeup();
  226. X#ifdef VMS
  227. X  exit(0);
  228. X#else /* !VMS */
  229. X  exit(e);
  230. X#endif /* ?VMS */
  231. X}
  232. X
  233. X
  234. Xvoid err(c, h)
  235. Xint c;                  /* error code from the ZE_ class */
  236. Xchar *h;                /* message about how it happened */
  237. X/* Issue a message for the error, clean up files and memory, and exit. */
  238. X{
  239. X  static int error_level;
  240. X  if (error_level++ > 0) exit(0);  /* avoid recursive err() */
  241. X
  242. X  if (PERR(c))
  243. X    perror("zip error");
  244. X  fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
  245. X  if (tempzip != NULL)
  246. X  {
  247. X    if (tempzip != zipfile) {
  248. X      if (tempzf != NULL)
  249. X        fclose(tempzf);
  250. X#ifndef DEBUG
  251. X      destroy(tempzip);
  252. X#endif
  253. X      free((voidp *)tempzip);
  254. X    } else {
  255. X      /* -g option, attempt to restore the old file */
  256. X      int k = 0;                        /* keep count for end header */
  257. X      ulg cb = cenbeg;                  /* get start of central */
  258. X      struct zlist far *z;  /* steps through zfiles linked list */
  259. X
  260. X      fprintf(stderr, "attempting to restore %s to its previous state\n",
  261. X         zipfile);
  262. X      fseek(tempzf, cenbeg, SEEK_SET);
  263. X      tempzn = cenbeg;
  264. X      for (z = zfiles; z != NULL; z = z->nxt)
  265. X      {
  266. X        putcentral(z, tempzf);
  267. X        tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
  268. X        k++;
  269. X      }
  270. X      putend(k, tempzn - cb, cb, zcomlen, zcomment, tempzf);
  271. X      tempzf = NULL;
  272. X      fclose(tempzf);
  273. X    }
  274. X  }
  275. X  if (key != NULL)
  276. X    free((voidp *)key);
  277. X  if (tempath != NULL)
  278. X    free((voidp *)tempath);
  279. X  if (zipfile != NULL)
  280. X    free((voidp *)zipfile);
  281. X  freeup();
  282. X#ifdef VMS
  283. X  c = 0;
  284. X#endif
  285. X  exit(c);
  286. X}
  287. X
  288. X
  289. Xvoid error(h)
  290. X  char *h;
  291. X/* Internal error, should never happen */
  292. X{
  293. X  err(ZE_LOGIC, h);
  294. X}
  295. X
  296. Xlocal void handler(s)
  297. Xint s;                  /* signal number (ignored) */
  298. X/* Upon getting a user interrupt, turn echo back on for tty and abort
  299. X   cleanly using err(). */
  300. X{
  301. X#ifndef MSDOS
  302. X# ifdef CRYPT
  303. X   echon();
  304. X# endif
  305. X  putc('\n', stderr);
  306. X#endif /* !MSDOS */
  307. X  err(ZE_ABORT, "aborting");
  308. X  s++;                                  /* keep some compilers happy */
  309. X}
  310. X
  311. X
  312. Xvoid warn(a, b)
  313. Xchar *a, *b;            /* message strings juxtaposed in output */
  314. X/* Print a warning message to stderr and return. */
  315. X{
  316. X  fprintf(stderr, "zip warning: %s%s\n", a, b);
  317. X}
  318. X
  319. X
  320. Xlocal void license()
  321. X/* Print license information to stdout. */
  322. X{
  323. X  extent i;             /* counter for copyright array */
  324. X
  325. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  326. X    printf(copyright[i], "zip");
  327. X    putchar('\n');
  328. X  }
  329. X  for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
  330. X    puts(disclaimer[i]);
  331. X}
  332. X
  333. X
  334. Xlocal void help()
  335. X/* Print help (along with license info) to stdout. */
  336. X{
  337. X  extent i;             /* counter for help array */
  338. X
  339. X  /* help array */
  340. X  static char *text[] = {
  341. X"",
  342. X"Zip %d.%d (%s). Usage:",
  343. X"zip [-options] [-b path] [-t mmddyy] [-n suffixes] [zipfile list] [-x list]",
  344. X"  The default action is to add or replace zipfile entries from list, which",
  345. X"  can include the special name - to compress standard input.",
  346. X"  If zipfile and list are ommitted, zip compresses stdin to stdout.",
  347. X"  -f   freshen: only changed files  -u   update: only changed or new files",
  348. X"  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
  349. X"  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
  350. X"  -h   show this help               -L   show software license",
  351. X"  -r   recurse into directories     -j   junk (don't record) directory names",
  352. X"  -0   store only                   -l   translate end-of-line",
  353. X"  -1   compress faster              -9   compress better",
  354. X"  -q   quiet operation              -n   don't compress these suffixes",
  355. X"  -c   add one-line comments        -z   add zipfile comment",
  356. X"  -b   use \"path\" for temp files    -t   only do files after \"mmddyy\"",
  357. X"  -@   read names from stdin        -o   make zipfile as old as latest entry",
  358. X#ifdef CRYPT
  359. X"  -e   encrypt  (-ee verify key)",
  360. X#endif
  361. X#ifdef VMS
  362. X"  -w   append the VMS version number to the name stored in the zip file",
  363. X"  -V   save VMS file attributes",
  364. X#endif /* VMS */
  365. X#ifdef OS2
  366. X"  -E   use the .LONGNAME Extended attribute (if found) as filename",
  367. X#endif /* OS2 */
  368. X#ifdef S_IFLNK
  369. X"  -y   store symbolic links as the link instead of the referenced file",
  370. X#endif /* !S_IFLNK */
  371. X"  -x   exclude the names that follow from those operated on"
  372. X  };
  373. X
  374. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
  375. X  {
  376. X    printf(copyright[i], "zip");
  377. X    putchar('\n');
  378. X  }
  379. X  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  380. X  {
  381. X    printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
  382. X    putchar('\n');
  383. X  }
  384. X}
  385. X
  386. X
  387. X/* Do command line expansion for MSDOS and VMS */
  388. X#if defined(MSVMS) && !defined(__GO32__)
  389. X#  define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
  390. X#else /* !MSVMS */
  391. X#  define PROCNAME(n) procname(n)
  392. X#endif /* ?MSVMS */
  393. X
  394. Xlocal void zipstdout()
  395. X/* setup for writing zip file on stdout */
  396. X{
  397. X  int r;
  398. X  mesg = stderr;
  399. X  if (isatty(1))
  400. X    err(ZE_PARMS, "no zip file provided");
  401. X  if ((zipfile = malloc(4)) == NULL)
  402. X    err(ZE_MEM, "was processing arguments");
  403. X  strcpy(zipfile, "-");
  404. X  if ((r = readzipfile()) != ZE_OK)
  405. X    err(r, zipfile);
  406. X}
  407. X
  408. X
  409. Xvoid main(argc, argv)
  410. Xint argc;               /* number of tokens in command line */
  411. Xchar **argv;            /* command line tokens */
  412. X/* Add, update, freshen, or delete zip entries in a zip file.  See the
  413. X   command help in help() above. */
  414. X{
  415. X  int a;                /* attributes of zip file */
  416. X  ulg c;                /* start of central directory */
  417. X  int d;                /* true if just adding to a zip file */
  418. X  char *e;              /* malloc'd comment buffer */
  419. X  struct flist far *f;  /* steps through found linked list */
  420. X  int i;                /* arg counter, root directory flag */
  421. X  int k;                /* next argument type, marked counter,
  422. X                           comment size, entry count */
  423. X  ulg n;                /* total of entry len's */
  424. X  int o;                /* true if there were any ZE_OPEN errors */
  425. X  char *p;              /* steps through option arguments */
  426. X  char *pp;             /* temporary pointer */
  427. X  int r;                /* temporary variable */
  428. X  ulg t;                /* file time, length of central directory */
  429. X  struct zlist far *v;  /* temporary variable */
  430. X  struct zlist far * far *w;    /* pointer to last link in zfiles list */
  431. X  FILE *x, *y;          /* input and output zip files */
  432. X  struct zlist far *z;  /* steps through zfiles linked list */
  433. X  char *zipbuf;         /* stdio buffer for the zip file */
  434. X
  435. X  mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
  436. X  init_upper();           /* build case map table */
  437. X
  438. X#ifdef MACOS
  439. X   argc = ccommand(&argv);
  440. X#endif
  441. X
  442. X  /* Process arguments */
  443. X  diag("processing arguments");
  444. X  if (argc == 1 && isatty(1))
  445. X  {
  446. X    help();
  447. X    exit(0);
  448. X  }
  449. X  envargs(&argc, &argv, "ZIPOPT"); /* get options from environment */
  450. X
  451. X  zipfile = tempzip = NULL;
  452. X  tempzf = NULL;
  453. X  d = 0;                        /* disallow adding to a zip file */
  454. X  signal(SIGINT, handler);
  455. X  signal(SIGTERM, handler);
  456. X  k = 0;                        /* Next non-option argument type */
  457. X  for (i = 1; i < argc; i++)
  458. X  {
  459. X    if (argv[i][0] == '-')
  460. X      if (argv[i][1])
  461. X        for (p = argv[i]+1; *p; p++)
  462. X          switch(*p)
  463. X          {
  464. X            case '0':
  465. X              method = STORE; level = 0; break;
  466. X            case '1':  case '2':  case '3':  case '4':
  467. X            case '5':  case '6':  case '7':  case '8':  case '9':
  468. X                        /* Set the compression efficacy */
  469. X              level = *p - '0';  break;
  470. X            case 'b':   /* Specify path for temporary file */
  471. X              if (k != 0)
  472. X                err(ZE_PARMS, "use -b before zip file name");
  473. X              else
  474. X                k = 1;          /* Next non-option is path */
  475. X              break;
  476. X            case 'c':   /* Add comments for new files in zip file */
  477. X              comadd = 1;  break;
  478. X            case 'd':   /* Delete files from zip file */
  479. X              if (action != ADD)
  480. X                err(ZE_PARMS, "specify just one action");
  481. X              action = DELETE;
  482. X              break;
  483. X#ifdef CRYPT
  484. X            case 'e':   /* Encrypt */
  485. X              e = key == NULL ? (char *)NULL : key;
  486. X              if ((key = malloc(PWLEN+1)) == NULL)
  487. X                err(ZE_MEM, "was getting encryption password");
  488. X              if (getp(e == NULL ? "Enter password: " : "Verify password: ",
  489. X                       key, PWLEN+1) == NULL)
  490. X                err(ZE_PARMS, "stderr is not a tty");
  491. X              if (e != NULL)
  492. X              {
  493. X                r = strcmp(key, e);
  494. X                free((voidp *)e);
  495. X                if (r)
  496. X                  err(ZE_PARMS, "password not verified");
  497. X              }
  498. X              latest = 1;               /* to make breaking the code harder */
  499. X              break;
  500. X#endif /* CRYPT */
  501. X            case 'f':   /* Freshen zip file--overwrite only */
  502. X              if (action != ADD)
  503. X                err(ZE_PARMS, "specify just one action");
  504. X              action = FRESHEN;
  505. X              break;
  506. X            case 'g':   /* Allow appending to a zip file */
  507. X              d = 1;  break;
  508. X            case 'h': case 'H': case '?':  /* Help */
  509. X              help();
  510. X              leave(ZE_OK);
  511. X            case 'j':   /* Junk directory names */
  512. X              pathput = 0;  break;
  513. X            case 'k':   /* Make entries using DOS names (k for Katz) */
  514. X              dosify = 1;  break;
  515. X            case 'l':   /* Translate end-of-line */
  516. X              translate_eol = 1; break;
  517. X            case 'L':   /* Show license, version */
  518. X              license();
  519. X              leave(ZE_OK);
  520. X            case 'm':   /* Delete files added or updated in zip file */
  521. X              dispose = 1;  break;
  522. X            case 'n':   /* Don't compress files with a special suffix */
  523. X              special = NULL;
  524. X              break;
  525. X            case 'o':   /* Set zip file time to time of latest file in it */
  526. X              latest = 1;  break;
  527. X            case 'p':   /* Store path with name */
  528. X              break;            /* (do nothing as annoyance avoidance) */
  529. X            case 'q':   /* Quiet operation */
  530. X              noisy = 0;  break;
  531. X            case 'r':   /* Recurse into subdirectories */
  532. X              recurse = 1;  break;
  533. X            case 't':   /* Exclude files earlier than specified date */
  534. X              if (before)
  535. X                err(ZE_PARMS, "can only have one -t");
  536. X              k = 2;  break;
  537. X            case 'u':   /* Update zip file--overwrite only if newer */
  538. X              if (action != ADD)
  539. X                err(ZE_PARMS, "specify just one action");
  540. X              action = UPDATE;
  541. X              break;
  542. X            case 'v':   /* Mention oddities in zip file structure */
  543. X              verbose++;
  544. X              break;
  545. X#ifdef VMS
  546. X            case 'w':   /* Append the VMS version number */
  547. X              vmsver = 1;  break;
  548. X            case 'V':   /* Store in VMS format */
  549. X              vms_native = 1; break;
  550. X#endif /* VMS */
  551. X            case 'x':   /* Exclude following files */
  552. X              if (k != 4 &&
  553. X                  (k != 3 || (action != UPDATE && action != FRESHEN)))
  554. X                err(ZE_PARMS, "nothing to exclude (-x) from");
  555. X              if (k == 3)       /* must be -u or -f */
  556. X                for (z = zfiles; z != NULL; z = z->nxt)
  557. X                  z->mark = 1;  /* mark all of them */
  558. X              k = 5;
  559. X              if ((r = exclude()) != ZE_OK)
  560. X                if (r == ZE_PARMS)
  561. X                  err(r, "cannot repeat names in zip file");
  562. X                else
  563. X                  err(r, "was processing list of files");
  564. X              break;
  565. X#ifdef S_IFLNK
  566. X            case 'y':   /* Store symbolic links as such */
  567. X              linkput = 1;  break;
  568. X#endif /* S_IFLNK */
  569. X            case 'z':   /* Edit zip file comment */
  570. X              zipedit = 1;  break;
  571. X            case '@':   /* read file names from stdin */
  572. X              while ((pp = getnam(errbuf)) != NULL)
  573. X              {
  574. X                if ((r = PROCNAME(pp)) != ZE_OK)
  575. X                  if (r == ZE_MISS)
  576. X                    warn("name not matched: ", pp);
  577. X                  else
  578. X                    err(r, pp);
  579. X              }
  580. X              break;
  581. X#ifdef OS2
  582. X            case 'E':
  583. X              /* use the .LONGNAME EA (if any) as the file's name. */
  584. X              use_longname_ea = 1;
  585. X              break;
  586. X#endif
  587. X            default:
  588. X            {
  589. X              sprintf(errbuf, "no such option: %c", *p);
  590. X              err(ZE_PARMS, errbuf);
  591. X            }
  592. X          }
  593. X      else              /* just a dash */
  594. X        switch (k)
  595. X        {
  596. X        case 0:
  597. X          zipstdout();
  598. X          k = 3;
  599. X          break;
  600. X        case 1:
  601. X          err(ZE_PARMS, "invalid path");
  602. X          break;
  603. X        case 2:
  604. X          err(ZE_PARMS, "invalid time");
  605. X          break;
  606. X        case 3:  case 4:  case 5:
  607. X          if ((r = PROCNAME(argv[i])) != ZE_OK)
  608. X            if (r == ZE_MISS)
  609. X              warn("name not matched: ", argv[i]);
  610. X            else
  611. X              err(r, argv[i]);
  612. X          if (k == 3)
  613. X            k = 4;
  614. X        }
  615. X    else                /* not an option */
  616. X    {
  617. X      if (special == NULL)
  618. X        special = argv[i];
  619. X      else
  620. X        switch (k)
  621. X      {
  622. X        case 0:
  623. X          if ((zipfile = ziptyp(argv[i])) == NULL)
  624. X            err(ZE_MEM, "was processing arguments");
  625. X          if ((r = readzipfile()) != ZE_OK)
  626. X            err(r, zipfile);
  627. X          k = 3;
  628. X          break;
  629. X        case 1:
  630. X          if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL)
  631. X            err(ZE_MEM, "was processing arguments");
  632. X          strcpy(tempath, argv[i]);
  633. X          k = 0;
  634. X          break;
  635. X        case 2:
  636. X        {
  637. X          int yy, mm, dd;       /* results of sscanf() */
  638. X
  639. X          if (sscanf(argv[i], "%2d%2d%2d", &mm, &dd, &yy) != 3 ||
  640. X              mm < 1 || mm > 12 || dd < 1 || dd > 31)
  641. X            err(ZE_PARMS, "invalid date entered for -t option");
  642. X          before = dostime(yy + (yy < 80 ? 2000 : 1900), mm, dd, 0, 0, 0);
  643. X          k = 0;
  644. X          break;
  645. X        }
  646. X        case 3:  case 4:  case 5:
  647. X          if ((r = PROCNAME(argv[i])) != ZE_OK)
  648. X            if (r == ZE_MISS)
  649. X              warn("name not matched: ", argv[i]);
  650. X            else
  651. X              err(r, argv[i]);
  652. X          if (k == 3)
  653. X            k = 4;
  654. X      }
  655. X    }
  656. X  }
  657. X  if (k < 3) {               /* zip used as filter */
  658. X    zipstdout();
  659. X    if ((r = procname("-")) != ZE_OK)
  660. X      if (r == ZE_MISS)
  661. X        warn("name not matched: ", "-");
  662. X      else
  663. X        err(r, "-");
  664. X    k = 4;
  665. X  }
  666. X
  667. X  if (k != 5)                   /* Clean up selections */
  668. X  {
  669. X    if (k == 3 && (action == UPDATE || action == FRESHEN))
  670. X      for (z = zfiles; z != NULL; z = z->nxt)
  671. X        z->mark = 1;                    /* if -u or -f with no args, do all */
  672. X    if ((r = exclude()) != ZE_OK)       /* remove duplicates in found list */
  673. X      if (r == ZE_PARMS)
  674. X        err(r, "cannot repeat names in zip file");
  675. X      else
  676. X        err(r, "was processing list of files");
  677. X  }
  678. X  if (zcount)
  679. X    free((voidp *)zsort);
  680. X
  681. X  /* Check option combinations */
  682. X  if (action == DELETE && (method != BEST || dispose || recurse ||
  683. X      key != NULL || comadd || zipedit))
  684. X    err(ZE_PARMS, "invalid option(s) used with -d");
  685. X  if (linkput && dosify)
  686. X    err(ZE_PARMS, "can't use -y with -k");
  687. X  if ((action != ADD || d) && !strcmp(zipfile, "-"))
  688. X    err(ZE_PARMS, "can't use -d,-f,-u or -g on standard output");
  689. X#ifdef VMS
  690. X  if (vms_native && translate_eol)
  691. X    err(ZE_PARMS, "can't use -V with -l");
  692. X#endif
  693. X  if (zcount == 0 && (action != ADD || d))
  694. X    warn(zipfile, " not found or empty");
  695. X
  696. X
  697. X  /* If -b not specified, make temporary path the same as the zip file */
  698. X#ifdef MSDOS
  699. X  if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
  700. X                          (p = strrchr(zipfile, '\\')) != NULL ||
  701. X                          (p = strrchr(zipfile, ':')) != NULL))
  702. X  {
  703. X    if (*p == ':')
  704. X      p++;
  705. X#else /* !MSDOS */
  706. X  if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
  707. X  {
  708. X#endif /* ?MSDOS */
  709. X    if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
  710. X      err(ZE_MEM, "was processing arguments");
  711. X    r = *p;  *p = 0;
  712. X    strcpy(tempath, zipfile);
  713. X    *p = (char)r;
  714. X  }
  715. X
  716. X  /* For each marked entry, if not deleting, check if it exists, and if
  717. X     updating or freshening, compare date with entry in old zip file.
  718. X     Unmark if it doesn't exist or is too old, else update marked count. */
  719. X  diag("stating marked entries");
  720. X  k = 0;                        /* Initialize marked count */
  721. X  for (z = zfiles; z != NULL; z = z->nxt)
  722. X    if (z->mark)
  723. X      if (action != DELETE &&
  724. X                ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
  725. X                 t < before ||
  726. X                 ((action == UPDATE || action == FRESHEN) && t <= z->tim)))
  727. X      {
  728. X        z->mark = 0;
  729. X        z->trash = t && t >= before;    /* delete if -um or -fm */
  730. X        if (verbose)
  731. X          fprintf(mesg, "zip diagnostic: %s %s\n", z->name,
  732. X                 z->trash ? "up to date" : "missing or early");
  733. X      }
  734. X      else
  735. X        k++;
  736. X
  737. X
  738. X  /* Remove entries from found list that do not exist or are too old */
  739. X  diag("stating new entries");
  740. X  for (f = found; f != NULL;)
  741. X    if (action == DELETE || action == FRESHEN ||
  742. X        (t = filetime(f->name, (ulg *)NULL, (long *)NULL)) == 0 ||
  743. X        t < before || (namecmp(f->name, zipfile) == 0 && strcmp(zipfile, "-")))
  744. X      f = fexpel(f);
  745. X    else
  746. X      f = f->nxt;
  747. X
  748. X  /* Make sure there's something left to do */
  749. X  if (k == 0 && found == NULL && !(zfiles != NULL && (latest || zipedit)))
  750. X    if (action == UPDATE || action == FRESHEN)
  751. X      leave(ZE_OK);
  752. X    else if (zfiles == NULL && latest)
  753. X      err(ZE_NAME, zipfile);
  754. X    else
  755. X      err(ZE_NONE, zipfile);
  756. X  d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
  757. X
  758. X
  759. X  /* Before we get carried away, make sure zip file is writeable */
  760. X  if (strcmp(zipfile, "-"))
  761. X  {
  762. X    x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) : 
  763. X                                        fopen(zipfile, FOPM);
  764. X    /* Note: FOPW and FOPM expand to several parameters for VMS */
  765. X    if (x == NULL)
  766. X      err(ZE_CREAT, zipfile);
  767. X    fclose(x);
  768. X    a = getfileattr(zipfile);
  769. X    if (zfiles == NULL && zipbeg == 0)
  770. X      destroy(zipfile);
  771. X  }
  772. X  else
  773. X    a = 0;
  774. X
  775. X
  776. X  /* Open zip file and temporary output file */
  777. X  diag("opening zip file and creating temporary zip file");
  778. X  x = NULL;
  779. X  tempzn = 0;
  780. X  if (strcmp(zipfile, "-") == 0)
  781. X  {
  782. X#ifdef MSDOS
  783. X    /* Set stdout mode to binary for MSDOS systems */
  784. X    setmode(fileno(stdout), O_BINARY);
  785. X    tempzf = y = fdopen(fileno(stdout), FOPW);
  786. X#else
  787. X    tempzf = y = stdout;
  788. X#endif
  789. X    tempzip = "-";
  790. X  }
  791. X  else if (d) /* d true if just appending (-g) */
  792. X  {
  793. X    if ((y = fopen(zipfile, FOPM)) == NULL)
  794. X      err(ZE_NAME, zipfile);
  795. X    tempzip = zipfile;
  796. X    tempzf = y;
  797. X    if (fseek(y, cenbeg, SEEK_SET))
  798. X      err(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
  799. X    tempzn = cenbeg;
  800. X  }
  801. X  else
  802. X  {
  803. X    if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL)
  804. X      err(ZE_NAME, zipfile);
  805. X    if ((tempzip = tempname(zipfile)) == NULL)
  806. X      err(ZE_MEM, tempzip);
  807. X    if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
  808. X      err(ZE_TEMP, tempzip);
  809. X    if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
  810. X      err(r, r == ZE_TEMP ? tempzip : zipfile);
  811. X    tempzn = zipbeg;
  812. X  }
  813. X#ifndef VMS
  814. X  /* Use large buffer to speed up stdio: */
  815. X  zipbuf = (char *)malloc(ZBSZ);
  816. X  if (zipbuf == NULL)
  817. X    err(ZE_MEM, tempzip);
  818. X# ifdef _IOFBF
  819. X  setvbuf(y, zipbuf, _IOFBF, ZBSZ);
  820. X# else
  821. X  setbuf(y, zipbuf);
  822. X# endif /* _IOBUF */
  823. X#endif /* VMS */
  824. X  o = 0;                                /* no ZE_OPEN errors yet */
  825. X
  826. X
  827. X  /* Process zip file, updating marked files */
  828. X  if (zfiles != NULL)
  829. X    diag("going through old zip file");
  830. X  w = &zfiles;
  831. X  while ((z = *w) != NULL)
  832. X    if (z->mark)
  833. X    {
  834. X      /* if not deleting, zip it up */
  835. X      if (action != DELETE)
  836. X      {
  837. X        if (noisy)
  838. X        {
  839. X          fprintf(mesg, "updating %s", z->zname);
  840. X          fflush(mesg);
  841. X        }
  842. X        if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
  843. X        {
  844. X          if (noisy)
  845. X          {
  846. X            putc('\n', mesg);
  847. X            fflush(mesg);
  848. X          }
  849. X          sprintf(errbuf, "was zipping %s", z->name);
  850. X          err(r, errbuf);
  851. X        }
  852. X        if (r == ZE_OPEN)
  853. X        {
  854. X          o = 1;
  855. X          if (noisy)
  856. X          {
  857. X            putc('\n', mesg);
  858. X            fflush(mesg);
  859. X          }
  860. X          perror("zip warning");
  861. X          warn("could not open for reading: ", z->name);
  862. X          warn("will just copy entry over: ", z->zname);
  863. X          if ((r = zipcopy(z, x, y)) != ZE_OK)
  864. X          {
  865. X            sprintf(errbuf, "was copying %s", z->zname);
  866. X            err(r, errbuf);
  867. X          }
  868. X          z->mark = 0;
  869. X        }
  870. X        w = &z->nxt;
  871. X      }
  872. X      else
  873. X      {
  874. X        if (noisy)
  875. X        {
  876. X          fprintf(mesg, "deleting %s\n", z->zname);
  877. X          fflush(mesg);
  878. X        }
  879. X        v = z->nxt;                     /* delete entry from list */
  880. X        free((voidp *)(z->name));
  881. X        free((voidp *)(z->zname));
  882. X        if (z->ext)
  883. X          free((voidp *)(z->extra));
  884. X        if (z->cext && z->cextra != z->extra)
  885. X          free((voidp *)(z->cextra));
  886. X        if (z->com)
  887. X          free((voidp *)(z->comment));
  888. X        farfree((voidp far *)z);
  889. X        *w = v;
  890. X        zcount--;
  891. X      }
  892. X    }
  893. X    else
  894. X    {
  895. X      /* copy the original entry verbatim */
  896. X      if (!d && (r = zipcopy(z, x, y)) != ZE_OK)
  897. X      {
  898. X        sprintf(errbuf, "was copying %s", z->zname);
  899. X        err(r, errbuf);
  900. X      }
  901. X      w = &z->nxt;
  902. X    }
  903. X
  904. X
  905. X  /* Process the edited found list, adding them to the zip file */
  906. X  diag("zipping up new entries, if any");
  907. X  for (f = found; f != NULL; f = fexpel(f))
  908. X  {
  909. X    /* add a new zfiles entry and set the name */
  910. X    if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
  911. X      err(ZE_MEM, "was adding files to zip file");
  912. X    z->nxt = NULL;
  913. X    z->name = f->name;
  914. X    f->name = NULL;
  915. X    z->zname = f->zname;
  916. X    f->zname = NULL;
  917. X    z->ext = z->cext = z->com = 0;
  918. X    z->mark = 1;
  919. X    z->dosflag = f->dosflag;
  920. X    /* zip it up */
  921. X    if (noisy)
  922. X    {
  923. X      fprintf(mesg, "adding %s", z->zname);
  924. X      fflush(mesg);
  925. X    }
  926. X    if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN)
  927. X    {
  928. X      if (noisy)
  929. X      {
  930. X        putc('\n', mesg);
  931. X        fflush(mesg);
  932. X      }
  933. X      sprintf(errbuf, "was zipping %s", z->name);
  934. X      err(r, errbuf);
  935. X    }
  936. X    if (r == ZE_OPEN)
  937. X    {
  938. X      o = 1;
  939. X      if (noisy)
  940. X      {
  941. X        putc('\n', mesg);
  942. X        fflush(mesg);
  943. X      }
  944. X      perror("zip warning");
  945. X      warn("could not open for reading: ", z->name);
  946. X      free((voidp *)(z->name));
  947. X      free((voidp *)(z->zname));
  948. X      farfree((voidp far *)z);
  949. X    }
  950. X    else
  951. X    {
  952. X      *w = z;
  953. X      w = &z->nxt;
  954. X      zcount++;
  955. X    }
  956. X  }
  957. X  if (key != NULL)
  958. X  {
  959. X    free((voidp *)key);
  960. X    key = NULL;
  961. X  }
  962. X
  963. X
  964. X  /* Get one line comment for each new entry */
  965. X  if (comadd)
  966. X  {
  967. X    if ((e = malloc(MAXCOM + 1)) == NULL)
  968. X      err(ZE_MEM, "was reading comment lines");
  969. X    for (z = zfiles; z != NULL; z = z->nxt)
  970. X      if (z->mark)
  971. X      {
  972. X        if (noisy)
  973. X          fprintf(mesg, "Enter comment for %s:\n", z->name);
  974. X        /* ??? reopen /dev/tty if one file was zipped from stdin
  975. X         * or if file names were read from stdin.
  976. X         */
  977. X        if (fgets(e, MAXCOM+1, stdin) != NULL)
  978. X        {
  979. X          if ((p = malloc((k = strlen(e))+1)) == NULL)
  980. X          {
  981. X            free((voidp *)e);
  982. X            err(ZE_MEM, "was reading comment lines");
  983. X          }
  984. X          strcpy(p, e);
  985. X          if (p[k-1] == '\n')
  986. X            p[--k] = 0;
  987. X          z->comment = p;
  988. X          z->com = k;
  989. X        }
  990. X      }
  991. X    free((voidp *)e);
  992. X  }
  993. X
  994. X  /* Get multi-line comment for the zip file */
  995. X  if (zipedit)
  996. X  {
  997. X    if ((e = malloc(MAXCOM + 1)) == NULL)
  998. X      err(ZE_MEM, "was reading comment lines");
  999. X    if (noisy && zcomlen)
  1000. X    {
  1001. X      fputs("current zip file comment is:\n", mesg);
  1002. X      fwrite(zcomment, 1, zcomlen, mesg);
  1003. X      if (zcomment[zcomlen-1] != '\n')
  1004. X        putc('\n', mesg);
  1005. X      free((voidp *)zcomment);
  1006. X    }
  1007. X    zcomment = malloc(1);
  1008. X    *zcomment = 0;
  1009. X    if (noisy)
  1010. X      fputs("enter new zip file comment (end with .):\n", mesg);
  1011. X     /* ??? reopen /dev/tty if one file was zipped from stdin
  1012. X      * or if file names were read from stdin.
  1013. X      */
  1014. X    while (fgets(e, MAXCOM+1, stdin) != NULL && strcmp(e, ".\n"))
  1015. X    {
  1016. X      if (e[(r = strlen(e)) - 1] == '\n')
  1017. X        e[--r] = 0;
  1018. X      if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
  1019. X      {
  1020. X        free((voidp *)e);
  1021. X        err(ZE_MEM, "was reading comment lines");
  1022. X      }
  1023. X      if (*zcomment)
  1024. X        strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
  1025. X      else
  1026. X        strcpy(p, *e ? e : "\r\n");
  1027. X      free((voidp *)zcomment);
  1028. X      zcomment = p;
  1029. X    }
  1030. X    zcomlen = strlen(zcomment);
  1031. X    free((voidp *)e);
  1032. X  }
  1033. X
  1034. X
  1035. X  /* Write central directory and end header to temporary zip */
  1036. X  diag("writing central directory");
  1037. X  k = 0;                        /* keep count for end header */
  1038. X  c = tempzn;                   /* get start of central */
  1039. X  n = t = 0;
  1040. X  for (z = zfiles; z != NULL; z = z->nxt)
  1041. X  {
  1042. X    if ((r = putcentral(z, y)) != ZE_OK)
  1043. X      err(r, tempzip);
  1044. X    tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
  1045. X    n += z->len;
  1046. X    t += z->siz;
  1047. X    k++;
  1048. X  }
  1049. X  if (k == 0)
  1050. X    warn("zip file empty", "");
  1051. X  if (verbose)
  1052. X    fprintf(mesg, "total bytes=%lu, compressed=%lu -> %d%% savings\n",
  1053. X           n, t, percent(n, t));
  1054. X  t = tempzn - c;               /* compute length of central */
  1055. X  diag("writing end of central directory");
  1056. X  if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK)
  1057. X    err(r, tempzip);
  1058. X  tempzf = NULL;
  1059. X  if (fclose(y))
  1060. X    err(d ? ZE_WRITE : ZE_TEMP, tempzip);
  1061. X  if (x != NULL)
  1062. X    fclose(x);
  1063. X
  1064. X
  1065. X  /* Replace old zip file with new zip file, leaving only the new one */
  1066. X  if (strcmp(zipfile, "-") && !d)
  1067. X  {
  1068. X    diag("replacing old zip file with new zip file");
  1069. X    if ((r = replace(zipfile, tempzip)) != ZE_OK)
  1070. X    {
  1071. X      warn("new zip file left as: ", tempzip);
  1072. X      free((voidp *)tempzip);
  1073. X      tempzip = NULL;
  1074. X      err(r, "was replacing the original zip file");
  1075. X    }
  1076. X    free((voidp *)tempzip);
  1077. X  }
  1078. X  tempzip = NULL;
  1079. X  if (strcmp(zipfile, "-")) {
  1080. X    setfileattr(zipfile, a);
  1081. X#ifdef VMS
  1082. X    /* If the zip file existed previously, restore its record format: */
  1083. X    if (x != NULL)
  1084. X      VMSmunch(zipfile, RESTORE_RTYPE, NULL);
  1085. X#endif
  1086. X  }
  1087. X
  1088. X  /* Finish up (process -o, -m, clean up).  Exit code depends on o. */
  1089. X  leave(o ? ZE_OPEN : ZE_OK);
  1090. X}
  1091. X
  1092. X/*****************************************************************
  1093. X | envargs - add default options from environment to command line
  1094. X |----------------------------------------------------------------
  1095. X | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
  1096. X | This program is in the public domain.
  1097. X |----------------------------------------------------------------
  1098. X | Minor program notes:
  1099. X |  1. Yes, the indirection is a tad complex
  1100. X |  2. Parenthesis were added where not needed in some cases
  1101. X |     to make the action of the code less obscure.
  1102. X ****************************************************************/
  1103. X
  1104. Xlocal void
  1105. Xenvargs(Pargc, Pargv, envstr)
  1106. Xint *Pargc;
  1107. Xchar ***Pargv;
  1108. Xchar *envstr;
  1109. X{
  1110. X    char *getenv();
  1111. X    char *envptr;                               /* value returned by getenv */
  1112. X    char *bufptr;                               /* copy of env info */
  1113. X    int argc = 0;                               /* internal arg count */
  1114. X    int ch;                                             /* spare temp value */
  1115. X    char **argv;                                /* internal arg vector */
  1116. X    char **argvect;                             /* copy of vector address */
  1117. X
  1118. X    /* see if anything in the environment */
  1119. X    envptr = getenv(envstr);
  1120. X    if (envptr == NULL || *envptr == 0) return;
  1121. X
  1122. X    /* count the args so we can allocate room for them */
  1123. X    argc = count_args(envptr);
  1124. X    bufptr = malloc(1+strlen(envptr));
  1125. X    if (bufptr == NULL)
  1126. X        err(ZE_MEM, "Can't get memory for arguments");
  1127. X
  1128. X    strcpy(bufptr, envptr);
  1129. X
  1130. X    /* allocate a vector large enough for all args */
  1131. X    argv = (char **)malloc((argc+*Pargc+1)*sizeof(char *));
  1132. X    if (argv == NULL)
  1133. X        err(ZE_MEM, "Can't get memory for arguments");
  1134. X    argvect = argv;
  1135. X
  1136. X    /* copy the program name first, that's always true */
  1137. X    *(argv++) = *((*Pargv)++);
  1138. X
  1139. X    /* copy the environment args first, may be changed */
  1140. X    do {
  1141. X        *(argv++) = bufptr;
  1142. X        /* skip the arg and any trailing blanks */
  1143. X        while ((ch = *bufptr) != '\0' && ch != ' ') ++bufptr;
  1144. X        if (ch == ' ') *(bufptr++) = '\0';
  1145. X        while ((ch = *bufptr) != '\0' && ch == ' ') ++bufptr;
  1146. X    } while (ch);
  1147. X
  1148. X    /* now save old argc and copy in the old args */
  1149. X    argc += *Pargc;
  1150. X    while (--(*Pargc)) *(argv++) = *((*Pargv)++);
  1151. X
  1152. X    /* finally, add a NULL after the last arg, like UNIX */
  1153. X    *argv = NULL;
  1154. X
  1155. X    /* save the values and return */
  1156. X    *Pargv = argvect;
  1157. X    *Pargc = argc;
  1158. X}
  1159. X
  1160. Xstatic int
  1161. Xcount_args(s)
  1162. Xchar *s;
  1163. X{
  1164. X    int count = 0;
  1165. X    int ch;
  1166. X
  1167. X    do {
  1168. X        /* count and skip args */
  1169. X        ++count;
  1170. X        while ((ch = *s) != '\0' && ch != ' ') ++s;
  1171. X        while ((ch = *s) != '\0' && ch == ' ') ++s;
  1172. X    } while (ch);
  1173. X
  1174. X    return count;
  1175. X}
  1176. END_OF_FILE
  1177.   if test 32880 -ne `wc -c <'zip.c'`; then
  1178.     echo shar: \"'zip.c'\" unpacked with wrong size!
  1179.   fi
  1180.   # end of 'zip.c'
  1181. fi
  1182. if test -f 'zip.doc' -a "${1}" != "-c" ; then 
  1183.   echo shar: Will not clobber existing file \"'zip.doc'\"
  1184. else
  1185.   echo shar: Extracting \"'zip.doc'\" \(23559 characters\)
  1186.   sed "s/^X//" >'zip.doc' <<'END_OF_FILE'
  1187. X
  1188. XZIP(1)                   USER COMMANDS                     ZIP(1)
  1189. X
  1190. XNAME
  1191. X     zip, zipcloak, zipnote,  zipsplit  -  package  and  compress
  1192. X     (archive) files
  1193. X
  1194. XSYNOPSIS
  1195. X     zip [ -cdeEfghjklmoqruwyz@ ] [ -b temppath ] [ -n suffixes ]
  1196. X     [ -t mmddyy ] [ zipfile list ] [ -x list ]
  1197. X
  1198. X     zipcloak [ -d ] [ -b path ] zipfile
  1199. X
  1200. X     zipnote [ -w ] [ -b path ] zipfile
  1201. X
  1202. X     zipsplit [ -ti ] [ -n size ] [ -b path ] zipfile
  1203. X
  1204. XDESCRIPTION
  1205. X     zip is a compression and file packaging  utility  for  Unix,
  1206. X     VMS,  MSDOS,  OS/2,  Windows NT, Minix, Atari and Macintosh.
  1207. X     It is analogous to a combination of tar and compress and  is
  1208. X     compatible with PKZIP (Phil Katz ZIP) for MSDOS systems.
  1209. X
  1210. X     There is a companion to zip called unzip (of  course)  which
  1211. X     you  should  be able to find the same place you got zip. zip
  1212. X     and unzip can work with files produced by PKZIP under MSDOS,
  1213. X     and PKZIP and PKUNZIP can work with files produced by zip.
  1214. X
  1215. X     zip version 1.9 is compatible with pkzip 1.93a.   Note  that
  1216. X     pkunzip 1.10 cannot extract files produced by pkzip 1.93a or
  1217. X     zip 1.9b. You must use pkunzip 1.93a or unzip 5.0 to extract
  1218. X     them.
  1219. X
  1220. X     For a brief help on zip and unzip, run each without specify-
  1221. X     ing any parameters on the command line.
  1222. X
  1223. X     zip puts one or more compressed files  into  a  single  "zip
  1224. X     file"  along with information about the files, including the
  1225. X     name, path if requested, date and time last  modified,  pro-
  1226. X     tection,  and  check  information  to verify the fidelity of
  1227. X     each entry.  zip can also be used as a  filter,  compressing
  1228. X     standard  input  to standard output.  zip can pack an entire
  1229. X     directory structure in a zip file  with  a  single  command.
  1230. X     Compression  ratios of 2:1 to 3:1 are common for text files.
  1231. X     zip has one compression  method  (deflation)  and  can  also
  1232. X     store  files  without  compression. It automatically chooses
  1233. X     the better of the two for each file to be compressed.
  1234. X
  1235. X     zip is useful for packaging a set of files to send to  some-
  1236. X     one  or for distribution; for archiving or backing up files;
  1237. X     and for saving disk space by temporarily compressing  unused
  1238. X     files or directories.
  1239. X
  1240. XHOW TO USE ZIP
  1241. X     The simplest use of zip is as follows:
  1242. X
  1243. X          zip stuff *
  1244. X
  1245. X     This will create the file "stuff.zip" (assuming it does  not
  1246. X     exist)  and  put  all  the files in the current directory in
  1247. X     stuff.zip in a compressed form.  The .zip  suffix  is  added
  1248. X     automatically,  unless  that  file name given contains a dot
  1249. X     already.  This allows specifying suffixes other than ".zip".
  1250. X
  1251. X     Because of the way the  shell  does  filename  substitution,
  1252. X     files  that  start  with a "." are not included.  To include
  1253. X     those as well, you can:
  1254. X
  1255. X          zip stuff .* *
  1256. X
  1257. X     Even this will not include any subdirectories  that  are  in
  1258. X     the  current  directory.  To zip up an entire directory, the
  1259. X     command:
  1260. X
  1261. X          zip -r foo foo
  1262. X
  1263. X     will create the file "foo.zip" containing all the files  and
  1264. X     directories  in  the  directory "foo" that is in the current
  1265. X     directory. (The first "foo" denotes the zip file, the second
  1266. X     one  denotes  the  directory.)  The "r" option means recurse
  1267. X     through the directory structure.   In  this  case,  all  the
  1268. X     files  and directories in foo are zipped, including the ones
  1269. X     that start with a ".", since the recursion does not use  the
  1270. X     shell's  file-name substitution.  You should not use -r with
  1271. X     the name ".*", since that matches ".." which will attempt to
  1272. X     zip up the parent directory--probably not what was intended.
  1273. X
  1274. X     You may want to make a zip file that contains the  files  in
  1275. X     foo,  but  not  record the directory name, foo.  You can use
  1276. X     the -j (junk path) option to leave off the path:
  1277. X
  1278. X          zip -j foo foo/*
  1279. X
  1280. X     The -y option (only under Unix) will store symbolic links as
  1281. X     such in the zip file, instead of compressing and storing the
  1282. X     file referred to in the link.
  1283. X
  1284. X     You might be zipping to save disk space, in which  case  you
  1285. X     could:
  1286. X
  1287. X          zip -rm foo foo
  1288. X
  1289. X     where the "m" option means "move".  This will delete foo and
  1290. X     its  contents  after  making  foo.zip.  No deletions will be
  1291. X     done until the zip  has  completed  with  no  errors.   This
  1292. X     option  is  obviously more dangerous and should be used with
  1293. X     care.
  1294. X
  1295. X     If the zip file already exists, these commands will  replace
  1296. X     existing  or  add new entries to the zip file.  For example,
  1297. X     if you were really short on disk space, you might  not  have
  1298. X     enough room simultaneously to hold the directory foo and the
  1299. X     compressed foo.zip.  In this case, you could do it in steps.
  1300. X     If  foo  contained  the subdirectories tom, dick, and harry,
  1301. X     then you could:
  1302. X
  1303. X          zip -rm foo foo/tom
  1304. X          zip -rm foo foo/dick
  1305. X          zip -rm foo foo/harry
  1306. X
  1307. X     where the first command would create foo.zip, and  the  next
  1308. X     two would add to it.  At the completion of each zip command,
  1309. X     the directory just zipped would be deleted, making  room  in
  1310. X     which the next zip command could work.
  1311. X
  1312. X     zip will also accept a single dash ("-")  as  the  zip  file
  1313. X     name,  in  which  case it will write the zip file to stdout,
  1314. X     allowing the output to be  piped  to  another  program.  For
  1315. X     example:
  1316. X
  1317. X          zip -r - . | dd of=/dev/nrst0 obs=16k
  1318. X
  1319. X     would write the zip output  directly  to  a  tape  with  the
  1320. X     specified  block  size  for  the  purpose  of backing up the
  1321. X     current directory.
  1322. X
  1323. X     zip also accepts a single dash ("-") as the name of  a  file
  1324. X     to  be  compressed,  in which case it will read the zip file
  1325. X     from stdin, allowing zip to take input from another program.
  1326. X     For example:
  1327. X
  1328. X          tar cf - . | zip backup -
  1329. X
  1330. X     would compress the output of the tar command for the purpose
  1331. X     of backing up the current directory. This generally produces
  1332. X     better compression than the previous example  using  the  -r
  1333. X     option, because zip can take advantage of redundancy between
  1334. X     files. The backup can be restored using the command
  1335. X
  1336. X          unzip -p backup | tar xf -
  1337. X
  1338. X     When no zip file name is given and stdout is not a terminal,
  1339. X     zip acts as a filter, compressing standard input to standard
  1340. X     output.  For example,
  1341. X
  1342. X          tar cf - . | zip | dd of=/dev/nrst0
  1343. X
  1344. X     is equivalent to
  1345. X
  1346. X          tar cf - . | zip - - | dd of=/dev/nrst0
  1347. X
  1348. X     Zip archives created in this manner can  be  extracted  with
  1349. X     the  program  funzip which is provided in the unzip package.
  1350. X     For example,
  1351. X
  1352. X             dd if=/dev/nrst0 | funzip | tar xvf -
  1353. X
  1354. XMODIFYING EXISTING ZIP FILES
  1355. X     When given the name of an existing zip file with  the  above
  1356. X     commands,  zip will replace identically named entries in the
  1357. X     zip file or add entries for  new  names.   For  example,  if
  1358. X     foo.zip exists and contains foo/file1 and foo/file2, and the
  1359. X     directory foo contains the files  foo/file1  and  foo/file3,
  1360. X     then:
  1361. X
  1362. X          zip -r foo foo
  1363. X
  1364. X     will replace foo/file1  in  foo.zip  and  add  foo/file3  to
  1365. X     foo.zip.  After this, foo.zip contains foo/file1, foo/file2,
  1366. X     and foo/file3, with foo/file2 unchanged from before.
  1367. X
  1368. X     When changing an existing zip file, zip will  write  a  tem-
  1369. X     porary  file with the new contents, and only replace the old
  1370. X     one when the zip has completed with no errors. You  can  use
  1371. X     the  -b  option  to specify a different path (usually a dif-
  1372. X     ferent device) to put the temporary file in.  For example:
  1373. X
  1374. X          zip -b /tmp stuff *
  1375. X
  1376. X     will put the temporary zip file and the  temporary  compres-
  1377. X     sion  files  in the directory "/tmp", copying over stuff.zip
  1378. X     in the current directory when done.
  1379. X
  1380. X     If you are only adding entries to a zip file, not replacing,
  1381. X     and  the -g option is given, then zip grows (appends to) the
  1382. X     file instead of copying it.  The danger of this is  that  if
  1383. X     the  operation fails, the original zip file is corrupted and
  1384. X     lost.
  1385. X
  1386. X     There are two other ways to change or add entries in  a  zip
  1387. X     file  that  are  restrictions of simple addition or replace-
  1388. X     ment.  The first is -u (update) which will add  new  entries
  1389. X     to  the zip file as before but will replace existing entries
  1390. X     only if the modified date of the file is  more  recent  than
  1391. X     the  date recorded for that name in the zip file.  For exam-
  1392. X     ple:
  1393. X
  1394. X          zip -u stuff *
  1395. X
  1396. X     will add any new files in the current directory, and  update
  1397. X     any  changed files in the zip file stuff.zip.  Note that zip
  1398. X     will not try to pack stuff.zip into itself when you do this.
  1399. X     zip will always exclude the zip file from the files on which
  1400. X     to be operated.
  1401. X
  1402. X     The second restriction is -f (freshen) which,  like  update,
  1403. X     will  only  replace entries with newer files; unlike update,
  1404. X     will not add files that are not already  in  the  zip  file.
  1405. X     For  this  option, you may want to simply freshen all of the
  1406. X     files that are in the specified zip file.  To  do  this  you
  1407. X     would simply:
  1408. X
  1409. X          zip -f foo
  1410. X
  1411. X     Note that the -f option with no arguments freshens  all  the
  1412. X     entries  in the zip file.  The same is true of -u, and hence
  1413. X     "zip -u foo" and "zip -f foo" both do the same thing.
  1414. X
  1415. X     This command should be run  from  the  same  directory  from
  1416. X     which  the  original zip command was run, since paths stored
  1417. X     in zip files are always relative.
  1418. X
  1419. X     Another restriction that can be used with adding,  updating,
  1420. X     or  freshening is -t (time), which will not operate on files
  1421. X     modified earlier than the specified date.  For example:
  1422. X
  1423. X          zip -rt 120791 infamy foo
  1424. X
  1425. X     will add all the files in foo and  its  subdirectories  that
  1426. X     were  last modified on December 7, 1991, or later to the zip
  1427. X     file infamy.zip.
  1428. X
  1429. X     Also, files can be explicitly excluded using the -x option:
  1430. X
  1431. X          zip -r foo foo -x \*.o
  1432. X
  1433. X     which will zip up the  contents  of  foo  into  foo.zip  but
  1434. X     exclude  all the files that end in ".o".  Here the backslash
  1435. X     causes zip to match file names that were found when foo  was
  1436. X     searched.
  1437. X
  1438. X     The last operation is -d (delete) which will remove  entries
  1439. X     from a zip file.  An example might be:
  1440. X
  1441. X          zip -d foo foo/tom/junk foo/harry/\* \*.o
  1442. X
  1443. X     which will remove the entry foo/tom/junk, all of  the  files
  1444. X     that  start with "foo/harry/", and all of the files that end
  1445. X     with ".o" (in any path).  Note that once  again,  the  shell
  1446. X     expansion  has  been inhibited with backslashes, so that zip
  1447. X     can see the asterisks. zip can then match on the contents of
  1448. X     the  zip  file instead of the contents of the current direc-
  1449. X     tory.
  1450. X
  1451. X     Under MSDOS, -d is case sensitive when it matches  names  in
  1452. X     the  zip  file.  This allows deleting names that were zipped
  1453. X     on other systems, but requires that the names be entered  in
  1454. X     upper  case  if they were zipped on an MSDOS system, so that
  1455. X     the names can be found in the zip file and deleted.
  1456. X
  1457. XMORE OPTIONS
  1458. X     As mentioned before, zip will use the best of  two  methods:
  1459. X     deflate or store.
  1460. X
  1461. X     The option -0 will force zip to use store on all files.  For
  1462. X     example:
  1463. X
  1464. X          zip -r0 foo foo
  1465. X
  1466. X     will zip up the directory foo into foo.zip using only store.
  1467. X
  1468. X     The speed of deflation can also be controlled  with  options
  1469. X     -1  (fastest  method  but  less  compression)  to  -9  (best
  1470. X     compression but slower). The default value is -5. For  exam-
  1471. X     ple:
  1472. X
  1473. X          zip -r8 foo foo
  1474. X
  1475. X     In nearly all cases, a file that is already compressed  can-
  1476. X     not  be  compressed further by zip, or if it can, the effect
  1477. X     is minimal.  The -n  option  prevents  zip  from  trying  to
  1478. X     compress files that have the given suffixes.  Such files are
  1479. X     simply stored (0% compression) in the output  zip  file,  so
  1480. X     that  zip  doesn't  waste  its time trying to compress them.
  1481. X     The suffixes are separated by either colons  or  semicolons.
  1482. X     For example:
  1483. X
  1484. X          zip -rn ".Z:.zip:.tiff:.gif:.snd"  foo foo
  1485. X
  1486. X     will put everything in foo into foo.zip, but will store  any
  1487. X     files  that  end  in  .Z, .zip, .tiff, .gif, or .snd without
  1488. X     trying to compress them.  (Image and sound files often  have
  1489. X     their own specialized compression methods.) The default suf-
  1490. X     fix list is ".Z:.zip;.zoo:.arc:.lzh:.arj".  The  environment
  1491. X     variable  ZIPOPT  can  be  used  to change this default. For
  1492. X     example under Unix with csh:
  1493. X
  1494. X          setenv ZIPOPT "-n .gif:.zip"
  1495. X
  1496. X     The variable ZIPOPT can be  used  for  any  option  and  can
  1497. X     include several options.
  1498. X
  1499. X     Under Unix and  under  OS/2  (if  files  from  an  HPFS  are
  1500. X     stored),  zip  will  store  the  full  path (relative to the
  1501. X     current path) and name of the file (or just the name  if  -j
  1502. X     is   specified)   in  the  zip  file  along  with  the  Unix
  1503. X     attributes, and it will mark the entry as made  under  Unix.
  1504. X     If  the  zip  file is intended for PKUNZIP under MSDOS, then
  1505. X     the -k (Katz) option should be used to  attempt  to  convert
  1506. X     the  names  and  paths  to  conform to MSDOS, store only the
  1507. X     MSDOS attribute (just the user write attribute  from  Unix),
  1508. X     and  mark  the  entry  as  made  under MSDOS (even though it
  1509. X     wasn't).
  1510. X
  1511. X     The -o (older) option will set the "last modified"  time  of
  1512. X     the  zip  file  to  the  latest  "last modified" time of the
  1513. X     entries in the zip file.  This can be used without any other
  1514. X     operations, if desired.  For example:
  1515. X
  1516. X          zip -o foo
  1517. X
  1518. X     will change the last modified time of foo.zip to the  latest
  1519. X     time of the entries in foo.zip.
  1520. X
  1521. X     The -e and -c options operate on all files updated or  added
  1522. X     to the zip file.  Encryption (-e) will prompt for a password
  1523. X     on the terminal and will not echo  the  password  as  it  is
  1524. X     typed (if stderr is not a TTY, zip will exit with an error).
  1525. X     New zip entries will be encrypted using that password.   For
  1526. X     added  peace of mind, you can use -ee, which will prompt for
  1527. X     the password twice, checking  that  the  two  are  the  same
  1528. X     before   using   it.  The  encryption  code  is  distributed
  1529. X     separately, so the -e option may not be  available  in  your
  1530. X     version.
  1531. X
  1532. X     One-line comments can be added for each  file  with  the  -c
  1533. X     option.   The  zip file operations (adding or updating) will
  1534. X     be done first, and you will then be prompted for a  one-line
  1535. X     comment  for each file.  You can then enter the comment fol-
  1536. X     lowed by return, or just return for no comment.
  1537. X
  1538. X     The -z option will prompt you for a multi-line  comment  for
  1539. X     the  entire zip file.  This option can be used by itself, or
  1540. X     in combination with other options.  The comment is ended  by
  1541. X     a line containing just a period, or an end of file condition
  1542. X     (^D on Unix, ^Z on MSDOS,  OS/2,  and  VAX/VMS).   Since  -z
  1543. X     reads  the lines from stdin, you can simply take the comment
  1544. X     from a file:
  1545. X
  1546. X          zip -z foo < foowhat
  1547. X
  1548. X     The -q (quiet) option eliminates the informational  messages
  1549. X     and  comment  prompts while zip is operating.  This might be
  1550. X     used in shell scripts, for example, or if the zip  operation
  1551. X     is  being  performed  as  a background task ("zip -q foo *.c
  1552. X     &").
  1553. X
  1554. X     zip can take a list of file names to operate on  from  stdin
  1555. X     using  the -@ option.  In Unix, this option can be used with
  1556. X     the find command to extend greatly the functionality of zip.
  1557. X     For example, to zip up all the C source files in the current
  1558. X     directory and its subdirectories, you can:
  1559. X
  1560. X          find . -type f -name "*.[ch]" -print | zip source -@
  1561. X
  1562. X     Note that the pattern must be quoted to keep the shell  from
  1563. X     expanding it.
  1564. X
  1565. X     Under VMS only, the -w option will append the version number
  1566. X     of  the  files  to  the name and zip up multiple versions of
  1567. X     files.  Without -w, zip will only use the most  recent  ver-
  1568. X     sion of the specified file(s).
  1569. X
  1570. X     The -l option translates the Unix end-of-line  character  LF
  1571. X     into  the  MSDOS convention CR LF. This option should not be
  1572. X     used on binary files.  This option can be used  on  Unix  if
  1573. X     the  zip  file  is  intended for PKUNZIP under MSDOS. If the
  1574. X     input files already contain CR LF, this option adds an extra
  1575. X     CR.  This  ensure  that  "unzip -a" on Unix will get back an
  1576. X     exact copy of the original file, to undo the effect of  "zip
  1577. X     -l".
  1578. X
  1579. X     If zip is run with the -h option, or with no  arguments  and
  1580. X     standard  output is a terminal, the license and the command-
  1581. X     argument and option help is shown.  The -L option just shows
  1582. X     the license.
  1583. X
  1584. XABOUT PATTERN MATCHING
  1585. X     (Note: this section applies to Unix.  Watch this  space  for
  1586. X     details on MSDOS and VMS operation.)
  1587. X
  1588. X     The Unix shell (sh or csh)  does  filename  substitution  on
  1589. X     command  arguments.   The  special  characters  are ?, which
  1590. X     matches any single character; * which matches any number  of
  1591. X     characters  (including none); and [] which matches any char-
  1592. X     acter in the  range  inside  the  brackets  (like  [a-f]  or
  1593. X     [0-9]).   When  these  characters  are  encountered (and not
  1594. X     escaped with a backslash or quotes), the shell will look for
  1595. X     files  relative  to the current path that match the pattern,
  1596. X     and replace the argument with  a  list  of  the  names  that
  1597. X     matched.
  1598. X
  1599. X     zip can do the same matching on names that are  in  the  zip
  1600. X     file  being  modified  or,  in  the case of the -x (exclude)
  1601. X     option, on the list of files to be  operated  on,  by  using
  1602. X     backslashes  or  quotes to tell the shell not to do the name
  1603. X     expansion.  In general, when zip encounters a  name  in  the
  1604. X     list of files to do, it first looks for the name in the file
  1605. X     system.  If it finds it, it then adds  it  to  the  list  of
  1606. X     files  to  do.  If it does not find it, it will look for the
  1607. X     name in the zip file being modified (if  it  exists),  using
  1608. X     the  pattern  matching  characters  above, if any.  For each
  1609. X     match, it will add that name to the list  of  files  to  do.
  1610. X     After  -x  (exclude),  the  names are removed from the to-do
  1611. X     list instead of added.
  1612. X
  1613. X     The pattern matching includes the path, and so patterns like
  1614. X     \*.o  match  names that end in ".o", no matter what the path
  1615. X     prefix is.  Note that the backslash must precede every  spe-
  1616. X     cial  character  (i.e. ?*[]), or the entire argument must be
  1617. X     enclosed in double quotes ("").
  1618. X
  1619. X     In general, using backslash  to  make  zip  do  the  pattern
  1620. X     matching  is  used  with  the  -f  (freshen) and -d (delete)
  1621. X     options, and sometimes after the -x  (exclude)  option  when
  1622. X     used  with  any  operation  (add,  -u, -f, or -d).  zip will
  1623. X     never use pattern matching to search the  file  system.   If
  1624. X     zip has recursed into a directory, all files (and all direc-
  1625. X     tories) in there are fair game.
  1626. X
  1627. XCOPYRIGHT
  1628. X     Copyright (C) 1990-1992 Mark Adler, Richard B. Wales,  Jean-
  1629. X     loup  Gailly, Kai Uwe Rommel and Igor Mandrichenko.  Permis-
  1630. X     sion is granted to any individual  or  institution  to  use,
  1631. X     copy,  or  redistribute  this software so long as all of the
  1632. X     original files are included unmodified, that it is not  sold
  1633. X     for profit, and that this copyright notice is retained.
  1634. X
  1635. XACKNOWLEDGEMENTS
  1636. X     Thanks to R. P.  Byrne  for  his  Shrink.Pas  program  which
  1637. X     inspired  this project; to Phil Katz for making the zip file
  1638. X     format, compression format, and .zip filename extension  all
  1639. X     public  domain;  to  Steve  Burg  and  Phil Katz for help on
  1640. X     unclear points of the deflate format; to Keith Petersen  and
  1641. X     Rich Wales for providing a mailing list and ftp site for the
  1642. X     INFO-ZIP group to use; and most importantly, to the INFO-ZIP
  1643. X     group  itself (listed in the file infozip.who) without whose
  1644. X     tireless testing and bug-fixing efforts a portable zip would
  1645. X     not have been possible.  Finally we should thank (blame) the
  1646. X     INFO-ZIP moderator, David Kirschbaum  for  getting  us  into
  1647. X     this mess in the first place.
  1648. X
  1649. XSEE ALSO
  1650. X     unzip(1), tar(1), compress(1)
  1651. X
  1652. XBUGS
  1653. X     WARNING: zip files produced by this version of zip must  not
  1654. X     be  *updated*  by  zip  1.0 or pkzip 1.10 or pkzip 1.93a, if
  1655. X     they contain encrypted members, or if they  have  been  pro-
  1656. X     duced  in  a  pipe or on a non seekable device. The old ver-
  1657. X     sions of zip or pkzip would destroy the zip  structure.  The
  1658. X     old  versions can list the contents of the zip file but can-
  1659. X     not extract it anyway (because of the new compression  algo-
  1660. X     rithm).   If  you do not use encryption and use regular disk
  1661. X     files, you do not have to care about this problem.
  1662. X
  1663. X     zip 1.9 is compatible with  pkzip  1.93a,  except  when  two
  1664. X     features  are used: encryption or zip file created in a pipe
  1665. X     or on a non seekable device. pkzip versions above  2.0  will
  1666. X     support such files, and unzip 5.0 already supports them.
  1667. X
  1668. X     Without -y, when zip must compress a symbolic link to an non
  1669. X     existing   file,  it  only  displays  a  warning  "name  not
  1670. X     matched". A better warnign should be given.
  1671. X
  1672. X     Under VMS, not all of the odd file formats are treated prop-
  1673. X     erly.   Only  zip files of format stream-LF and fixed length
  1674. X     512 are expected to work with zip.  Others can be  converted
  1675. X     using  Rahul Dhesi's BILF program.  This version of zip does
  1676. X     handle some of the conversion internally.  When using Kermit
  1677. X     to transfer zip files from Vax to MSDOS, type "set file type
  1678. X     block" on the Vax.  When transfering from MSDOS to Vax, type
  1679. X     "set  file type fixed" on the Vax.  In both cases, type "set
  1680. X     file type binary" on MSDOS.
  1681. X
  1682. X     Under VMS, zip hangs for file specification that uses DECnet
  1683. X     syntax (foo::*.*).
  1684. X
  1685. X     Under OS/2, the amount of External Attributes  displayed  by
  1686. X     DIR is (for compatibility) the amount returned by the 16-bit
  1687. X     version of DosQueryPathInfo(). Otherwise OS/2  1.3  and  2.0
  1688. X     would  report  different  EA sizes when DIRing a file.  How-
  1689. X     ever,  the  structure  layout   returned   by   the   32-bit
  1690. X     DosQueryPathInfo() is a bit different, it uses extra padding
  1691. X     bytes and link pointers (it's a linked  list)  to  have  all
  1692. X     fields  on  4-byte boundaries for portability to future RISC
  1693. X     OS/2 versions. Therefore the value reported  by  ZIP  (which
  1694. X     uses  this  32-bit-mode  size) differs from that reported by
  1695. X     DIR.  ZIP stores the 32-bit format for portability, even the
  1696. X     16-bit  MS-C-compiled  version  running on OS/2 1.3, so even
  1697. X     this one shows the 32-bit-mode size.
  1698. X
  1699. X     LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTIL-
  1700. X     ITIES  ARE  PROVIDED  AS IS AND COME WITH NO WARRANTY OF ANY
  1701. X     KIND, EITHER EXPRESSED OR IMPLIED.  IN  NO  EVENT  WILL  THE
  1702. X     COPYRIGHT  HOLDERS  BE LIABLE FOR ANY DAMAGES RESULTING FROM
  1703. X     THE USE OF THIS SOFTWARE.
  1704. X
  1705. X     That having been said, please send any problems or  comments
  1706. X     via email to the Internet address zip-bugs@cs.ucla.edu.  For
  1707. X     bug reports, please include the version  of  zip,  the  make
  1708. X     options  you  used  to compile it, the machine and operating
  1709. X     system you are using, and as much additional information  as
  1710. X     possible.  Thank you for your support.
  1711. END_OF_FILE
  1712.   if test 23559 -ne `wc -c <'zip.doc'`; then
  1713.     echo shar: \"'zip.doc'\" unpacked with wrong size!
  1714.   fi
  1715.   # end of 'zip.doc'
  1716. fi
  1717. echo shar: End of archive 4 \(of 11\).
  1718. cp /dev/null ark4isdone
  1719. MISSING=""
  1720. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1721.     if test ! -f ark${I}isdone ; then
  1722.     MISSING="${MISSING} ${I}"
  1723.     fi
  1724. done
  1725. if test "${MISSING}" = "" ; then
  1726.     echo You have unpacked all 11 archives.
  1727.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1728. else
  1729.     echo You still must unpack the following archives:
  1730.     echo "        " ${MISSING}
  1731. fi
  1732. exit 0
  1733. exit 0 # Just in case...
  1734.