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

  1. Newsgroups: comp.sources.misc
  2. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  3. Subject:  v31i098:  zip19 - Info-ZIP portable Zip, version 1.9, Part06/11
  4. Message-ID: <1992Aug23.064718.29270@sparky.imd.sterling.com>
  5. X-Md4-Signature: cc24ed17dbea073912fe1473810d2c72
  6. Date: Sun, 23 Aug 1992 06:47:18 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
  10. Posting-number: Volume 31, Issue 98
  11. Archive-name: zip19/part06
  12. Supersedes: zip: Volume 23, Issue 88-96
  13. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, XOS, !AMIGA, ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun, PC
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  os2/zip.def.UU zip.1 zip.h zipfile.c
  22. # Wrapped by kent@sparky on Sun Aug 23 01:00:45 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 6 (of 11)."'
  26. if test -f 'os2/zip.def.UU' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'os2/zip.def.UU'\"
  28. else
  29.   echo shar: Extracting \"'os2/zip.def.UU'\" \(152 characters\)
  30.   sed "s/^X//" >'os2/zip.def.UU' <<'END_OF_FILE'
  31. Xbegin 666 os2/zip.def
  32. XM3D%-12!724Y$3U=#3TU0050@3D571DE,15,-"D1%4T-225!424].("=4:&4@
  33. XK=V]R;&0M9F%M;W5S('II<"!U=&EL:71I97,@9G)O;2!);F9O+5I)4"<-"F4@
  34. Xend
  35. END_OF_FILE
  36.  if test 152 -ne `wc -c <'os2/zip.def.UU'`; then
  37.     echo shar: \"'os2/zip.def.UU'\" unpacked with wrong size!
  38.   else
  39.     echo shar: Uudecoding \"'os2/zip.def'\" \(88 characters\)
  40.     cat os2/zip.def.UU | uudecode
  41.     if test 88 -ne `wc -c <'os2/zip.def'`; then
  42.       echo shar: \"'os2/zip.def'\" uudecoded with wrong size!
  43.     else
  44.       rm os2/zip.def.UU
  45.     fi
  46.   fi
  47.   # end of 'os2/zip.def.UU'
  48. fi
  49. if test -f 'zip.1' -a "${1}" != "-c" ; then 
  50.   echo shar: Will not clobber existing file \"'zip.1'\"
  51. else
  52.   echo shar: Extracting \"'zip.1'\" \(21796 characters\)
  53.   sed "s/^X//" >'zip.1' <<'END_OF_FILE'
  54. X.\" Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  55. X.\" Kai Uwe Rommel and Igor Mandrichenko.
  56. X.\" Permission is granted to any individual or institution to use, copy, or
  57. X.\" redistribute this software so long as all of the original files are included
  58. X.\" unmodified, that it is not sold for profit, and that this copyright notice
  59. X.\" is retained.
  60. X.\"
  61. X.\" zip.1 by Mark Adler.
  62. X.\"
  63. X.TH ZIP 1
  64. X.SH NAME
  65. Xzip, zipcloak, zipnote, zipsplit \- package and compress (archive) files
  66. X.SH SYNOPSIS
  67. X.B zip
  68. X[
  69. X.B \-cdeEfghjklmoqruwyz@
  70. X] [
  71. X.B \-b
  72. Xtemppath ] [
  73. X.B \-n
  74. Xsuffixes ] [
  75. X.B \-t
  76. Xmmddyy ] [ zipfile list ] [
  77. X.B \-x
  78. Xlist ]
  79. X.PP
  80. X.B zipcloak
  81. X[
  82. X.B \-d
  83. X] [
  84. X.BI -b " path"
  85. X]
  86. X.I zipfile
  87. X.PP
  88. X.B zipnote
  89. X[
  90. X.B -w
  91. X] [
  92. X.BI \-b " path"
  93. X]
  94. X.I zipfile
  95. X.PP
  96. X.B zipsplit
  97. X[
  98. X.B \-ti
  99. X] [
  100. X.BI \-n " size"
  101. X] [
  102. X.BI \-b " path"
  103. X]
  104. X.I zipfile
  105. X.br
  106. X.SH DESCRIPTION
  107. X.I zip
  108. Xis a compression and file packaging utility for Unix, VMS, MSDOS,
  109. XOS/2, Windows NT, Minix, Atari and Macintosh.  It is analogous to a
  110. Xcombination of tar and compress and is compatible with PKZIP (Phil
  111. XKatz ZIP) for MSDOS systems.
  112. X.PP
  113. XThere is a companion to
  114. X.I zip
  115. Xcalled
  116. X.I unzip
  117. X(of course) which you should be able
  118. Xto find the same place you got
  119. X.I zip.  zip
  120. Xand
  121. X.I unzip
  122. Xcan work with files
  123. Xproduced by PKZIP under MSDOS, and PKZIP and PKUNZIP can work with files
  124. Xproduced by
  125. X.I zip.
  126. X.PP
  127. X.I zip
  128. Xversion 1.9 is compatible with pkzip 1.93a.
  129. XNote that pkunzip 1.10 cannot extract files produced by pkzip 1.93a
  130. Xor zip 1.9. You must use pkunzip 1.93a or unzip 5.0 to extract them.
  131. X.PP
  132. XFor a brief help on
  133. X.I zip
  134. Xand
  135. X.I unzip,
  136. Xrun each without specifying any parameters on the command line.
  137. X.PP
  138. X.I zip
  139. Xputs one or more compressed files into a single "zip file" along with
  140. Xinformation about the files, including the name, path if requested, date
  141. Xand time last modified, protection, and check information to verify the
  142. Xfidelity of each entry.
  143. X.I zip
  144. Xcan also be used as a filter, compressing standard input to standard output.
  145. X.I zip
  146. Xcan pack an entire directory structure in a
  147. Xzip file with a single command.  Compression ratios of 2:1 to 3:1 are
  148. Xcommon for text files.
  149. X.I zip
  150. Xhas one compression method (deflation) and can also store files without
  151. Xcompression. It automatically chooses the better of the two for each file
  152. Xto be compressed.
  153. X.PP
  154. X.I zip
  155. Xis useful for packaging a set of files to send to someone or for distribution;
  156. Xfor archiving or backing up files; and for saving disk space by temporarily
  157. Xcompressing unused files or directories.
  158. X.SH "HOW TO USE ZIP"
  159. XThe simplest use of
  160. X.I zip
  161. Xis as follows:
  162. X.PP
  163. X.ti +5n
  164. Xzip stuff *
  165. X.PP
  166. XThis will create the file "stuff.zip" (assuming it does not exist) and put
  167. Xall the files in the current directory in stuff.zip in a compressed form.
  168. XThe .zip suffix is added automatically, unless that file name given contains
  169. Xa dot already.  This allows specifying suffixes other than ".zip".
  170. X.PP
  171. XBecause of the way the shell does filename substitution, files that start
  172. Xwith a "." are not included.  To include those as well, you can:
  173. X.PP
  174. X.ti +5n
  175. Xzip stuff .* *
  176. X.PP
  177. XEven this will not include any subdirectories that are in the current
  178. Xdirectory.  To zip up an entire directory, the command:
  179. X.PP
  180. X.ti +5n
  181. Xzip -r foo foo
  182. X.PP
  183. Xwill create the file "foo.zip" containing all the files and directories in
  184. Xthe directory "foo" that is in the current directory. (The first "foo" denotes
  185. Xthe zip file, the second one denotes the directory.)  The "r" option means
  186. Xrecurse through the directory structure.  In this case, all the
  187. Xfiles and directories in foo are zipped, including the ones that start with
  188. Xa ".", since the recursion does not use the shell's file-name substitution.
  189. XYou should not use -r with the name ".*", since that matches ".." which will
  190. Xattempt to zip up the parent directory--probably not what was intended.
  191. X.PP
  192. XYou may want to make a zip file that contains the files in foo, but not record
  193. Xthe directory name, foo.  You can use the -j (junk path) option to leave off
  194. Xthe path:
  195. X.PP
  196. X.ti +5n
  197. Xzip -j foo foo/*
  198. X.PP
  199. XThe -y option (only under Unix) will store symbolic links as such in the
  200. Xzip file, instead of compressing and storing the file referred to in the link.
  201. X.PP
  202. XYou might be zipping to save disk space, in which case you could:
  203. X.PP
  204. X.ti +5n
  205. Xzip -rm foo foo
  206. X.PP
  207. Xwhere the "m" option means "move".  This will delete foo and its contents
  208. Xafter making foo.zip.  No deletions will be done until the zip has completed
  209. Xwith no errors.  This option is obviously more dangerous and should be
  210. Xused with care.
  211. X.PP
  212. XIf the zip file already exists, these commands will replace existing or add
  213. Xnew entries to the zip file.  For example, if you were really short on disk
  214. Xspace, you might not have enough room simultaneously to hold the directory
  215. Xfoo and the compressed foo.zip.  In this case, you could do it in steps.  If
  216. Xfoo contained the subdirectories tom, dick, and harry, then you could:
  217. X.PP
  218. X.ti +5n
  219. Xzip -rm foo foo/tom
  220. X.ti +5n
  221. Xzip -rm foo foo/dick
  222. X.ti +5n
  223. Xzip -rm foo foo/harry
  224. X.PP
  225. Xwhere the first command would create foo.zip, and the next two would add to
  226. Xit.  At the completion of each zip command, the directory just zipped would
  227. Xbe deleted, making room in which the next
  228. X.I zip
  229. Xcommand could work.
  230. X.PP
  231. X.I zip
  232. Xwill also accept a single dash ("-") as the zip file name, in which case it
  233. Xwill write the zip file to stdout, allowing the output to be piped to another
  234. Xprogram. For example:
  235. X.PP
  236. X.ti +5n
  237. Xzip -r - . | dd of=/dev/nrst0 obs=16k
  238. X.PP
  239. Xwould write the zip output directly to a tape with the specified block size
  240. Xfor the purpose of backing up the current directory.
  241. X.PP
  242. X.I zip
  243. Xalso accepts a single dash ("-") as the name of a file to be compressed, in
  244. Xwhich case it will read the zip file from stdin, allowing zip to take
  245. Xinput from another program. For example:
  246. X.PP
  247. X.ti +5n
  248. Xtar cf - . | zip backup -
  249. X.PP
  250. Xwould compress the output of the tar command for the purpose of backing up
  251. Xthe current directory. This generally produces better compression than
  252. Xthe previous example using the -r option, because
  253. X.I zip
  254. Xcan take advantage of redundancy between files. The backup can be restored
  255. Xusing the command
  256. X.PP
  257. X.ti +5n
  258. Xunzip -p backup | tar xf -
  259. X.PP
  260. XWhen no zip file name is given and stdout is not a terminal,
  261. X.I zip
  262. Xacts as a filter, compressing standard input to standard output.
  263. XFor example,
  264. X.PP
  265. X.ti +5n
  266. Xtar cf - . | zip | dd of=/dev/nrst0
  267. X.PP
  268. Xis equivalent to
  269. X.PP
  270. X.ti +5n
  271. Xtar cf - . | zip - - | dd of=/dev/nrst0
  272. X.PP
  273. XZip archives created in this manner can be extracted with the program
  274. X.I funzip
  275. Xwhich is provided in the
  276. X.I unzip
  277. Xpackage. For example,
  278. X.PP
  279. X.ti +5n
  280. X   dd if=/dev/nrst0 | funzip | tar xvf -
  281. X.SH "MODIFYING EXISTING ZIP FILES"
  282. XWhen given the name of an existing zip file with the above commands,
  283. X.I zip
  284. Xwill replace identically named entries in the
  285. X.I zip
  286. Xfile or add entries for
  287. Xnew names.  For example, if foo.zip exists and contains foo/file1 and
  288. Xfoo/file2, and the directory foo contains the files foo/file1 and foo/file3,
  289. Xthen:
  290. X.PP
  291. X.ti +5n
  292. Xzip -r foo foo
  293. X.PP
  294. Xwill replace foo/file1 in foo.zip and add foo/file3 to foo.zip.  After
  295. Xthis, foo.zip contains foo/file1, foo/file2, and foo/file3, with foo/file2
  296. Xunchanged from before.
  297. X.PP
  298. XWhen changing an existing zip file,
  299. X.I zip
  300. Xwill write a temporary file with
  301. Xthe new contents, and only replace the old one when the zip has completed
  302. Xwith no errors. You can use
  303. Xthe -b option to specify a different path (usually a different device) to
  304. Xput the temporary file in.  For example:
  305. X.PP
  306. X.ti +5n
  307. Xzip -b /tmp stuff *
  308. X.PP
  309. Xwill put the temporary zip file and the temporary compression files in the
  310. Xdirectory "/tmp", copying over stuff.zip in the current directory when
  311. Xdone.
  312. X.PP
  313. XIf you are only adding entries to a zip file, not replacing, and the
  314. X-g option is given, then
  315. X.I zip
  316. Xgrows (appends to) the file instead of copying it.  The danger of this is that
  317. Xif the operation fails, the original zip file is corrupted and lost.
  318. X.PP
  319. XThere are two other ways to change or add entries in a zip file that are
  320. Xrestrictions of simple addition or replacement.  The first is -u (update)
  321. Xwhich will add new entries to the zip file as before but will replace
  322. Xexisting entries only if the modified date of the file is more recent than
  323. Xthe date recorded for that name in the zip file.  For example:
  324. X.PP
  325. X.ti +5n
  326. Xzip -u stuff *
  327. X.PP
  328. Xwill add any new files in the current directory, and update any changed files
  329. Xin the zip file stuff.zip.  Note that
  330. X.I zip
  331. Xwill not try to pack stuff.zip into
  332. Xitself when you do this. 
  333. X.I zip
  334. Xwill always exclude the zip file from the files on which to be operated.
  335. X.PP
  336. XThe second restriction is -f (freshen) which, like update, will only replace
  337. Xentries with newer files; unlike update, will not add files that are not
  338. Xalready in the zip file.  For this option, you may want to simply freshen all
  339. Xof the files that are in the specified zip file.  To do this you would simply:
  340. X.PP
  341. X.ti +5n
  342. Xzip -f foo
  343. X.PP
  344. XNote that the -f option with no arguments freshens all the entries in the
  345. Xzip file.  The same is true of -u, and hence "zip -u foo" and "zip -f foo"
  346. Xboth do the same thing.
  347. X.PP
  348. XThis command should
  349. Xbe run from the same directory from which the original zip command was run,
  350. Xsince paths stored in zip files are always relative.
  351. X.PP
  352. XAnother restriction that can be used with adding, updating, or freshening is
  353. X-t (time), which will not operate on files modified earlier than the specified
  354. Xdate.  For example:
  355. X.PP
  356. X.ti +5n
  357. Xzip -rt 120791 infamy foo
  358. X.PP
  359. Xwill add all the files in foo and its subdirectories that were last modified
  360. Xon December 7, 1991, or later to the zip file infamy.zip.
  361. X.PP
  362. XAlso, files can be explicitly excluded using the -x option:
  363. X.PP
  364. X.ti +5n
  365. Xzip -r foo foo -x \\*.o
  366. X.PP
  367. Xwhich will zip up the contents of foo into foo.zip but exclude all the
  368. Xfiles that end in ".o".  Here the backslash causes
  369. X.I zip
  370. Xto match file names
  371. Xthat were found when foo was searched.
  372. X.PP
  373. XThe last operation is -d (delete) which will remove entries from a zip file.
  374. XAn example might be:
  375. X.PP
  376. X.ti +5n
  377. Xzip -d foo foo/tom/junk foo/harry/\\* \\*.o
  378. X.PP
  379. Xwhich will remove the entry foo/tom/junk, all of the files that start with
  380. X"foo/harry/", and all of the files that end with ".o" (in any path).  Note
  381. Xthat once again, the shell expansion has been inhibited with backslashes, so
  382. Xthat
  383. X.I zip
  384. Xcan see the asterisks.  
  385. X.I zip
  386. Xcan then match on the contents of the zip
  387. Xfile instead of the contents of the current directory.
  388. X.PP
  389. XUnder MSDOS, -d is case sensitive when it matches names in the zip file.
  390. XThis allows deleting names that were zipped on other systems, but requires
  391. Xthat the names be entered in upper case if they were zipped on an MSDOS
  392. Xsystem, so that the names can be found in the zip file and deleted.
  393. X.SH "MORE OPTIONS"
  394. XAs mentioned before,
  395. X.I zip
  396. Xwill use the best of two methods: deflate or store.
  397. X.PP
  398. XThe option -0 will force
  399. X.I zip
  400. Xto use store on all files. For example:
  401. X.PP
  402. X.ti +5n
  403. Xzip -r0 foo foo
  404. X.PP
  405. Xwill zip up the directory foo into foo.zip using only store.
  406. X.PP
  407. XThe speed of deflation can also be controlled with options -1 (fastest
  408. Xmethod but less compression) to -9 (best compression but slower). The
  409. Xdefault value is -5. For example:
  410. X.PP
  411. X.ti +5n
  412. Xzip -r8 foo foo
  413. X.PP
  414. XIn nearly all cases, a file that is already compressed cannot be compressed
  415. Xfurther by
  416. X.I zip,
  417. Xor if it can, the effect is minimal.  The -n option prevents
  418. X.I zip
  419. Xfrom trying to compress files that have the given suffixes.
  420. XSuch files are simply stored (0% compression) in the output zip file,
  421. Xso that
  422. X.I zip
  423. Xdoesn't waste its time trying to compress them.
  424. XThe suffixes are separated by
  425. Xeither colons or semicolons.  For example:
  426. X.PP
  427. X.ti +5n
  428. Xzip -rn ".Z:.zip:.tiff:.gif:.snd"  foo foo
  429. X.PP
  430. Xwill put everything in foo into foo.zip, but will store any files that end
  431. Xin .Z, .zip, .tiff, .gif, or .snd without trying to compress them.  (Image
  432. Xand sound files often have their own specialized compression methods.)
  433. XThe default suffix list is ".Z:.zip;.zoo:.arc:.lzh:.arj".
  434. XThe environment variable ZIPOPT can be used to change this default. For
  435. Xexample under Unix with csh:
  436. X.PP
  437. X.ti +5n
  438. Xsetenv ZIPOPT "-n .gif:.zip"
  439. X.PP
  440. XThe variable ZIPOPT can be used for any option and can include several
  441. Xoptions.
  442. X.PP
  443. XUnder Unix and under OS/2 (if files from an HPFS are stored),
  444. X.I zip
  445. Xwill store the full path (relative to the current path) and name of the
  446. Xfile (or just the name if -j is specified) in the zip file along with the
  447. XUnix attributes, and it will mark
  448. Xthe entry as made under Unix.  If the zip file is intended for PKUNZIP under
  449. XMSDOS, then the -k (Katz) option should be used to attempt to convert the
  450. Xnames and paths to conform to MSDOS, store only the MSDOS attribute (just
  451. Xthe user write attribute from Unix), and mark the entry as made under MSDOS
  452. X(even though it wasn't).
  453. X.PP
  454. XThe -o (older) option will set the "last modified" time of the zip file to
  455. Xthe latest "last modified" time of the entries in the zip file.  This can
  456. Xbe used without any other operations, if desired.  For example:
  457. X.PP
  458. X.ti +5n
  459. Xzip -o foo
  460. X.PP
  461. Xwill change the last modified time of foo.zip to the latest time of the
  462. Xentries in foo.zip.
  463. X.PP
  464. XThe -e and -c options operate on all files updated or added to the zip file.
  465. XEncryption (-e) will prompt for a password on the terminal and will
  466. Xnot echo the password as it is typed (if stderr is not a TTY, zip will exit
  467. Xwith an error).  New zip entries will be encrypted using that password.  For
  468. Xadded peace of mind, you can use -ee, which will prompt for the password
  469. Xtwice, checking that the two are the same before using it. The encryption
  470. Xcode is distributed separately, so the -e option may not be available
  471. Xin your version.
  472. X.PP
  473. XOne-line comments can be added for each file with the -c option.  The zip
  474. Xfile operations (adding or updating) will be done first, and you will then be
  475. Xprompted for a one-line comment for each file.  You can then enter the comment
  476. Xfollowed by return, or just return for no comment.
  477. X.PP
  478. XThe -z option will prompt you for a multi-line comment for the entire zip
  479. Xfile.  This option can be used by itself, or in combination with other
  480. Xoptions.  The comment is ended by a line containing just a period, or an end
  481. Xof file condition (^D on Unix, ^Z on MSDOS, OS/2, and VAX/VMS).
  482. XSince -z reads the
  483. Xlines from stdin, you can simply take the comment from a file:
  484. X.PP
  485. X.ti +5n
  486. Xzip -z foo < foowhat
  487. X.PP
  488. XThe -q (quiet) option eliminates the informational messages and comment prompts
  489. Xwhile
  490. X.I zip
  491. Xis operating.  This might be used in shell scripts, for example, or if the
  492. Xzip operation is being performed as a background task ("zip -q foo *.c &").
  493. X.PP
  494. X.I zip
  495. Xcan take a list of file names to operate on from stdin using the -@ option.
  496. XIn Unix, this option can be used with the find command to extend greatly
  497. Xthe functionality of
  498. X.I zip.
  499. XFor example, to zip up all the C source files in the current directory and
  500. Xits subdirectories, you can:
  501. X.PP
  502. X.ti +5n
  503. Xfind . -type f -name "*.[ch]" -print | zip source -@
  504. X.PP
  505. XNote that the pattern must be quoted to keep the shell from expanding it.
  506. X.PP
  507. XUnder VMS only, the -w option will append the version number of the files to
  508. Xthe name and zip up multiple versions of files.  Without -w,
  509. X.I zip
  510. Xwill only use the most recent version of the specified file(s).
  511. X.PP
  512. XThe -l option translates the Unix end-of-line character LF into the
  513. XMSDOS convention CR LF. This option should not be used on binary files.
  514. XThis option can be used on Unix if the zip file is intended for PKUNZIP
  515. Xunder MSDOS. If the input files already contain CR LF, this option adds
  516. Xan extra CR. This ensure that "unzip -a" on Unix will get back an exact
  517. Xcopy of the original file, to undo the effect of "zip -l".
  518. X.PP
  519. XIf
  520. X.I zip
  521. Xis run with the -h option, or with no arguments and standard output is
  522. Xa terminal, the license and the command-argument and option help is shown.
  523. XThe -L option just shows the license.
  524. X.SH "ABOUT PATTERN MATCHING"
  525. X(Note: this section applies to Unix.  Watch this space for details on MSDOS
  526. Xand VMS operation.)
  527. X.PP
  528. XThe Unix shell (sh or csh) does filename substitution on command arguments.
  529. XThe special characters are ?, which matches any single character; * which
  530. Xmatches any number of characters (including none); and [] which matches any
  531. Xcharacter in the range inside the brackets (like [a\-f] or [0\-9]).  When
  532. Xthese characters are encountered (and not escaped with a backslash or
  533. Xquotes), the
  534. Xshell will look for files relative to the current path that match the
  535. Xpattern, and replace the argument with a list of the names that matched.
  536. X.PP
  537. X.I zip
  538. Xcan do the same matching on names that are in the zip file being
  539. Xmodified or, in the case of the -x (exclude) option, on the list of
  540. Xfiles to be operated on, by using backslashes or quotes
  541. Xto tell the shell not to do the name expansion.  In general, when
  542. X.I zip
  543. Xencounters a name in the list
  544. Xof files to do, it first looks for the name in the file system.  If it
  545. Xfinds it, it then adds it to the list of files to do.  If it does not
  546. Xfind it, it will look for the name in the zip file being modified (if it
  547. Xexists), using the pattern matching characters above, if any.  For each
  548. Xmatch, it will add that name to the list of files to do.  After -x
  549. X(exclude), the names are removed from the to-do list instead of added.
  550. X.PP
  551. XThe pattern matching includes the path, and so patterns like \\*.o match
  552. Xnames that end in ".o", no matter what the path prefix is.  Note that the
  553. Xbackslash must precede every special character (i.e. ?*[]), or the entire
  554. Xargument must be enclosed in double quotes ("").
  555. X.PP
  556. XIn general, using backslash to make
  557. X.I zip
  558. Xdo the pattern matching is used
  559. Xwith the -f (freshen) and -d (delete) options, and sometimes after the
  560. X-x (exclude) option when used with any operation (add, -u, -f, or -d).
  561. X.I zip
  562. Xwill never use pattern matching to search the file system.  If
  563. X.I zip
  564. Xhas recursed into a directory, all files (and all directories) in there
  565. Xare fair game.
  566. X.SH COPYRIGHT
  567. XCopyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  568. XKai Uwe Rommel and Igor Mandrichenko.
  569. XPermission is granted to any individual or institution to use, copy, or
  570. Xredistribute this software so long as all of the original files are included
  571. Xunmodified, that it is not sold for profit, and that this copyright notice
  572. Xis retained.
  573. X.SH ACKNOWLEDGEMENTS
  574. XThanks to R. P. Byrne for his Shrink.Pas program which inspired this project;
  575. Xto Phil Katz for making the zip
  576. Xfile format, compression format, and .zip filename extension all public domain;
  577. Xto Steve Burg and Phil Katz for help on unclear points of the deflate format;
  578. Xto Keith Petersen and Rich Wales for providing a mailing list and ftp site for
  579. Xthe INFO-ZIP group to use; and most importantly, to the INFO-ZIP group itself
  580. X(listed in the file infozip.who) without whose tireless testing and bug-fixing
  581. Xefforts a portable
  582. X.I zip
  583. Xwould not have been possible.  Finally we should thank (blame) the INFO-ZIP
  584. Xmoderator, David Kirschbaum for getting us into this mess in the first place.
  585. X.SH "SEE ALSO"
  586. Xunzip(1), tar(1), compress(1)
  587. X.SH BUGS
  588. XWARNING: zip files produced by zip 1.9 must not be
  589. X*updated* by zip 1.0 or pkzip 1.10 or pkzip 1.93a, if they contain
  590. Xencrypted members, or if they have been produced in a pipe or on a non
  591. Xseekable device. The old versions of zip or pkzip would destroy the
  592. Xzip structure. The old versions can list the contents of the zip file
  593. Xbut cannot extract it anyway (because of the new compression algorithm).
  594. XIf you do not use encryption and use regular disk files, you do
  595. Xnot have to care about this problem.
  596. X.PP
  597. Xzip 1.9 is compatible with pkzip 1.93a, except when two features
  598. Xare used: encryption or zip file created in a pipe or on a non
  599. Xseekable device. pkzip versions above 2.0 will support such files, and
  600. Xunzip 5.0 already supports them.
  601. X.PP
  602. XWithout -y, when zip must compress a symbolic link to an non existing file,
  603. Xit only displays a warning "name not matched". A better warnign should be
  604. Xgiven.
  605. X.PP
  606. XUnder VMS, not all of the odd file formats are treated properly.  Only
  607. Xzip files of format stream-LF and fixed length 512 are expected to work
  608. Xwith zip.  Others can be converted using Rahul Dhesi's BILF program.
  609. XThis version of zip does handle some of the conversion internally.
  610. XWhen using Kermit to transfer zip files from Vax to MSDOS, type "set
  611. Xfile type block" on the Vax.  When transfering from MSDOS to Vax, type
  612. X"set file type fixed" on the Vax.  In both cases, type "set file type
  613. Xbinary" on MSDOS.
  614. X.PP
  615. XUnder VMS, zip hangs for file specification that uses DECnet syntax (foo::*.*).
  616. X.PP
  617. XUnder OS/2, the amount of External Attributes displayed by DIR is (for
  618. Xcompatibility) the amount returned by the 16-bit version of
  619. XDosQueryPathInfo(). Otherwise OS/2 1.3 and 2.0 would report different
  620. XEA sizes when DIRing a file.
  621. XHowever, the structure layout returned by the 32-bit DosQueryPathInfo()
  622. Xis a bit different, it uses extra padding bytes and link pointers (it's
  623. Xa linked list) to have all fields on 4-byte boundaries for portability
  624. Xto future RISC OS/2 versions. Therefore the value reported by ZIP
  625. X(which uses this 32-bit-mode size) differs from that reported by DIR.
  626. XZIP stores the 32-bit format for portability, even the 16-bit
  627. XMS-C-compiled version running on OS/2 1.3, so even this one shows the
  628. X32-bit-mode size.
  629. X.PP
  630. XLIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE
  631. XPROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR
  632. XIMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
  633. XRESULTING FROM THE USE OF THIS SOFTWARE.
  634. X.PP
  635. XThat having been said, please send any problems or comments via email to
  636. Xthe Internet address
  637. Xzip\-bugs@cs.ucla.edu.  For bug reports, please include the
  638. Xversion of zip, the make options you used to compile it, the machine and
  639. Xoperating system you are using, and as much additional information as
  640. Xpossible.  Thank you for your support.
  641. END_OF_FILE
  642.   if test 21796 -ne `wc -c <'zip.1'`; then
  643.     echo shar: \"'zip.1'\" unpacked with wrong size!
  644.   fi
  645.   # end of 'zip.1'
  646. fi
  647. if test -f 'zip.h' -a "${1}" != "-c" ; then 
  648.   echo shar: Will not clobber existing file \"'zip.h'\"
  649. else
  650.   echo shar: Extracting \"'zip.h'\" \(10606 characters\)
  651.   sed "s/^X//" >'zip.h' <<'END_OF_FILE'
  652. X/*
  653. X
  654. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  655. X Kai Uwe Rommel and Igor Mandrichenko.
  656. X Permission is granted to any individual or institution to use, copy, or
  657. X redistribute this software so long as all of the original files are included
  658. X unmodified, that it is not sold for profit, and that this copyright notice
  659. X is retained.
  660. X
  661. X*/
  662. X
  663. X/*
  664. X *  zip.h by Mark Adler.
  665. X */
  666. X
  667. X
  668. X/* Set up portability */
  669. X#include "tailor.h"
  670. X
  671. X#define MIN_MATCH  3
  672. X#define MAX_MATCH  258
  673. X/* The minimum and maximum match lengths */
  674. X
  675. X#ifndef WSIZE
  676. X#  define WSIZE  ((unsigned)32768)
  677. X#endif
  678. X/* Maximum window size = 32K. If you are really short of memory, compile
  679. X * with a smaller WSIZE but this reduces the compression ratio for files
  680. X * of size > WSIZE. WSIZE must be a power of two in the current implementation.
  681. X */
  682. X
  683. X#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
  684. X/* Minimum amount of lookahead, except at the end of the input file.
  685. X * See deflate.c for comments about the MIN_MATCH+1.
  686. X */
  687. X
  688. X#define MAX_DIST  (WSIZE-MIN_LOOKAHEAD)
  689. X/* In order to simplify the code, particularly on 16 bit machines, match
  690. X * distances are limited to MAX_DIST instead of WSIZE.
  691. X */
  692. X
  693. X/* Define malloc() and string functions */
  694. X#ifdef MODERN
  695. X#  include <string.h>
  696. X#else /* !MODERN */
  697. X   voidp *malloc();
  698. X   char *getenv();
  699. X   long atol();
  700. X   char *strcpy();
  701. X   char *strcat();
  702. X   char *strchr();
  703. X   char *strrchr();
  704. X#  ifndef ZMEM
  705. X     char *memset();
  706. X     char *memcpy();
  707. X#  endif /* !ZMEM */
  708. X#endif /* ?MODERN */
  709. X
  710. X
  711. X/* Define fseek() commands */
  712. X#ifndef SEEK_SET
  713. X#  define SEEK_SET 0
  714. X#endif /* !SEEK_SET */
  715. X
  716. X#ifndef SEEK_CUR
  717. X#  define SEEK_CUR 1
  718. X#endif /* !SEEK_CUR */
  719. X
  720. X
  721. X/* Forget FILENAME_MAX (incorrectly = 14 on some System V) */
  722. X#ifdef MSDOS
  723. X#  define FNMAX 256
  724. X#else /* !MSDOS */
  725. X#  define FNMAX 1024
  726. X#endif /* ?MSDOS */
  727. X
  728. X
  729. X/* For setting stdout to binary */
  730. X#ifdef MSDOS
  731. X#  include <io.h>
  732. X#  include <fcntl.h>
  733. X#endif /* MSDOS */
  734. X
  735. X
  736. X/* Types centralized here for easy modification */
  737. X#define local static            /* More meaningful outside functions */
  738. Xtypedef unsigned char uch;      /* unsigned 8-bit value */
  739. Xtypedef unsigned short ush;     /* unsigned 16-bit value */
  740. Xtypedef unsigned long ulg;      /* unsigned 32-bit value */
  741. X
  742. X
  743. X/* Lengths of headers after signatures in bytes */
  744. X#define LOCHEAD 26
  745. X#define CENHEAD 42
  746. X#define ENDHEAD 18
  747. X
  748. X
  749. X/* Structures for in-memory file information */
  750. Xstruct zlist {
  751. X  /* See central header in zipfile.c for what vem..off are */
  752. X  ush vem, ver, flg, how;
  753. X  ulg tim, crc, siz, len;
  754. X  extent nam, ext, cext, com;   /* offset of ext must be >= LOCHEAD */
  755. X  ush dsk, att, lflg;           /* offset of lflg must be >= LOCHEAD */
  756. X  ulg atx, off;
  757. X  char *name;                   /* File name in zip file */
  758. X  char *extra;                  /* Extra field (set only if ext != 0) */
  759. X  char *cextra;                 /* Extra in central (set only if cext != 0) */
  760. X  char *comment;                /* Comment (set only if com != 0) */
  761. X  char *zname;                  /* Name for new zip file header */
  762. X  int mark;                     /* Marker for files to operate on */
  763. X  int trash;                    /* Marker for files to delete */
  764. X  int dosflag;                  /* Set to force MSDOS file attributes */
  765. X  struct zlist far *nxt;        /* Pointer to next header in list */
  766. X};
  767. Xstruct flist {
  768. X  char *name;                   /* Pointer to zero-delimited name */
  769. X  char *zname;                  /* Name used for zip file headers */
  770. X  int dosflag;                  /* Set to force MSDOS file attributes */
  771. X  struct flist far * far *lst;  /* Pointer to link pointing here */
  772. X  struct flist far *nxt;        /* Link to next name */
  773. X};
  774. X
  775. X/* internal file attribute */
  776. X#define UNKNOWN (-1)
  777. X#define BINARY  0
  778. X#define ASCII   1
  779. X
  780. X/* Error return codes and PERR macro */
  781. X#include "ziperr.h"
  782. X
  783. X
  784. X/* Public globals */
  785. Xextern uch upper[256];          /* Country dependent case map table */
  786. Xextern uch lower[256];
  787. Xextern char errbuf[];           /* Handy place to build error messages */
  788. Xextern int recurse;             /* Recurse into directories encountered */
  789. Xextern int pathput;             /* Store path with name */
  790. X
  791. X#define BEST -1                 /* Use best method (deflation or store) */
  792. X#define STORE 0                 /* Store method */
  793. X#define DEFLATE 8               /* Deflation method*/
  794. Xextern int method;              /* Restriction on compression method */
  795. X
  796. Xextern int dosify;              /* Make new entries look like MSDOS */
  797. Xextern char *special;           /* Don't compress special suffixes */
  798. Xextern int verbose;             /* Report oddities in zip file structure */
  799. Xextern int level;               /* Compression level */
  800. Xextern int translate_eol;       /* Translate end-of-line LF -> CR LF */
  801. X#ifdef VMS
  802. X   extern int vmsver;           /* Append VMS version number to file names */
  803. X   extern int vms_native;       /* Store in VMS formait */
  804. X#endif /* VMS */
  805. X#ifdef OS2
  806. X   extern int use_longname_ea;   /* use the .LONGNAME EA as the file's name */
  807. X#endif /* OS2 */
  808. Xextern int linkput;             /* Store symbolic links as such */
  809. Xextern int noisy;               /* False for quiet operation */
  810. Xextern char *key;               /* Scramble password or NULL */
  811. Xextern char *tempath;           /* Path for temporary files */
  812. Xextern FILE *mesg;              /* Where informational output goes */
  813. Xextern char *zipfile;           /* New or existing zip archive (zip file) */
  814. Xextern ulg zipbeg;              /* Starting offset of zip structures */
  815. Xextern ulg cenbeg;              /* Starting offset of central directory */
  816. Xextern struct zlist far *zfiles;/* Pointer to list of files in zip file */
  817. Xextern extent zcount;           /* Number of files in zip file */
  818. Xextern extent zcomlen;          /* Length of zip file comment */
  819. Xextern char *zcomment;          /* Zip file comment (not zero-terminated) */
  820. Xextern struct zlist far **zsort;/* List of files sorted by name */
  821. Xextern ulg tempzn;              /* Count of bytes written to output zip file */
  822. Xextern struct flist far *found; /* List of names found */
  823. Xextern struct flist far * far *fnxt;    /* Where to put next in found list */
  824. Xextern extent fcount;           /* Count of names in found list */
  825. X
  826. X
  827. X/* Diagnostic functions */
  828. X#ifdef DEBUG
  829. X# ifdef MSDOS
  830. X#  undef  stderr
  831. X#  define stderr stdout
  832. X# endif
  833. X#  define diag(where) fprintf(stderr, "zip diagnostic: %s\n", where)
  834. X#  define Assert(cond,msg) {if(!(cond)) error(msg);}
  835. X#  define Trace(x) fprintf x
  836. X#  define Tracev(x) {if (verbose) fprintf x ;}
  837. X#  define Tracevv(x) {if (verbose>1) fprintf x ;}
  838. X#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
  839. X#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
  840. X#else
  841. X#  define diag(where)
  842. X#  define Assert(cond,msg)
  843. X#  define Trace(x)
  844. X#  define Tracev(x)
  845. X#  define Tracevv(x)
  846. X#  define Tracec(c,x)
  847. X#  define Tracecv(c,x)
  848. X#endif
  849. X
  850. X
  851. X/* Public function prototypes */
  852. X
  853. X        /* in zip.c, zipcloak.c, or zipsplit.c */
  854. Xvoid warn  OF((char *, char *));
  855. Xvoid err   OF((int c, char *h));
  856. Xvoid error OF((char *h));
  857. X
  858. X        /* in zipup.c */
  859. Xint zipcopy OF((struct zlist far *, FILE *, FILE *));
  860. X#ifndef UTIL
  861. X   int percent OF((long, long));
  862. X   int zipup OF((struct zlist far *, FILE *));
  863. X   int file_read OF((char *buf, unsigned size));
  864. X#endif /* !UTIL */
  865. X
  866. X        /* in zipfile.c */
  867. X#ifndef UTIL
  868. X   struct zlist far *zsearch OF((char *));
  869. X   int trash OF((void));
  870. X#endif /* !UTIL */
  871. Xchar *ziptyp OF((char *));
  872. Xint readzipfile OF((void));
  873. Xint putlocal OF((struct zlist far *, FILE *));
  874. Xint putextended OF((struct zlist far *, FILE *));
  875. Xint putcentral OF((struct zlist far *, FILE *));
  876. Xint putend OF((int, ulg, ulg, extent, char *, FILE *));
  877. X
  878. X        /* in fileio.c */
  879. X#ifndef UTIL
  880. X#  ifdef MSDOS
  881. X     int wild OF((char *));
  882. X#  endif /* MSDOS */
  883. X#  ifdef VMS
  884. X     int wild OF((char *));
  885. X#  endif /* VMS */
  886. X   char *getnam OF((char *));
  887. X   struct flist far *fexpel OF((struct flist far *));
  888. X   char *in2ex OF((char *));
  889. X   int exclude OF((void));
  890. X   int procname OF((char *));
  891. X   void stamp OF((char *, ulg));
  892. X   ulg dostime OF((int, int, int, int, int, int));
  893. X   ulg filetime OF((char *, ulg *, long *));
  894. X   int issymlnk OF((ulg a));
  895. X#  ifdef S_IFLNK
  896. X#    define rdsymlnk(p,b,n) readlink(p,b,n)
  897. X     extern int readlink OF((char *, char *, int));
  898. X#  else /* !S_IFLNK */
  899. X#    define rdsymlnk(p,b,n) (0)
  900. X#  endif /* !S_IFLNK */
  901. X   int deletedir OF((char *));
  902. X#endif /* !UTIL */
  903. Xint destroy OF((char *));
  904. Xint replace OF((char *, char *));
  905. Xint getfileattr OF((char *));
  906. Xint setfileattr OF((char *, int));
  907. Xchar *tempname OF((char *));
  908. Xint fcopy OF((FILE *, FILE *, ulg));
  909. X#ifdef CRYPT
  910. X#  ifndef MSVMS
  911. X     void echoff OF((int));
  912. X     void echon OF((void));
  913. X#  endif /* !MSVMS */
  914. X   char *getp OF((char *, char *, int));
  915. X#endif /* !CRYPT */
  916. X#ifdef ZMEM
  917. X   char *memset OF((char *, int, unsigned int));
  918. X   char *memcpy OF((char *, char *, unsigned int));
  919. X   int memcmp OF((char *, char *, unsigned int));
  920. X#endif /* ZMEM */
  921. X
  922. X        /* in crypt.c */
  923. X#ifndef CRYPT
  924. X#  define zfwrite fwrite
  925. X#  define zputc putc
  926. X#else /* CRYPT */
  927. X   void crypthead OF((char *, ulg, FILE *));
  928. X#  ifdef UTIL
  929. X     int zipcloak OF ((struct zlist far *, FILE *, FILE *, char *));
  930. X     int zipbare OF ((struct zlist far *, FILE *, FILE *, char *));
  931. X#  else /* !UTIL */
  932. X     unsigned zfwrite OF((voidp *, extent, extent, FILE *));
  933. X     int zencode OF((int c));
  934. X     extern char *key;
  935. X#    define zputc(c,f) (putc(key!=NULL? zencode(c) : (c),(f)))
  936. X#  endif /* ?UTIL */
  937. X#endif /* ?CRYPT */
  938. X
  939. X        /* in util.c */
  940. Xchar *isshexp OF((char *));
  941. Xint   shmatch OF((char *, char *));
  942. X#ifdef MSDOS
  943. X   int dosmatch OF((char *, char *));
  944. X#endif /* MSDOS */
  945. Xvoid     init_upper OF((void));
  946. Xint      namecmp    OF((char *string1, char *string2));
  947. Xvoidp far **search  OF((voidp *, voidp far **, extent,
  948. X                       int (*)(voidp *, voidp far *)));
  949. Xulg crc32 OF((ulg, int));
  950. Xulg updcrc OF((char *, extent));
  951. X
  952. X#ifndef UTIL
  953. X        /* in deflate.c */
  954. Xvoid lm_init OF((int pack_level, ush *flags));
  955. Xulg  deflate OF((void));
  956. X
  957. X        /* in trees.c */
  958. Xvoid ct_init     OF((ush *attr, int *method));
  959. Xint  ct_tally    OF((int dist, int lc));
  960. Xulg  flush_block OF((char far *buf, ulg stored_len, int eof));
  961. X
  962. X        /* in bits.c */
  963. Xvoid     bi_init    OF((FILE *zipfile));
  964. Xvoid     send_bits  OF((int value, int length));
  965. Xunsigned bi_reverse OF((unsigned value, int length));
  966. Xvoid     bi_windup  OF((void));
  967. Xvoid     copy_block OF((char far *buf, unsigned len, int header));
  968. Xint      seekable   OF((void));
  969. Xextern   int (*read_buf) OF((char *buf, unsigned size));
  970. Xulg     memcompress OF((char *tgt, ulg tgtsize, char *src, ulg srcsize));
  971. X
  972. X#endif /* !UTIL */
  973. X
  974. X
  975. X/* end of zip.h */
  976. END_OF_FILE
  977.   if test 10606 -ne `wc -c <'zip.h'`; then
  978.     echo shar: \"'zip.h'\" unpacked with wrong size!
  979.   fi
  980.   # end of 'zip.h'
  981. fi
  982. if test -f 'zipfile.c' -a "${1}" != "-c" ; then 
  983.   echo shar: Will not clobber existing file \"'zipfile.c'\"
  984. else
  985.   echo shar: Extracting \"'zipfile.c'\" \(24578 characters\)
  986.   sed "s/^X//" >'zipfile.c' <<'END_OF_FILE'
  987. X/*
  988. X
  989. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  990. X Kai Uwe Rommel and Igor Mandrichenko.
  991. X Permission is granted to any individual or institution to use, copy, or
  992. X redistribute this software so long as all of the original files are included
  993. X unmodified, that it is not sold for profit, and that this copyright notice
  994. X is retained.
  995. X
  996. X*/
  997. X
  998. X/*
  999. X *  zipfile.c by Mark Adler.
  1000. X */
  1001. X
  1002. X#include "zip.h"
  1003. X
  1004. X#ifdef VMS
  1005. X#  include "VMSmunch.h"
  1006. X#  include <rms.h>
  1007. X#endif
  1008. X
  1009. X
  1010. X/* Macros for converting integers in little-endian to machine format */
  1011. X#define SH(a) (((ush)(uch)(a)[0]) | (((ush)(uch)(a)[1]) << 8))
  1012. X#define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16))
  1013. X
  1014. X/* Macros for writing machine integers to little-endian format */
  1015. X#define PUTSH(a,f) {putc((char)(a),(f)); putc((char)((a) >> 8),(f));}
  1016. X#define PUTLG(a,f) {PUTSH(a,f) PUTSH((a) >> 16,f)}
  1017. X
  1018. X
  1019. X/* -- Structure of a ZIP file -- */
  1020. X
  1021. X/* Signatures for zip file information headers */
  1022. X#define LOCSIG     0x04034b50L
  1023. X#define CENSIG     0x02014b50L
  1024. X#define ENDSIG     0x06054b50L
  1025. X#define EXTLOCSIG  0x08074b50L
  1026. X
  1027. X/* Offsets of values in headers */
  1028. X#define LOCVER  0               /* version needed to extract */
  1029. X#define LOCFLG  2               /* encrypt, deflate flags */
  1030. X#define LOCHOW  4               /* compression method */
  1031. X#define LOCTIM  6               /* last modified file time, DOS format */
  1032. X#define LOCDAT  8               /* last modified file date, DOS format */
  1033. X#define LOCCRC  10              /* uncompressed crc-32 for file */
  1034. X#define LOCSIZ  14              /* compressed size in zip file */
  1035. X#define LOCLEN  18              /* uncompressed size */
  1036. X#define LOCNAM  22              /* length of filename */
  1037. X#define LOCEXT  24              /* length of extra field */
  1038. X
  1039. X#define CENVEM  0               /* version made by */
  1040. X#define CENVER  2               /* version needed to extract */
  1041. X#define CENFLG  4               /* encrypt, deflate flags */
  1042. X#define CENHOW  6               /* compression method */
  1043. X#define CENTIM  8               /* last modified file time, DOS format */
  1044. X#define CENDAT  10              /* last modified file date, DOS format */
  1045. X#define CENCRC  12              /* uncompressed crc-32 for file */
  1046. X#define CENSIZ  16              /* compressed size in zip file */
  1047. X#define CENLEN  20              /* uncompressed size */
  1048. X#define CENNAM  24              /* length of filename */
  1049. X#define CENEXT  26              /* length of extra field */
  1050. X#define CENCOM  28              /* file comment length */
  1051. X#define CENDSK  30              /* disk number start */
  1052. X#define CENATT  32              /* internal file attributes */
  1053. X#define CENATX  34              /* external file attributes */
  1054. X#define CENOFF  38              /* relative offset of local header */
  1055. X
  1056. X#define ENDDSK  0               /* number of this disk */
  1057. X#define ENDBEG  2               /* number of the starting disk */
  1058. X#define ENDSUB  4               /* entries on this disk */
  1059. X#define ENDTOT  6               /* total number of entries */
  1060. X#define ENDSIZ  8               /* size of entire central directory */
  1061. X#define ENDOFF  12              /* offset of central on starting disk */
  1062. X#define ENDCOM  16              /* length of zip file comment */
  1063. X
  1064. X
  1065. X/* Local functions */
  1066. X#ifdef PROTO
  1067. X   local int zqcmp(voidp *, voidp *);
  1068. X#  ifndef UTIL
  1069. X     local int zbcmp(voidp *, voidp far *);
  1070. X     local char *cutpath(char *);
  1071. X#  endif /* !UTIL */
  1072. X#endif /* PROTO */
  1073. X
  1074. X
  1075. Xlocal int zqcmp(a, b)
  1076. Xvoidp *a, *b;           /* pointers to pointers to zip entries */
  1077. X/* Used by qsort() to compare entries in the zfile list.  */
  1078. X{
  1079. X  return namecmp((*(struct zlist far **)a)->zname,
  1080. X                (*(struct zlist far **)b)->zname);
  1081. X}
  1082. X
  1083. X
  1084. X#ifndef UTIL
  1085. X
  1086. Xlocal int zbcmp(n, z)
  1087. Xvoidp *n;               /* string to search for */
  1088. Xvoidp far *z;           /* pointer to a pointer to a zip entry */
  1089. X/* Used by search() to compare a target to an entry in the zfile list. */
  1090. X{
  1091. X  return namecmp((char *)n, ((struct zlist far *)z)->zname);
  1092. X}
  1093. X
  1094. X
  1095. Xstruct zlist far *zsearch(n)
  1096. Xchar *n;                /* name to find */
  1097. X/* Return a pointer to the entry in zfile with the name n, or NULL if
  1098. X   not found. */
  1099. X{
  1100. X  voidp far **p;        /* result of search() */
  1101. X
  1102. X  if (zcount && (p = search(n, (voidp far **)zsort, zcount, zbcmp)) != NULL)
  1103. X    return *(struct zlist far **)p;
  1104. X  else
  1105. X    return NULL;
  1106. X}
  1107. X
  1108. X#endif /* !UTIL */
  1109. X
  1110. X#ifndef VMS
  1111. X#  define PATHCUT '/'
  1112. X
  1113. Xchar *ziptyp(s)
  1114. Xchar *s;                /* file name to force to zip */
  1115. X/* If the file name *s has a dot (other than the first char), then return
  1116. X   the name, otherwise append .zip to the name.  Allocate the space for
  1117. X   the name in either case.  Return a pointer to the new name, or NULL
  1118. X   if malloc() fails. */
  1119. X{
  1120. X  char *q;              /* temporary pointer */
  1121. X  char *t;              /* pointer to malloc'ed string */
  1122. X
  1123. X  if ((t = malloc(strlen(s) + 5)) == NULL)
  1124. X    return NULL;
  1125. X  strcpy(t, s);
  1126. X#ifdef MSDOS
  1127. X  for (q = t; *q; q++)
  1128. X    if (*q == '\\')
  1129. X      *q = '/';
  1130. X#endif /* MSDOS */
  1131. X  if (strrchr((q = strrchr(t, PATHCUT)) == NULL ? t : q + 1, '.') == NULL)
  1132. X    strcat(t, ".zip");
  1133. X#if defined(FORCE_UPPER) && defined(MSDOS) && !defined(OS2)
  1134. X  strupr(t);
  1135. X#endif
  1136. X  return t;
  1137. X}
  1138. X
  1139. X#else /* VMS */
  1140. X
  1141. X# define PATHCUT ']'
  1142. X
  1143. Xchar *ziptyp(s)
  1144. Xchar *s;
  1145. X{   int status;
  1146. X    struct FAB fab;
  1147. X    struct NAM nam;
  1148. X    static char zero=0;
  1149. X    char result[NAM$C_MAXRSS+1],exp[NAM$C_MAXRSS+1];
  1150. X    char *p;
  1151. X
  1152. X    fab = cc$rms_fab;
  1153. X    nam = cc$rms_nam;
  1154. X
  1155. X    fab.fab$l_fna = s;
  1156. X    fab.fab$b_fns = strlen(fab.fab$l_fna);
  1157. X
  1158. X    fab.fab$l_dna = "sys$disk:[].zip";          /* Default fspec */
  1159. X    fab.fab$b_dns = strlen(fab.fab$l_dna);
  1160. X
  1161. X    fab.fab$l_nam = &nam;
  1162. X    
  1163. X    nam.nam$l_rsa = result;                     /* Put resultant name of */
  1164. X    nam.nam$b_rss = sizeof(result)-1;           /* existing zipfile here */
  1165. X
  1166. X    nam.nam$l_esa = exp;                        /* For full spec of */
  1167. X    nam.nam$b_ess = sizeof(exp)-1;              /* file to create */
  1168. X
  1169. X    status = sys$parse(&fab);
  1170. X    if( (status & 1) == 0 )
  1171. X        return &zero;
  1172. X
  1173. X    status = sys$search(&fab);
  1174. X    if( status & 1 )
  1175. X    {               /* Existing ZIP file */
  1176. X        int l;
  1177. X        if( (p=malloc( (l=nam.nam$b_rsl) + 1 )) != NULL )
  1178. X        {       result[l] = 0;
  1179. X                strcpy(p,result);
  1180. X        }
  1181. X    }
  1182. X    else
  1183. X    {               /* New ZIP file */
  1184. X        int l;
  1185. X        if( (p=malloc( (l=nam.nam$b_esl) + 1 )) != NULL )
  1186. X        {       exp[l] = 0;
  1187. X                strcpy(p,exp);
  1188. X        }
  1189. X    }
  1190. X    return p;
  1191. X}
  1192. X
  1193. X#endif  /* VMS */
  1194. X
  1195. X
  1196. Xint readzipfile()
  1197. X/*
  1198. X   Make first pass through zip file, reading information from local file
  1199. X   headers and then verifying that information with the central file
  1200. X   headers.  Any deviation from the expected zip file format returns an
  1201. X   error.  At the end, a sorted list of file names in the zip file is made
  1202. X   to facilitate searching by name.
  1203. X
  1204. X   The name of the zip file is pointed to by the global "zipfile".  The
  1205. X   globals zfiles, zcount, zcomlen, zcomment, and zsort are filled in.
  1206. X   Return an error code in the ZE_ class.
  1207. X*/
  1208. X{
  1209. X  char b[CENHEAD];      /* buffer for central headers */
  1210. X  FILE *f;              /* zip file */
  1211. X  ush flg;              /* general purpose bit flag */
  1212. X  int m;                /* mismatch flag */
  1213. X  extent n;             /* length of name */
  1214. X  ulg p;                /* current file offset */
  1215. X  char r;               /* holds reserved bits during memcmp() */
  1216. X  ulg s;                /* size of data, start of central */
  1217. X  char *t;              /* temporary variable */
  1218. X  char far *u;          /* temporary variable */
  1219. X  struct zlist far * far *x;    /* pointer last entry's link */
  1220. X  struct zlist far *z;  /* current zip entry structure */
  1221. X
  1222. X  /* Initialize zip file info */
  1223. X  zipbeg = 0;
  1224. X  zfiles = NULL;                        /* Points to first header */
  1225. X  zcomlen = 0;                          /* zip file comment length */
  1226. X
  1227. X  /* If zip file exists, read headers and check structure */
  1228. X#ifdef VMS
  1229. X  if (zipfile == NULL || !(*zipfile) || !strcmp(zipfile, "-"))
  1230. X    return ZE_OK;
  1231. X  {
  1232. X    int rtype;
  1233. X    VMSmunch(zipfile, GET_RTYPE, (char *)&rtype);
  1234. X    if (rtype == FAT$C_VARIABLE) {
  1235. X      fprintf(stderr,
  1236. X     "\n     Error:  zipfile is in variable-length record format.  Please\n\
  1237. X     run \"bilf b %s\" to convert the zipfile to fixed-length\n\
  1238. X     record format.  (Bilf.exe, bilf.c and make_bilf.com are included\n\
  1239. X     in the VMS UnZip distribution.)\n\n", zipfile);
  1240. X      return ZE_FORM;
  1241. X    }
  1242. X  }
  1243. X  if ((f = fopen(zipfile, FOPR)) != NULL)
  1244. X#else /* !VMS */
  1245. X  if (zipfile != NULL && *zipfile && strcmp(zipfile, "-") &&
  1246. X      (f = fopen(zipfile, FOPR)) != NULL)
  1247. X#endif /* ?VMS */
  1248. X  {
  1249. X    x = &zfiles;                        /* first link */
  1250. X    p = 0;                              /* starting file offset */
  1251. X    zcount = 0;                         /* number of files */
  1252. X
  1253. X    /* Find start of zip structures */
  1254. X    for (;;) {
  1255. X      while ((m = getc(f)) != EOF && m != 'P') p++;
  1256. X      b[0] = (char) m;
  1257. X      if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG || s == ENDSIG)
  1258. X        break;
  1259. X      if (fseek(f, -3L, SEEK_CUR))
  1260. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1261. X      p++;
  1262. X    }
  1263. X    zipbeg = p;
  1264. X
  1265. X    /* Read local headers */
  1266. X    while (LG(b) == LOCSIG)
  1267. X    {
  1268. X      /* Read local header raw to compare later with central header
  1269. X         (this requires that the offest of ext in the zlist structure
  1270. X         be greater than or equal to LOCHEAD) */
  1271. X      if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
  1272. X        return ZE_MEM;
  1273. X      if (fread(b, LOCHEAD, 1, f) != 1)
  1274. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1275. X      t = b;  u = (char far *)z;  n = LOCHEAD;
  1276. X      do {
  1277. X        *u++ = *t++;
  1278. X      } while (--n);
  1279. X
  1280. X      /* Link into list */
  1281. X      *x = z;
  1282. X      z->nxt = NULL;
  1283. X      x = &z->nxt;
  1284. X
  1285. X      /* Read file name and extra field and skip data */
  1286. X      n = SH(LOCNAM + (uch far *)z);
  1287. X      z->ext = SH(LOCEXT + (uch far *)z);
  1288. X      s = LG(LOCSIZ + (uch far *)z);
  1289. X      if (n == 0)
  1290. X      {
  1291. X        sprintf(errbuf, "%d", zcount + 1);
  1292. X        warn("zero-length name for entry #", errbuf);
  1293. X        return ZE_FORM;
  1294. X      }
  1295. X      if ((z->zname = malloc(n+1)) ==  NULL ||
  1296. X          (z->ext && (z->extra = malloc(z->ext)) == NULL))
  1297. X        return ZE_MEM;
  1298. X      if (fread(z->zname, n, 1, f) != 1 ||
  1299. X          (z->ext && fread(z->extra, z->ext, 1, f) != 1) ||
  1300. X          fseek(f, (long)s, SEEK_CUR))
  1301. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1302. X      /* If there is an extended local header, s is either 0 or
  1303. X       * the correct compressed size.
  1304. X       */
  1305. X      z->zname[n] = 0;                  /* terminate name */
  1306. X#ifdef UTIL
  1307. X      z->name = z->zname;
  1308. X#else /* !UTIL */
  1309. X      z->name = in2ex(z->zname);        /* convert to external name */
  1310. X      if (z->name == NULL)
  1311. X        return ZE_MEM;
  1312. X#endif /* ?UTIL */
  1313. X
  1314. X      /* Save offset, update for next header */
  1315. X      z->off = p;
  1316. X      p += 4 + LOCHEAD + n + z->ext + s;
  1317. X      zcount++;
  1318. X
  1319. X      /* Skip extended local header if there is one */
  1320. X      flg = SH(b+LOCFLG);
  1321. X      if ((flg & 8) != 0) {
  1322. X        /* Skip the compressed data if compressed size is unknown.
  1323. X         * For safety, we should use the central directory.
  1324. X         */
  1325. X        if (s == 0) {
  1326. X          for (;;) {
  1327. X            while ((m = getc(f)) != EOF && m != 'P') ;
  1328. X            b[0] = (char) m;
  1329. X            if (fread(b+1, 15, 1, f) != 1 || LG(b) == EXTLOCSIG)
  1330. X              break;
  1331. X            if (fseek(f, -15L, SEEK_CUR))
  1332. X              return ferror(f) ? ZE_READ : ZE_EOF;
  1333. X          }
  1334. X          s = LG(b+8);
  1335. X          p += s;
  1336. X          if ((ulg) ftell(f) != p+16L) {
  1337. X            warn("bad extended local header for ", z->zname);
  1338. X            return ZE_FORM;
  1339. X          }
  1340. X        } else {
  1341. X          /* compressed size non zero, assume that it is valid: */
  1342. X          if (fseek(f, p, SEEK_SET) || fread(b, 16, 1, f) != 1)
  1343. X            return ferror(f) ? ZE_READ : ZE_EOF;
  1344. X          if (LG(b) != EXTLOCSIG) {
  1345. X            warn("extended local header not found for ", z->zname);
  1346. X            return ZE_FORM;
  1347. X          }
  1348. X        }
  1349. X        /* overwrite the unknown values of the local header: */
  1350. X        t = b+4;  u = (char far *)z+LOCCRC;  n = 12;
  1351. X        do {
  1352. X          *u++ = *t++;
  1353. X        } while (--n);
  1354. X        p += 16L;
  1355. X      }
  1356. X      /* Read next signature */
  1357. X      if (fread(b, 4, 1, f) != 1)
  1358. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1359. X    }
  1360. X
  1361. X    /* Point to start of header list and read central headers */
  1362. X    z = zfiles;
  1363. X    s = p;                              /* save start of central */
  1364. X    while (LG(b) == CENSIG)
  1365. X    {
  1366. X      if (z == NULL)
  1367. X      {
  1368. X        warn("extraneous central header signature", "");
  1369. X        return ZE_FORM;
  1370. X      }
  1371. X
  1372. X      /* Read central header */
  1373. X      if (fread(b, CENHEAD, 1, f) != 1)
  1374. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1375. X
  1376. X      /* Compare local header with that part of central header (except
  1377. X         for the reserved bits in the general purpose flags and except
  1378. X         for length of extra fields--authentication can make these
  1379. X         different in central and local headers) */
  1380. X      z->lflg = SH(LOCFLG + (uch far *)z);      /* Save reserved bits */
  1381. X      r = b[CENFLG+1];
  1382. X      ((uch far *)z)[LOCFLG+1] &= 0x1f; /* Zero out reserved bits */
  1383. X      b[CENFLG+1] &= 0x1f;
  1384. X      for (m = 0, u = (char far *)z, n = 0; n < LOCHEAD - 2; n++)
  1385. X        if (u[n] != b[n+2])
  1386. X        {
  1387. X          if (!m)
  1388. X            warn("local and central headers differ for ", z->zname);
  1389. X          m = 1;
  1390. X          sprintf(errbuf, " offset %d--local = %02x, central = %02x",
  1391. X                  n, (uch)u[n], (uch)b[n+2]);
  1392. X          warn(errbuf, "");
  1393. X        }
  1394. X      if (m)
  1395. X        return ZE_FORM;
  1396. X      b[CENFLG+1] = r;                  /* Restore reserved bits */
  1397. X
  1398. X      /* Overwrite local header with translated central header */
  1399. X      z->vem = SH(CENVEM + b);
  1400. X      z->ver = SH(CENVER + b);
  1401. X      z->flg = SH(CENFLG + b);          /* may be different from z->lflg */
  1402. X      z->how = SH(CENHOW + b);
  1403. X      z->tim = LG(CENTIM + b);          /* time and date into one long */
  1404. X      z->crc = LG(CENCRC + b);
  1405. X      z->siz = LG(CENSIZ + b);
  1406. X      z->len = LG(CENLEN + b);
  1407. X      z->nam = SH(CENNAM + b);
  1408. X      z->cext = SH(CENEXT + b);         /* may be different from z->ext */
  1409. X      z->com = SH(CENCOM + b);
  1410. X      z->dsk = SH(CENDSK + b);
  1411. X      z->att = SH(CENATT + b);
  1412. X      z->atx = LG(CENATX + b);
  1413. X      if (z->off != LG(CENOFF + b))
  1414. X      {
  1415. X        warn("local offset in central header incorrect for ", z->zname);
  1416. X        return ZE_FORM;
  1417. X      }
  1418. X
  1419. X      /* Compare name and extra fields and read comment field */
  1420. X      if ((t = malloc(z->nam)) == NULL)
  1421. X        return ZE_MEM;
  1422. X      if (fread(t, z->nam, 1, f) != 1)
  1423. X      {
  1424. X        free((voidp *)t);
  1425. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1426. X      }
  1427. X      if (memcmp(t, z->zname, z->nam))
  1428. X      {
  1429. X        free((voidp *)t);
  1430. X        warn("names in local and central differ for ", z->zname);
  1431. X        return ZE_FORM;
  1432. X      }
  1433. X      free((voidp *)t);
  1434. X      if (z->cext)
  1435. X      {
  1436. X        if ((z->cextra = malloc(z->cext)) == NULL)
  1437. X          return ZE_MEM;
  1438. X        if (fread(z->cextra, z->cext, 1, f) != 1)
  1439. X        {
  1440. X          free((voidp *)(z->cextra));
  1441. X          return ferror(f) ? ZE_READ : ZE_EOF;
  1442. X        }
  1443. X        if (z->ext == z->cext && memcmp(z->extra, z->cextra, z->ext) == 0)
  1444. X        {
  1445. X          free((voidp *)(z->cextra));
  1446. X          z->cextra = z->extra;
  1447. X        }
  1448. X      }
  1449. X      if (z->com)
  1450. X      {
  1451. X        if ((z->comment = malloc(z->com)) == NULL)
  1452. X          return ZE_MEM;
  1453. X        if (fread(z->comment, z->com, 1, f) != 1)
  1454. X        {
  1455. X          free((voidp *)(z->comment));
  1456. X          return ferror(f) ? ZE_READ : ZE_EOF;
  1457. X        }
  1458. X      }
  1459. X
  1460. X      /* Note oddities */
  1461. X      if (verbose)
  1462. X      {
  1463. X        if (z->vem != 10 && z->vem != 11 && z->vem != 20 &&
  1464. X            (n = z->vem >> 8) != 3 && n != 2 && n != 6 && n != 0)
  1465. X        {
  1466. X          sprintf(errbuf, "made by version %d.%d on system type %d: ",
  1467. X            (ush)(z->vem & 0xff) / (ush)10,
  1468. X            (ush)(z->vem & 0xff) % (ush)10, z->vem >> 8);
  1469. X          warn(errbuf, z->zname);
  1470. X        }
  1471. X        if (z->ver != 10 && z->ver != 11 && z->ver != 20)
  1472. X        {
  1473. X          sprintf(errbuf, "needs unzip %d.%d on system type %d: ",
  1474. X            (ush)(z->ver & 0xff) / (ush)10,
  1475. X            (ush)(z->ver & 0xff) % (ush)10, z->ver >> 8);
  1476. X          warn(errbuf, z->zname);
  1477. X        }
  1478. X        if (z->flg != z->lflg)
  1479. X        {
  1480. X          sprintf(errbuf, "local flags = 0x%04x, central = 0x%04x: ",
  1481. X                  z->lflg, z->flg);
  1482. X          warn(errbuf, z->zname);
  1483. X        }
  1484. X        else if (z->flg & ~0xf)
  1485. X        {
  1486. X          sprintf(errbuf, "undefined bits used in flags = 0x%04x: ", z->flg);
  1487. X          warn(errbuf, z->zname);
  1488. X        }
  1489. X        if (z->how > DEFLATE)
  1490. X        {
  1491. X          sprintf(errbuf, "unknown compression method %u: ", z->how);
  1492. X          warn(errbuf, z->zname);
  1493. X        }
  1494. X        if (z->dsk)
  1495. X        {
  1496. X          sprintf(errbuf, "starts on disk %u: ", z->dsk);
  1497. X          warn(errbuf, z->zname);
  1498. X        }
  1499. X        if (z->att & ~1)
  1500. X        {
  1501. X          sprintf(errbuf, "unknown internal attributes = 0x%04x: ", z->att);
  1502. X          warn(errbuf, z->zname);
  1503. X        }
  1504. X        if (((n = z->vem >> 8) != 3) && n != 2 && z->atx & ~0xffL)
  1505. X        {
  1506. X          sprintf(errbuf, "unknown external attributes = 0x%08lx: ", z->atx);
  1507. X          warn(errbuf, z->zname);
  1508. X        }
  1509. X        if (z->ext || z->cext)
  1510. X          if (z->ext == z->cext && z->extra == z->cextra)
  1511. X          {
  1512. X            sprintf(errbuf, "has %d bytes of extra data: ", z->ext);
  1513. X            warn(errbuf, z->zname);
  1514. X          }
  1515. X          else
  1516. X          {
  1517. X            sprintf(errbuf,
  1518. X                    "local extra (%d bytes) != central extra (%d bytes): ",
  1519. X                    z->ext, z->cext);
  1520. X            warn(errbuf, z->zname);
  1521. X          }
  1522. X      }
  1523. X
  1524. X      /* Clear actions */
  1525. X      z->mark = 0;
  1526. X      z->trash = 0;
  1527. X
  1528. X      /* Update file offset */
  1529. X      p += 4 + CENHEAD + z->nam + z->cext + z->com;
  1530. X
  1531. X      /* Advance to next header structure */
  1532. X      z = z->nxt;
  1533. X
  1534. X      /* Read next signature */
  1535. X      if (fread(b, 4, 1, f) != 1)
  1536. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1537. X    }
  1538. X    
  1539. X    /* Read end header */
  1540. X    if (z != NULL || LG(b) != ENDSIG)
  1541. X    {
  1542. X      warn("missing end signature--probably not a zip file (did you", "");
  1543. X      warn("remember to use binary mode when you transferred it?)", "");
  1544. X      return ZE_FORM;
  1545. X    }
  1546. X    if (fread(b, ENDHEAD, 1, f) != 1)
  1547. X      return ferror(f) ? ZE_READ : ZE_EOF;
  1548. X    if (SH(ENDDSK + b) || SH(ENDBEG + b) ||
  1549. X        SH(ENDSUB + b) != SH(ENDTOT + b))
  1550. X      warn("multiple disk information ignored", "");
  1551. X    if (zcount != SH(ENDSUB + b))
  1552. X    {
  1553. X      warn("count in end of central directory incorrect", "");
  1554. X      return ZE_FORM;
  1555. X    }
  1556. X    if (LG(ENDSIZ + b) != p - s)
  1557. X    {
  1558. X      warn("central directory size is incorrect (made by stzip?)", "");
  1559. X      /* stzip 0.9 gets this wrong, so be tolerant */
  1560. X      /* return ZE_FORM; */
  1561. X    }
  1562. X    if (LG(ENDOFF + b) != s)
  1563. X    {
  1564. X      warn("central directory start is incorrect", "");
  1565. X      return ZE_FORM;
  1566. X    }
  1567. X    cenbeg = s;
  1568. X    zcomlen = SH(ENDCOM + b);
  1569. X    if (zcomlen)
  1570. X    {
  1571. X      if ((zcomment = malloc(zcomlen)) == NULL)
  1572. X        return ZE_MEM;
  1573. X      if (fread(zcomment, zcomlen, 1, f) != 1)
  1574. X      {
  1575. X        free((voidp *)zcomment);
  1576. X        return ferror(f) ? ZE_READ : ZE_EOF;
  1577. X      }
  1578. X    }
  1579. X    if (zipbeg)
  1580. X    {
  1581. X      sprintf(errbuf, " has a preamble of %ld bytes", zipbeg);
  1582. X      warn(zipfile, errbuf);
  1583. X    }
  1584. X    if (getc(f) != EOF)
  1585. X      warn("garbage at end of zip file ignored", "");
  1586. X
  1587. X    /* Done with zip file for now */
  1588. X    fclose(f);
  1589. X    
  1590. X    /* If one or more files, sort by name */
  1591. X    if (zcount)
  1592. X    {
  1593. X      if ((x = zsort =
  1594. X          (struct zlist far **)malloc(zcount * sizeof(struct zlist far *))) ==
  1595. X          NULL)
  1596. X        return ZE_MEM;
  1597. X      for (z = zfiles; z != NULL; z = z->nxt)
  1598. X        *x++ = z;
  1599. X      qsort((char *)zsort, zcount, sizeof(struct zlist far *), zqcmp);
  1600. X    }
  1601. X  }
  1602. X  return ZE_OK;
  1603. X}
  1604. X
  1605. X
  1606. Xint putlocal(z, f)
  1607. Xstruct zlist far *z;    /* zip entry to write local header for */
  1608. XFILE *f;                /* file to write to */
  1609. X/* Write a local header described by *z to file *f.  Return an error code
  1610. X   in the ZE_ class. */
  1611. X{
  1612. X  PUTLG(LOCSIG, f);
  1613. X  PUTSH(z->ver, f);
  1614. X  PUTSH(z->lflg, f);
  1615. X  PUTSH(z->how, f);
  1616. X  PUTLG(z->tim, f);
  1617. X  PUTLG(z->crc, f);
  1618. X  PUTLG(z->siz, f);
  1619. X  PUTLG(z->len, f);
  1620. X  PUTSH(z->nam, f);
  1621. X  PUTSH(z->ext, f);
  1622. X  if (fwrite(z->zname, 1, z->nam, f) != z->nam ||
  1623. X      (z->ext && fwrite(z->extra, 1, z->ext, f) != z->ext))
  1624. X    return ZE_TEMP;
  1625. X  return ZE_OK;
  1626. X}
  1627. X
  1628. Xint putextended(z, f)
  1629. Xstruct zlist far *z;    /* zip entry to write local header for */
  1630. XFILE *f;                /* file to write to */
  1631. X/* Write an extended local header described by *z to file *f.
  1632. X * Return an error code in the ZE_ class. */
  1633. X{
  1634. X  PUTLG(EXTLOCSIG, f);
  1635. X  PUTLG(z->crc, f);
  1636. X  PUTLG(z->siz, f);
  1637. X  PUTLG(z->len, f);
  1638. X  return ZE_OK;
  1639. X}
  1640. X
  1641. Xint putcentral(z, f)
  1642. Xstruct zlist far *z;    /* zip entry to write central header for */
  1643. XFILE *f;                /* file to write to */
  1644. X/* Write a central header described by *z to file *f.  Return an error code
  1645. X   in the ZE_ class. */
  1646. X{
  1647. X  PUTLG(CENSIG, f);
  1648. X  PUTSH(z->vem, f);
  1649. X  PUTSH(z->ver, f);
  1650. X  PUTSH(z->flg, f);
  1651. X  PUTSH(z->how, f);
  1652. X  PUTLG(z->tim, f);
  1653. X  PUTLG(z->crc, f);
  1654. X  PUTLG(z->siz, f);
  1655. X  PUTLG(z->len, f);
  1656. X  PUTSH(z->nam, f);
  1657. X  PUTSH(z->cext, f);
  1658. X  PUTSH(z->com, f);
  1659. X  PUTSH(z->dsk, f);
  1660. X  PUTSH(z->att, f);
  1661. X  PUTLG(z->atx, f);
  1662. X  PUTLG(z->off, f);
  1663. X  if (fwrite(z->zname, 1, z->nam, f) != z->nam ||
  1664. X      (z->cext && fwrite(z->cextra, 1, z->cext, f) != z->cext) ||
  1665. X      (z->com && fwrite(z->comment, 1, z->com, f) != z->com))
  1666. X    return ZE_TEMP;
  1667. X  return ZE_OK;
  1668. X}
  1669. X
  1670. X
  1671. Xint putend(n, s, c, m, z, f)
  1672. Xint n;                  /* number of entries in central directory */
  1673. Xulg s, c;               /* size and offset of central directory */
  1674. Xextent m;               /* length of zip file comment (0 if none) */
  1675. Xchar *z;                /* zip file comment if m != 0 */
  1676. XFILE *f;                /* file to write to */
  1677. X/* Write the end of central directory data to file *f.  Return an error code
  1678. X   in the ZE_ class. */
  1679. X{
  1680. X  PUTLG(ENDSIG, f);
  1681. X  PUTSH(0, f);
  1682. X  PUTSH(0, f);
  1683. X  PUTSH(n, f);
  1684. X  PUTSH(n, f);
  1685. X  PUTLG(s, f);
  1686. X  PUTLG(c, f);
  1687. X  PUTSH(m, f);
  1688. X  if (m && fwrite(z, 1, m, f) != m)
  1689. X    return ZE_TEMP;
  1690. X  return ZE_OK;
  1691. X}
  1692. X
  1693. X
  1694. X#ifndef UTIL
  1695. X
  1696. Xlocal char *cutpath(p)
  1697. Xchar *p;                /* path string */
  1698. X/* Cut the last path component off the name *p in place.  Return p. */
  1699. X{
  1700. X  char *r;              /* pointer to last path delimiter */
  1701. X
  1702. X#ifdef VMS                      /* change [w.x.y]z to [w.x]y.DIR */
  1703. X  if ((r = strrchr(p, ']')) != NULL)
  1704. X  {
  1705. X    *r = 0;
  1706. X    if ((r = strrchr(p, '.')) != NULL)
  1707. X    {
  1708. X      *r = ']';
  1709. X      strcat(r, ".DIR");        /* this assumes a little padding--see PAD */
  1710. X    }
  1711. X    else
  1712. X      *p = 0;
  1713. X  }
  1714. X  else
  1715. X    *p = 0;
  1716. X#else /* !VMS */                /* change w/x/y/z to w/x/y */
  1717. X  if ((r = strrchr(p, '/')) != NULL)
  1718. X    *r = 0;
  1719. X  else
  1720. X    *p = 0;
  1721. X#endif /* ?VMS */
  1722. X  return p;
  1723. X}
  1724. X
  1725. X
  1726. Xint trash()
  1727. X/* Delete the compressed files and the directories that contained the deleted
  1728. X   files, if empty.  Return an error code in the ZE_ class.  Failure of
  1729. X   destroy() or deletedir() is ignored. */
  1730. X{
  1731. X  extent i;             /* counter on deleted names */
  1732. X  extent k;             /* number of deleted directories this pass */
  1733. X  extent n;             /* number of deleted names left to handle */
  1734. X  struct zlist far **s; /* table of zip entries to handle, sorted */
  1735. X  struct zlist far *z;  /* current zip entry */
  1736. X
  1737. X  /* Count and delete marked names */
  1738. X  n = 0;
  1739. X  for (z = zfiles; z != NULL; z = z->nxt)
  1740. X    if (z->mark || z->trash)
  1741. X    {
  1742. X      z->mark = 1;
  1743. X      n++;
  1744. X      if (verbose)
  1745. X        printf("zip diagnostic: trashing file %s\n", z->name);
  1746. X      destroy(z->name);
  1747. X    }
  1748. X
  1749. X  /* Try to delete all paths that lead up to marked names */
  1750. X  if (n)
  1751. X  {
  1752. X    if ((s = (struct zlist far **)malloc((n+1)*sizeof(struct zlist far *))) ==
  1753. X        NULL ||
  1754. X        (s[0] = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
  1755. X      return ZE_MEM;
  1756. X    s[0]->name = "";
  1757. X    s++;
  1758. X    do {
  1759. X      n = k = 0;
  1760. X      for (z = zfiles; z != NULL; z = z->nxt)
  1761. X        if (z->mark)
  1762. X          s[n++] = z;
  1763. X      qsort((char *)s, n, sizeof(struct zlist far *), zqcmp);
  1764. X      for (i = 0; i < n; i++)
  1765. X        if (*cutpath(s[i]->name) && strcmp(s[i]->name, s[i-1]->name))
  1766. X        {
  1767. X          if (verbose)
  1768. X            printf("zip diagnostic: trashing directory %s\n", s[i]->name);
  1769. X          deletedir(s[i]->name);
  1770. X          k++;
  1771. X        }
  1772. X        else
  1773. X          s[i]->mark = 0;
  1774. X    } while (k);
  1775. X    farfree((voidp far *)((--s)[0]));
  1776. X    free((voidp *)s);
  1777. X  }
  1778. X  return ZE_OK;
  1779. X}
  1780. X
  1781. X#endif /* !UTIL */
  1782. END_OF_FILE
  1783.   if test 24578 -ne `wc -c <'zipfile.c'`; then
  1784.     echo shar: \"'zipfile.c'\" unpacked with wrong size!
  1785.   fi
  1786.   # end of 'zipfile.c'
  1787. fi
  1788. echo shar: End of archive 6 \(of 11\).
  1789. cp /dev/null ark6isdone
  1790. MISSING=""
  1791. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1792.     if test ! -f ark${I}isdone ; then
  1793.     MISSING="${MISSING} ${I}"
  1794.     fi
  1795. done
  1796. if test "${MISSING}" = "" ; then
  1797.     echo You have unpacked all 11 archives.
  1798.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1799. else
  1800.     echo You still must unpack the following archives:
  1801.     echo "        " ${MISSING}
  1802. fi
  1803. exit 0
  1804. exit 0 # Just in case...
  1805.