home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume23 / zip / part06 < prev    next >
Text File  |  1991-10-21  |  55KB  |  1,586 lines

  1. Newsgroups: comp.sources.misc
  2. From: kirsch@usasoc.soc.mil (David Kirschbaum)
  3. Subject:  v23i093:  zip - Portable zip v1.0, Part06/09
  4. Message-ID: <1991Oct21.042200.8119@sparky.imd.sterling.com>
  5. X-Md4-Signature: 003d705b369a9b2db49a54f526e80aa5
  6. Date: Mon, 21 Oct 1991 04:22:00 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
  10. Posting-number: Volume 23, Issue 93
  11. Archive-name: zip/part06
  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:  Contents zip.1 zip.c
  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 6 (of 9)."'
  24. if test -f 'Contents' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'Contents'\"
  26. else
  27.   echo shar: Extracting \"'Contents'\" \(3587 characters\)
  28.   sed "s/^X//" >'Contents' <<'END_OF_FILE'
  29. XCopyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  30. XPermission is granted to any individual or institution to use, copy, or
  31. Xredistribute this software so long as all of the original files are included
  32. Xunmodified, that it is not sold for profit, and that this copyright notice
  33. Xis retained.
  34. X
  35. XThis file is a complete list of files mentioned in the above copyright.  Some
  36. Xof the files in this list explicitly state in their text that they are public
  37. Xdomain or not copyrighted.  These files can be distributed separately and are
  38. Xmarked below with asterisks.
  39. X
  40. Xfile            what it is
  41. X----            ----------
  42. Xcontents        This file.
  43. Xcrypt.c         Code for encryption and decryption (not in export version).
  44. Xcrypt.h         Header used in implode modules to access encryption routines.
  45. Xdir_os2.c       * Directory routines for OS/2.
  46. Xdir_os2.h       * Definitions of functions in dir_os2.c.
  47. Xdoturboc.bat    Batch file for compiling under Turbo C 2.0.
  48. Xfileio.c        System dependent routines (most of them anyway).
  49. Xglobals.c       Global variables.
  50. Xhistory         List of changes in the versions leading up to this one.
  51. Xim_bits.c       Output variable-length bit strings.
  52. Xim_ctree.c      Encode source values using variable-length binary code trees.
  53. Xim_lm.asm       An 80x86 assembler version of a routine in im_lmat.c.
  54. Xim_lmat.c       Find redundant text in a sliding window.
  55. Ximplode.c       Implode compression method (calls other im* modules).
  56. Ximplode.h       Definitions of functions external to the im* modules.
  57. Xinfozip.who     List of contributors to the portable Zip project.
  58. Xmakecrc.c       * Generate the CRC table in util.c and shrink.c.
  59. Xmakefile        Unix make file.
  60. Xmakefile.bor    MSDOS Borland C++ make file.
  61. Xmakefile.exp    Export make file (leaves out encryption and zipcloak).
  62. Xmakefile.msc    MSDOS Microsoft C make file.
  63. Xmakefile.os2    OS/2 make file.
  64. Xmakefile.pwc    Power C make file.
  65. Xmakevms.com     VMS command file for compilation.
  66. Xreadme          Short file to point to zip.doc.
  67. Xrevision.h      Contains the program version number and revision date.
  68. Xship.c          * Encodes a binary stream into a mailable text stream.
  69. Xship.def        OS/2 def file for Ship.
  70. Xshrink.c        Shrink compression method.
  71. Xtailor.h        * Tailors the compilation to the system being compiled on.
  72. Xtempf.c         Temporary memory/file interface.
  73. Xtempf.h         Definitions of functions in tempf.c.
  74. Xutil.c          Miscellaneous utility routines.
  75. Xzip.1           Source for the Zip man page (zip.doc).
  76. Xzip.c           Main routine for Zip.
  77. Xzip.def         OS/2 def file for Zip.
  78. Xzip.doc         Documentation for Zip (zip.1 processed).
  79. Xzip.h           Header for all Zip modules.
  80. Xzip.prj         Project file for Borland (Turbo) C++.
  81. Xzipcloak.c      Main routine for ZipCloak.
  82. Xziperr.h        Error messages in Zip.
  83. Xzipfile.c       Zip file format handler.
  84. Xzipnote.c       Main routine for ZipNote.
  85. Xzipsplit.c      Main routine for ZipSplit.
  86. Xzipup.c         Applies shrink and/or implode methods to compress an entry.
  87. X
  88. XAll of the files are in Unix (LF only) format execpt for the documentation
  89. Xfiles, zip.prj, and doturboc.bat.  On MSDOS systems, you can use the -a
  90. Xoption of unzip to convert the source files to CRLF format.  This is only
  91. Xnecessary if you wish to edit the files--they will compile as is with
  92. XMicrosoft C and Turbo/Borland C++ 1.0 or later.  However, you will have to
  93. Xconvert the files (using unzip -a) to the CRLF format to compile with the
  94. Xolder Turbo C 1.0 or 2.0.  You should be able to find unzip the same place
  95. Xyou found this.
  96. END_OF_FILE
  97.   if test 3587 -ne `wc -c <'Contents'`; then
  98.     echo shar: \"'Contents'\" unpacked with wrong size!
  99.   fi
  100.   # end of 'Contents'
  101. fi
  102. if test -f 'zip.1' -a "${1}" != "-c" ; then 
  103.   echo shar: Will not clobber existing file \"'zip.1'\"
  104. else
  105.   echo shar: Extracting \"'zip.1'\" \(21611 characters\)
  106.   sed "s/^X//" >'zip.1' <<'END_OF_FILE'
  107. X.\" Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  108. X.\" Permission is granted to any individual or institution to use, copy, or
  109. X.\" redistribute this software so long as all of the original files are included
  110. X.\" unmodified, that it is not sold for profit, and that this copyright notice
  111. X.\" is retained.
  112. X.\"
  113. X.\" zip.1 by Mark Adler.
  114. X.\"
  115. X.TH ZIP 1
  116. X.SH NAME
  117. Xzip \- package and compress (archive) files
  118. X.SH SYNOPSIS
  119. X.B zip
  120. X[
  121. X.B \-cdefghijklmnoqrsuwyz
  122. X] [
  123. X.B \-b
  124. Xpath ] [
  125. X.B \-t
  126. Xmmddyy ] zipfile list [
  127. X.B \-x
  128. Xlist ]
  129. X.br
  130. X.SH DESCRIPTION
  131. X.I Zip
  132. Xis a compression and file packaging utility for Unix, MSDOS, OS/2, and VMS.
  133. XIt is
  134. Xanalogous to a combination of tar and compress and is compatible with PKZIP
  135. X(Phil Katz ZIP) for MSDOS systems.
  136. X.PP
  137. XThere is a companion to
  138. X.I Zip
  139. Xcalled
  140. X.I UnZip
  141. X(of course) which you should be able
  142. Xto find the same place you got
  143. X.I Zip.  Zip
  144. Xand
  145. X.I UnZip
  146. Xcan work with files
  147. Xproduced by PKZIP under MSDOS, and PKZIP and PKUNZIP can work with files
  148. Xproduced by
  149. X.I Zip.
  150. X.PP
  151. X.I Zip
  152. Xputs one or more compressed files into a single "zip file" along with
  153. Xinformation about the files, including the name, path if requested, date
  154. Xand time last modified, protection, and check information to verify the
  155. Xfidelity of each entry.
  156. X.I Zip
  157. Xcan pack an entire directory structure in a
  158. Xzip file with a single command.  Compression ratios of 2:1 to 3:1 are
  159. Xcommon for text files.
  160. X.I Zip
  161. Xhas two compression methods, implosion and
  162. Xshrinking, and automatically chooses the better of the two for each file
  163. Xto be compressed.
  164. X.PP
  165. X.I Zip
  166. Xis useful for packaging a set of files to send to someone or for
  167. Xdistribution; for archiving or backing up files; and for saving disk space by temporarily
  168. Xcompressing unused files or directories.
  169. X.SH "HOW TO INSTALL ZIP"
  170. X.I Zip
  171. Xis distributed as C source code that can be compiled on a wide range of
  172. XUnix machines, VAXes running VMS, and MSDOS machines using
  173. XMicrosoft or Borland C++, and OS/2 machines using Microsoft C.
  174. XYou will
  175. Xneed Unzip (under Unix, MSDOS, or VMS) or PKUNZIP (under MSDOS) to unpack the
  176. Xdistribution file, zip10.zip.
  177. X.PP
  178. XFirst, unpack the source as follows, assuming that you
  179. Xhave zip10.zip in the current directory:
  180. X.PP
  181. X.ti+5n
  182. Xmkdir zipsrc
  183. X.ti+5n
  184. Xcd zipsrc
  185. X.ti+5n
  186. Xunzip ../zip10
  187. X.PP
  188. XThis extracts all source files and documentation in the directory called
  189. X"zipsrc". You then do:
  190. X.PP
  191. X.ti+5n
  192. Xmake system
  193. X.PP
  194. Xwhere "system" is one of: bsd, bsdold, sysv, next, next10, sun, hpux, dnix,
  195. Xcray, 3b1, zilog, aux, convex, aix, or minix.  If you are using a NeXT
  196. Xrunning version
  197. X2.0 or greater, then make next.  If you are using 1.0, then make
  198. Xnext10.  If you
  199. Xare using Sun OS 4.x, then make sun.  If you are using HPUX, then make hpux.
  200. XThe other special systems are DNIX 5.2 or 5.3, Cray Unicos,
  201. XAT&T 3B1 (also known as Unix PC or PC 7300), Zilog Zeus, A/UX, Convex, AIX,
  202. Xand MINIX.
  203. XOtherwise, if you are using BSD Unix, try bsd.  If the linker cannot find
  204. X_memset or _memcpy, try bsdold.  If you are using System V Unix or SCO Unix,
  205. Xtry sysv.  Also use sysv on a Silicon Graphics (SGI) machine.
  206. XYou can also cross-compile
  207. X.I Zip
  208. Xfor MSDOS under SCO 386 Unix using "make scodos".
  209. X.PP
  210. XIf none of these compiles, links, and functions properly on your Unix system,
  211. Xsee the section BUGS below for how to get help.
  212. X.PP
  213. XIf the appropriate system was selected, then the executable "zip" will be
  214. Xcreated.  You can move the executable "zip" to an appropriate directory
  215. Xin the search path using a command like:
  216. X.PP
  217. X.ti+5n
  218. Xmv zip ~/bin
  219. X.PP
  220. Xor
  221. X.PP
  222. X.ti+5n
  223. Xmv zip /usr/local/bin
  224. X.PP
  225. XYou can use the command "set" to see the current search path.  If you are
  226. Xusing the C-Shell (csh), enter the command:
  227. X.PP
  228. X.ti+5n
  229. Xrehash
  230. X.PP
  231. Xso csh can find the new command in the path.  You are now ready to use
  232. X.I Zip.
  233. X.PP
  234. XYou can also move the manual page (the raw form of what you're reading)
  235. Xto where the Unix man command can find it (assuming you have the necessary
  236. Xprivileges):
  237. X.PP
  238. X.ti+5n
  239. Xmv zip.1 /usr/man/man1
  240. X.PP
  241. XYou can get rid of the now unnecessary source and object files with:
  242. X.PP
  243. X.ti+5n
  244. Xcd ..
  245. X.ti+5n
  246. Xrm -r zipsrc
  247. X.PP
  248. XThis will remove the directory zip and its contents created by unzip.
  249. XYou should keep the zip10.zip file around though, in case you
  250. Xneed to build it again or want to give it to a colleague.
  251. X.PP
  252. XThe steps for installation under MSDOS, OS/2, and VMS are similar to the above:
  253. Xfirst unzip the distribution files into their own directory.  Then under
  254. XMSDOS do one of:
  255. X.PP
  256. X.ti+5n
  257. Xmake makefile.msc
  258. X.ti+5n
  259. Xmake -fmakefile.bor
  260. X.PP
  261. Xfor Microsoft or Borland C++, respectively.  Under OS/2:
  262. X.PP
  263. X.ti+5n
  264. Xnmake -f makefile.os2
  265. X.PP
  266. Xfor Microsoft C 6.00.  Under VAX VMS:
  267. X.PP
  268. X.ti+5n
  269. X@makevms
  270. X.PP
  271. XThe installation process will also compile and link several
  272. Xother utilities.  They are zipcloak for encrypting and decrypting zip files,
  273. Xzipnote for editing zip file comments, zipsplit for splitting a zip file
  274. Xinto several zip files, and ship for sending zip files or any other binary
  275. Xfile via electronic mail.  For command help on any of the zip* utilities,
  276. Xsimply enter the name with no arguments.  For help with ship, enter "ship -h".
  277. X.SH "HOW TO USE ZIP"
  278. XThe simplest use of
  279. X.I Zip
  280. Xis as follows:
  281. X.PP
  282. X.ti+5n
  283. Xzip stuff *
  284. X.PP
  285. XThis will create the file "stuff.zip" (assuming it does not exist) and put
  286. Xall the files in the current directory in stuff.zip in a compressed form.
  287. XThe .zip suffix is added automatically, unless that file name given contains
  288. Xa dot already.  This allows specifying suffixes other than ".zip".
  289. X.PP
  290. XBecause of the way the shell does filename substitution, files that start
  291. Xwith a "." are not included.  To include those as well, you can:
  292. X.PP
  293. X.ti+5n
  294. Xzip stuff .* *
  295. X.PP
  296. XEven this will not include any subdirectories that are in the current
  297. Xdirectory.  To zip up an entire directory, the command:
  298. X.PP
  299. X.ti+5n
  300. Xzip -r foo foo
  301. X.PP
  302. Xwill create the file "foo.zip" containing all the files and directories in
  303. Xthe directory "foo" that is in the current directory.  The "r" option means
  304. Xrecurse through the directory structure.  In this case, all the
  305. Xfiles and directories in foo are zipped, including the ones that start with
  306. Xa ".", since the recursion does not use the shell's file-name substitution.
  307. XYou should not use -r with the name ".*", since that matches ".." which will
  308. Xattempt to zip up the parent directory--probably not what was intended.
  309. X.PP
  310. XYou may want to make a zip file that contains the files in foo, but not record
  311. Xthe directory name, foo.  You can use the -j (junk path) option to leave off
  312. Xthe path:
  313. X.PP
  314. X.ti+5n
  315. Xzip -j foo foo/*
  316. X.PP
  317. XThe -y option (only under Unix) will store symbolic links as such in the
  318. Xzip file, instead of compressing and storing the file referred to in the link.
  319. X.PP
  320. XYou might be zipping to save disk space, in which case you could:
  321. X.PP
  322. X.ti+5n
  323. Xzip -rm foo foo
  324. X.PP
  325. Xwhere the "m" option means "move".  This will delete foo and its contents
  326. Xafter making foo.zip.  No deletions will be done until the zip has completed
  327. Xwith no errors.  This option is obviously more dangerous and should be
  328. Xused with care.
  329. X.PP
  330. XIf the zip file already exists, these commands will replace existing or add
  331. Xnew entries to the zip file.  For example, if you were really short on disk
  332. Xspace, you might not have enough room simultaneously to hold the directory
  333. Xfoo and the compressed foo.zip.  In this case, you could do it in steps.  If
  334. Xfoo contained the subdirectories tom, dick, and harry, then you could:
  335. X.PP
  336. X.ti+5n
  337. Xzip -rm foo foo/tom
  338. X.ti+5n
  339. Xzip -rm foo foo/dick
  340. X.ti+5n
  341. Xzip -rm foo foo/harry
  342. X.PP
  343. Xwhere the first command would create foo.zip, and the next two would add to
  344. Xit.  At the completion of each zip command, the directory just zipped would
  345. Xbe deleted, making room in which the next
  346. X.I Zip
  347. Xcommand could work.
  348. X.SH "MODIFYING EXISTING ZIP FILES"
  349. XWhen given the name of an existing zip file with the above commands,
  350. X.I Zip
  351. Xwill replace identically named entries in the
  352. X.I Zip
  353. Xfile or add entries for
  354. Xnew names.  For example, if foo.zip exists and contains foo/file1 and
  355. Xfoo/file2, and the directory foo contains the files foo/file1 and foo/file3,
  356. Xthen:
  357. X.PP
  358. X.ti+5n
  359. Xzip -r foo foo
  360. X.PP
  361. Xwill replace foo/file1 in foo.zip and add foo/file3 to foo.zip.  After
  362. Xthis, foo.zip contains foo/file1, foo/file2, and foo/file3, with foo/file2
  363. Xunchanged from before.
  364. X.PP
  365. XWhen changing an existing zip file,
  366. X.I Zip
  367. Xwill write a temporary file with
  368. Xthe new contents, and only replace the old one when the zip has completed
  369. Xwith no errors.  Also, the two methods, shrink and implode, create
  370. Xtemporary files that are deleted after each file is zipped.  You can use
  371. Xthe -b option to specify a different path (usually a different device) to
  372. Xput the temporary files in.  For example:
  373. X.PP
  374. X.ti+5n
  375. Xzip -b /tmp stuff *
  376. X.PP
  377. Xwill put the temporary zip file and the temporary compression files in the
  378. Xdirectory "/tmp", copying over stuff.zip in the current directory when
  379. Xdone.
  380. X.PP
  381. XIf you are only adding entries to a zip file, not replacing, and the
  382. X-g option is given, then
  383. X.I Zip
  384. Xgrows (appends to) the file instead of copying it.  The danger of this is that
  385. Xif the operation fails, the original zip file is corrupted and lost.
  386. X.PP
  387. XThere are two other ways to change or add entries in a zip file that are
  388. Xrestrictions of simple addition or replacement.  The first is -u (update)
  389. Xwhich will add new entries to the zip file as before but will replace
  390. Xexisting entries only if the modified date of the file is more recent than
  391. Xthe date recorded for that name in the zip file.  For example:
  392. X.PP
  393. X.ti+5n
  394. Xzip -u stuff *
  395. X.PP
  396. Xwill add any new files in the current directory, and update any changed files
  397. Xin the zip file stuff.zip.  Note that
  398. X.I Zip
  399. Xwill not try to pack stuff.zip into
  400. Xitself when you do this. 
  401. X.I Zip
  402. Xwill always exclude the zip file from the files on which to be operated.
  403. X.PP
  404. XThe second restriction is -f (freshen) which, like update, will only replace
  405. Xentries with newer files; unlike update, will not add files that are not
  406. Xalready in the zip file.  For this option, you may want to simply freshen all
  407. Xof the files that are in the specified zip file.  To do this you would simply:
  408. X.PP
  409. X.ti+5n
  410. Xzip -f foo
  411. X.PP
  412. XNote that the -f option with no arguments freshens all the entries in the
  413. Xzip file.  The same is true of -u, and hence "zip -u foo" and "zip -f foo"
  414. Xboth do the same thing.
  415. X.PP
  416. XThis command should
  417. Xbe run from the same directory from which the original zip command was run,
  418. Xsince paths stored in zip files are always relative.
  419. X.PP
  420. XAnother restriction that can be used with adding, updating, or freshening is
  421. X-t (time), which will not operate on files modified earlier than the specified
  422. Xdate.  For example:
  423. X.PP
  424. X.ti+5n
  425. Xzip -rt 120791 infamy foo
  426. X.PP
  427. Xwill add all the files in foo and its subdirectories that were last modified
  428. Xon December 7, 1991, or later to the zip file infamy.zip.
  429. X.PP
  430. XAlso, files can be explicitly excluded using the -x option:
  431. X.PP
  432. X.ti+5n
  433. Xzip -r foo foo -x \\*.o
  434. X.PP
  435. Xwhich will zip up the contents of foo into foo.zip but exclude all the
  436. Xfiles that end in ".o".  Here the backslash causes
  437. X.I Zip
  438. Xto match file names
  439. Xthat were found when foo was searched.
  440. X.PP
  441. XThe last operation is -d (delete) which will remove entries from a zip file.
  442. XAn example might be:
  443. X.PP
  444. X.ti+5n
  445. Xzip -d foo foo/tom/junk foo/harry/\\* \\*.o
  446. X.PP
  447. Xwhich will remove the entry foo/tom/junk, all of the files that start with
  448. X"foo/harry/", and all of the files that end with ".o" (in any path).  Note
  449. Xthat once again, the shell expansion has been inhibited with backslashes, so
  450. Xthat
  451. X.I Zip
  452. Xcan see the asterisks.  
  453. X.I Zip
  454. Xcan then match on the contents of the zip
  455. Xfile instead of the contents of the current directory.
  456. X.PP
  457. XUnder MSDOS, -d is case sensitive when it matches names in the zip file.
  458. XThis allows deleting names that were zipped on other systems, but requires
  459. Xthat the names be entered in upper case if they were zipped on an MSDOS
  460. Xsystem, so that the names can be found in the zip file and deleted.
  461. X.SH "MORE OPTIONS"
  462. XAs mentioned before,
  463. X.I Zip
  464. Xwill use the best of two methods: shrink or implode.
  465. XUsually implode is better, but sometimes shrink is better, especially for
  466. Xsmaller files.  Sometimes neither method produces a packed version smaller
  467. Xthan the original file, in which case it is stored in the zip file with no
  468. Xcompression (called the "store" method).
  469. X.PP
  470. XThe option -s (shrink) will force
  471. X.I Zip
  472. Xalways to use shrink or store, and the
  473. X-i (implode) option forces
  474. X.I Zip
  475. Xto use implode or store.  Shrinking is faster
  476. Xthan imploding, and so -s might be used when speed is more important than
  477. Xoptimal compression.  Implode only (-i) might be used when the unzipper 
  478. Xfor which the
  479. Xzip file is destined can only handle implosion.  An example of this is
  480. Xthe PKSFXjr program that comes with PKZIP.  Also, -i is slightly faster
  481. Xthan imploding and shrinking at the same time.  For example:
  482. X.PP
  483. X.ti+5n
  484. Xzip -rs foo foo
  485. X.PP
  486. Xwill zip up the directory foo into foo.zip using only shrink or store.
  487. XThe speed of implosion can also be controlled with options -0 (fastest
  488. Xmethod but less compression) to -9 (best compression but slower). The
  489. Xdefault value is -5. For example:
  490. X.PP
  491. X.ti+5n
  492. Xzip -r0 foo foo
  493. X.PP
  494. XIn nearly all cases, a file that is already compressed cannot be compressed
  495. Xfurther by
  496. X.I Zip,
  497. Xor if it can, the effect is minimal.  The -n option prevents
  498. X.I Zip
  499. Xfrom trying to compress files that have the suffixes: .Z, .zip, .zoo,
  500. Xor .arc.  Such files are simply stored (0% compression) in the output zip file,
  501. Xso that
  502. X.I Zip
  503. Xdoesn't waste its time trying to compress them.
  504. XIf the environment variable NOZIP is set, then the suffixes listed
  505. Xthere are used instead of the default list.  The suffixes are separated by
  506. Xeither colons or semicolons.  For example, in Unix csh:
  507. X.PP
  508. X.ti+5n
  509. Xsetenv NOZIP .Z:.zip:.tiff:.gif:.snd
  510. X.ti+5n
  511. Xzip -rn foo foo
  512. X.PP
  513. Xwill put everything in foo into foo.zip, but will store any files that end
  514. Xin .Z, .zip, .tiff, .gif, or .snd without trying to compress them.  (Image
  515. Xand sound files often have their own specialized compression methods.)  If
  516. Xthe environment variable NOZIP exists but is empty or contains just a colon
  517. Xor semicolon, then zip -n will store all the entries and do no compression.
  518. X.PP
  519. XUnder Unix and under OS/2 (if files from a HPFS are stored),
  520. X.I Zip
  521. Xwill store the full path (relative to the current path) and name of the
  522. Xfile (or just the name if -j is specified) in the zip file along with the
  523. XUnix attributes, and it will mark
  524. Xthe entry as made under Unix.  If the zip file is intended for PKUNZIP under
  525. XMSDOS, then the -k (Katz) option should be used to attempt to convert the
  526. Xnames and paths to conform to MSDOS, store only the MSDOS attribute (just
  527. Xthe user write attribute from Unix), and mark the entry as made under MSDOS
  528. X(even though it wasn't).
  529. X.PP
  530. XThe -o (older) option will set the "last modified" time of the zip file to
  531. Xthe latest "last modified" time of the entries in the zip file.  This can
  532. Xbe used without any other operations, if desired.  For example:
  533. X.PP
  534. X.ti+5n
  535. Xzip -o foo
  536. X.PP
  537. Xwill change the last modified time of foo.zip to the latest time of the
  538. Xentries in foo.zip.
  539. X.PP
  540. XThe -e and -c options operate on all files updated or added to the zip file.
  541. XEncryption (-e) will prompt for a password on the terminal and will
  542. Xnot echo the password as it is typed (if stderr is not a TTY, Zip will exit
  543. Xwith an error).  New zip entries will be encrypted using that password.  For
  544. Xadded peace of mind, you can use -ee, which will prompt for the password
  545. Xtwice, checking that the two are the same before using it.
  546. X.PP
  547. XOne-line comments can be added for each file with the -c option.  The zip
  548. Xfile operations (adding or updating) will be done first, and you will then be
  549. Xprompted for a one-line comment for each file.  You can then enter the comment
  550. Xfollowed by return, or just return for no comment.
  551. X.PP
  552. XThe -z option will prompt you for a multi-line comment for the entire zip
  553. Xfile.  This option can be used by itself, or in combination with other
  554. Xoptions.  The comment is ended by a line containing just a period, or an end
  555. Xof file condition (^D on Unix, ^Z on MSDOS, OS/2, and VAX/VMS).
  556. XSince -z reads the
  557. Xlines from stdin, you can simply take the comment from a file:
  558. X.PP
  559. X.ti+5n
  560. Xzip -z foo < foowhat
  561. X.PP
  562. XThe -q (quiet) option eliminates the informational messages and comment prompts
  563. Xwhile
  564. X.I Zip
  565. Xis operating.  This might be used in shell scripts, for example, or if the
  566. Xzip operation is being performed as a background task ("zip -q foo *.c &").
  567. X.PP
  568. X.I Zip
  569. Xcan take a list of file names to operate on from stdin using the - option.
  570. XIn Unix, this option can be used with the find command to extend greatly
  571. Xthe functionality of
  572. X.I Zip.
  573. XFor example, to zip up all the C source files in the current directory and
  574. Xits subdirectories, you can:
  575. X.PP
  576. X.ti+5n
  577. Xfind . -type f -name "*.[ch]" -print | zip source -
  578. X.PP
  579. XNote that the pattern must be quoted to keep the shell from expanding it.
  580. X.PP
  581. XUnder VMS only, the -w option will append the version number of the files to
  582. Xthe name and zip up multiple versions of files.  Without -w,
  583. X.I Zip
  584. Xwill only use the most recent version of the specified file(s).
  585. X.PP
  586. XIf
  587. X.I Zip
  588. Xis run with no arguments or with the -h option, the license and the
  589. Xcommand-argument and option help is shown.  The -l option just shows the
  590. Xlicense.
  591. X.SH "ABOUT PATTERN MATCHING"
  592. X(Note: this section applies to Unix.  Watch this space for details on MSDOS
  593. Xand VMS operation.)
  594. X.PP
  595. XThe Unix shell (sh or csh) does filename substitution on command arguments.
  596. XThe special characters are ?, which matches any single character; * which
  597. Xmatches any number of characters (including none); and [] which matches any
  598. Xcharacter in the range inside the brackets (like [a\-f] or [0\-9]).  When
  599. Xthese characters are encountered (and not escaped with a backslash or
  600. Xquotes), the
  601. Xshell will look for files relative to the current path that match the
  602. Xpattern, and replace the argument with a list of the names that matched.
  603. X.PP
  604. X.I Zip
  605. Xcan do the same matching on names that are in the zip file being
  606. Xmodified or, in the case of the -x (exclude) option, on the list of
  607. Xfiles to be operated on, by using backslashes or quotes
  608. Xto tell the shell not to do the name expansion.  In general, when
  609. X.I Zip
  610. Xencounters a name in the list
  611. Xof files to do, it first looks for the name in the file system.  If it
  612. Xfinds it, it then adds it to the list of files to do.  If it does not
  613. Xfind it, it will look for the name in the zip file being modified (if it
  614. Xexists), using the pattern matching characters above, if any.  For each
  615. Xmatch, it will add that name to the list of files to do.  After -x
  616. X(exclude), the names are removed from the to-do list instead of added.
  617. X.PP
  618. XThe pattern matching includes the path, and so patterns like \\*.o match
  619. Xnames that end in ".o", no matter what the path prefix is.  Note that the
  620. Xbackslash must precede every special character (i.e. ?*[]), or the entire
  621. Xargument must be enclosed in double quotes ("").
  622. X.PP
  623. XIn general, using backslash to make
  624. X.I Zip
  625. Xdo the pattern matching is used
  626. Xwith the -f (freshen) and -d (delete) options, and sometimes after the
  627. X-x (exclude) option when used with any operation (add, -u, -f, or -d).
  628. X.I Zip
  629. Xwill never use pattern matching to search the file system.  If
  630. X.I Zip
  631. Xhas recursed into a directory, all files (and all directories) in there
  632. Xare fair game.
  633. X.SH COPYRIGHT
  634. XCopyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  635. XPermission is granted to any individual or institution to use, copy, or
  636. Xredistribute this software so long as all of the original files are included
  637. Xunmodified, that it is not sold for profit, and that this copyright notice
  638. Xis retained.
  639. X.SH ACKNOWLEDGEMENTS
  640. XThanks to R. P. Byrne for his Shrink.Pas program which inspired this project,
  641. Xand from which the shrink algorithm was stolen; to Phil Katz for making the zip
  642. Xfile format, compression format, and .ZIP filename extension all public domain;
  643. Xto Keith Petersen for providing a mailing list and ftp site for the INFO-ZIP
  644. Xgroup to use; and most importantly, to the INFO-ZIP group itself (listed in
  645. Xthe file infozip.who) without whose tireless testing and bug-fixing efforts
  646. Xa portable
  647. X.I Zip
  648. Xwould not have been possible.  Finally we should thank (blame) the INFO-ZIP
  649. Xmoderator, David Kirschbaum for getting us into this mess in the first place.
  650. X.SH "SEE ALSO"
  651. Xunzip(1), tar(1), compress(1)
  652. X.SH BUGS
  653. XVersions of PKUNZIP before 1.1 have a bug that on rare occasions will prevent
  654. Xit from unzipping files produced by
  655. X.I Zip
  656. Xor PKZIP 1.1.  If you experience such problems, we recommend that you get
  657. XPKUNZIP 1.1 or the portable
  658. X.I Unzip,
  659. Xneither of which have this problem.
  660. X.PP
  661. XUnder MSDOS, Zip will find hidden and system files, but not set the
  662. Xattributes appropriately in the zip file so that Unzip can restore them.
  663. XThis will be fixed in the next version.
  664. X.PP
  665. XUnder VMS, not all of the odd file formats are treated properly.  Only
  666. Xstream-LF format zip files are expected to work with Zip.  Others can be
  667. Xconverted using Rahul Dhesi's BILF program.  The next version of Zip will
  668. Xhandle some of the conversion internally.
  669. X.PP
  670. XLIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE
  671. XPROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR
  672. XIMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
  673. XRESULTING FROM THE USE OF THIS SOFTWARE.
  674. X.PP
  675. XThat having been said, please send any problems or comments via email to
  676. Xthe Internet address
  677. Xzip\-bugs@cs.ucla.edu.  For bug reports, please include the
  678. Xversion of Zip, the make options you used to compile it, the machine and
  679. Xoperating system you are using, and as much additional information as
  680. Xpossible.  Thank you for your support.
  681. END_OF_FILE
  682.   if test 21611 -ne `wc -c <'zip.1'`; then
  683.     echo shar: \"'zip.1'\" unpacked with wrong size!
  684.   fi
  685.   # end of 'zip.1'
  686. fi
  687. if test -f 'zip.c' -a "${1}" != "-c" ; then 
  688.   echo shar: Will not clobber existing file \"'zip.c'\"
  689. else
  690.   echo shar: Extracting \"'zip.c'\" \(25825 characters\)
  691.   sed "s/^X//" >'zip.c' <<'END_OF_FILE'
  692. X/*
  693. X
  694. X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  695. X Permission is granted to any individual or institution to use, copy, or
  696. X redistribute this software so long as all of the original files are included
  697. X unmodified, that it is not sold for profit, and that this copyright notice
  698. X is retained.
  699. X
  700. X*/
  701. X
  702. X/*
  703. X *  zip.c by Mark Adler.
  704. X */
  705. X
  706. X#include "revision.h"
  707. X#include "zip.h"
  708. X#include <signal.h>
  709. X
  710. X#define PWLEN 80        /* Input buffer size for reading encryption key */
  711. X#define MAXCOM 256      /* Maximum one-line comment size */
  712. X
  713. X
  714. X/* Local option flags */
  715. X#define DELETE  0
  716. X#define ADD     1
  717. X#define UPDATE  2
  718. X#define FRESHEN 3
  719. Xlocal int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
  720. Xlocal int comadd = 0;   /* 1=add comments for new files */
  721. Xlocal int zipedit = 0;  /* 1=edit zip comment and all file comments */
  722. Xlocal int dispose = 0;  /* 1=remove files after put in zip file */
  723. Xlocal int latest = 0;   /* 1=set zip file time to time of latest file */
  724. Xlocal ulg before = 0;   /* 0=ignore, else exclude files before this time */
  725. X
  726. X
  727. X/* Temporary zip file name and file pointer */
  728. Xlocal char *tempzip;
  729. Xlocal FILE *tempzf;
  730. X
  731. X
  732. X/* Local functions */
  733. X#ifdef PROTO
  734. X   local void freeup(void);
  735. X   local void leave(int);
  736. X   local void err(int, char *);
  737. X   local void handler(int);
  738. X   local void license(void);
  739. X   local void help(void);
  740. X   void main(int, char **);
  741. X#endif /* PROTO */
  742. X
  743. X
  744. X
  745. Xlocal void freeup()
  746. X/* Free all allocations in the found list and the zfiles list */
  747. X{
  748. X  struct flist far *f;  /* steps through found list */
  749. X  struct zlist far *z;  /* pointer to next entry in zfiles list */
  750. X
  751. X  for (f = found; f != NULL; f = fexpel(f))
  752. X    ;
  753. X  while (zfiles != NULL)
  754. X  {
  755. X    z = zfiles->nxt;
  756. X    free((voidp *)(zfiles->name));
  757. X    free((voidp *)(zfiles->zname));
  758. X    if (zfiles->ext)
  759. X      free((voidp *)(zfiles->extra));
  760. X    if (zfiles->cext && zfiles->cextra != zfiles->extra)
  761. X      free((voidp *)(zfiles->cextra));
  762. X    if (zfiles->com)
  763. X      free((voidp *)(zfiles->comment));
  764. X    farfree((voidp far *)zfiles);
  765. X    zfiles = z;
  766. X    zcount--;
  767. X  }
  768. X}
  769. X
  770. X
  771. Xlocal void leave(e)
  772. Xint e;                  /* exit code */
  773. X/* Process -o and -m options (if specified), free up malloc'ed stuff, and
  774. X   exit with the code e. */
  775. X{
  776. X  int r;                /* return value from trash() */
  777. X  ulg t;                /* latest time in zip file */
  778. X  struct zlist far *z;  /* pointer into zfile list */
  779. X
  780. X  /* If latest, set time to zip file to latest file in zip file */
  781. X  if (latest)
  782. X  {
  783. X    diag("changing time of zip file to time of latest file in it");
  784. X    /* find latest time in zip file */
  785. X    t = zfiles->tim;
  786. X    for (z = zfiles->nxt; z != NULL; z = z->nxt)
  787. X      if (t < z->tim)
  788. X        t = z->tim;
  789. X    /* set modified time of zip file to that time */
  790. X    stamp(zipfile, t);
  791. X  }
  792. X  if (tempath != NULL)
  793. X  {
  794. X    free((voidp *)tempath);
  795. X    tempath = NULL;
  796. X  }
  797. X  if (zipfile != NULL)
  798. X  {
  799. X    free((voidp *)zipfile);
  800. X    zipfile = NULL;
  801. X  }
  802. X
  803. X
  804. X  /* If dispose, delete all files in the zfiles list that are marked */
  805. X  if (dispose)
  806. X  {
  807. X    diag("deleting files that were added to zip file");
  808. X    if ((r = trash()) != ZE_OK)
  809. X      err(r, "was deleting moved files and directories");
  810. X  }
  811. X
  812. X
  813. X  /* Done! */
  814. X  freeup();
  815. X#ifdef VMS
  816. X  exit(0);
  817. X#else /* !VMS */
  818. X  exit(e);
  819. X#endif /* ?VMS */
  820. X}
  821. X
  822. X
  823. Xlocal void err(c, h)
  824. Xint c;                  /* error code from the ZE_ class */
  825. Xchar *h;                /* message about how it happened */
  826. X/* Issue a message for the error, clean up files and memory, and exit. */
  827. X{
  828. X  if (PERR(c))
  829. X    perror("zip error");
  830. X  fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
  831. X  if (shract)
  832. X  {
  833. X    shr_clear();
  834. X    shract = 0;
  835. X  }
  836. X#ifndef NOIMPLODE
  837. X  if (impact)
  838. X  {
  839. X    imp_clear();
  840. X    impact = 0;
  841. X  }
  842. X#endif /* !NOIMPLODE */
  843. X  if (tempzf != NULL)
  844. X    fclose(tempzf);
  845. X  if (tempzip != NULL)
  846. X  {
  847. X    destroy(tempzip);
  848. X    if (tempzip != zipfile)
  849. X      free((voidp *)tempzip);
  850. X  }
  851. X  if (key != NULL)
  852. X    free((voidp *)key);
  853. X  if (tempath != NULL)
  854. X    free((voidp *)tempath);
  855. X  if (zipfile != NULL)
  856. X    free((voidp *)zipfile);
  857. X  freeup();
  858. X#ifdef VMS
  859. X  exit(0);
  860. X#else /* !VMS */
  861. X  exit(c);
  862. X#endif /* ?VMS */
  863. X}
  864. X
  865. X
  866. Xlocal void handler(s)
  867. Xint s;                  /* signal number (ignored) */
  868. X/* Upon getting a user interrupt, turn echo back on for tty and abort
  869. X   cleanly using err(). */
  870. X{
  871. X#ifndef MSVMS
  872. X#ifndef EXPORT
  873. X  echon();
  874. X#endif /* !EXPORT */
  875. X  putc('\n', stderr);
  876. X#endif /* !MSVMS */
  877. X  err(ZE_ABORT, "aborting");
  878. X  s++;                                  /* keep some compilers happy */
  879. X}
  880. X
  881. X
  882. Xvoid warn(a, b)
  883. Xchar *a, *b;            /* message strings juxtaposed in output */
  884. X/* Print a warning message to stderr and return. */
  885. X{
  886. X  fprintf(stderr, "zip warning: %s%s\n", a, b);
  887. X}
  888. X
  889. X
  890. Xlocal void license()
  891. X/* Print license information to stdout. */
  892. X{
  893. X  extent i;             /* counter for copyright array */
  894. X
  895. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
  896. X    puts(copyright[i]);
  897. X  for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
  898. X    puts(disclaimer[i]);
  899. X}
  900. X
  901. X
  902. Xlocal void help()
  903. X/* Print help (along with license info) to stdout. */
  904. X{
  905. X  extent i;             /* counter for help array */
  906. X
  907. X  /* help array */
  908. X  static char *text[] = {
  909. X"",
  910. X"Zip %d.%d (%s)",
  911. X"Usage:  zip [-options] [-b path] [-t mmddyy] zipfile list [-x list]",
  912. X"  the default action is to add or replace zipfile entries from list, which",
  913. X"  can include the special name - to read names from stdin.",
  914. X"  -f   freshen: only changed files  -u   update: only changed or new files",
  915. X"  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
  916. X"  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
  917. X"  -h   show this help               -l   show software license",
  918. X"  -r   recurse into directories     -j   junk (don't record) directory names",
  919. X"  -i   implode only                 -s   shrink only",
  920. X"  -0   compress faster              -9   compress better",
  921. X"  -q   quiet operation              -n   don't compress special suffixes",
  922. X"  -c   add one-line comments        -z   add zipfile comment",
  923. X"  -b   use \"path\" for temp files    -t   only do files after \"mmddyy\"",
  924. X#ifdef EXPORT
  925. X"  -o   make zipfile as old as latest entry",
  926. X#else /* !EXPORT */
  927. X"  -e   encrypt  (-ee verify key)    -o   make zipfile as old as latest entry",
  928. X#endif /* ?EXPORT */
  929. X#ifdef VMS
  930. X"  -w   append the VMS version number to the name stored in the zip file",
  931. X#endif /* VMS */
  932. X#ifdef S_IFLNK
  933. X"  -y   store symbolic links as the link instead of the referenced file",
  934. X#endif /* !S_IFLNK */
  935. X"  -x   exclude the names that follow from those operated on"
  936. X  };
  937. X
  938. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
  939. X    puts(copyright[i]);
  940. X  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  941. X  {
  942. X    printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
  943. X    putchar('\n');
  944. X  }
  945. X}
  946. X
  947. X
  948. X/* Do command line expansion for MSDOS and VMS */
  949. X#ifdef MSVMS
  950. X#  define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
  951. X#else /* !MSVMS */
  952. X#  define PROCNAME(n) procname(n)
  953. X#endif /* ?MSVMS */
  954. X
  955. X
  956. Xvoid main(argc, argv)
  957. Xint argc;               /* number of tokens in command line */
  958. Xchar **argv;            /* command line tokens */
  959. X/* Add, update, freshen, or delete zip entries in a zip file.  See the
  960. X   command help in help() above. */
  961. X{
  962. X  int a;                /* attributes of zip file */
  963. X  ulg c;                /* start of central directory */
  964. X  int d;                /* true if just adding to a zip file */
  965. X  char *e;              /* malloc'd comment buffer */
  966. X  struct flist far *f;  /* steps through found linked list */
  967. X  int i;                /* arg counter, root directory flag */
  968. X  int k;                /* next argument type, marked counter,
  969. X                           comment size, entry count */
  970. X  ulg n;                /* total of entry len's */
  971. X  int o;                /* true if there were any ZE_OPEN errors */
  972. X  char *p;              /* steps through option arguments */
  973. X  int r;                /* temporary variable */
  974. X  ulg t;                /* file time, length of central directory */
  975. X  struct zlist far *v;  /* temporary variable */
  976. X  struct zlist far * far *w;    /* pointer to last link in zfiles list */
  977. X  FILE *x, *y;          /* input and output zip files */
  978. X  struct zlist far *z;  /* steps through zfiles linked list */
  979. X
  980. X
  981. X  /* Process arguments */
  982. X  diag("processing arguments");
  983. X  if (argc == 1)
  984. X  {
  985. X    help();
  986. X    exit(0);
  987. X  }
  988. X  zipfile = tempzip = NULL;
  989. X  tempzf = NULL;
  990. X  d = 0;                        /* disallow adding to a zip file */
  991. X  signal(SIGINT, handler);
  992. X  signal(SIGTERM, handler);
  993. X  k = 0;                        /* Next non-option argument type */
  994. X  for (i = 1; i < argc; i++)
  995. X  {
  996. X    if (argv[i][0] == '-')
  997. X      if (argv[i][1])
  998. X        for (p = argv[i]+1; *p; p++)
  999. X          switch(*p)
  1000. X          {
  1001. X            case '0':  case '1':  case '2':  case '3':  case '4':
  1002. X            case '5':  case '6':  case '7':  case '8':  case '9':
  1003. X                        /* Set the compression efficacy */
  1004. X              level = *p - '0';  break;
  1005. X            case 'b':   /* Specify path for temporary file */
  1006. X              if (k != 0)
  1007. X                err(ZE_PARMS, "use -b before zip file name");
  1008. X              else
  1009. X                k = 1;          /* Next non-option is path */
  1010. X              break;
  1011. X            case 'c':   /* Add comments for new files in zip file */
  1012. X              comadd = 1;  break;
  1013. X            case 'd':   /* Delete files from zip file */
  1014. X              if (action != ADD)
  1015. X                err(ZE_PARMS, "specify just one action");
  1016. X              action = DELETE;
  1017. X              break;
  1018. X#ifndef EXPORT
  1019. X            case 'e':   /* Encrypt */
  1020. X              e = key == NULL ? (char *)NULL : key;
  1021. X              if ((key = malloc(PWLEN+1)) == NULL)
  1022. X                err(ZE_MEM, "was getting encryption password");
  1023. X              if (getp(e == NULL ? "Enter password: " : "Verify password: ",
  1024. X                       key, PWLEN+1) == NULL)
  1025. X                err(ZE_PARMS, "stderr is not a tty");
  1026. X              if (e != NULL)
  1027. X              {
  1028. X                r = strcmp(key, e);
  1029. X                free((voidp *)e);
  1030. X                if (r)
  1031. X                  err(ZE_PARMS, "password not verified");
  1032. X              }
  1033. X              break;
  1034. X#endif /* !EXPORT */
  1035. X            case 'f':   /* Freshen zip file--overwrite only */
  1036. X              if (action != ADD)
  1037. X                err(ZE_PARMS, "specify just one action");
  1038. X              action = FRESHEN;
  1039. X              break;
  1040. X            case 'g':   /* Allow appending to a zip file */
  1041. X              d = 1;  break;
  1042. X            case 'h':   /* Help */
  1043. X              help();  break;
  1044. X            case 'i':   /* Implode only */
  1045. X              method = IMPLODE;  break;
  1046. X            case 'j':   /* Junk directory names */
  1047. X              pathput = 0;  break;
  1048. X            case 'k':   /* Make entries using DOS names (k for Katz) */
  1049. X              dosify = 2;  break;
  1050. X            case 'l':   /* Show license, version */
  1051. X              license();  break;
  1052. X            case 'm':   /* Delete files added or updated in zip file */
  1053. X              dispose = 1;  break;
  1054. X            case 'n':   /* Don't compress files with a special suffix */
  1055. X              if ((special = getenv("NOZIP")) == NULL)
  1056. X                special = ".Z:.zip:.zoo:.arc";
  1057. X#ifndef OS2
  1058. X#ifdef MSDOS
  1059. X              strupr(special);
  1060. X#endif /* MSDOS */
  1061. X#endif /* !OS2 */
  1062. X              break;
  1063. X            case 'o':   /* Set zip file time to time of latest file in it */
  1064. X              latest = 1;  break;
  1065. X            case 'p':   /* Store path with name */
  1066. X              break;            /* (do nothing as annoyance avoidance) */
  1067. X            case 'q':   /* Quiet operation */
  1068. X              noisy = 0;  break;
  1069. X            case 'r':   /* Recurse into subdirectories */
  1070. X              recurse = 1;  break;
  1071. X            case 's':   /* Shrink only */
  1072. X              method = SHRINK;  break;
  1073. X            case 't':   /* Exclude files earlier than specified date */
  1074. X              if (before)
  1075. X                err(ZE_PARMS, "can only have one -t");
  1076. X              k = 2;  break;
  1077. X            case 'u':   /* Update zip file--overwrite only if newer */
  1078. X              if (action != ADD)
  1079. X                err(ZE_PARMS, "specify just one action");
  1080. X              action = UPDATE;
  1081. X              break;
  1082. X            case 'v':   /* Mention oddities in zip file structure */
  1083. X              verbose = 1;
  1084. X              break;
  1085. X#ifdef VMS
  1086. X            case 'w':   /* Append the VMS version number */
  1087. X              vmsver = 1;  break;
  1088. X#endif /* VMS */
  1089. X            case 'x':   /* Exclude following files */
  1090. X              if (k != 4 &&
  1091. X                  (k != 3 || (action != UPDATE && action != FRESHEN)))
  1092. X                err(ZE_PARMS, "nothing to exclude (-x) from");
  1093. X              if (k == 3)       /* must be -u or -f */
  1094. X                for (z = zfiles; z != NULL; z = z->nxt)
  1095. X                  z->mark = 1;  /* mark all of them */
  1096. X              k = 5;
  1097. X              if ((r = exclude()) != ZE_OK)
  1098. X                if (r == ZE_PARMS)
  1099. X                  err(r, "cannot repeat names in zip file");
  1100. X                else
  1101. X                  err(r, "was processing list of files");
  1102. X              break;
  1103. X#ifdef S_IFLNK
  1104. X            case 'y':   /* Store symbolic links as such */
  1105. X              linkput = 1;  break;
  1106. X#endif /* !S_IFLNK */
  1107. X            case 'z':   /* Edit zip file comment */
  1108. X              zipedit = 1;  break;
  1109. X            default:
  1110. X            {
  1111. X              sprintf(errbuf, "no such option: %c", *p);
  1112. X              err(ZE_PARMS, errbuf);
  1113. X            }
  1114. X          }
  1115. X      else              /* just a dash */
  1116. X        if (k < 3)
  1117. X          err(ZE_PARMS, "zip file cannot be stdin");
  1118. X        else            /* read names from stdin */
  1119. X          while ((p = getnam(errbuf)) != NULL)
  1120. X          {
  1121. X            if ((r = PROCNAME(p)) != ZE_OK)
  1122. X              if (r == ZE_MISS)
  1123. X                warn("name not matched: ", p);
  1124. X              else
  1125. X                err(r, p);
  1126. X          }
  1127. X    else                /* not an option */
  1128. X    {
  1129. X      switch (k)
  1130. X      {
  1131. X        case 0:
  1132. X          if ((zipfile = ziptyp(argv[i])) == NULL)
  1133. X            err(ZE_MEM, "was processing arguments");
  1134. X          if ((r = readzipfile()) != ZE_OK)
  1135. X            err(r, zipfile);
  1136. X          found = NULL;
  1137. X          fnxt = &found;
  1138. X          k = 3;
  1139. X          break;
  1140. X        case 1:
  1141. X          if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL)
  1142. X            err(ZE_MEM, "was processing arguments");
  1143. X          strcpy(tempath, argv[i]);
  1144. X          k = 0;
  1145. X          break;
  1146. X        case 2:
  1147. X        {
  1148. X          int yy, mm, dd;       /* results of sscanf() */
  1149. X
  1150. X          if (sscanf(argv[i], "%2d%2d%2d", &mm, &dd, &yy) != 3 ||
  1151. X              mm < 1 || mm > 12 || dd < 1 || dd > 31)
  1152. X            err(ZE_PARMS, "invalid date entered for -t option");
  1153. X          before = dostime(yy + (yy < 80 ? 2000 : 1900), mm, dd, 0, 0, 0);
  1154. X          k = 0;
  1155. X          break;
  1156. X        }
  1157. X        case 3:  case 4:  case 5:
  1158. X          if ((r = PROCNAME(argv[i])) != ZE_OK)
  1159. X            if (r == ZE_MISS)
  1160. X              warn("name not matched: ", argv[i]);
  1161. X            else
  1162. X              err(r, argv[i]);
  1163. X          if (k == 3)
  1164. X            k = 4;
  1165. X      }
  1166. X    }
  1167. X  }
  1168. X  if (k < 3)
  1169. X    exit(0);                    /* No zip file, don't complain */
  1170. X  if (k != 5)                   /* Clean up selections */
  1171. X  {
  1172. X    if (k == 3 && (action == UPDATE || action == FRESHEN))
  1173. X      for (z = zfiles; z != NULL; z = z->nxt)
  1174. X        z->mark = 1;                    /* if -u or -f with no args, do all */
  1175. X    if ((r = exclude()) != ZE_OK)       /* remove duplicates in found list */
  1176. X      if (r == ZE_PARMS)
  1177. X        err(r, "cannot repeat names in zip file");
  1178. X      else
  1179. X        err(r, "was processing list of files");
  1180. X  }
  1181. X  if (zcount)
  1182. X    free((voidp *)zsort);
  1183. X
  1184. X
  1185. X  /* Check option combinations */
  1186. X  if (action == DELETE && (method != BEST || dispose || recurse ||
  1187. X      dosify || key != NULL || comadd || zipedit))
  1188. X    err(ZE_PARMS, "invalid option(s) used with -d");
  1189. X  if (linkput && dosify)
  1190. X    err(ZE_PARMS, "can't use -y with -k");
  1191. X
  1192. X  /* If -b not specified, make temporary path the same as the zip file */
  1193. X#ifdef MSDOS
  1194. X  if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
  1195. X                          (p = strrchr(zipfile, '\\')) != NULL ||
  1196. X                          (p = strrchr(zipfile, ':')) != NULL))
  1197. X  {
  1198. X    if (*p == ':')
  1199. X      p++;
  1200. X#else /* !MSDOS */
  1201. X  if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
  1202. X  {
  1203. X#endif /* ?MSDOS */
  1204. X    if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
  1205. X      err(ZE_MEM, "was processing arguments");
  1206. X    r = *p;  *p = 0;
  1207. X    strcpy(tempath, zipfile);
  1208. X    *p = (char)r;
  1209. X  }
  1210. X
  1211. X  /* If under MSDOS, force entries to look like made by PKZIP */
  1212. X#ifndef OS2
  1213. X#ifdef MSDOS
  1214. X  dosify = 1;
  1215. X#endif /* MSDOS */
  1216. X#endif /* !OS2 */
  1217. X
  1218. X
  1219. X  /* For each marked entry, if not deleting, check if it exists, and if
  1220. X     updating or freshening, compare date with entry in old zip file.
  1221. X     Unmark if it doesn't exist or is too old, else update marked count. */
  1222. X  diag("stating marked entries");
  1223. X  k = 0;                        /* Initialize marked count */
  1224. X  for (z = zfiles; z != NULL; z = z->nxt)
  1225. X    if (z->mark)
  1226. X      if (action != DELETE &&
  1227. X                ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
  1228. X                 t < before ||
  1229. X                 ((action == UPDATE || action == FRESHEN) && t <= z->tim)))
  1230. X      {
  1231. X        z->mark = 0;
  1232. X        z->trash = t && t >= before;    /* delete if -um or -fm */
  1233. X        if (verbose)
  1234. X          printf("zip diagnostic: %s %s\n", z->name,
  1235. X                 z->trash ? "up to date" : "missing or early");
  1236. X      }
  1237. X      else
  1238. X        k++;
  1239. X
  1240. X
  1241. X  /* Remove entries from found list that do not exist or are too old */
  1242. X  diag("stating new entries");
  1243. X  for (f = found; f != NULL;)
  1244. X    if (action == DELETE || action == FRESHEN ||
  1245. X        (t = filetime(f->name, (ulg *)NULL, (long *)NULL)) == 0 ||
  1246. X        t < before || strcmp(f->name, zipfile) == 0)
  1247. X      f = fexpel(f);
  1248. X    else
  1249. X      f = f->nxt;
  1250. X
  1251. X
  1252. X  /* Make sure there's something left to do */
  1253. X  if (k == 0 && found == NULL && !(zfiles != NULL && (latest || zipedit)))
  1254. X    if (action == UPDATE || action == FRESHEN)
  1255. X      leave(ZE_OK);
  1256. X    else
  1257. X      err(ZE_NONE, zipfile);
  1258. X  d = (d && k == 0 && zfiles != NULL);  /* d true if just appending */
  1259. X
  1260. X
  1261. X  /* Before we get carried away, make sure zip file is writeable */
  1262. X  if ((x = fopen(zipfile, zfiles == NULL ? FOPW : FOPM)) == NULL)
  1263. X    err(ZE_CREAT, zipfile);
  1264. X  fclose(x);
  1265. X  a = getfileattr(zipfile);
  1266. X  if (zfiles == NULL)
  1267. X    destroy(zipfile);
  1268. X
  1269. X
  1270. X  /* Open zip file and temporary output file */
  1271. X  diag("opening zip file and creating temporary zip file");
  1272. X  x = NULL;
  1273. X  if (d)
  1274. X  {
  1275. X    if ((y = fopen(zipfile, FOPM)) == NULL)
  1276. X      err(ZE_NAME, zipfile);
  1277. X    tempzip = zipfile;
  1278. X    tempzf = y;
  1279. X#ifdef MSDOS
  1280. X    {
  1281. X      char *zipbuf;
  1282. X
  1283. X      zipbuf = (char *)malloc(BSZ);
  1284. X      if (zipbuf == NULL)
  1285. X        err(ZE_MEM, tempzip);
  1286. X      setbuf(y, zipbuf);
  1287. X    }
  1288. X#endif /* MSDOS */
  1289. X    if (fseek(y, cenbeg, SEEK_SET))
  1290. X      err(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
  1291. X  }
  1292. X  else
  1293. X  {
  1294. X    if (zfiles != NULL && (x = fopen(zipfile, FOPR)) == NULL)
  1295. X      err(ZE_NAME, zipfile);
  1296. X    if ((tempzip = tempname('Z')) == NULL)
  1297. X      err(ZE_MEM, tempzip);
  1298. X    if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
  1299. X      err(ZE_TEMP, tempzip);
  1300. X    if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
  1301. X      err(r, r == ZE_TEMP ? tempzip : zipfile);
  1302. X  }
  1303. X  o = 0;                                /* no ZE_OPEN errors yet */
  1304. X
  1305. X
  1306. X  /* Process zip file, updating marked files */
  1307. X  if (zfiles != NULL)
  1308. X    diag("going through old zip file");
  1309. X  w = &zfiles;
  1310. X  while ((z = *w) != NULL)
  1311. X    if (z->mark)
  1312. X    {
  1313. X      /* if not deleting, zip it up */
  1314. X      if (action != DELETE)
  1315. X      {
  1316. X        if (noisy)
  1317. X        {
  1318. X          printf("updating %s", z->zname);
  1319. X          fflush(stdout);
  1320. X        }
  1321. X        if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
  1322. X        {
  1323. X          if (noisy)
  1324. X          {
  1325. X            putchar('\n');
  1326. X            fflush(stdout);
  1327. X          }
  1328. X          sprintf(errbuf, "was zipping %s", z->name);
  1329. X          err(r, errbuf);
  1330. X        }
  1331. X        if (r == ZE_OPEN)
  1332. X        {
  1333. X          o = 1;
  1334. X          if (noisy)
  1335. X          {
  1336. X            putchar('\n');
  1337. X            fflush(stdout);
  1338. X          }
  1339. X          perror("zip warning");
  1340. X          warn("could not open for reading: ", z->name);
  1341. X          warn("will just copy entry over: ", z->zname);
  1342. X          if ((r = zipcopy(z, x, y)) != ZE_OK)
  1343. X          {
  1344. X            sprintf(errbuf, "was copying %s", z->zname);
  1345. X            err(r, errbuf);
  1346. X          }
  1347. X          z->mark = 0;
  1348. X        }
  1349. X        w = &z->nxt;
  1350. X      }
  1351. X      else
  1352. X      {
  1353. X        if (noisy)
  1354. X        {
  1355. X          printf("deleting %s\n", z->zname);
  1356. X          fflush(stdout);
  1357. X        }
  1358. X        v = z->nxt;                     /* delete entry from list */
  1359. X        free((voidp *)(z->name));
  1360. X        free((voidp *)(z->zname));
  1361. X        if (z->ext)
  1362. X          free((voidp *)(z->extra));
  1363. X        if (z->cext && z->cextra != z->extra)
  1364. X          free((voidp *)(z->cextra));
  1365. X        if (z->com)
  1366. X          free((voidp *)(z->comment));
  1367. X        farfree((voidp far *)z);
  1368. X        *w = v;
  1369. X        zcount--;
  1370. X      }
  1371. X    }
  1372. X    else
  1373. X    {
  1374. X      /* copy the original entry verbatim */
  1375. X      if (!d && (r = zipcopy(z, x, y)) != ZE_OK)
  1376. X      {
  1377. X        sprintf(errbuf, "was copying %s", z->zname);
  1378. X        err(r, errbuf);
  1379. X      }
  1380. X      w = &z->nxt;
  1381. X    }
  1382. X  if (x != NULL)
  1383. X    fclose(x);
  1384. X
  1385. X
  1386. X  /* Process the edited found list, adding them to the zip file */
  1387. X  diag("zipping up new entries, if any");
  1388. X  for (f = found; f != NULL; f = fexpel(f))
  1389. X  {
  1390. X    /* add a new zfiles entry and set the name */
  1391. X    if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
  1392. X      err(ZE_MEM, "was adding files to zip file");
  1393. X    z->nxt = NULL;
  1394. X    z->name = f->name;
  1395. X    f->name = NULL;
  1396. X    z->zname = f->zname;
  1397. X    f->zname = NULL;
  1398. X    z->ext = z->cext = z->com = 0;
  1399. X    z->mark = 1;
  1400. X    /* zip it up */
  1401. X    if (noisy)
  1402. X    {
  1403. X      printf("adding %s", z->zname);
  1404. X      fflush(stdout);
  1405. X    }
  1406. X    if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN)
  1407. X    {
  1408. X      if (noisy)
  1409. X      {
  1410. X        putchar('\n');
  1411. X        fflush(stdout);
  1412. X      }
  1413. X      sprintf(errbuf, "was zipping %s", z->name);
  1414. X      err(r, errbuf);
  1415. X    }
  1416. X    if (r == ZE_OPEN)
  1417. X    {
  1418. X      o = 1;
  1419. X      if (noisy)
  1420. X      {
  1421. X        putchar('\n');
  1422. X        fflush(stdout);
  1423. X      }
  1424. X      perror("zip warning");
  1425. X      warn("could not open for reading: ", z->name);
  1426. X      free((voidp *)(z->name));
  1427. X      free((voidp *)(z->zname));
  1428. X      farfree((voidp far *)z);
  1429. X    }
  1430. X    else
  1431. X    {
  1432. X      *w = z;
  1433. X      w = &z->nxt;
  1434. X      zcount++;
  1435. X    }
  1436. X  }
  1437. X  if (key != NULL)
  1438. X  {
  1439. X    free((voidp *)key);
  1440. X    key = NULL;
  1441. X  }
  1442. X
  1443. X
  1444. X  /* Get one line comment for each new entry */
  1445. X  if (comadd)
  1446. X  {
  1447. X    if ((e = malloc(MAXCOM + 1)) == NULL)
  1448. X      err(ZE_MEM, "was reading comment lines");
  1449. X    for (z = zfiles; z != NULL; z = z->nxt)
  1450. X      if (z->mark)
  1451. X      {
  1452. X        if (noisy)
  1453. X          printf("Enter comment for %s:\n", z->name);
  1454. X        if (fgets(e, MAXCOM+1, stdin) != NULL)
  1455. X        {
  1456. X          if ((p = malloc((k = strlen(e))+1)) == NULL)
  1457. X          {
  1458. X            free((voidp *)e);
  1459. X            err(ZE_MEM, "was reading comment lines");
  1460. X          }
  1461. X          strcpy(p, e);
  1462. X          if (p[k-1] == '\n')
  1463. X            p[--k] = 0;
  1464. X          z->comment = p;
  1465. X          z->com = k;
  1466. X        }
  1467. X      }
  1468. X    free((voidp *)e);
  1469. X  }
  1470. X
  1471. X  /* Get multi-line comment for the zip file */
  1472. X  if (zipedit)
  1473. X  {
  1474. X    if ((e = malloc(MAXCOM + 1)) == NULL)
  1475. X      err(ZE_MEM, "was reading comment lines");
  1476. X    if (noisy && zcomlen)
  1477. X    {
  1478. X      puts("current zip file comment is:");
  1479. X      fwrite(zcomment, 1, zcomlen, stdout);
  1480. X      if (zcomment[zcomlen-1] != '\n')
  1481. X        putchar('\n');
  1482. X      free((voidp *)zcomment);
  1483. X    }
  1484. X    zcomment = malloc(1);
  1485. X    *zcomment = 0;
  1486. X    if (noisy)
  1487. X      puts("enter new zip file comment (end with .):");
  1488. X    while (fgets(e, MAXCOM+1, stdin) != NULL && strcmp(e, ".\n"))
  1489. X    {
  1490. X      if (e[(r = strlen(e)) - 1] == '\n')
  1491. X        e[--r] = 0;
  1492. X      if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
  1493. X      {
  1494. X        free((voidp *)e);
  1495. X        err(ZE_MEM, "was reading comment lines");
  1496. X      }
  1497. X      if (*zcomment)
  1498. X        strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
  1499. X      else
  1500. X        strcpy(p, *e ? e : "\r\n");
  1501. X      free((voidp *)zcomment);
  1502. X      zcomment = p;
  1503. X    }
  1504. X    zcomlen = strlen(zcomment);
  1505. X    free((voidp *)e);
  1506. X  }
  1507. X
  1508. X
  1509. X  /* Write central directory and end header to temporary zip */
  1510. X  diag("writing central directory");
  1511. X  k = 0;                        /* keep count for end header */
  1512. X  if ((c = ftell(y)) == -1L)    /* get start of central */
  1513. X    err(d ? ZE_WRITE : ZE_TEMP, tempzip);
  1514. X  n = t = 0;
  1515. X  for (z = zfiles; z != NULL; z = z->nxt)
  1516. X  {
  1517. X    if ((r = putcentral(z, y)) != ZE_OK)
  1518. X      err(r, tempzip);
  1519. X    n += z->len;
  1520. X    t += z->siz;
  1521. X    k++;
  1522. X  }
  1523. X  if (k == 0)
  1524. X    warn("zip file empty", "");
  1525. X  if (verbose)
  1526. X    printf("total bytes=%lu, compressed=%lu -> %d%% savings\n",
  1527. X           n, t, percent(n, t));
  1528. X  if ((t = ftell(y)) == -1L)    /* get end of central */
  1529. X    err(d ? ZE_WRITE : ZE_TEMP, tempzip);
  1530. X  t -= c;                       /* compute length of central */
  1531. X  diag("writing end of central directory");
  1532. X  if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK)
  1533. X    err(r, tempzip);
  1534. X  tempzf = NULL;
  1535. X  if (fclose(y))
  1536. X    err(d ? ZE_WRITE : ZE_TEMP, tempzip);
  1537. X
  1538. X
  1539. X  /* Replace old zip file with new zip file, leaving only the new one */
  1540. X  if (!d)
  1541. X  {
  1542. X    diag("replacing old zip file with new zip file");
  1543. X    if ((r = replace(zipfile, tempzip)) != ZE_OK)
  1544. X    {
  1545. X      warn("new zip file left as: ", tempzip);
  1546. X      free((voidp *)tempzip);
  1547. X      tempzip = NULL;
  1548. X      err(r, "was replacing the original zip file");
  1549. X    }
  1550. X    free((voidp *)tempzip);
  1551. X  }
  1552. X  tempzip = NULL;
  1553. X  setfileattr(zipfile, a);
  1554. X
  1555. X  /* Finish up (process -o, -m, clean up).  Exit code depends on o. */
  1556. X  leave(o ? ZE_OPEN : ZE_OK);
  1557. X}
  1558. END_OF_FILE
  1559.   if test 25825 -ne `wc -c <'zip.c'`; then
  1560.     echo shar: \"'zip.c'\" unpacked with wrong size!
  1561.   fi
  1562.   # end of 'zip.c'
  1563. fi
  1564. echo shar: End of archive 6 \(of 9\).
  1565. cp /dev/null ark6isdone
  1566. MISSING=""
  1567. for I in 1 2 3 4 5 6 7 8 9 ; do
  1568.     if test ! -f ark${I}isdone ; then
  1569.     MISSING="${MISSING} ${I}"
  1570.     fi
  1571. done
  1572. if test "${MISSING}" = "" ; then
  1573.     echo You have unpacked all 9 archives.
  1574.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1575. else
  1576.     echo You still must unpack the following archives:
  1577.     echo "        " ${MISSING}
  1578. fi
  1579. exit 0
  1580. exit 0 # Just in case...
  1581. -- 
  1582. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1583. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1584. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1585. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1586.