home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume23
/
zip
/
part06
< prev
next >
Wrap
Text File
|
1991-10-21
|
55KB
|
1,586 lines
Newsgroups: comp.sources.misc
From: kirsch@usasoc.soc.mil (David Kirschbaum)
Subject: v23i093: zip - Portable zip v1.0, Part06/09
Message-ID: <1991Oct21.042200.8119@sparky.imd.sterling.com>
X-Md4-Signature: 003d705b369a9b2db49a54f526e80aa5
Date: Mon, 21 Oct 1991 04:22:00 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
Posting-number: Volume 23, Issue 93
Archive-name: zip/part06
Environment: UNIX, Minix, MSDOS, OS/2, VMS
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents: Contents zip.1 zip.c
# Wrapped by kent@sparky on Sun Oct 20 22:58:54 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 6 (of 9)."'
if test -f 'Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Contents'\"
else
echo shar: Extracting \"'Contents'\" \(3587 characters\)
sed "s/^X//" >'Contents' <<'END_OF_FILE'
XCopyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as all of the original files are included
Xunmodified, that it is not sold for profit, and that this copyright notice
Xis retained.
X
XThis file is a complete list of files mentioned in the above copyright. Some
Xof the files in this list explicitly state in their text that they are public
Xdomain or not copyrighted. These files can be distributed separately and are
Xmarked below with asterisks.
X
Xfile what it is
X---- ----------
Xcontents This file.
Xcrypt.c Code for encryption and decryption (not in export version).
Xcrypt.h Header used in implode modules to access encryption routines.
Xdir_os2.c * Directory routines for OS/2.
Xdir_os2.h * Definitions of functions in dir_os2.c.
Xdoturboc.bat Batch file for compiling under Turbo C 2.0.
Xfileio.c System dependent routines (most of them anyway).
Xglobals.c Global variables.
Xhistory List of changes in the versions leading up to this one.
Xim_bits.c Output variable-length bit strings.
Xim_ctree.c Encode source values using variable-length binary code trees.
Xim_lm.asm An 80x86 assembler version of a routine in im_lmat.c.
Xim_lmat.c Find redundant text in a sliding window.
Ximplode.c Implode compression method (calls other im* modules).
Ximplode.h Definitions of functions external to the im* modules.
Xinfozip.who List of contributors to the portable Zip project.
Xmakecrc.c * Generate the CRC table in util.c and shrink.c.
Xmakefile Unix make file.
Xmakefile.bor MSDOS Borland C++ make file.
Xmakefile.exp Export make file (leaves out encryption and zipcloak).
Xmakefile.msc MSDOS Microsoft C make file.
Xmakefile.os2 OS/2 make file.
Xmakefile.pwc Power C make file.
Xmakevms.com VMS command file for compilation.
Xreadme Short file to point to zip.doc.
Xrevision.h Contains the program version number and revision date.
Xship.c * Encodes a binary stream into a mailable text stream.
Xship.def OS/2 def file for Ship.
Xshrink.c Shrink compression method.
Xtailor.h * Tailors the compilation to the system being compiled on.
Xtempf.c Temporary memory/file interface.
Xtempf.h Definitions of functions in tempf.c.
Xutil.c Miscellaneous utility routines.
Xzip.1 Source for the Zip man page (zip.doc).
Xzip.c Main routine for Zip.
Xzip.def OS/2 def file for Zip.
Xzip.doc Documentation for Zip (zip.1 processed).
Xzip.h Header for all Zip modules.
Xzip.prj Project file for Borland (Turbo) C++.
Xzipcloak.c Main routine for ZipCloak.
Xziperr.h Error messages in Zip.
Xzipfile.c Zip file format handler.
Xzipnote.c Main routine for ZipNote.
Xzipsplit.c Main routine for ZipSplit.
Xzipup.c Applies shrink and/or implode methods to compress an entry.
X
XAll of the files are in Unix (LF only) format execpt for the documentation
Xfiles, zip.prj, and doturboc.bat. On MSDOS systems, you can use the -a
Xoption of unzip to convert the source files to CRLF format. This is only
Xnecessary if you wish to edit the files--they will compile as is with
XMicrosoft C and Turbo/Borland C++ 1.0 or later. However, you will have to
Xconvert the files (using unzip -a) to the CRLF format to compile with the
Xolder Turbo C 1.0 or 2.0. You should be able to find unzip the same place
Xyou found this.
END_OF_FILE
if test 3587 -ne `wc -c <'Contents'`; then
echo shar: \"'Contents'\" unpacked with wrong size!
fi
# end of 'Contents'
fi
if test -f 'zip.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'zip.1'\"
else
echo shar: Extracting \"'zip.1'\" \(21611 characters\)
sed "s/^X//" >'zip.1' <<'END_OF_FILE'
X.\" Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
X.\" Permission is granted to any individual or institution to use, copy, or
X.\" redistribute this software so long as all of the original files are included
X.\" unmodified, that it is not sold for profit, and that this copyright notice
X.\" is retained.
X.\"
X.\" zip.1 by Mark Adler.
X.\"
X.TH ZIP 1
X.SH NAME
Xzip \- package and compress (archive) files
X.SH SYNOPSIS
X.B zip
X[
X.B \-cdefghijklmnoqrsuwyz
X] [
X.B \-b
Xpath ] [
X.B \-t
Xmmddyy ] zipfile list [
X.B \-x
Xlist ]
X.br
X.SH DESCRIPTION
X.I Zip
Xis a compression and file packaging utility for Unix, MSDOS, OS/2, and VMS.
XIt is
Xanalogous to a combination of tar and compress and is compatible with PKZIP
X(Phil Katz ZIP) for MSDOS systems.
X.PP
XThere is a companion to
X.I Zip
Xcalled
X.I UnZip
X(of course) which you should be able
Xto find the same place you got
X.I Zip. Zip
Xand
X.I UnZip
Xcan work with files
Xproduced by PKZIP under MSDOS, and PKZIP and PKUNZIP can work with files
Xproduced by
X.I Zip.
X.PP
X.I Zip
Xputs one or more compressed files into a single "zip file" along with
Xinformation about the files, including the name, path if requested, date
Xand time last modified, protection, and check information to verify the
Xfidelity of each entry.
X.I Zip
Xcan pack an entire directory structure in a
Xzip file with a single command. Compression ratios of 2:1 to 3:1 are
Xcommon for text files.
X.I Zip
Xhas two compression methods, implosion and
Xshrinking, and automatically chooses the better of the two for each file
Xto be compressed.
X.PP
X.I Zip
Xis useful for packaging a set of files to send to someone or for
Xdistribution; for archiving or backing up files; and for saving disk space by temporarily
Xcompressing unused files or directories.
X.SH "HOW TO INSTALL ZIP"
X.I Zip
Xis distributed as C source code that can be compiled on a wide range of
XUnix machines, VAXes running VMS, and MSDOS machines using
XMicrosoft or Borland C++, and OS/2 machines using Microsoft C.
XYou will
Xneed Unzip (under Unix, MSDOS, or VMS) or PKUNZIP (under MSDOS) to unpack the
Xdistribution file, zip10.zip.
X.PP
XFirst, unpack the source as follows, assuming that you
Xhave zip10.zip in the current directory:
X.PP
X.ti+5n
Xmkdir zipsrc
X.ti+5n
Xcd zipsrc
X.ti+5n
Xunzip ../zip10
X.PP
XThis extracts all source files and documentation in the directory called
X"zipsrc". You then do:
X.PP
X.ti+5n
Xmake system
X.PP
Xwhere "system" is one of: bsd, bsdold, sysv, next, next10, sun, hpux, dnix,
Xcray, 3b1, zilog, aux, convex, aix, or minix. If you are using a NeXT
Xrunning version
X2.0 or greater, then make next. If you are using 1.0, then make
Xnext10. If you
Xare using Sun OS 4.x, then make sun. If you are using HPUX, then make hpux.
XThe other special systems are DNIX 5.2 or 5.3, Cray Unicos,
XAT&T 3B1 (also known as Unix PC or PC 7300), Zilog Zeus, A/UX, Convex, AIX,
Xand MINIX.
XOtherwise, if you are using BSD Unix, try bsd. If the linker cannot find
X_memset or _memcpy, try bsdold. If you are using System V Unix or SCO Unix,
Xtry sysv. Also use sysv on a Silicon Graphics (SGI) machine.
XYou can also cross-compile
X.I Zip
Xfor MSDOS under SCO 386 Unix using "make scodos".
X.PP
XIf none of these compiles, links, and functions properly on your Unix system,
Xsee the section BUGS below for how to get help.
X.PP
XIf the appropriate system was selected, then the executable "zip" will be
Xcreated. You can move the executable "zip" to an appropriate directory
Xin the search path using a command like:
X.PP
X.ti+5n
Xmv zip ~/bin
X.PP
Xor
X.PP
X.ti+5n
Xmv zip /usr/local/bin
X.PP
XYou can use the command "set" to see the current search path. If you are
Xusing the C-Shell (csh), enter the command:
X.PP
X.ti+5n
Xrehash
X.PP
Xso csh can find the new command in the path. You are now ready to use
X.I Zip.
X.PP
XYou can also move the manual page (the raw form of what you're reading)
Xto where the Unix man command can find it (assuming you have the necessary
Xprivileges):
X.PP
X.ti+5n
Xmv zip.1 /usr/man/man1
X.PP
XYou can get rid of the now unnecessary source and object files with:
X.PP
X.ti+5n
Xcd ..
X.ti+5n
Xrm -r zipsrc
X.PP
XThis will remove the directory zip and its contents created by unzip.
XYou should keep the zip10.zip file around though, in case you
Xneed to build it again or want to give it to a colleague.
X.PP
XThe steps for installation under MSDOS, OS/2, and VMS are similar to the above:
Xfirst unzip the distribution files into their own directory. Then under
XMSDOS do one of:
X.PP
X.ti+5n
Xmake makefile.msc
X.ti+5n
Xmake -fmakefile.bor
X.PP
Xfor Microsoft or Borland C++, respectively. Under OS/2:
X.PP
X.ti+5n
Xnmake -f makefile.os2
X.PP
Xfor Microsoft C 6.00. Under VAX VMS:
X.PP
X.ti+5n
X@makevms
X.PP
XThe installation process will also compile and link several
Xother utilities. They are zipcloak for encrypting and decrypting zip files,
Xzipnote for editing zip file comments, zipsplit for splitting a zip file
Xinto several zip files, and ship for sending zip files or any other binary
Xfile via electronic mail. For command help on any of the zip* utilities,
Xsimply enter the name with no arguments. For help with ship, enter "ship -h".
X.SH "HOW TO USE ZIP"
XThe simplest use of
X.I Zip
Xis as follows:
X.PP
X.ti+5n
Xzip stuff *
X.PP
XThis will create the file "stuff.zip" (assuming it does not exist) and put
Xall the files in the current directory in stuff.zip in a compressed form.
XThe .zip suffix is added automatically, unless that file name given contains
Xa dot already. This allows specifying suffixes other than ".zip".
X.PP
XBecause of the way the shell does filename substitution, files that start
Xwith a "." are not included. To include those as well, you can:
X.PP
X.ti+5n
Xzip stuff .* *
X.PP
XEven this will not include any subdirectories that are in the current
Xdirectory. To zip up an entire directory, the command:
X.PP
X.ti+5n
Xzip -r foo foo
X.PP
Xwill create the file "foo.zip" containing all the files and directories in
Xthe directory "foo" that is in the current directory. The "r" option means
Xrecurse through the directory structure. In this case, all the
Xfiles and directories in foo are zipped, including the ones that start with
Xa ".", since the recursion does not use the shell's file-name substitution.
XYou should not use -r with the name ".*", since that matches ".." which will
Xattempt to zip up the parent directory--probably not what was intended.
X.PP
XYou may want to make a zip file that contains the files in foo, but not record
Xthe directory name, foo. You can use the -j (junk path) option to leave off
Xthe path:
X.PP
X.ti+5n
Xzip -j foo foo/*
X.PP
XThe -y option (only under Unix) will store symbolic links as such in the
Xzip file, instead of compressing and storing the file referred to in the link.
X.PP
XYou might be zipping to save disk space, in which case you could:
X.PP
X.ti+5n
Xzip -rm foo foo
X.PP
Xwhere the "m" option means "move". This will delete foo and its contents
Xafter making foo.zip. No deletions will be done until the zip has completed
Xwith no errors. This option is obviously more dangerous and should be
Xused with care.
X.PP
XIf the zip file already exists, these commands will replace existing or add
Xnew entries to the zip file. For example, if you were really short on disk
Xspace, you might not have enough room simultaneously to hold the directory
Xfoo and the compressed foo.zip. In this case, you could do it in steps. If
Xfoo contained the subdirectories tom, dick, and harry, then you could:
X.PP
X.ti+5n
Xzip -rm foo foo/tom
X.ti+5n
Xzip -rm foo foo/dick
X.ti+5n
Xzip -rm foo foo/harry
X.PP
Xwhere the first command would create foo.zip, and the next two would add to
Xit. At the completion of each zip command, the directory just zipped would
Xbe deleted, making room in which the next
X.I Zip
Xcommand could work.
X.SH "MODIFYING EXISTING ZIP FILES"
XWhen given the name of an existing zip file with the above commands,
X.I Zip
Xwill replace identically named entries in the
X.I Zip
Xfile or add entries for
Xnew names. For example, if foo.zip exists and contains foo/file1 and
Xfoo/file2, and the directory foo contains the files foo/file1 and foo/file3,
Xthen:
X.PP
X.ti+5n
Xzip -r foo foo
X.PP
Xwill replace foo/file1 in foo.zip and add foo/file3 to foo.zip. After
Xthis, foo.zip contains foo/file1, foo/file2, and foo/file3, with foo/file2
Xunchanged from before.
X.PP
XWhen changing an existing zip file,
X.I Zip
Xwill write a temporary file with
Xthe new contents, and only replace the old one when the zip has completed
Xwith no errors. Also, the two methods, shrink and implode, create
Xtemporary files that are deleted after each file is zipped. You can use
Xthe -b option to specify a different path (usually a different device) to
Xput the temporary files in. For example:
X.PP
X.ti+5n
Xzip -b /tmp stuff *
X.PP
Xwill put the temporary zip file and the temporary compression files in the
Xdirectory "/tmp", copying over stuff.zip in the current directory when
Xdone.
X.PP
XIf you are only adding entries to a zip file, not replacing, and the
X-g option is given, then
X.I Zip
Xgrows (appends to) the file instead of copying it. The danger of this is that
Xif the operation fails, the original zip file is corrupted and lost.
X.PP
XThere are two other ways to change or add entries in a zip file that are
Xrestrictions of simple addition or replacement. The first is -u (update)
Xwhich will add new entries to the zip file as before but will replace
Xexisting entries only if the modified date of the file is more recent than
Xthe date recorded for that name in the zip file. For example:
X.PP
X.ti+5n
Xzip -u stuff *
X.PP
Xwill add any new files in the current directory, and update any changed files
Xin the zip file stuff.zip. Note that
X.I Zip
Xwill not try to pack stuff.zip into
Xitself when you do this.
X.I Zip
Xwill always exclude the zip file from the files on which to be operated.
X.PP
XThe second restriction is -f (freshen) which, like update, will only replace
Xentries with newer files; unlike update, will not add files that are not
Xalready in the zip file. For this option, you may want to simply freshen all
Xof the files that are in the specified zip file. To do this you would simply:
X.PP
X.ti+5n
Xzip -f foo
X.PP
XNote that the -f option with no arguments freshens all the entries in the
Xzip file. The same is true of -u, and hence "zip -u foo" and "zip -f foo"
Xboth do the same thing.
X.PP
XThis command should
Xbe run from the same directory from which the original zip command was run,
Xsince paths stored in zip files are always relative.
X.PP
XAnother restriction that can be used with adding, updating, or freshening is
X-t (time), which will not operate on files modified earlier than the specified
Xdate. For example:
X.PP
X.ti+5n
Xzip -rt 120791 infamy foo
X.PP
Xwill add all the files in foo and its subdirectories that were last modified
Xon December 7, 1991, or later to the zip file infamy.zip.
X.PP
XAlso, files can be explicitly excluded using the -x option:
X.PP
X.ti+5n
Xzip -r foo foo -x \\*.o
X.PP
Xwhich will zip up the contents of foo into foo.zip but exclude all the
Xfiles that end in ".o". Here the backslash causes
X.I Zip
Xto match file names
Xthat were found when foo was searched.
X.PP
XThe last operation is -d (delete) which will remove entries from a zip file.
XAn example might be:
X.PP
X.ti+5n
Xzip -d foo foo/tom/junk foo/harry/\\* \\*.o
X.PP
Xwhich will remove the entry foo/tom/junk, all of the files that start with
X"foo/harry/", and all of the files that end with ".o" (in any path). Note
Xthat once again, the shell expansion has been inhibited with backslashes, so
Xthat
X.I Zip
Xcan see the asterisks.
X.I Zip
Xcan then match on the contents of the zip
Xfile instead of the contents of the current directory.
X.PP
XUnder MSDOS, -d is case sensitive when it matches names in the zip file.
XThis allows deleting names that were zipped on other systems, but requires
Xthat the names be entered in upper case if they were zipped on an MSDOS
Xsystem, so that the names can be found in the zip file and deleted.
X.SH "MORE OPTIONS"
XAs mentioned before,
X.I Zip
Xwill use the best of two methods: shrink or implode.
XUsually implode is better, but sometimes shrink is better, especially for
Xsmaller files. Sometimes neither method produces a packed version smaller
Xthan the original file, in which case it is stored in the zip file with no
Xcompression (called the "store" method).
X.PP
XThe option -s (shrink) will force
X.I Zip
Xalways to use shrink or store, and the
X-i (implode) option forces
X.I Zip
Xto use implode or store. Shrinking is faster
Xthan imploding, and so -s might be used when speed is more important than
Xoptimal compression. Implode only (-i) might be used when the unzipper
Xfor which the
Xzip file is destined can only handle implosion. An example of this is
Xthe PKSFXjr program that comes with PKZIP. Also, -i is slightly faster
Xthan imploding and shrinking at the same time. For example:
X.PP
X.ti+5n
Xzip -rs foo foo
X.PP
Xwill zip up the directory foo into foo.zip using only shrink or store.
XThe speed of implosion can also be controlled with options -0 (fastest
Xmethod but less compression) to -9 (best compression but slower). The
Xdefault value is -5. For example:
X.PP
X.ti+5n
Xzip -r0 foo foo
X.PP
XIn nearly all cases, a file that is already compressed cannot be compressed
Xfurther by
X.I Zip,
Xor if it can, the effect is minimal. The -n option prevents
X.I Zip
Xfrom trying to compress files that have the suffixes: .Z, .zip, .zoo,
Xor .arc. Such files are simply stored (0% compression) in the output zip file,
Xso that
X.I Zip
Xdoesn't waste its time trying to compress them.
XIf the environment variable NOZIP is set, then the suffixes listed
Xthere are used instead of the default list. The suffixes are separated by
Xeither colons or semicolons. For example, in Unix csh:
X.PP
X.ti+5n
Xsetenv NOZIP .Z:.zip:.tiff:.gif:.snd
X.ti+5n
Xzip -rn foo foo
X.PP
Xwill put everything in foo into foo.zip, but will store any files that end
Xin .Z, .zip, .tiff, .gif, or .snd without trying to compress them. (Image
Xand sound files often have their own specialized compression methods.) If
Xthe environment variable NOZIP exists but is empty or contains just a colon
Xor semicolon, then zip -n will store all the entries and do no compression.
X.PP
XUnder Unix and under OS/2 (if files from a HPFS are stored),
X.I Zip
Xwill store the full path (relative to the current path) and name of the
Xfile (or just the name if -j is specified) in the zip file along with the
XUnix attributes, and it will mark
Xthe entry as made under Unix. If the zip file is intended for PKUNZIP under
XMSDOS, then the -k (Katz) option should be used to attempt to convert the
Xnames and paths to conform to MSDOS, store only the MSDOS attribute (just
Xthe user write attribute from Unix), and mark the entry as made under MSDOS
X(even though it wasn't).
X.PP
XThe -o (older) option will set the "last modified" time of the zip file to
Xthe latest "last modified" time of the entries in the zip file. This can
Xbe used without any other operations, if desired. For example:
X.PP
X.ti+5n
Xzip -o foo
X.PP
Xwill change the last modified time of foo.zip to the latest time of the
Xentries in foo.zip.
X.PP
XThe -e and -c options operate on all files updated or added to the zip file.
XEncryption (-e) will prompt for a password on the terminal and will
Xnot echo the password as it is typed (if stderr is not a TTY, Zip will exit
Xwith an error). New zip entries will be encrypted using that password. For
Xadded peace of mind, you can use -ee, which will prompt for the password
Xtwice, checking that the two are the same before using it.
X.PP
XOne-line comments can be added for each file with the -c option. The zip
Xfile operations (adding or updating) will be done first, and you will then be
Xprompted for a one-line comment for each file. You can then enter the comment
Xfollowed by return, or just return for no comment.
X.PP
XThe -z option will prompt you for a multi-line comment for the entire zip
Xfile. This option can be used by itself, or in combination with other
Xoptions. The comment is ended by a line containing just a period, or an end
Xof file condition (^D on Unix, ^Z on MSDOS, OS/2, and VAX/VMS).
XSince -z reads the
Xlines from stdin, you can simply take the comment from a file:
X.PP
X.ti+5n
Xzip -z foo < foowhat
X.PP
XThe -q (quiet) option eliminates the informational messages and comment prompts
Xwhile
X.I Zip
Xis operating. This might be used in shell scripts, for example, or if the
Xzip operation is being performed as a background task ("zip -q foo *.c &").
X.PP
X.I Zip
Xcan take a list of file names to operate on from stdin using the - option.
XIn Unix, this option can be used with the find command to extend greatly
Xthe functionality of
X.I Zip.
XFor example, to zip up all the C source files in the current directory and
Xits subdirectories, you can:
X.PP
X.ti+5n
Xfind . -type f -name "*.[ch]" -print | zip source -
X.PP
XNote that the pattern must be quoted to keep the shell from expanding it.
X.PP
XUnder VMS only, the -w option will append the version number of the files to
Xthe name and zip up multiple versions of files. Without -w,
X.I Zip
Xwill only use the most recent version of the specified file(s).
X.PP
XIf
X.I Zip
Xis run with no arguments or with the -h option, the license and the
Xcommand-argument and option help is shown. The -l option just shows the
Xlicense.
X.SH "ABOUT PATTERN MATCHING"
X(Note: this section applies to Unix. Watch this space for details on MSDOS
Xand VMS operation.)
X.PP
XThe Unix shell (sh or csh) does filename substitution on command arguments.
XThe special characters are ?, which matches any single character; * which
Xmatches any number of characters (including none); and [] which matches any
Xcharacter in the range inside the brackets (like [a\-f] or [0\-9]). When
Xthese characters are encountered (and not escaped with a backslash or
Xquotes), the
Xshell will look for files relative to the current path that match the
Xpattern, and replace the argument with a list of the names that matched.
X.PP
X.I Zip
Xcan do the same matching on names that are in the zip file being
Xmodified or, in the case of the -x (exclude) option, on the list of
Xfiles to be operated on, by using backslashes or quotes
Xto tell the shell not to do the name expansion. In general, when
X.I Zip
Xencounters a name in the list
Xof files to do, it first looks for the name in the file system. If it
Xfinds it, it then adds it to the list of files to do. If it does not
Xfind it, it will look for the name in the zip file being modified (if it
Xexists), using the pattern matching characters above, if any. For each
Xmatch, it will add that name to the list of files to do. After -x
X(exclude), the names are removed from the to-do list instead of added.
X.PP
XThe pattern matching includes the path, and so patterns like \\*.o match
Xnames that end in ".o", no matter what the path prefix is. Note that the
Xbackslash must precede every special character (i.e. ?*[]), or the entire
Xargument must be enclosed in double quotes ("").
X.PP
XIn general, using backslash to make
X.I Zip
Xdo the pattern matching is used
Xwith the -f (freshen) and -d (delete) options, and sometimes after the
X-x (exclude) option when used with any operation (add, -u, -f, or -d).
X.I Zip
Xwill never use pattern matching to search the file system. If
X.I Zip
Xhas recursed into a directory, all files (and all directories) in there
Xare fair game.
X.SH COPYRIGHT
XCopyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as all of the original files are included
Xunmodified, that it is not sold for profit, and that this copyright notice
Xis retained.
X.SH ACKNOWLEDGEMENTS
XThanks to R. P. Byrne for his Shrink.Pas program which inspired this project,
Xand from which the shrink algorithm was stolen; to Phil Katz for making the zip
Xfile format, compression format, and .ZIP filename extension all public domain;
Xto Keith Petersen for providing a mailing list and ftp site for the INFO-ZIP
Xgroup to use; and most importantly, to the INFO-ZIP group itself (listed in
Xthe file infozip.who) without whose tireless testing and bug-fixing efforts
Xa portable
X.I Zip
Xwould not have been possible. Finally we should thank (blame) the INFO-ZIP
Xmoderator, David Kirschbaum for getting us into this mess in the first place.
X.SH "SEE ALSO"
Xunzip(1), tar(1), compress(1)
X.SH BUGS
XVersions of PKUNZIP before 1.1 have a bug that on rare occasions will prevent
Xit from unzipping files produced by
X.I Zip
Xor PKZIP 1.1. If you experience such problems, we recommend that you get
XPKUNZIP 1.1 or the portable
X.I Unzip,
Xneither of which have this problem.
X.PP
XUnder MSDOS, Zip will find hidden and system files, but not set the
Xattributes appropriately in the zip file so that Unzip can restore them.
XThis will be fixed in the next version.
X.PP
XUnder VMS, not all of the odd file formats are treated properly. Only
Xstream-LF format zip files are expected to work with Zip. Others can be
Xconverted using Rahul Dhesi's BILF program. The next version of Zip will
Xhandle some of the conversion internally.
X.PP
XLIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE
XPROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR
XIMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
XRESULTING FROM THE USE OF THIS SOFTWARE.
X.PP
XThat having been said, please send any problems or comments via email to
Xthe Internet address
Xzip\-bugs@cs.ucla.edu. For bug reports, please include the
Xversion of Zip, the make options you used to compile it, the machine and
Xoperating system you are using, and as much additional information as
Xpossible. Thank you for your support.
END_OF_FILE
if test 21611 -ne `wc -c <'zip.1'`; then
echo shar: \"'zip.1'\" unpacked with wrong size!
fi
# end of 'zip.1'
fi
if test -f 'zip.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'zip.c'\"
else
echo shar: Extracting \"'zip.c'\" \(25825 characters\)
sed "s/^X//" >'zip.c' <<'END_OF_FILE'
X/*
X
X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
X Permission is granted to any individual or institution to use, copy, or
X redistribute this software so long as all of the original files are included
X unmodified, that it is not sold for profit, and that this copyright notice
X is retained.
X
X*/
X
X/*
X * zip.c by Mark Adler.
X */
X
X#include "revision.h"
X#include "zip.h"
X#include <signal.h>
X
X#define PWLEN 80 /* Input buffer size for reading encryption key */
X#define MAXCOM 256 /* Maximum one-line comment size */
X
X
X/* Local option flags */
X#define DELETE 0
X#define ADD 1
X#define UPDATE 2
X#define FRESHEN 3
Xlocal int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
Xlocal int comadd = 0; /* 1=add comments for new files */
Xlocal int zipedit = 0; /* 1=edit zip comment and all file comments */
Xlocal int dispose = 0; /* 1=remove files after put in zip file */
Xlocal int latest = 0; /* 1=set zip file time to time of latest file */
Xlocal ulg before = 0; /* 0=ignore, else exclude files before this time */
X
X
X/* Temporary zip file name and file pointer */
Xlocal char *tempzip;
Xlocal FILE *tempzf;
X
X
X/* Local functions */
X#ifdef PROTO
X local void freeup(void);
X local void leave(int);
X local void err(int, char *);
X local void handler(int);
X local void license(void);
X local void help(void);
X void main(int, char **);
X#endif /* PROTO */
X
X
X
Xlocal void freeup()
X/* Free all allocations in the found list and the zfiles list */
X{
X struct flist far *f; /* steps through found list */
X struct zlist far *z; /* pointer to next entry in zfiles list */
X
X for (f = found; f != NULL; f = fexpel(f))
X ;
X while (zfiles != NULL)
X {
X z = zfiles->nxt;
X free((voidp *)(zfiles->name));
X free((voidp *)(zfiles->zname));
X if (zfiles->ext)
X free((voidp *)(zfiles->extra));
X if (zfiles->cext && zfiles->cextra != zfiles->extra)
X free((voidp *)(zfiles->cextra));
X if (zfiles->com)
X free((voidp *)(zfiles->comment));
X farfree((voidp far *)zfiles);
X zfiles = z;
X zcount--;
X }
X}
X
X
Xlocal void leave(e)
Xint e; /* exit code */
X/* Process -o and -m options (if specified), free up malloc'ed stuff, and
X exit with the code e. */
X{
X int r; /* return value from trash() */
X ulg t; /* latest time in zip file */
X struct zlist far *z; /* pointer into zfile list */
X
X /* If latest, set time to zip file to latest file in zip file */
X if (latest)
X {
X diag("changing time of zip file to time of latest file in it");
X /* find latest time in zip file */
X t = zfiles->tim;
X for (z = zfiles->nxt; z != NULL; z = z->nxt)
X if (t < z->tim)
X t = z->tim;
X /* set modified time of zip file to that time */
X stamp(zipfile, t);
X }
X if (tempath != NULL)
X {
X free((voidp *)tempath);
X tempath = NULL;
X }
X if (zipfile != NULL)
X {
X free((voidp *)zipfile);
X zipfile = NULL;
X }
X
X
X /* If dispose, delete all files in the zfiles list that are marked */
X if (dispose)
X {
X diag("deleting files that were added to zip file");
X if ((r = trash()) != ZE_OK)
X err(r, "was deleting moved files and directories");
X }
X
X
X /* Done! */
X freeup();
X#ifdef VMS
X exit(0);
X#else /* !VMS */
X exit(e);
X#endif /* ?VMS */
X}
X
X
Xlocal void err(c, h)
Xint c; /* error code from the ZE_ class */
Xchar *h; /* message about how it happened */
X/* Issue a message for the error, clean up files and memory, and exit. */
X{
X if (PERR(c))
X perror("zip error");
X fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
X if (shract)
X {
X shr_clear();
X shract = 0;
X }
X#ifndef NOIMPLODE
X if (impact)
X {
X imp_clear();
X impact = 0;
X }
X#endif /* !NOIMPLODE */
X if (tempzf != NULL)
X fclose(tempzf);
X if (tempzip != NULL)
X {
X destroy(tempzip);
X if (tempzip != zipfile)
X free((voidp *)tempzip);
X }
X if (key != NULL)
X free((voidp *)key);
X if (tempath != NULL)
X free((voidp *)tempath);
X if (zipfile != NULL)
X free((voidp *)zipfile);
X freeup();
X#ifdef VMS
X exit(0);
X#else /* !VMS */
X exit(c);
X#endif /* ?VMS */
X}
X
X
Xlocal void handler(s)
Xint s; /* signal number (ignored) */
X/* Upon getting a user interrupt, turn echo back on for tty and abort
X cleanly using err(). */
X{
X#ifndef MSVMS
X#ifndef EXPORT
X echon();
X#endif /* !EXPORT */
X putc('\n', stderr);
X#endif /* !MSVMS */
X err(ZE_ABORT, "aborting");
X s++; /* keep some compilers happy */
X}
X
X
Xvoid warn(a, b)
Xchar *a, *b; /* message strings juxtaposed in output */
X/* Print a warning message to stderr and return. */
X{
X fprintf(stderr, "zip warning: %s%s\n", a, b);
X}
X
X
Xlocal void license()
X/* Print license information to stdout. */
X{
X extent i; /* counter for copyright array */
X
X for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
X puts(copyright[i]);
X for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
X puts(disclaimer[i]);
X}
X
X
Xlocal void help()
X/* Print help (along with license info) to stdout. */
X{
X extent i; /* counter for help array */
X
X /* help array */
X static char *text[] = {
X"",
X"Zip %d.%d (%s)",
X"Usage: zip [-options] [-b path] [-t mmddyy] zipfile list [-x list]",
X" the default action is to add or replace zipfile entries from list, which",
X" can include the special name - to read names from stdin.",
X" -f freshen: only changed files -u update: only changed or new files",
X" -d delete entries in zipfile -m move into zipfile (delete files)",
X" -k simulate PKZIP made zipfile -g allow growing existing zipfile",
X" -h show this help -l show software license",
X" -r recurse into directories -j junk (don't record) directory names",
X" -i implode only -s shrink only",
X" -0 compress faster -9 compress better",
X" -q quiet operation -n don't compress special suffixes",
X" -c add one-line comments -z add zipfile comment",
X" -b use \"path\" for temp files -t only do files after \"mmddyy\"",
X#ifdef EXPORT
X" -o make zipfile as old as latest entry",
X#else /* !EXPORT */
X" -e encrypt (-ee verify key) -o make zipfile as old as latest entry",
X#endif /* ?EXPORT */
X#ifdef VMS
X" -w append the VMS version number to the name stored in the zip file",
X#endif /* VMS */
X#ifdef S_IFLNK
X" -y store symbolic links as the link instead of the referenced file",
X#endif /* !S_IFLNK */
X" -x exclude the names that follow from those operated on"
X };
X
X for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
X puts(copyright[i]);
X for (i = 0; i < sizeof(text)/sizeof(char *); i++)
X {
X printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
X putchar('\n');
X }
X}
X
X
X/* Do command line expansion for MSDOS and VMS */
X#ifdef MSVMS
X# define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
X#else /* !MSVMS */
X# define PROCNAME(n) procname(n)
X#endif /* ?MSVMS */
X
X
Xvoid main(argc, argv)
Xint argc; /* number of tokens in command line */
Xchar **argv; /* command line tokens */
X/* Add, update, freshen, or delete zip entries in a zip file. See the
X command help in help() above. */
X{
X int a; /* attributes of zip file */
X ulg c; /* start of central directory */
X int d; /* true if just adding to a zip file */
X char *e; /* malloc'd comment buffer */
X struct flist far *f; /* steps through found linked list */
X int i; /* arg counter, root directory flag */
X int k; /* next argument type, marked counter,
X comment size, entry count */
X ulg n; /* total of entry len's */
X int o; /* true if there were any ZE_OPEN errors */
X char *p; /* steps through option arguments */
X int r; /* temporary variable */
X ulg t; /* file time, length of central directory */
X struct zlist far *v; /* temporary variable */
X struct zlist far * far *w; /* pointer to last link in zfiles list */
X FILE *x, *y; /* input and output zip files */
X struct zlist far *z; /* steps through zfiles linked list */
X
X
X /* Process arguments */
X diag("processing arguments");
X if (argc == 1)
X {
X help();
X exit(0);
X }
X zipfile = tempzip = NULL;
X tempzf = NULL;
X d = 0; /* disallow adding to a zip file */
X signal(SIGINT, handler);
X signal(SIGTERM, handler);
X k = 0; /* Next non-option argument type */
X for (i = 1; i < argc; i++)
X {
X if (argv[i][0] == '-')
X if (argv[i][1])
X for (p = argv[i]+1; *p; p++)
X switch(*p)
X {
X case '0': case '1': case '2': case '3': case '4':
X case '5': case '6': case '7': case '8': case '9':
X /* Set the compression efficacy */
X level = *p - '0'; break;
X case 'b': /* Specify path for temporary file */
X if (k != 0)
X err(ZE_PARMS, "use -b before zip file name");
X else
X k = 1; /* Next non-option is path */
X break;
X case 'c': /* Add comments for new files in zip file */
X comadd = 1; break;
X case 'd': /* Delete files from zip file */
X if (action != ADD)
X err(ZE_PARMS, "specify just one action");
X action = DELETE;
X break;
X#ifndef EXPORT
X case 'e': /* Encrypt */
X e = key == NULL ? (char *)NULL : key;
X if ((key = malloc(PWLEN+1)) == NULL)
X err(ZE_MEM, "was getting encryption password");
X if (getp(e == NULL ? "Enter password: " : "Verify password: ",
X key, PWLEN+1) == NULL)
X err(ZE_PARMS, "stderr is not a tty");
X if (e != NULL)
X {
X r = strcmp(key, e);
X free((voidp *)e);
X if (r)
X err(ZE_PARMS, "password not verified");
X }
X break;
X#endif /* !EXPORT */
X case 'f': /* Freshen zip file--overwrite only */
X if (action != ADD)
X err(ZE_PARMS, "specify just one action");
X action = FRESHEN;
X break;
X case 'g': /* Allow appending to a zip file */
X d = 1; break;
X case 'h': /* Help */
X help(); break;
X case 'i': /* Implode only */
X method = IMPLODE; break;
X case 'j': /* Junk directory names */
X pathput = 0; break;
X case 'k': /* Make entries using DOS names (k for Katz) */
X dosify = 2; break;
X case 'l': /* Show license, version */
X license(); break;
X case 'm': /* Delete files added or updated in zip file */
X dispose = 1; break;
X case 'n': /* Don't compress files with a special suffix */
X if ((special = getenv("NOZIP")) == NULL)
X special = ".Z:.zip:.zoo:.arc";
X#ifndef OS2
X#ifdef MSDOS
X strupr(special);
X#endif /* MSDOS */
X#endif /* !OS2 */
X break;
X case 'o': /* Set zip file time to time of latest file in it */
X latest = 1; break;
X case 'p': /* Store path with name */
X break; /* (do nothing as annoyance avoidance) */
X case 'q': /* Quiet operation */
X noisy = 0; break;
X case 'r': /* Recurse into subdirectories */
X recurse = 1; break;
X case 's': /* Shrink only */
X method = SHRINK; break;
X case 't': /* Exclude files earlier than specified date */
X if (before)
X err(ZE_PARMS, "can only have one -t");
X k = 2; break;
X case 'u': /* Update zip file--overwrite only if newer */
X if (action != ADD)
X err(ZE_PARMS, "specify just one action");
X action = UPDATE;
X break;
X case 'v': /* Mention oddities in zip file structure */
X verbose = 1;
X break;
X#ifdef VMS
X case 'w': /* Append the VMS version number */
X vmsver = 1; break;
X#endif /* VMS */
X case 'x': /* Exclude following files */
X if (k != 4 &&
X (k != 3 || (action != UPDATE && action != FRESHEN)))
X err(ZE_PARMS, "nothing to exclude (-x) from");
X if (k == 3) /* must be -u or -f */
X for (z = zfiles; z != NULL; z = z->nxt)
X z->mark = 1; /* mark all of them */
X k = 5;
X if ((r = exclude()) != ZE_OK)
X if (r == ZE_PARMS)
X err(r, "cannot repeat names in zip file");
X else
X err(r, "was processing list of files");
X break;
X#ifdef S_IFLNK
X case 'y': /* Store symbolic links as such */
X linkput = 1; break;
X#endif /* !S_IFLNK */
X case 'z': /* Edit zip file comment */
X zipedit = 1; break;
X default:
X {
X sprintf(errbuf, "no such option: %c", *p);
X err(ZE_PARMS, errbuf);
X }
X }
X else /* just a dash */
X if (k < 3)
X err(ZE_PARMS, "zip file cannot be stdin");
X else /* read names from stdin */
X while ((p = getnam(errbuf)) != NULL)
X {
X if ((r = PROCNAME(p)) != ZE_OK)
X if (r == ZE_MISS)
X warn("name not matched: ", p);
X else
X err(r, p);
X }
X else /* not an option */
X {
X switch (k)
X {
X case 0:
X if ((zipfile = ziptyp(argv[i])) == NULL)
X err(ZE_MEM, "was processing arguments");
X if ((r = readzipfile()) != ZE_OK)
X err(r, zipfile);
X found = NULL;
X fnxt = &found;
X k = 3;
X break;
X case 1:
X if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL)
X err(ZE_MEM, "was processing arguments");
X strcpy(tempath, argv[i]);
X k = 0;
X break;
X case 2:
X {
X int yy, mm, dd; /* results of sscanf() */
X
X if (sscanf(argv[i], "%2d%2d%2d", &mm, &dd, &yy) != 3 ||
X mm < 1 || mm > 12 || dd < 1 || dd > 31)
X err(ZE_PARMS, "invalid date entered for -t option");
X before = dostime(yy + (yy < 80 ? 2000 : 1900), mm, dd, 0, 0, 0);
X k = 0;
X break;
X }
X case 3: case 4: case 5:
X if ((r = PROCNAME(argv[i])) != ZE_OK)
X if (r == ZE_MISS)
X warn("name not matched: ", argv[i]);
X else
X err(r, argv[i]);
X if (k == 3)
X k = 4;
X }
X }
X }
X if (k < 3)
X exit(0); /* No zip file, don't complain */
X if (k != 5) /* Clean up selections */
X {
X if (k == 3 && (action == UPDATE || action == FRESHEN))
X for (z = zfiles; z != NULL; z = z->nxt)
X z->mark = 1; /* if -u or -f with no args, do all */
X if ((r = exclude()) != ZE_OK) /* remove duplicates in found list */
X if (r == ZE_PARMS)
X err(r, "cannot repeat names in zip file");
X else
X err(r, "was processing list of files");
X }
X if (zcount)
X free((voidp *)zsort);
X
X
X /* Check option combinations */
X if (action == DELETE && (method != BEST || dispose || recurse ||
X dosify || key != NULL || comadd || zipedit))
X err(ZE_PARMS, "invalid option(s) used with -d");
X if (linkput && dosify)
X err(ZE_PARMS, "can't use -y with -k");
X
X /* If -b not specified, make temporary path the same as the zip file */
X#ifdef MSDOS
X if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
X (p = strrchr(zipfile, '\\')) != NULL ||
X (p = strrchr(zipfile, ':')) != NULL))
X {
X if (*p == ':')
X p++;
X#else /* !MSDOS */
X if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
X {
X#endif /* ?MSDOS */
X if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
X err(ZE_MEM, "was processing arguments");
X r = *p; *p = 0;
X strcpy(tempath, zipfile);
X *p = (char)r;
X }
X
X /* If under MSDOS, force entries to look like made by PKZIP */
X#ifndef OS2
X#ifdef MSDOS
X dosify = 1;
X#endif /* MSDOS */
X#endif /* !OS2 */
X
X
X /* For each marked entry, if not deleting, check if it exists, and if
X updating or freshening, compare date with entry in old zip file.
X Unmark if it doesn't exist or is too old, else update marked count. */
X diag("stating marked entries");
X k = 0; /* Initialize marked count */
X for (z = zfiles; z != NULL; z = z->nxt)
X if (z->mark)
X if (action != DELETE &&
X ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
X t < before ||
X ((action == UPDATE || action == FRESHEN) && t <= z->tim)))
X {
X z->mark = 0;
X z->trash = t && t >= before; /* delete if -um or -fm */
X if (verbose)
X printf("zip diagnostic: %s %s\n", z->name,
X z->trash ? "up to date" : "missing or early");
X }
X else
X k++;
X
X
X /* Remove entries from found list that do not exist or are too old */
X diag("stating new entries");
X for (f = found; f != NULL;)
X if (action == DELETE || action == FRESHEN ||
X (t = filetime(f->name, (ulg *)NULL, (long *)NULL)) == 0 ||
X t < before || strcmp(f->name, zipfile) == 0)
X f = fexpel(f);
X else
X f = f->nxt;
X
X
X /* Make sure there's something left to do */
X if (k == 0 && found == NULL && !(zfiles != NULL && (latest || zipedit)))
X if (action == UPDATE || action == FRESHEN)
X leave(ZE_OK);
X else
X err(ZE_NONE, zipfile);
X d = (d && k == 0 && zfiles != NULL); /* d true if just appending */
X
X
X /* Before we get carried away, make sure zip file is writeable */
X if ((x = fopen(zipfile, zfiles == NULL ? FOPW : FOPM)) == NULL)
X err(ZE_CREAT, zipfile);
X fclose(x);
X a = getfileattr(zipfile);
X if (zfiles == NULL)
X destroy(zipfile);
X
X
X /* Open zip file and temporary output file */
X diag("opening zip file and creating temporary zip file");
X x = NULL;
X if (d)
X {
X if ((y = fopen(zipfile, FOPM)) == NULL)
X err(ZE_NAME, zipfile);
X tempzip = zipfile;
X tempzf = y;
X#ifdef MSDOS
X {
X char *zipbuf;
X
X zipbuf = (char *)malloc(BSZ);
X if (zipbuf == NULL)
X err(ZE_MEM, tempzip);
X setbuf(y, zipbuf);
X }
X#endif /* MSDOS */
X if (fseek(y, cenbeg, SEEK_SET))
X err(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
X }
X else
X {
X if (zfiles != NULL && (x = fopen(zipfile, FOPR)) == NULL)
X err(ZE_NAME, zipfile);
X if ((tempzip = tempname('Z')) == NULL)
X err(ZE_MEM, tempzip);
X if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
X err(ZE_TEMP, tempzip);
X if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
X err(r, r == ZE_TEMP ? tempzip : zipfile);
X }
X o = 0; /* no ZE_OPEN errors yet */
X
X
X /* Process zip file, updating marked files */
X if (zfiles != NULL)
X diag("going through old zip file");
X w = &zfiles;
X while ((z = *w) != NULL)
X if (z->mark)
X {
X /* if not deleting, zip it up */
X if (action != DELETE)
X {
X if (noisy)
X {
X printf("updating %s", z->zname);
X fflush(stdout);
X }
X if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
X {
X if (noisy)
X {
X putchar('\n');
X fflush(stdout);
X }
X sprintf(errbuf, "was zipping %s", z->name);
X err(r, errbuf);
X }
X if (r == ZE_OPEN)
X {
X o = 1;
X if (noisy)
X {
X putchar('\n');
X fflush(stdout);
X }
X perror("zip warning");
X warn("could not open for reading: ", z->name);
X warn("will just copy entry over: ", z->zname);
X if ((r = zipcopy(z, x, y)) != ZE_OK)
X {
X sprintf(errbuf, "was copying %s", z->zname);
X err(r, errbuf);
X }
X z->mark = 0;
X }
X w = &z->nxt;
X }
X else
X {
X if (noisy)
X {
X printf("deleting %s\n", z->zname);
X fflush(stdout);
X }
X v = z->nxt; /* delete entry from list */
X free((voidp *)(z->name));
X free((voidp *)(z->zname));
X if (z->ext)
X free((voidp *)(z->extra));
X if (z->cext && z->cextra != z->extra)
X free((voidp *)(z->cextra));
X if (z->com)
X free((voidp *)(z->comment));
X farfree((voidp far *)z);
X *w = v;
X zcount--;
X }
X }
X else
X {
X /* copy the original entry verbatim */
X if (!d && (r = zipcopy(z, x, y)) != ZE_OK)
X {
X sprintf(errbuf, "was copying %s", z->zname);
X err(r, errbuf);
X }
X w = &z->nxt;
X }
X if (x != NULL)
X fclose(x);
X
X
X /* Process the edited found list, adding them to the zip file */
X diag("zipping up new entries, if any");
X for (f = found; f != NULL; f = fexpel(f))
X {
X /* add a new zfiles entry and set the name */
X if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
X err(ZE_MEM, "was adding files to zip file");
X z->nxt = NULL;
X z->name = f->name;
X f->name = NULL;
X z->zname = f->zname;
X f->zname = NULL;
X z->ext = z->cext = z->com = 0;
X z->mark = 1;
X /* zip it up */
X if (noisy)
X {
X printf("adding %s", z->zname);
X fflush(stdout);
X }
X if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
X {
X if (noisy)
X {
X putchar('\n');
X fflush(stdout);
X }
X sprintf(errbuf, "was zipping %s", z->name);
X err(r, errbuf);
X }
X if (r == ZE_OPEN)
X {
X o = 1;
X if (noisy)
X {
X putchar('\n');
X fflush(stdout);
X }
X perror("zip warning");
X warn("could not open for reading: ", z->name);
X free((voidp *)(z->name));
X free((voidp *)(z->zname));
X farfree((voidp far *)z);
X }
X else
X {
X *w = z;
X w = &z->nxt;
X zcount++;
X }
X }
X if (key != NULL)
X {
X free((voidp *)key);
X key = NULL;
X }
X
X
X /* Get one line comment for each new entry */
X if (comadd)
X {
X if ((e = malloc(MAXCOM + 1)) == NULL)
X err(ZE_MEM, "was reading comment lines");
X for (z = zfiles; z != NULL; z = z->nxt)
X if (z->mark)
X {
X if (noisy)
X printf("Enter comment for %s:\n", z->name);
X if (fgets(e, MAXCOM+1, stdin) != NULL)
X {
X if ((p = malloc((k = strlen(e))+1)) == NULL)
X {
X free((voidp *)e);
X err(ZE_MEM, "was reading comment lines");
X }
X strcpy(p, e);
X if (p[k-1] == '\n')
X p[--k] = 0;
X z->comment = p;
X z->com = k;
X }
X }
X free((voidp *)e);
X }
X
X /* Get multi-line comment for the zip file */
X if (zipedit)
X {
X if ((e = malloc(MAXCOM + 1)) == NULL)
X err(ZE_MEM, "was reading comment lines");
X if (noisy && zcomlen)
X {
X puts("current zip file comment is:");
X fwrite(zcomment, 1, zcomlen, stdout);
X if (zcomment[zcomlen-1] != '\n')
X putchar('\n');
X free((voidp *)zcomment);
X }
X zcomment = malloc(1);
X *zcomment = 0;
X if (noisy)
X puts("enter new zip file comment (end with .):");
X while (fgets(e, MAXCOM+1, stdin) != NULL && strcmp(e, ".\n"))
X {
X if (e[(r = strlen(e)) - 1] == '\n')
X e[--r] = 0;
X if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
X {
X free((voidp *)e);
X err(ZE_MEM, "was reading comment lines");
X }
X if (*zcomment)
X strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
X else
X strcpy(p, *e ? e : "\r\n");
X free((voidp *)zcomment);
X zcomment = p;
X }
X zcomlen = strlen(zcomment);
X free((voidp *)e);
X }
X
X
X /* Write central directory and end header to temporary zip */
X diag("writing central directory");
X k = 0; /* keep count for end header */
X if ((c = ftell(y)) == -1L) /* get start of central */
X err(d ? ZE_WRITE : ZE_TEMP, tempzip);
X n = t = 0;
X for (z = zfiles; z != NULL; z = z->nxt)
X {
X if ((r = putcentral(z, y)) != ZE_OK)
X err(r, tempzip);
X n += z->len;
X t += z->siz;
X k++;
X }
X if (k == 0)
X warn("zip file empty", "");
X if (verbose)
X printf("total bytes=%lu, compressed=%lu -> %d%% savings\n",
X n, t, percent(n, t));
X if ((t = ftell(y)) == -1L) /* get end of central */
X err(d ? ZE_WRITE : ZE_TEMP, tempzip);
X t -= c; /* compute length of central */
X diag("writing end of central directory");
X if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK)
X err(r, tempzip);
X tempzf = NULL;
X if (fclose(y))
X err(d ? ZE_WRITE : ZE_TEMP, tempzip);
X
X
X /* Replace old zip file with new zip file, leaving only the new one */
X if (!d)
X {
X diag("replacing old zip file with new zip file");
X if ((r = replace(zipfile, tempzip)) != ZE_OK)
X {
X warn("new zip file left as: ", tempzip);
X free((voidp *)tempzip);
X tempzip = NULL;
X err(r, "was replacing the original zip file");
X }
X free((voidp *)tempzip);
X }
X tempzip = NULL;
X setfileattr(zipfile, a);
X
X /* Finish up (process -o, -m, clean up). Exit code depends on o. */
X leave(o ? ZE_OPEN : ZE_OK);
X}
END_OF_FILE
if test 25825 -ne `wc -c <'zip.c'`; then
echo shar: \"'zip.c'\" unpacked with wrong size!
fi
# end of 'zip.c'
fi
echo shar: End of archive 6 \(of 9\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 9 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.