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

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