Only in .: Makefile
diff -c ../zip19i/README ./README
*** ../zip19i/README	Tue Nov  3 21:07:53 1992
--- ./README	Wed Sep  8 00:23:06 1993
***************
*** 1,8 ****
! zip 1.9i is a BETA version. Do not distribute outside the info-zip
! group. See the file history for all changes with respect to previous
! versions. There are only minor differences with 1.9h, to allow
! again compilation gcc on SCO and BC++ on MSDOS.
  
- Send problem reports to zip-bugs@wkuvx1.bitnet. Thanks.
  
! Jean-loup
--- 1,151 ----
! Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
! Kai Uwe Rommel, Igor Mandrichenko and John Bush.
! Permission is granted to any individual or institution to use, copy, or
! redistribute this software so long as all of the original files are included,
! that it is not sold for profit, and that this copyright notice is retained.
  
  
! Zip 2.0 is a compression and file packaging utility.  It is compatible with
! PKZIP 2.04g (Phil Katz ZIP) for MSDOS systems.  There is a companion to zip
! called unzip (of course) which you should be able to find the same place
! you got zip. See the file 'Where' for details on ftp sites and mail
! servers.
! 
! This version of zip has been ported to a wide array of Unix and other
! mainframes, minis, and micros including VMS, OS/2, Minix, MSDOS, Windows NT,
! Atari and Amiga. Although highly compatible with PKware's PKZIP and PKUNZIP
! utilities of MSDOS fame, our primary objective has been one of portability
! and other-than-MSDOS functionality.  Features not found in the PKWare version
! include creation of zip files in a pipe or on a device, VMS and OS/2 extended
! file attributes, conversion from Unix to MSDOS text file format; and, of
! course, the ability to run on most of your favorite operating systems.
! And it's free.
! 
! Main changes since zip 1.9p1:
! 
! - new -i option (include only the following names).
! - new -T option to test zip file integrity before overwriting original
! - new -F and -FF (zipfix) options
! - new -D option (do not create entries for directories)
! - new -S option to include hidden/system files on MSDOS and OS/2
! - new -$ option to include a volume label on MSDOS and OS/2
! - new -ll option for CR LF to LF translation
! - new -p option for zipsplit (pause between diskettes)
! - speed up for the fast options (-1 to -3)
! - support for new systems (Amiga, TOPS 20, Human68k, ...)
! - many portability improvements
! - many bug fixes
! 
! See the file 'history' for a detailed list of all changes.
! 
! This version does not support multi-volume archives as in pkzip 2.04g.
! This may be provided in a future version if time permits.
! 
! Please read the file install.doc for information on how to compile and
! install zip, zipsplit and zipnote.  Please read the file zip.doc for
! information on how to use them.  The file "contents" is a complete
! list of the files you should have in this distribution.  Also, if you
! are using MSDOS, you should read the note on file formats at the end
! of the contents file.
! 
! This version supports encryption, but the encryption code is distributed
! separately because of the US export regulations. See the file 'Where'
! for access to the encryption code. Decryption can be made with unzip 5.0p1
! or later, or with zipcloak (which is provided in the encryption supplement).
! 
! All bug reports should go to zip-bugs@wkuvx1.bitnet, and suggestions for
! new features can be sent to info-zip@wkuvx1.bitnet (although we don't
! promise to use all suggestions). Patches should be sent as context diffs
! only (diff -c).
! 
! If you're considering a port, please check in with zip-bugs FIRST,
! since the code is constantly being updated behind the scenes.  We'll
! arrange to give you access to the latest source.  The alternative is the
! possibility that your hard work will be tucked away in a sub-archive
! and pretty much ignored. Ports to VM/CMS and MVS would be welcome.
! 
! All bug reports should go to zip-bugs@wkuvx1.bitnet, and suggestions for
! new features can be sent to info-zip@wkuvx1.bitnet (although we don't
! promise to use all suggestions). If you can't reach bitnet, try
! zip-bugs%wkuvx1.bitnet@ukcc.uky.edu.
! 
! If you'd like to keep up to date with our Zip (and companion UnZip utility)
! development, join the ranks of BETA testers, add your own thoughts and con-
! tributions, etc., send a two-line mail message containing the commands HELP
! and LIST (on separate lines in the body of the message, not on the subject
! line) to mxserver@wkuvx1.bitnet.  You'll receive two messages listing the
! various Info-ZIP mailing-list formats which are available (and also various
! unrelated lists) and instructions on how to subscribe to one or more of them
! (courtesy of Hunter Goatley).
! 
! Frequently asked questions on zip and unzip:
! 
! Q. When unzipping I get an error message about "compression method 8".
! 
! A. Please get the latest version of unzip. See the file Where for details.
! 
! 
! Q. I can't extract this zip file that I just downloaded. I get
!    "zipfile is part of multi-disk archive" or some other message.
! 
! A. Please make sure that you made the transfer in binary mode. Check
!    in particular that your copy has exactly the same size as the original.
!    
! 
! Q. When running unzip, I get a message about "End-of-central-directory
!    signature not found".
! 
! A. This usually means that your zip archive is damaged, or that you
!    have an uncompressed file with the same name in the same directory.
!    In the first case, it makes more sense to contact the person you
!    obtained the zip file from rather than the Info-Zip software
!    developers, and to make sure that your copy is strictly identical to
!    the original.  In the second case, use "unzip zipfile.zip" instead
!    of "unzip zipfile", to let unzip know which file is the zip archive
!    you want to extract.
! 
! 
! Q. Why doesn't zip do <something> just like PKZIP does?
! 
! A. Zip is not a PKZIP clone and is not intended to be one.  In some
!    cases we feel PKZIP does not do the right thing (e.g., not
!    including pathnames by default); in some cases the operating system
!    itself is responsible (e.g., under Unix it is the shell which
!    expands wildcards, not zip).  Info-ZIP's and PKWARE's zipfiles
!    are interchangeable, not the programs.
! 
! 
! Q. Can I distribute zip and unzip sources and/or executables?
! 
! A. You may redistribute the latest official distributions without any
!    modification, without even asking us for permission. You can charge
!    for the cost of the media (CDROM, diskettes, etc...) and a small copying
!    fee.  If you want to distribute modified versions please contact us at
!    zip-bugs@wkuvx1.bitnet first. You must not distribute beta versions.
!    The latest official distributions are always on ftp.uu.net in directory
!    /pub/archiving/zip and subdirectories.
! 
! 
! Q. Can I use the executables of zip and unzip to distribute my software?
! 
! A. Yes, so long as it is made clear in the product documentation that
!    zip or unzip are not being sold, that the source code is freely
!    available, and that there are no extra or hidden charges resulting
!    from its use by or inclusion with the commercial product. Here is
!    an example of a suitable notice:
! 
!      NOTE:  <Product> is packaged on this CD using Info-ZIP's compression
!      utility.  The installation program uses UnZip to read zip files from
!      the CD.  Info-ZIP's software (Zip, UnZip and related utilities) is
!      free and can be obtained as source code or executables from various
!      anonymous-ftp sites, including ftp.uu.net:/pub/archiving/zip/*.
! 
! 
! Q. Can I use the source code of zip and unzip in my commercial application?
! 
! A. Yes, so long as you include in your product an acknowledgment and an
!    offer of the original compression sources for free or for a small
!    copying fee, and make clear that there are no extra or hidden charges
!    resulting from the use of the compression code by your product. In other
!    words, you are allowed to sell only your own work, not ours. If you have
!    special requirements contact us at zip-bugs@wkuvx1.bitnet.
diff -c ../zip19i/Where ./Where
*** ../zip19i/Where	Tue Nov  3 21:07:53 1992
--- ./Where	Thu Sep  2 19:50:54 1993
***************
*** 1,11 ****
  __________________________________________________________________________
  
!   This is the Info-ZIP file ``Where,'' last updated on 22 October 1992.
  __________________________________________________________________________
  
     Note that some ftp sites may not yet have the latest versions of
     Zip and UnZip when you read this.  The latest versions, including
!    the crypt sources, are always in the comp.sources.misc archives.
  
     SITE OWNERS:  If you're listed in here but the information is not
     correct (or if you're a big site but aren't listed at all), please
--- 1,11 ----
  __________________________________________________________________________
  
!   This is the Info-ZIP file ``Where,'' last updated on Sept 2nd 1993.
  __________________________________________________________________________
  
     Note that some ftp sites may not yet have the latest versions of
     Zip and UnZip when you read this.  The latest versions, including
!    the crypt sources, are always in ftp.uu.net:/pub/archiving/zip/...
  
     SITE OWNERS:  If you're listed in here but the information is not
     correct (or if you're a big site but aren't listed at all), please
***************
*** 18,83 ****
  utilities (on some ftp sites, the .zip files may have a .zoo equivalent
  in Zoo 2.10 format):
  
!    zip19p1.zip     Zip 1.9, patchlevel 1 (deflation; includes zipnote, zipsplit)
!    zip19p1.tar.Z   ditto, compress'd tar format
  
     zip11.zip       Zip 1.1 (shrinking, implosion; compatible with PKUNZIP 1.1)
     zip11.tar.Z     ditto, compress'd tar format
  
!    unzip50.zip     UnZip 5.0 (all methods supported; includes zipinfo, funzip)
!    unzip50.tar.Z   ditto, compress'd tar format
  
!    wunz13sr.zip    WizUnZip 1.3 support files for Windows 3.1, UnZip 5.0
  
!    zcrypt19.zip    encryption/decryption support (includes zipcloak)
  
  Related archives and files:
  
     UnzpHist.zip    complete changes history of UnZip and precursors
  
!    zip19p1x.zip    MSDOS executables and docs for zip, zipnote, zipsplit
!    unzip50.exe     MSDOS self-extracting executable (contains unzip, docs)
  
!    zip19_16.zip    OS/2 1.x 16-bit executables and docs
!    zip19_32.zip    OS/2 2.x 32-bit executables and docs
!    unz50_16.exe    OS/2 1.x 16-bit executable
!    unz50_32.exe    OS/2 2.x 32-bit executable
! 
!    zip19vms.zip    VMS executables and docs for zip, zipnote, zipsplit
     unz50vms.exe    VMS executable for unzip
  
!    zip_unzip.hqx   Macintosh executables (zip 1.0 only, 1.9 not ready)
  
!    wunz13.zip      Windows 3.1 executable and docs for unzip (WizUnZip)
  
!    pkz110eu.exe    MS-DOS PKZIP/PKUNZIP 1.1 (self-extracting archive)
!    pkz193a.exe     MS-DOS PKZIP/PKUNZIP beta 1.93 (self-extracting)
     pkz102-2.exe    OS/2 PKZIP/PKUNZIP 1.02 (self-extracting)
  
  ftp sites for the US-exportable sources and executables:
  
     NOTE:  Look for the file names given above in the following
     directories.  Some sites like to use slightly different names,
!    such as zip-1.9p1.tar-z instead of zip19p1.tar.Z.  In the case
     of comp.sources.misc archive sites, directories may be used
!    (zip19/part01.Z ... part11.Z, zip19/patch01.Z).
  
!    wuarchive.wustl.edu:/usenet/comp.sources.misc/volume31/...
!    wuarchive.wustl.edu:/packages/compression/...
     wuarchive.wustl.edu:/mirrors/misc/unix/...
     wuarchive.wustl.edu:/mirrors/misc/vaxvms/...
     wuarchive.wustl.edu:/mirrors/msdos/zip/...
     wuarchive.wustl.edu:/mirrors/msdos/windows3/...
  
!    ftp.uu.net:/usenet/comp.sources.misc/volume31/...
!    ftp.uu.net:/pub/zip/...
  
!    ftp-os2.nmsu.edu:/pub/os2/2.0/archivers/...
!    ftp-os2.nmsu.edu:/pub/os2/all/archivers/...
!    ftp-os2.nmsu.edu:/pub/downloads/Info-ZIP/...
  
!    wuarchive.wustl.edu:/mirrors/msdos/zip/pkz110eu.exe
!    ux1.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe        [128.174.5.59]
  
  ftp sites for the encryption and decryption sources and/or executables:
  
--- 18,85 ----
  utilities (on some ftp sites, the .zip files may have a .zoo equivalent
  in Zoo 2.10 format):
  
!    zip20.zip       Zip 2.0 (deflation; includes zipnote, zipsplit)
!    zip20.tar.Z     ditto, compress'd tar format
  
     zip11.zip       Zip 1.1 (shrinking, implosion; compatible with PKUNZIP 1.1)
     zip11.tar.Z     ditto, compress'd tar format
  
!    unz50p1.zip     UnZip 5.0, patchlevel 1 (all methods; incl. zipinfo, funzip)
!    unz50p1.tar.Z   ditto, compress'd tar format
  
!    wunz20sr.zip    WizUnZip 2.0 support files for Windows 3.1, UnZip 5.0p1
!                    (not yet released)
  
!    zcrypt20.zip    encryption/decryption support (includes zipcloak)
  
  Related archives and files:
  
     UnzpHist.zip    complete changes history of UnZip and precursors
  
!    zip20x.zip      MSDOS executables and docs for zip, zipnote, zipsplit
!    zcryp20x.zip    MSDOS encryption executables and docs for zip, zipcloak
!    unz50p1.exe     MSDOS self-extracting executable (contains unzip, docs)
! 
!    zip20x16.zip    OS/2 1.x 16-bit executables and docs
!    zip20x32.zip    OS/2 2.x 32-bit executables and docs
!    unz50x16.exe    OS/2 1.x 16-bit executables and docs
!    unz50x32.exe    OS/2 2.x 32-bit executables and docs
  
!    zip20vms.zip    VMS executables and docs for zip, zipnote, zipsplit
     unz50vms.exe    VMS executable for unzip
  
!    mac-unzip-50p1.hqx  Macintosh executable (unzip only, zip not done yet).
  
!    wunz20x.zip     WizUnZip 2.0 executable and docs for Windows 3.1, NT 3.1
!    wunl20x.zip     same as wunz20x.zip, plus two DLLs for Win 3.0 and OS/2 2.x
  
!    pkz204g.exe     MS-DOS PKZIP/PKUNZIP 2.04g (self-extracting archive)
!    pkz110eu.exe    MS-DOS PKZIP/PKUNZIP 1.1 (self-extracting)
     pkz102-2.exe    OS/2 PKZIP/PKUNZIP 1.02 (self-extracting)
  
  ftp sites for the US-exportable sources and executables:
  
     NOTE:  Look for the file names given above in the following
     directories.  Some sites like to use slightly different names,
!    such as zip-2.0.tar-z instead of zip20.tar.Z.  In the case
     of comp.sources.misc archive sites, directories may be used
!    (zip20/part01.Z ... part11.Z, zip20/patch01.Z).
  
!    ftp.uu.net:/pub/archiving/zip/...    [THIS MIRRORS THE INFO-ZIP HOME SITE]
! 
     wuarchive.wustl.edu:/mirrors/misc/unix/...
+    wuarchive.wustl.edu:/packages/compression/...
     wuarchive.wustl.edu:/mirrors/misc/vaxvms/...
     wuarchive.wustl.edu:/mirrors/msdos/zip/...
     wuarchive.wustl.edu:/mirrors/msdos/windows3/...
  
!    ftp-os2.cdrom.com:/pub/os2/{2_x,all}/archivers/...
!    ftp-os2.nmsu.edu:/pub/os2/{2.x,all}/archivers/...
!    ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/archiver/...
  
!    wuarchive.wustl.edu:/mirrors/msdos/zip/pkz204g.exe
  
!    sumex-aim.stanford.edu:/info-mac/util/mac-unzip-50p1.hqx
  
  ftp sites for the encryption and decryption sources and/or executables:
  
***************
*** 87,114 ****
     a waste of expensive bandwidth).
  
     NOTE 2:  Some sites may carry both encryption and non-encryption
!    executables with slightly different names; for example, zip19c32.zip
!    instead of zip19x32.zip ("c" == crypt version).
  
     From the US:
!       wuarchive.wustl.edu:/mirrors/garbo.uwasa.fi/arcutil/zcrypt19.zip
!       wuarchive.wustl.edu:/usenet/comp.sources.misc/volume31/zcrypt19/part01.Z
!       ftp.uu.net:/usenet/comp.sources.misc/volume31/zcrypt19/part01.Z
  
     Outside the US:
!       garbo.uwasa.fi:/pc/arcutil/zcrypt19.zip
!       ftp.win.tue.nl:/pub/compression/zip/zcrypt19.zip
!       ftp.inria.fr:/system/arch-compr/zcrypt19.zip
!       ftp.informatik.tu-muenchen.de:/pub/utils/archiver/zcrypt19.zip
!          (mail server at ftp-mailer@ftp.informatik.tu-muenchen.de)
! 
!       ftp.uni-erlangen.de:/pub/pc/utilities/zip/...
!       ftp.uni-erlangen.de:/pub/pc/os2/Arc/ArcProgs/...
!          (131.188.1.43, 131.188.31.3, 131.188.34.43, 131.188.44.43)
  
! ftp site for VMS-format Zip/UnZip package (sources and executables, no
  encryption/decryption--see also "Mail servers" section below):
  
     The ZIP-UNZIP package for VMS is available via anonymous ftp from
     ftp.spc.edu [192.107.46.27]; the following files are needed:
  
--- 89,117 ----
     a waste of expensive bandwidth).
  
     NOTE 2:  Some sites may carry both encryption and non-encryption
!    executables with slightly different names; for example, zip20c32.zip
!    instead of zip20x32.zip ("c" == crypt version).  Other sites may
!    include *only* the encryption-related executables (zip and zipcloak)
!    in a second archive (e.g., zcryp20x.zip).
  
     From the US:
!       wuarchive.wustl.edu:/mirrors/garbo.uwasa.fi/arcutil/zcrypt20.zip
!       ftp.uu.net:/pub/archiving/zip/zcrypt20.zip
  
     Outside the US:
!       garbo.uwasa.fi:/pc/arcutil/zcrypt20.zip
!       ftp.inria.fr:/system/arch-compr/zcrypt20.zip
!       ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/archiver/zcrypt20.zip
!          (mail server at ftp-mailer@informatik.tu-muenchen.de)
! 
!       ftp.win.tue.nl:/pub/compression/zip/...
!       ftp.uni-erlangen.de:/pub/pc/msdos/utilities/zip/...
  
! ftp sites for VMS-format Zip/UnZip package (sources and executables, no
  encryption/decryption--see also "Mail servers" section below):
  
+       ftp.uu.net:/pub/archiving/zip/VMS/*
+ 
     The ZIP-UNZIP package for VMS is available via anonymous ftp from
     ftp.spc.edu [192.107.46.27]; the following files are needed:
  
***************
*** 128,136 ****
  
  UUCP sites:
  
!    uunet!~/usenet/comp.sources.misc/volume31/...
!    uunet!~/pub/zip/ ...
  
  Mail servers:
  
     If you don't have anonymous FTP capability, you can mail one
--- 131,143 ----
  
  UUCP sites:
  
!    uunet!~/pub/archiving/zip/ ...
! 
! Bulletin boards (Atari only, so far; not there yet...):
  
+    Gilligan's Island (v.32, 24 hours/day, etc.):  (519) 895-1294
+    GEnie (Atari ST RoundTable)
+ 
  Mail servers:
  
     If you don't have anonymous FTP capability, you can mail one
***************
*** 138,150 ****
     listserv@vm1.nodak.edu or listserv@vm.ecs.rpi.edu in order to
     get a copy via e-mail:
  
!       /pdget mail pd8:<misc.unix>unzip50.tar-z uuencode
!       /pdget mail pd8:<misc.unix>zip19p1.tar-z uuencode
  
     To get the encryption source by e-mail, send the following commands
!    to ftp-mailer@ftp.informatik.tu-muenchen.de:
  
!       get /pub/utils/archiver/zcrypt19.zip
        quit
  
     To get the VMS Zip/UnZip package by e-mail, send the following
--- 145,157 ----
     listserv@vm1.nodak.edu or listserv@vm.ecs.rpi.edu in order to
     get a copy via e-mail:
  
!       /pdget mail pd8:<misc.unix>unz50p1.tar-z uuencode
!       /pdget mail pd8:<misc.unix>zip20.zip uuencode
  
     To get the encryption source by e-mail, send the following commands
!    to ftp-mailer@informatik.tu-muenchen.de:
  
!       get /pub/utils/archiver/zcrypt20.zip
        quit
  
     To get the VMS Zip/UnZip package by e-mail, send the following
***************
*** 158,164 ****
  __________________________________________________________________________
  
     Again, if someone repackages any of the source or executable archives
!    in Mac-, Amiga- or Atari-specific formats, please let us know (send
     e-mail to zip-bugs at the address listed in README).
  __________________________________________________________________________
- 
--- 165,170 ----
  __________________________________________________________________________
  
     Again, if someone repackages any of the source or executable archives
!    in Mac- or Atari-specific formats, please let us know (send
     e-mail to zip-bugs at the address listed in README).
  __________________________________________________________________________
diff -c ../zip19i/algorith.doc ./algorith.doc
*** ../zip19i/algorith.doc	Tue Nov  3 21:07:53 1992
--- ./algorith.doc	Sat Aug 28 03:35:28 1993
***************
*** 46,51 ****
--- 46,57 ----
  important than speed, zip attempts a complete second search even if
  the first match is already long enough.
  
+ The lazy match evaluation is no performed for the fastest compression
+ modes (speed options -1 to -3). For these fast modes, new strings
+ are inserted in the hash table only when no match was found, or
+ when the match is not too long. This degrades the compression ratio
+ but saves time since there are both fewer insertions and fewer searches.
+ 
  Jean-loup Gailly
  jloup@chorus.fr
  
***************
*** 56,59 ****
  pp. 337-343.
  
  APPNOTE.TXT documentation file in PKZIP 1.93a. It is available by
! ftp in ux1.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe [128.174.5.59]
--- 62,65 ----
  pp. 337-343.
  
  APPNOTE.TXT documentation file in PKZIP 1.93a. It is available by
! ftp in ftp.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe [128.174.5.59]
Only in .: amiga
Only in .: atari
diff -c ../zip19i/bits.c ./bits.c
*** ../zip19i/bits.c	Tue Nov  3 21:07:53 1992
--- ./bits.c	Tue Aug 31 22:08:28 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 332,338 ****
  
      bi_init((FILE *)NULL);
      ct_init(&att, &method);
!     lm_init(level, &flags);
      deflate();
  
      /* For portability, force little-endian order on all machines: */
--- 331,337 ----
  
      bi_init((FILE *)NULL);
      ct_init(&att, &method);
!     lm_init((level != 0 ? level : 1), &flags);
      deflate();
  
      /* For portability, force little-endian order on all machines: */
Only in .: configure
diff -c ../zip19i/contents ./contents
*** ../zip19i/contents	Tue Nov  3 21:07:53 1992
--- ./contents	Tue Sep  7 05:00:38 1993
***************
*** 1,22 ****
! Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  Kai Uwe Rommel and Igor Mandrichenko.
  Permission is granted to any individual or institution to use, copy, or
  redistribute this software so long as all of the original files are included
  unmodified, that it is not sold for profit, and that this copyright notice
  is retained.
  
! This file is a complete list of files mentioned in the above copyright.  Some
! of the files in this list explicitly state in their text that they are public
! domain or not copyrighted.  These files can be distributed separately and are
! marked below with asterisks.
  
  file            what it is
  ----            ----------
! Readme          What zip is; general information.
  Where           where Zip/UnZip and encryption/decryption support can be found
  algorith.doc    Description of the deflation algorithm
  bits.c          Output variable-length bit strings.
  contents        This file.
  deflate.c       Deflation compression method
  fileio.c        System dependent routines (most of them anyway).
  globals.c       Global variables.
--- 1,26 ----
! Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  Kai Uwe Rommel and Igor Mandrichenko.
  Permission is granted to any individual or institution to use, copy, or
  redistribute this software so long as all of the original files are included
  unmodified, that it is not sold for profit, and that this copyright notice
  is retained.
  
! This file is a complete list of files mentioned in the above copyright
! notice.  Some of the files in this list explicitly state in their text
! that they are public domain or not copyrighted.  These files can be
! distributed separately and are marked below with asterisks.
  
  file            what it is
  ----            ----------
! Makefile        Unix make file.
! README          What zip is; general information.
  Where           where Zip/UnZip and encryption/decryption support can be found
  algorith.doc    Description of the deflation algorithm
  bits.c          Output variable-length bit strings.
+ configure       Shell script for automatic configuration.
  contents        This file.
+ crypt.c         * Dummy encryption sources.
+ crypt.h         * Dummy encryption sources.
  deflate.c       Deflation compression method
  fileio.c        System dependent routines (most of them anyway).
  globals.c       Global variables.
***************
*** 24,30 ****
  infozip.who     List of contributors to the portable Zip project.
  install.doc     Documentation for Zip compilation and installation
  makecrc.c       * Generate the CRC table in util.c and shrink.c.
- makefile        Unix make file.
  match.s         Optimized 386 version of longest_match() (Unix & OS/2)
  mktime.c        Version of mktime for systems without it (currently unused)
  revision.h      Contains the program version number and revision date.
--- 28,33 ----
***************
*** 35,75 ****
  zip.c           Main routine for Zip.
  zip.doc         Documentation for Zip (zip.1 processed).
  zip.h           Header for all Zip modules.
  ziperr.h        Error messages in Zip.
  zipfile.c       Zip file format handler.
  zipnote.c       Main routine for ZipNote.
  zipsplit.c      Main routine for ZipSplit.
  zipup.c         Applies deflate or store methods to compress an entry.
  atari/atari.c         Atari ST specific routines
  atari/makefile.st     Turbo C makefile
  atari/stzip.lnk       Linker command file for zip
- atari/stzip.prj       Turbo C project file
  atari/stzipn.lnk      Linker command file for zipnote
  atari/stzips.lnk      Linker command file for zipsplit
! atari/tc.cfg          Turbo C configuration file
  mac/macfile.c         Macintosh specific routines
  mac/macstat.c         Macintosh specific routines
  mac/macstat.h         Macintosh specific header file
- msdos/doturboc.bat    Batch file for compiling under Turbo C 2.0.
  msdos/makefile.bor    MSDOS Borland C++ make file.
  msdos/makefile.gcc    MSDOS DJGCC make file.
  msdos/makefile.msc    MSDOS Microsoft C make file.
  msdos/match.asm       Optimized 8086 version of longest_match().
- msdos/tcconfig.tc     TurboC 2.0 configuration file
- msdos/zip.prj         Project file for Borland (Turbo) C++.
- msdos/zipcloak.prj    Project file for Borland (Turbo) C++.
- msdos/zipnote.prj     Project file for Borland (Turbo) C++.
- msdos/zipsplit.prj    Project file for Borland (Turbo) C++.
- msdos/zip.tc          Configuration file for Turbo C
- msdos/zipcloak.tc     Configuration file for Turbo C
- msdos/zipnote.tc      Configuration file for Turbo C
- msdos/zipsplit.tc     Configuration file for Turbo C
  nt/makefile.nt        Makefile for Windows NT
  os2/makefile.os2      OS/2 make file.
! os2/match32.asm       Optimized 386 version of longest_match() (*untested*)
  os2/os2zip.c          * Directory routines for OS/2.
  os2/os2zip.h          * Definitions of functions in os2zip.c.
  os2/zip.def           OS/2 def file for Zip.
  vms/VMSmunch.c        file manipulation, adapted from Joe Meadows' FILE
  vms/VMSmunch.h        definitions for VMSmunch.c
  vms/descrip.mms       VMS makefile
--- 38,88 ----
  zip.c           Main routine for Zip.
  zip.doc         Documentation for Zip (zip.1 processed).
  zip.h           Header for all Zip modules.
+ zipcloak.c      * Dummy encryption sources.
  ziperr.h        Error messages in Zip.
  zipfile.c       Zip file format handler.
+ zipgrep         Shell script to search a string or pattern in a zip file
+ zipgrep.1       Man page for zipgrep
  zipnote.c       Main routine for ZipNote.
  zipsplit.c      Main routine for ZipSplit.
  zipup.c         Applies deflate or store methods to compress an entry.
+ amiga/LMKfile         Amiga makefile for SAS/C version 5.10b
+ amiga/SMakeFile       Amiga makefile for SAS/C version 6.x
+ amiga/amiga.h         Amiga specific code
+ amiga/amiga.c         Amiga specific code
+ amiga/filedate.c      Amiga specific "set file time"  routine
+ amiga/makefile.azt    Amiga makefile for Manx Aztec C version 5.2
+ amiga/match.a         Optimized 68000 version of longest_match().
+ amiga/match_68.a      Optimized 68020 version of longest_match().
+ amiga/stat.c          Manx Aztec C callable version of stat()
+ amiga/z-stat.h        Manx Aztec include file for stat()
  atari/atari.c         Atari ST specific routines
  atari/makefile.st     Turbo C makefile
  atari/stzip.lnk       Linker command file for zip
  atari/stzipn.lnk      Linker command file for zipnote
  atari/stzips.lnk      Linker command file for zipsplit
! human68k/Makefile.gcc Makefile for the Human68k system.
! human68k/human68k.c   Human68K specific routines
! human68k/match.s      Optimized 68k version of longest_match().
  mac/macfile.c         Macintosh specific routines
  mac/macstat.c         Macintosh specific routines
  mac/macstat.h         Macintosh specific header file
  msdos/makefile.bor    MSDOS Borland C++ make file.
+ msdos/makefile.tc     MSDOS Turboc 2.0 make file.
  msdos/makefile.gcc    MSDOS DJGCC make file.
  msdos/makefile.msc    MSDOS Microsoft C make file.
  msdos/match.asm       Optimized 8086 version of longest_match().
  nt/makefile.nt        Makefile for Windows NT
+ nt/nt.c               NT specific routines
+ nt/ntzip.h            NT specific header file
  os2/makefile.os2      OS/2 make file.
! os2/match32.asm       Optimized 386 version of longest_match()
  os2/os2zip.c          * Directory routines for OS/2.
  os2/os2zip.h          * Definitions of functions in os2zip.c.
  os2/zip.def           OS/2 def file for Zip.
+ os2/zip16.def         OS/2 def file for Zip (16 bit version)
+ tops20/make.mic       TOPS 20 command file
+ tops20/rename.mic     TOPS 20 command file
  vms/VMSmunch.c        file manipulation, adapted from Joe Meadows' FILE
  vms/VMSmunch.h        definitions for VMSmunch.c
  vms/descrip.mms       VMS makefile
***************
*** 80,91 ****
  vms/vms.c             VMS specific code
  vms/vms_zip.rnh       VMS manual page
  
! All of the files are in Unix (LF only) format except for the msdos and os2
! files.  On MSDOS and OS/2 systems, you can use the -a option of unzip to
! convert the source files to CRLF format.  This is only necessary if you wish
! to edit the files -- they will compile as is with Microsoft C and
! Turbo/Borland C++ 1.0 or later.  However, you will have to convert the files
! (using unzip -a) to the CRLF format to compile with the older Turbo C 1.0 or
! 2.0. In this case, do not convert the binary file turboc.cfg.
! You should be able to find unzip the same place you found this (see the
! file 'where').
--- 93,100 ----
  vms/vms.c             VMS specific code
  vms/vms_zip.rnh       VMS manual page
  
! All of the files are in Unix (LF only) format. On MSDOS and OS/2
! systems, you can use the -a option of unzip to convert the source
! files to CRLF format.  This is only necessary if you use Turbo/Borland C
! -- they will compile as is with Microsoft C. You should be able to
! find unzip the same place you found this (see the file 'Where').
diff -c ../zip19i/crypt.c ./crypt.c
*** ../zip19i/crypt.c	Tue Nov  3 21:07:53 1992
--- ./crypt.c	Thu Sep  2 03:50:00 1993
***************
*** 1,653 ****
  /*
!    crypt.c (full version) by Info-ZIP.        Last revised:  23 Oct 92
  
!    This code is not copyrighted and is put in the public domain.  The
!    encryption/decryption parts (as opposed to the non-echoing password
!    parts) were originally written in Europe; the whole file can there-
!    fore be freely distributed from any country except the USA.  If this
!    code is imported into the USA, it cannot be re-exported from from
!    there to another country.  (This restriction might seem curious, but
!    this is what US law requires.)
   */
  
! /* This encryption code is a direct transcription of the algorithm from
!    Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
!    file (appnote.txt) is distributed with the PKZIP program (even in the
!    version without encryption capabilities).
!  */
! 
! #include "zip.h"
! #include "crypt.h"
! 
! #ifndef UNZIP         /* time.h already included in unzip's zip.h */
! #  include <time.h>
! #endif
! 
! #if ((defined(DOS_OS2) || defined(WIN32)) && !defined(__GO32__))
! #  include <process.h>
! #else
! #  if !defined(__386BSD__) && !defined(SYSV)  /* getpid() in unistd.h */
!      int  getpid OF((void));
! #  endif
! #endif
! 
! #ifndef __GNUC__
! void srand  OF((unsigned int));
! #endif
! int  rand   OF((void));
! 
! /* For now, assume DIRENT implies System V implies TERMIO */
! #if (defined(DIRENT) && !defined(NO_TERMIO) && !defined(TERMIO))
! #  define TERMIO
! #endif
! 
! #if (defined(DOS_OS2) || defined(VMS))
! #  ifndef MSVMS
! #    define MSVMS
! #  endif
! #  ifdef DOS_OS2
! #    ifdef __EMX__
! #      define getch() _read_kbd(0, 1, 0)
! #    else
! #      ifdef __GO32__
! #        include <pc.h>
! #        define getch() getkey()
! #      else /* !__GO32__ */
! #        include <conio.h>
! #      endif /* ?__GO32__ */
! #    endif
! #  else /* !DOS_OS2 */
! #    define getch() getc(stderr)
! #    include <descrip.h>
! #    include <iodef.h>
! #    include <ttdef.h>
! #    if !defined(SS$_NORMAL)
! #      define SS$_NORMAL 1   /* only thing we need from <ssdef.h> */
! #    endif
! #  endif /* ?DOS_OS2 */
! #else /* !(DOS_OS2 || VMS) */
! #  ifdef TERMIO       /* Amdahl, Cray, all SysV? */
! #    ifdef COHERENT
! #      include <termio.h>
! #    else
! #     ifdef LINUX
! #      include <termios.h>
! #     else
! #      include <sys/termio.h>
! #     endif
! #    endif /* COHERENT */
! #    define sgttyb termio
! #    define sg_flags c_lflag
! #    if !defined(__386BSD__) && !defined(SYSV)
!        int ioctl OF((int, int, voidp *)); /* already in unistd.h */
! #    endif
! #    define GTTY(f,s) ioctl(f,TCGETA,(voidp *)s)
! #    define STTY(f,s) ioctl(f,TCSETAW,(voidp *)s)
! #  else /* !TERMIO */
! #    if (!defined(MINIX) && !defined(__386BSD__))
! #      include <sys/ioctl.h>
! #    endif /* !MINIX && !__386BSD__ */
! #    include <sgtty.h>
! #    ifdef __386BSD__
! #      define GTTY(f, s) ioctl(f, TIOCGETP, (voidp *) s)
! #      define STTY(f, s) ioctl(f, TIOCSETP, (voidp *) s)
! #    else /* !__386BSD__ */
! #      define GTTY gtty
! #      define STTY stty
!        int gtty OF((int, struct sgttyb *));
!        int stty OF((int, struct sgttyb *));
! #    endif /* ?__386BSD__ */
! #  endif /* ?TERMIO */
! #  if defined(__386BSD__) || defined(SYSV)
! #    if !defined(UNZIP)
! #      include <fcntl.h>
! #    endif
! #  else
!      int isatty OF((int));
!      char *ttyname OF((int));
!      /* int open OF((char *, int));  works in zipup.c but not here. Strange. */
!      int close OF((int));
!      int read OF((int, voidp *, int));
! #  endif
! #endif /* ?(DOS_OS2 || VMS) */
! 
! #if (defined(UNZIP) && !defined(FUNZIP))
!   local int testp OF((uch *h));
! #endif
! 
! local ulg keys[3]; /* keys defining the pseudo-random sequence */
! 
! #ifdef CRYPT_DEBUG
! #  define Tracecr(x) printf x
! #else
! #  define Tracecr(x)
! #endif
! 
! /***********************************************************************
!  * Return the next byte in the pseudo-random sequence
!  */
! int decrypt_byte()
! {
!    ush temp;
! 
!    temp = (ush)keys[2] | 2;
!    return (int)(((ush)(temp * (temp ^ 1)) >> 8) & 0xff);
! }
! 
! /***********************************************************************
!  * Update the encryption keys with the next byte of plain text
!  */
! void update_keys(c)
!     int c;                  /* byte of plain text */
! {
!     keys[0] = CRC32(keys[0], c);
!     keys[1] += keys[0] & 0xff;
!     keys[1] = keys[1] * 134775813L + 1;
!     keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
! }
! 
! 
! /***********************************************************************
!  * Initialize the encryption keys and the random header according to
!  * the given password.
!  */
! void init_keys(passwd)
!     char *passwd;             /* password string with which to modify keys */
! {
!     keys[0] = 305419896L;
!     keys[1] = 591751049L;
!     keys[2] = 878082192L;
!     while (*passwd != '\0') {
!         update_keys((int)*passwd);
!         passwd++;
!     }
! }
! 
! /***********************************************************************
!  * Write encryption header to file zfile using the password passwd
!  * and the cyclic redundancy check crc.
!  */
! void crypthead(passwd, crc, zfile)
!     char *passwd;                /* password string */
!     ulg crc;                     /* crc of file being encrypted */
!     FILE *zfile;                 /* where to write header */
! {
!     int n;                       /* index in random header */
!     int t;                       /* temporary */
!     int c;                       /* random byte */
!     uch header[RAND_HEAD_LEN-2]; /* random header */
!     static unsigned calls = 0;   /* ensure different random header each time */
! 
!     /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
!      * output of rand() to get less predictability, since rand() is
!      * often poorly implemented.
!      */
!     if (++calls == 1) {
!         srand((unsigned)time(NULL) ^ getpid());
!     }
!     init_keys(passwd);
!     for (n = 0; n < RAND_HEAD_LEN-2; n++) {
!         c = (rand() >> 7) & 0xff;
!         header[n] = (uch)zencode(c, t);
!     }
!     /* Encrypt random header (last two bytes is high word of crc) */
!     init_keys(passwd);
!     for (n = 0; n < RAND_HEAD_LEN-2; n++) {
!         putc(zencode(header[n], t), zfile);
!     }
!     putc(zencode((int)(crc >> 16) & 0xff, t), zfile);
!     putc(zencode((int)(crc >> 24), t), zfile);
! }
! 
! 
! #ifdef UTIL
! 
! /***********************************************************************
!  * Encrypt the zip entry described by z from file source to file dest
!  * using the password passwd.  Return an error code in the ZE_ class.
!  */
! int zipcloak(z, source, dest, passwd)
!     struct zlist far *z;    /* zip entry to encrypt */
!     FILE *source, *dest;    /* source and destination files */
!     char *passwd;           /* password string */
! {
!     int c;                  /* input byte */
!     int res;                /* result code */
!     ulg n;                  /* holds offset and counts size */
!     ush flag;               /* previous flags */
!     int t;                  /* temporary */
! 
!     /* Set encrypted bit, clear extended local header bit and write local
!        header to output file */
!     if ((n = ftell(dest)) == -1L) return ZE_TEMP;
!     z->off = n;
!     flag = z->flg;
!     z->flg |= 1,  z->flg &= ~8;
!     z->lflg |= 1, z->lflg &= ~8;
!     z->siz += RAND_HEAD_LEN;
!     if ((res = putlocal(z, dest)) != ZE_OK) return res;
! 
!     /* Initialize keys with password and write random header */
!     crypthead(passwd, z->crc, dest);
! 
!     /* Skip local header in input file */
!     if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
!               SEEK_CUR)) {
!         return ferror(source) ? ZE_READ : ZE_EOF;
!     }
! 
!     /* Encrypt data */
!     for (n = z->siz - RAND_HEAD_LEN; n; n--) {
!         if ((c = getc(source)) == EOF) {
!             return ferror(source) ? ZE_READ : ZE_EOF;
!         }
!         putc(zencode(c, t), dest);
!     }
!     /* Skip extended local header in input file if there is one */
!     if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
!         return ferror(source) ? ZE_READ : ZE_EOF;
!     }
!     if (fflush(dest) == EOF) return ZE_TEMP;
!     return ZE_OK;
! }
! 
! /***********************************************************************
!  * Decrypt the zip entry described by z from file source to file dest
!  * using the password passwd.  Return an error code in the ZE_ class.
!  */
! int zipbare(z, source, dest, passwd)
!     struct zlist far *z;  /* zip entry to encrypt */
!     FILE *source, *dest;  /* source and destination files */
!     char *passwd;         /* password string */
! {
!     int c0, c1;           /* last two input bytes */
!     ulg offset;           /* used for file offsets */
!     ulg size;             /* size of input data */
!     int r;                /* size of encryption header */
!     int res;              /* return code */
!     ush flag;             /* previous flags */
! 
!     /* Save position and skip local header in input file */
!     if ((offset = ftell(source)) == -1L ||
!         fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
!               SEEK_CUR)) {
!         return ferror(source) ? ZE_READ : ZE_EOF;
!     }
!     /* Initialize keys with password */
!     init_keys(passwd);
! 
!     /* Decrypt encryption header, save last two bytes */
!     c1 = 0;
!     for (r = RAND_HEAD_LEN; r; r--) {
!         c0 = c1;
!         if ((c1 = getc(source)) == EOF) {
!             return ferror(source) ? ZE_READ : ZE_EOF;
!         }
!         Tracecr((" (%02x)", c1));
!         zdecode(c1);
!         Tracecr((" %02x", c1));
!     }
!     Tracecr(("\n"));
! 
!     /* If last two bytes of header don't match crc (or file time in the
!      * case of an extended local header), back up and just copy. For
!      * pkzip 2.0, the check has been reduced to one byte only.
!      */
! #ifdef ZIP10
!     if ((ush)(c0 | (c1<<8)) !=
!         (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
! #else
!     c0++; /* avoid warning on unused variable */
!     if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
! #endif
!         if (fseek(source, offset, SEEK_SET)) {
!             return ferror(source) ? ZE_READ : ZE_EOF;
!         }
!         if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
!         return ZE_MISS;
!     }
! 
!     /* Clear encrypted bit and local header bit, and write local header to
!        output file */
!     if ((offset = ftell(dest)) == -1L) return ZE_TEMP;
!     z->off = offset;
!     flag = z->flg;
!     z->flg &= ~9;
!     z->lflg &= ~9;
!     z->siz -= RAND_HEAD_LEN;
!     if ((res = putlocal(z, dest)) != ZE_OK) return res;
! 
!     /* Decrypt data */
!     for (size = z->siz; size; size--) {
!         if ((c1 = getc(source)) == EOF) {
!             return ferror(source) ? ZE_READ : ZE_EOF;
!         }
!         zdecode(c1);
!         putc(c1, dest);
!     }
!     /* Skip extended local header in input file if there is one */
!     if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
!         return ferror(source) ? ZE_READ : ZE_EOF;
!     }
!     if (fflush(dest) == EOF) return ZE_TEMP;
! 
!     return ZE_OK;
! }
! 
! 
! #else /* !UTIL */
! 
! /***********************************************************************
!  * If requested, encrypt the data in buf, and in any case call fwrite()
!  * with the arguments to zfwrite().  Return what fwrite() returns.
!  */
! unsigned zfwrite(buf, item_size, nb, f)
!     voidp *buf;                /* data buffer */
!     extent item_size;          /* size of each item in bytes */
!     extent nb;                 /* number of items */
!     FILE *f;                   /* file to write to */
! {
!     int t;                    /* temporary */
! 
!     if (key != (char *)NULL) { /* key is the global password pointer */
!         ulg size;              /* buffer size */
!         char *p = (char*)buf;  /* steps through buffer */
! 
!         /* Encrypt data in buffer */
!         for (size = item_size*(ulg)nb; size != 0; p++, size--) {
!             *p = (char)zencode(*p, t);
!         }
!     }
!     /* Write the buffer out */
!     return fwrite(buf, item_size, nb, f);
! }
! 
! #endif /* ?UTIL */
! 
! 
! #ifndef DOS_OS2
! #ifdef VMS
! 
! /***********************************************************************
!  * Turn keyboard echoing on or off (VMS).  Loosely based on VMSmunch.c
!  * and hence on Joe Meadows' file.c code.
!  */
! int echo(opt)
!     int opt;
! {
!     /*
!      * For VMS v5.x:
!      *   IO$_SENSEMODE/SETMODE info:  Programming, Vol. 7A, System Programming,
!      *     I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
!      *   sys$assign(), sys$qio() info:  Programming, Vol. 4B, System Services,
!      *     System Services Reference Manual, pp. sys-23, sys-379
!      *   fixed-length descriptor info:  Programming, Vol. 3, System Services,
!      *     Intro to System Routines, sec. 2.9.2
!      * GRR, 15 Aug 91
!      */
! 
!     static struct dsc$descriptor_s DevDesc =
!         {9, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$INPUT"};
!      /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
!     static short           DevChan, iosb[4];
!     static long            i, status;
!     static unsigned long   oldmode[2], newmode[2];   /* each = 8 bytes */
!   
! 
!     /* assign a channel to standard input */
!     status = sys$assign(&DevDesc, &DevChan, 0, 0);
!     if (!(status & 1))
!         return status;
! 
!     /* use sys$qio and the IO$_SENSEMODE function to determine the current
!      * tty status (for password reading, could use IO$_READVBLK function
!      * instead, but echo on/off will be more general)
!      */
!     status = sys$qio(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
!                      oldmode, 8, 0, 0, 0, 0);
!     if (!(status & 1))
!         return status;
!     status = iosb[0];
!     if (!(status & 1))
!         return status;
! 
!     /* copy old mode into new-mode buffer, then modify to be either NOECHO or
!      * ECHO (depending on function argument opt)
!      */
!     newmode[0] = oldmode[0];
!     newmode[1] = oldmode[1];
!     if (opt == 0)   /* off */
!         newmode[1] |= TT$M_NOECHO;                      /* set NOECHO bit */
!     else
!         newmode[1] &= ~((unsigned long) TT$M_NOECHO);   /* clear NOECHO bit */
! 
!     /* use the IO$_SETMODE function to change the tty status */
!     status = sys$qio(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
!                      newmode, 8, 0, 0, 0, 0);
!     if (!(status & 1))
!         return status;
!     status = iosb[0];
!     if (!(status & 1))
!         return status;
! 
!     /* deassign the sys$input channel by way of clean-up */
!     status = sys$dassgn(DevChan);
!     if (!(status & 1))
!         return status;
! 
!     return SS$_NORMAL;   /* we be happy */
! 
! } /* end function echo() */
! 
! 
! #else /* !VMS */
! 
! static int echofd=(-1);       /* file descriptor whose echo is off */
! 
! /***********************************************************************
!  * Turn echo off for file descriptor f.  Assumes that f is a tty device.
!  */
! void echoff(f)
!     int f;                    /* file descriptor for which to turn echo off */
! {
!     struct sgttyb sg;         /* tty device structure */
! 
!     echofd = f;
!     GTTY(f, &sg);             /* get settings */
!     sg.sg_flags &= ~ECHO;     /* turn echo off */
!     STTY(f, &sg);
! }
! 
! /***********************************************************************
!  * Turn echo back on for file descriptor echofd.
!  */
! void echon()
! {
!     struct sgttyb sg;         /* tty device structure */
! 
!     if (echofd != -1) {
!         GTTY(echofd, &sg);    /* get settings */
!         sg.sg_flags |= ECHO;  /* turn echo on */
!         STTY(echofd, &sg);
!         echofd = -1;
!     }
! }
! 
! #endif /* ?VMS */
! #endif /* !DOS_OS2 */
! 
! 
! /***********************************************************************
!  * Get a password of length n-1 or less into *p using the prompt *m.
!  * The entered password is not echoed.  Return p on success, NULL on
!  * failure (can't get controlling tty).
!  */
! char *getp(m, p, n)
!     char *m;                  /* prompt for password */
!     char *p;                  /* return value: line input */
!     int n;                    /* bytes available in p[] */
! {
!     char c;                   /* one-byte buffer for read() to use */
!     int i;                    /* number of characters input */
!     char *w;                  /* warning on retry */
! 
! #ifndef DOS_OS2
! #ifndef VMS
!     int f;                    /* file decsriptor for tty device */
! 
!     /* turn off echo on tty */
!     if (!isatty(2))
!         return NULL;          /* error if not tty */
!     if ((f = open(ttyname(2), 0)) == -1)
!         return NULL;
! #endif /* !VMS */
!     echoff(f);                /* turn echo off */
! #endif /* !DOS_OS2 */
! 
!     /* get password */
!     w = "";
!     do {
! #ifdef VMS   /* bug:  VMS adds '\n' to NULL fputs (apparently) */
!         if (*w)
! #endif /* VMS */
!             fputs(w, stderr); /* warning if back again */
!         fputs(m, stderr);     /* prompt */
!         fflush(stderr);
!         i = 0;
!         do {                  /* read line, keeping n */
! #ifdef MSVMS
!             if ((c = (char)getch()) == '\r')
!                 c = '\n';
! #else /* !MSVMS */
!             read(f, &c, 1);
! #endif /* ?MSVMS */
!             if (i < n)
!                 p[i++] = c;
!         } while (c != '\n');
!         putc('\n', stderr);  fflush(stderr);
!         w = "(line too long--try again)\n";
!     } while (p[i-1] != '\n');
!     p[i-1] = 0;               /* terminate at newline */
! 
! #ifndef DOS_OS2
!     echon();                  /* turn echo back on */
! #ifndef VMS
!     close(f);
! #endif /* !VMS */
! #endif /* !DOS_OS2 */
! 
!     /* return pointer to password */
!     return p;
! }
! 
! 
! #if (defined(UNZIP) && !defined(FUNZIP))
! 
! /***********************************************************************
!  * Get the password and set up keys for current zipfile member.  Return
!  * PK_ class error.
!  */
! int decrypt_member()
! {
!     ush b;
!     int n, r;
!     static int nopwd=FALSE;
!     char *m, *prompt;
!     uch h[RAND_HEAD_LEN];
! 
!     Tracecr(("\n[incnt = %d]: ", incnt));
! 
!     /* get header once (turn off "encrypted" flag temporarily so we don't
!      * try to decrypt the same data twice) */
!     pInfo->encrypted = FALSE;
!     for (n = 0; n < RAND_HEAD_LEN; n++) {
!         ReadByte(&b);
!         h[n] = (uch)b;
!         Tracecr((" (%02x)", h[n]));
!     }
!     pInfo->encrypted = TRUE;
! 
!     /* if have key already, test it; else allocate memory for it */
!     if (key) {
!         if (!testp(h))
!             return PK_COOL;   /* existing password OK (else prompt for new) */
!         else if (nopwd)
!             return PK_WARN;   /* user indicated no more prompting */
!     } else if ((key = (char *)malloc(PWLEN+1)) == (char *)NULL)
!         return PK_MEM2;
! 
!     if ((prompt = (char *)malloc(FILNAMSIZ+15)) != (char *)NULL) {
!         sprintf(prompt, "%s password: ", filename);
!         m = prompt;
!     } else
!         m = "Enter password: ";
! 
!     /* try a few keys */
!     for (r = 0;  r < 3;  ++r) {
!         m = getp(m, key, PWLEN+1);
!         if (prompt != (char *)NULL) {
!             free(prompt);
!             prompt = (char *)NULL;
!         }
!         if (m == (char *)NULL)
!             return PK_MEM2;
!         if (!testp(h))
!             return PK_COOL;
!         if (*key == '\0') {
!             nopwd = TRUE;
!             return PK_WARN;
!         }
!         m = "password incorrect--reenter: ";
!     }
!     return PK_WARN;
! } /* end function decrypt_member() */
! 
! /***********************************************************************
!  * Test the password.  Return -1 if bad, 0 if OK.
!  */
! local int testp(h)
!     uch *h;
! {
!     ush b, c;
!     int n;
!     uch *p;
!     uch hh[RAND_HEAD_LEN]; /* decrypted header */
! 
!     /* set keys and save the encrypted header */
!     init_keys(key);
!     memcpy(hh, h, RAND_HEAD_LEN);
! 
!     /* check password */
!     for (n = 0; n < RAND_HEAD_LEN; n++) {
!         zdecode(hh[n]);
!         Tracecr((" %02x", hh[n]));
!     }
!     c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
! 
!     Tracecr(("\n  lrec.crc= %08lx  crec.crc= %08lx  pInfo->ExtLocHdr= %s\n",
!       lrec.crc32, pInfo->crc, pInfo->ExtLocHdr? "true":"false"));
!     Tracecr(("  incnt = %d  unzip offset into zipfile = %ld\n", incnt,
!       cur_zipfile_bufstart+(inptr-inbuf)));
!     Tracecr(("  (c | (b<<8)) = %04x  (crc >> 16) = %04x  lrec.time = %04x\n",
!       (ush)(c | (b<<8)), (ush)(lrec.crc32 >> 16), lrec.last_mod_file_time));
! 
!     /* same test as in zipbare(): */
! 
! #ifdef ZIP10 /* check two bytes */
!     if ((ush)(c | (b<<8)) != (pInfo->ExtLocHdr? lrec.last_mod_file_time :
!         (ush)(lrec.crc32 >> 16)))
!         return -1;  /* bad */
! #else
!     c++; /* avoid warning on unused variable */
!     if (b != (pInfo->ExtLocHdr? lrec.last_mod_file_time >> 8 :
!         (ush)(lrec.crc32 >> 24)))
!         return -1;  /* bad */
! #endif
!     /* password OK:  decrypt current buffer contents before leaving */
!     for (n = (longint)incnt > csize ? (int)csize : incnt, p = inptr; n--; p++)
!         zdecode(*p);
!     return 0;       /* OK */
! 
! } /* end function testp() */
! 
! #endif /* UNZIP && !FUNZIP */
--- 1,11 ----
  /*
!    crypt.c (dummy version) by Info-ZIP.      Last revised:  11 Sep 92
  
!    This is a non-functional version of Info-ZIP's crypt.c encryption/
!    decryption code for Zip, ZipCloak, UnZip and FUnZip.  This file is
!    not copyrighted and may be distributed freely. :-)  See the "Where"
!    file for sites from which to obtain the full encryption/decryption
!    sources (zcrypt20.zip or later).
   */
  
! int dummy_crypt; /* avoid warning about empty translation unit */
diff -c ../zip19i/crypt.h ./crypt.h
*** ../zip19i/crypt.h	Tue Nov  3 21:07:53 1992
--- ./crypt.h	Sat Aug 21 02:01:48 1993
***************
*** 1,57 ****
  /*
!    crypt.h (full version) by Info-ZIP.       Last revised:  23 Oct 92
  
!    This header file is not copyrighted and may be distributed without
!    restriction.
   */
  
  #ifndef __crypt_h   /* don't include more than once */
  #define __crypt_h
  
! #ifndef CRYPT
! #  define CRYPT     /* full version */
  #endif
  
! #define PWLEN  80   /* input buffer size for reading encryption key */
! #define RAND_HEAD_LEN  12    /* length of encryption random header */
  
! /* encode byte c, using temp t.  Warning: c must not have side effects. */
! #define zencode(c,t)  (t=decrypt_byte(), update_keys(c), t^(c))
  
! /* decode byte c in place */
! #define zdecode(c)   update_keys(c ^= decrypt_byte())
  
! int  decrypt_byte OF((void));
! void update_keys OF((int c));
! void init_keys OF((char *passwd));
! void crypthead OF((char *, ulg, FILE *));
! char *getp OF((char *m, char *p, int n));
! int  decrypt_member OF((void));
! 
! #ifdef UTIL
!    int zipcloak OF((struct zlist far *, FILE *, FILE *, char *));
!    int zipbare OF((struct zlist far *, FILE *, FILE *, char *));
! #else /* !UTIL */
!    unsigned zfwrite OF((voidp *, extent, extent, FILE *));
!    extern char *key;
! #endif /* ?UTIL */
! 
! #ifdef VMS
! #  define echoff(f)  echo(0)
! #  define echon()    echo(1)
!    int echo OF((int));
! #else
!    void echoff OF((int));
!    void echon OF((void));
! #endif
! 
! #if (defined(MSDOS) || defined(OS2)) && (!defined(DOS_OS2))
! #  define DOS_OS2
! #endif
! 
! #ifdef TOPS20
! #  define decrypt_member dcrmem
! #  define decrypt_byte   dcrbyt
! #endif
  
  #endif /* !__crypt_h */
--- 1,28 ----
  /*
!    crypt.h (dummy version) by Info-ZIP.      Last revised:  26 Oct 92
  
!    This is a non-functional version of Info-ZIP's crypt.h encryption/
!    decryption header file for Zip, ZipCloak, UnZip and FUnZip.  This
!    file is not copyrighted and may be distributed without restriction.
!    See the "Where" file for sites from which to obtain the full crypt
!    sources (zcrypt20.zip or later).
   */
  
  #ifndef __crypt_h   /* don't include more than once */
  #define __crypt_h
  
! #ifdef CRYPT
! #  undef CRYPT      /* dummy version */
  #endif
  
! #define RAND_HEAD_LEN  12    /* needed to compile funzip */
  
! #define zencode
! #define zdecode
  
! #define zfwrite  fwrite
  
! #define echoff(f)
! #define echon()
  
  #endif /* !__crypt_h */
diff -c ../zip19i/deflate.c ./deflate.c
*** ../zip19i/deflate.c	Tue Nov  3 21:07:54 1992
--- ./deflate.c	Fri Sep 10 03:41:50 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 25,31 ****
   *
   *      The most straightforward technique turns out to be the fastest for
   *      most input files: try all possible matches and select the longest.
!  *      The key feature is of this algorithm is that insertions into the string
   *      dictionary are very simple and thus fast, and deletions are avoided
   *      completely. Insertions are performed at each input character, whereas
   *      string matches are performed only when the previous match ends. So it
--- 24,30 ----
   *
   *      The most straightforward technique turns out to be the fastest for
   *      most input files: try all possible matches and select the longest.
!  *      The key feature of this algorithm is that insertions into the string
   *      dictionary are very simple and thus fast, and deletions are avoided
   *      completely. Insertions are performed at each input character, whereas
   *      string matches are performed only when the previous match ends. So it
***************
*** 120,125 ****
--- 119,127 ----
  #if defined(ASMV) && !defined(MSDOS) && defined(DYN_ALLOC)
    error: DYN_ALLOC not yet supported in match.s
  #endif
+ #if defined(MSDOS) && !defined(__32BIT__)
+ #  define MAXSEG_64K
+ #endif
  
  /* ===========================================================================
   * Local data used by the "longest match" routines.
***************
*** 160,166 ****
    Pos    * near prev   = NULL;
    Pos    * near head;
  #endif
! ulg window_size = (ulg)2*WSIZE;
  /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
   * input file length plus MIN_LOOKAHEAD.
   */
--- 162,168 ----
    Pos    * near prev   = NULL;
    Pos    * near head;
  #endif
! ulg window_size;
  /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
   * input file length plus MIN_LOOKAHEAD.
   */
***************
*** 170,175 ****
--- 172,180 ----
   * negative when the window is moved backwards.
   */
  
+ local int sliding;
+ /* Set to false when the input file is already in memory */
+ 
  local unsigned ins_h;  /* hash index of string to be inserted */
  
  #define H_SHIFT  ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
***************
*** 196,205 ****
  
  local unsigned int max_lazy_match;
  /* Attempt to find a better match only when the current match is strictly
!  * smaller than this value.
   */
  
! int near good_match;
  /* Use a faster search when the previous match is longer than this */
  
  
--- 201,216 ----
  
  local unsigned int max_lazy_match;
  /* Attempt to find a better match only when the current match is strictly
!  * smaller than this value. This mechanism is used only for compression
!  * levels >= 4.
   */
+ #define max_insert_length  max_lazy_match
+ /* Insert new strings in the hash table only if the match length
+  * is not greater than this length. This saves time but degrades compression.
+  * max_insert_length is used only for compression levels <= 3.
+  */
  
! unsigned near good_match;
  /* Use a faster search when the previous match is longer than this */
  
  
***************
*** 216,226 ****
     ush max_chain;
  } config;
  
- #if defined(ASMV) && !defined(FULL_SEARCH)
- # define FULL_SEARCH
-   /* not yet had time to update the asm code, sorry */
- #endif
- 
  #ifdef  FULL_SEARCH
  # define nice_match MAX_MATCH
  #else
--- 227,232 ----
***************
*** 230,259 ****
  local config configuration_table[10] = {
  /*      good lazy nice chain */
  /* 0 */ {0,    0,  0,    0},  /* store only */
! /* 1 */ {4,    4, 16,   16},  /* maximum speed */
! /* 2 */ {6,    8, 16,   16},
! /* 3 */ {8,   16, 32,   32},
! /* 4 */ {8,   16, 64,   64},
! /* 5 */ {8,   16, 128, 128},
! /* 6 */ {8,   32, 128, 256},
! /* 7 */ {8,   64, 128, 512},
  /* 8 */ {32, 128, 258, 1024},
  /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
  
! /* Note: the current code requires max_lazy >= MIN_MATCH and max_chain >= 4
!  * but these restrictions can easily be removed at a small cost.
   */
  
  #define EQUAL 0
  /* result of memcmp for equal strings */
  
  /* ===========================================================================
!  *  Prototypes for local functions. Use asm version by default for
!  *  MSDOS but not Unix. However the asm version version is recommended
!  *  for 386 Unix.
   */
  
  local void fill_window   OF((void));
        int  longest_match OF((IPos cur_match));
  #ifdef ASMV
        void match_init OF((void)); /* asm code initialization */
--- 236,267 ----
  local config configuration_table[10] = {
  /*      good lazy nice chain */
  /* 0 */ {0,    0,  0,    0},  /* store only */
! /* 1 */ {4,    4,  8,    4},  /* maximum speed, no lazy matches */
! /* 2 */ {4,    5, 16,    8},
! /* 3 */ {4,    6, 32,   32},
! 
! /* 4 */ {4,    4, 16,   16},  /* lazy matches */
! /* 5 */ {8,   16, 32,   32},
! /* 6 */ {8,   16, 128, 128},
! /* 7 */ {8,   32, 128, 256},
  /* 8 */ {32, 128, 258, 1024},
  /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
  
! /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
!  * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
!  * meaning.
   */
  
  #define EQUAL 0
  /* result of memcmp for equal strings */
  
  /* ===========================================================================
!  *  Prototypes for local functions.
   */
  
  local void fill_window   OF((void));
+ local ulg deflate_fast   OF((void));
+ 
        int  longest_match OF((IPos cur_match));
  #ifdef ASMV
        void match_init OF((void)); /* asm code initialization */
***************
*** 263,271 ****
  local  void check_match OF((IPos start, IPos match, int length));
  #endif
  
- #define MIN(a,b) ((a) <= (b) ? (a) : (b))
- /* The arguments must not have side effects. */
- 
  /* ===========================================================================
   * Update a hash value with the given input byte
   * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
--- 271,276 ----
***************
*** 289,294 ****
--- 294,305 ----
  
  /* ===========================================================================
   * Initialize the "longest match" routines for a new file
+  *
+  * IN assertion: window_size is > 0 if the input file is already read or
+  *    mmap'ed in the window[] array, 0 otherwise. In the first case,
+  *    window_size is sufficient to contain the whole input file plus
+  *    MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end
+  *    of window[] when looking for matches towards the end).
   */
  void lm_init (pack_level, flags)
      int pack_level; /* 0: store, 1: best speed, 9: best compression */
***************
*** 298,309 ****
  
      if (pack_level < 1 || pack_level > 9) error("bad pack level");
  
      /* Use dynamic allocation if compiler does not like big static arrays: */
  #ifdef DYN_ALLOC
      if (window == NULL) {
          window = (uch*) fcalloc(WSIZE,   2*sizeof(uch));
          if (window == NULL) err(ZE_MEM, "window allocation");
-         window_size = (ulg)2*WSIZE;
      }
      if (prev == NULL) {
          prev   = (Pos*) fcalloc(WSIZE,     sizeof(Pos));
--- 309,328 ----
  
      if (pack_level < 1 || pack_level > 9) error("bad pack level");
  
+     /* Do not slide the window if the whole input is already in memory
+      * (window_size > 0)
+      */
+     sliding = 0;
+     if (window_size == 0L) {
+         sliding = 1;
+         window_size = (ulg)2L*WSIZE;
+     }
+ 
      /* Use dynamic allocation if compiler does not like big static arrays: */
  #ifdef DYN_ALLOC
      if (window == NULL) {
          window = (uch*) fcalloc(WSIZE,   2*sizeof(uch));
          if (window == NULL) err(ZE_MEM, "window allocation");
      }
      if (prev == NULL) {
          prev   = (Pos*) fcalloc(WSIZE,     sizeof(Pos));
***************
*** 313,324 ****
          }
      }
  #endif /* DYN_ALLOC */
! #ifdef ASMV
!     match_init(); /* initialize the asm code */
! #endif
!     /* Initialize the hash table. */
!     for (j = 0;  j < HASH_SIZE; j++) head[j] = NIL;
!     /* prev will be initialized on the fly */
  
      /* Set the default configuration parameters:
       */
--- 332,343 ----
          }
      }
  #endif /* DYN_ALLOC */
! 
!     /* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
!      * prev[] will be initialized on the fly.
!      */
!     head[HASH_SIZE-1] = NIL;
!     memset((char*)head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*head));
  
      /* Set the default configuration parameters:
       */
***************
*** 337,349 ****
  
      strstart = 0;
      block_start = 0L;
  
! #if defined(MSDOS) && !defined(__32BIT__)
!     /* Can't read a 64K block under MSDOS */
!     lookahead = read_buf((char*)window, (unsigned)WSIZE);
! #else
!     lookahead = read_buf((char*)window, 2*WSIZE);
  #endif
      if (lookahead == 0 || lookahead == (unsigned)EOF) {
         eofile = 1, lookahead = 0;
         return;
--- 356,371 ----
  
      strstart = 0;
      block_start = 0L;
+ #ifdef ASMV
+     match_init(); /* initialize the asm code */
+ #endif
  
!     j = WSIZE;
! #ifndef MAXSEG_64K
!     if (sizeof(int) > 2) j <<= 1; /* Can read 64K in one step */
  #endif
+     lookahead = (*read_buf)((char*)window, j);
+ 
      if (lookahead == 0 || lookahead == (unsigned)EOF) {
         eofile = 1, lookahead = 0;
         return;
***************
*** 362,367 ****
--- 384,407 ----
  }
  
  /* ===========================================================================
+  * Free the window and hash table
+  */
+ void lm_free()
+ {
+ #ifdef DYN_ALLOC
+     if (window != NULL) {
+         fcfree(window);
+         window = NULL;
+     }
+     if (prev != NULL) {
+         fcfree(prev);
+         fcfree(head);
+         prev = head = NULL;
+     }
+ #endif /* DYN_ALLOC */
+ }
+ 
+ /* ===========================================================================
   * Set match_start to the longest match starting at the given string and
   * return its length. Matches shorter or equal to prev_length are discarded,
   * in which case the result is equal to prev_length and match_start is
***************
*** 372,396 ****
  #ifndef ASMV
  /* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or
   * match.s. The code is functionally equivalent, so you can use the C version
!  * if desired.
   */
  int longest_match(cur_match)
      IPos cur_match;                             /* current match */
  {
      unsigned chain_length = max_chain_length;   /* max hash chain length */
      register uch *scan = window + strstart;     /* current string */
!     register uch *match = scan;                 /* matched string */
      register int len;                           /* length of current match */
      int best_len = prev_length;                 /* best match length so far */
      IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL;
      /* Stop when cur_match becomes <= limit. To simplify the code,
       * we prevent matches with the string of window index 0.
       */
  #ifdef UNALIGNED_OK
      register ush scan_start = *(ush*)scan;
      register ush scan_end   = *(ush*)(scan+best_len-1);
  #else
!     register uch scan_start = *scan;
      register uch scan_end1  = scan[best_len-1];
      register uch scan_end   = scan[best_len];
  #endif
--- 412,449 ----
  #ifndef ASMV
  /* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or
   * match.s. The code is functionally equivalent, so you can use the C version
!  * if desired.  A 68000 version is in amiga/match_68.a -- this could be used
!  * with other 68000 based systems such as Macintosh with a little effort.
   */
  int longest_match(cur_match)
      IPos cur_match;                             /* current match */
  {
      unsigned chain_length = max_chain_length;   /* max hash chain length */
      register uch *scan = window + strstart;     /* current string */
!     register uch *match;                        /* matched string */
      register int len;                           /* length of current match */
      int best_len = prev_length;                 /* best match length so far */
      IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL;
      /* Stop when cur_match becomes <= limit. To simplify the code,
       * we prevent matches with the string of window index 0.
       */
+ 
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+  * It is easy to get rid of this optimization if necessary.
+  */
+ #if HASH_BITS < 8 || MAX_MATCH != 258
+    error: Code too clever
+ #endif
+ 
  #ifdef UNALIGNED_OK
+     /* Compare two bytes at a time. Note: this is not always beneficial.
+      * Try with and without -DUNALIGNED_OK to check.
+      */
+     register uch *strend = window + strstart + MAX_MATCH - 1;
      register ush scan_start = *(ush*)scan;
      register ush scan_end   = *(ush*)(scan+best_len-1);
  #else
!     register uch *strend = window + strstart + MAX_MATCH;
      register uch scan_end1  = scan[best_len-1];
      register uch scan_end   = scan[best_len];
  #endif
***************
*** 399,404 ****
--- 452,458 ----
      if (prev_length >= good_match) {
          chain_length >>= 2;
      }
+     Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");
  
      do {
          Assert(cur_match < strstart, "no future");
***************
*** 407,450 ****
          /* Skip to next match if the match length cannot increase
           * or if the match length is less than 2:
           */
! #if (defined(UNALIGNED_OK) && HASH_BITS >= 8)
!         /* This code assumes sizeof(unsigned short) == 2 and
!          * sizeof(unsigned long) == 4. Do not use UNALIGNED_OK if your
!          * compiler uses different sizes.
           */
          if (*(ush*)(match+best_len-1) != scan_end ||
              *(ush*)match != scan_start) continue;
  
-         len = MIN_MATCH - 4;
          /* It is not necessary to compare scan[2] and match[2] since they are
           * always equal when the other bytes match, given that the hash keys
!          * are equal and that HASH_BITS >= 8.
!          */
!         do {} while ((len+=4) < MAX_MATCH-3 &&
!                      *(ulg*)(scan+len) == *(ulg*)(match+len));
!         /* The funny do {} generates better code for most compilers */
  
!         if (*(ush*)(scan+len) == *(ush*)(match+len)) len += 2;
!         if (scan[len] == match[len]) len++;
  
  #else /* UNALIGNED_OK */
!         if (match[best_len] != scan_end ||
! /*          match[best_len-1] != scan_end1 || */ *match != scan_start)
!            continue;
!         /* It is not necessary to compare scan[1] and match[1] since they
           * are always equal when the other bytes match, given that
!          * the hash keys are equal and that h_shift+8 <= HASH_BITS,
!          * that is, when the last byte is entirely included in the hash key.
!          * The condition is equivalent to
!          *       (HASH_BITS+2)/3 + 8 <= HASH_BITS
!          * or: HASH_BITS >= 13
           */
! #if HASH_BITS >= 13
!         len = 1;
! #else
!         len = 0;
! #endif
!         do {} while (++len < MAX_MATCH && scan[len] == match[len]);
  
  #endif /* UNALIGNED_OK */
  
--- 461,525 ----
          /* Skip to next match if the match length cannot increase
           * or if the match length is less than 2:
           */
! #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
!         /* This code assumes sizeof(unsigned short) == 2. Do not use
!          * UNALIGNED_OK if your compiler uses a different size.
           */
          if (*(ush*)(match+best_len-1) != scan_end ||
              *(ush*)match != scan_start) continue;
  
          /* It is not necessary to compare scan[2] and match[2] since they are
           * always equal when the other bytes match, given that the hash keys
!          * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
!          * strstart+3, +5, ... up to strstart+257. We check for insufficient
!          * lookahead only every 4th comparison; the 128th check will be made
!          * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
!          * necessary to put more guard bytes at the end of the window, or
!          * to check more often for insufficient lookahead.
!          */
!         scan++, match++;
!         do {
!         } while (*(ush*)(scan+=2) == *(ush*)(match+=2) &&
!                  *(ush*)(scan+=2) == *(ush*)(match+=2) &&
!                  *(ush*)(scan+=2) == *(ush*)(match+=2) &&
!                  *(ush*)(scan+=2) == *(ush*)(match+=2) &&
!                  scan < strend);
!         /* The funny "do {}" generates better code on most compilers */
! 
!         /* Here, scan <= window+strstart+257 */
!         Assert(scan <= window+(unsigned)(window_size-1), "wild scan");
!         if (*scan == *match) scan++;
  
!         len = (MAX_MATCH - 1) - (int)(strend-scan);
!         scan = strend - (MAX_MATCH-1);
  
  #else /* UNALIGNED_OK */
! 
!         if (match[best_len]   != scan_end  ||
!             match[best_len-1] != scan_end1 ||
!             *match            != *scan     ||
!             *++match          != scan[1])      continue;
! 
!         /* The check at best_len-1 can be removed because it will be made
!          * again later. (This heuristic is not always a win.)
!          * It is not necessary to compare scan[2] and match[2] since they
           * are always equal when the other bytes match, given that
!          * the hash keys are equal and that HASH_BITS >= 8.
           */
!         scan += 2, match++;
! 
!         /* We check for insufficient lookahead only every 8th comparison;
!          * the 256th check will be made at strstart+258.
!          */
!         do {
!         } while (*++scan == *++match && *++scan == *++match &&
!                  *++scan == *++match && *++scan == *++match &&
!                  *++scan == *++match && *++scan == *++match &&
!                  *++scan == *++match && *++scan == *++match &&
!                  scan < strend);
! 
!         len = MAX_MATCH - (int)(strend - scan);
!         scan = strend - MAX_MATCH;
  
  #endif /* UNALIGNED_OK */
  
***************
*** 459,466 ****
              scan_end   = scan[best_len];
  #endif
          }
!     } while (--chain_length != 0 &&
!              (cur_match = prev[cur_match & WMASK]) > limit);
  
      return best_len;
  }
--- 534,541 ----
              scan_end   = scan[best_len];
  #endif
          }
!     } while ((cur_match = prev[cur_match & WMASK]) > limit
!              && --chain_length != 0);
  
      return best_len;
  }
***************
*** 494,499 ****
--- 569,575 ----
  /* ===========================================================================
   * Fill the window when the lookahead becomes insufficient.
   * Updates strstart and lookahead, and sets eofile if end of input file.
+  *
   * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
   * OUT assertions: at least one byte has been read, or eofile is set;
   *    file reads are performed for at least two bytes (required for the
***************
*** 505,531 ****
      unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart);
      /* Amount of free space at the end of the window. */
  
!     /* If the window is full, move the upper half to the lower one to make
!      * room in the upper half.
       */
      if (more == (unsigned)EOF) {
          /* Very unlikely, but possible on 16 bit machine if strstart == 0
           * and lookahead == 1 (input done one byte at time)
           */
          more--;
!     } else if (more <= 1) {
          /* By the IN assertion, the window is not empty so we can't confuse
           * more == 0 with more == 64K on a 16 bit machine.
           */
-         Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM");
- 
          memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
          match_start -= WSIZE;
!         strstart    -= WSIZE;
!         /* strstart - WSIZE >= WSIZE - 1 - lookahead >= WSIZE - MIN_LOOKAHEAD
!          * so we now have strstart >= MAX_DIST:
!          */
!         Assert (strstart >= MAX_DIST, "window slide too early");
          block_start -= (long) WSIZE;
  
          for (n = 0; n < HASH_SIZE; n++) {
--- 581,608 ----
      unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart);
      /* Amount of free space at the end of the window. */
  
!     /* If the window is almost full and there is insufficient lookahead,
!      * move the upper half to the lower one to make room in the upper half.
       */
      if (more == (unsigned)EOF) {
          /* Very unlikely, but possible on 16 bit machine if strstart == 0
           * and lookahead == 1 (input done one byte at time)
           */
          more--;
! 
!     /* For MMAP or BIG_MEM, the whole input file is already in memory
!      * so we must not perform sliding. We must however call file_read
!      * in order to compute the crc, update lookahead and possibly set eofile.
!      */
!     } else if (strstart >= WSIZE+MAX_DIST && sliding) {
! 
          /* By the IN assertion, the window is not empty so we can't confuse
           * more == 0 with more == 64K on a 16 bit machine.
           */
          memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
          match_start -= WSIZE;
!         strstart    -= WSIZE; /* we now have strstart >= MAX_DIST: */
! 
          block_start -= (long) WSIZE;
  
          for (n = 0; n < HASH_SIZE; n++) {
***************
*** 543,553 ****
          if (verbose) putc('.', stderr);
      }
      /* At this point, more >= 2 */
!     n = read_buf((char*)window+strstart+lookahead, more);
!     if (n == 0 || n == (unsigned)EOF) {
!         eofile = 1;
!     } else {
!         lookahead += n;
      }
  }
  
--- 620,632 ----
          if (verbose) putc('.', stderr);
      }
      /* At this point, more >= 2 */
!     if (!eofile) {
!         n = (*read_buf)((char*)window+strstart+lookahead, more);
!         if (n == 0 || n == (unsigned)EOF) {
!             eofile = 1;
!         } else {
!             lookahead += n;
!         }
      }
  }
  
***************
*** 560,569 ****
                  (char*)NULL, (long)strstart - block_start, (eof))
  
  /* ===========================================================================
!  * Processes a new input file and return its compressed length.
   */
! #ifdef NO_LAZY
! ulg deflate()
  {
      IPos hash_head; /* head of the hash chain */
      int flush;      /* set if current block must be flushed */
--- 639,650 ----
                  (char*)NULL, (long)strstart - block_start, (eof))
  
  /* ===========================================================================
!  * Processes a new input file and return its compressed length. This
!  * function does not perform lazy evaluationof matches and inserts
!  * new strings in the dictionary only for unmatched strings or for short
!  * matches. It is used only for the fast compression options.
   */
! local ulg deflate_fast()
  {
      IPos hash_head; /* head of the hash chain */
      int flush;      /* set if current block must be flushed */
***************
*** 594,615 ****
              flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
  
              lookahead -= match_length;
!             match_length--; /* string at strstart already in hash table */
!             do {
!                 strstart++;
!                 INSERT_STRING(strstart, hash_head);
!                 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
!                  * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
!                  * these bytes are garbage, but it does not matter since the
!                  * next lookahead bytes will always be emitted as literals.
!                  */
!             } while (--match_length != 0);
          } else {
              /* No match, output a literal byte */
              flush = ct_tally (0, window[strstart]);
              lookahead--;
          }
-         strstart++; 
          if (flush) FLUSH_BLOCK(0), block_start = strstart;
  
          /* Make sure that we always have enough lookahead, except
--- 675,712 ----
              flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
  
              lookahead -= match_length;
! 
!             /* Insert new strings in the hash table only if the match length
!              * is not too large. This saves time but degrades compression.
!              */
!             if (match_length <= max_insert_length) {
!                 match_length--; /* string at strstart already in hash table */
!                 do {
!                     strstart++;
!                     INSERT_STRING(strstart, hash_head);
!                     /* strstart never exceeds WSIZE-MAX_MATCH, so there are
!                      * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
!                      * these bytes are garbage, but it does not matter since
!                      * the next lookahead bytes will be emitted as literals.
!                      */
!                 } while (--match_length != 0);
!                 strstart++; 
!             } else {
!                 strstart += match_length;
!                 match_length = 0;
!                 ins_h = window[strstart];
!                 UPDATE_HASH(ins_h, window[strstart+1]);
! #if MIN_MATCH != 3
!                 Call UPDATE_HASH() MIN_MATCH-3 more times
! #endif
!             }
          } else {
              /* No match, output a literal byte */
+             Tracevv((stderr,"%c",window[strstart]));
              flush = ct_tally (0, window[strstart]);
              lookahead--;
+             strstart++; 
          }
          if (flush) FLUSH_BLOCK(0), block_start = strstart;
  
          /* Make sure that we always have enough lookahead, except
***************
*** 622,628 ****
      }
      return FLUSH_BLOCK(1); /* eof */
  }
! #else /* LAZY */
  /* ===========================================================================
   * Same as above, but achieves better compression. We use a lazy
   * evaluation for matches: a match is finally adopted only if there is
--- 719,725 ----
      }
      return FLUSH_BLOCK(1); /* eof */
  }
! 
  /* ===========================================================================
   * Same as above, but achieves better compression. We use a lazy
   * evaluation for matches: a match is finally adopted only if there is
***************
*** 639,644 ****
--- 736,743 ----
      extern ulg isize;        /* byte length of input file, for debug only */
  #endif
  
+     if (level <= 3) return deflate_fast(); /* optimized for speed */
+ 
      /* Process the input block. */
      while (lookahead != 0) {
          /* Insert the string window[strstart .. strstart+2] in the
***************
*** 729,732 ****
  
      return FLUSH_BLOCK(1); /* eof */
  }
! #endif /* LAZY */
--- 828,831 ----
  
      return FLUSH_BLOCK(1); /* eof */
  }
! 
diff -c ../zip19i/fileio.c ./fileio.c
*** ../zip19i/fileio.c	Tue Nov  3 21:07:54 1992
--- ./fileio.c	Fri Sep 10 05:02:28 1993
***************
*** 1,16 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
  /*
   *  fileio.c by Mark Adler.
   */
  
  #include "zip.h"
--- 1,18 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
  /*
   *  fileio.c by Mark Adler.
+  *
+  *  This file has become a big mess over time, and will be split in the
+  *  next version, one file per operating system.
   */
  
  #include "zip.h"
***************
*** 20,25 ****
--- 22,28 ----
  #ifdef WIN32
  #  include <sys/utime.h>
  #  include <windows.h> /* for findfirst/findnext */
+    char *GetLongPathEA OF((char *name));
  #endif
  
  #ifdef MACOS
***************
*** 53,63 ****
  #    endif
  #  endif /* ?__TURBOC__ */
  #  define link rename
! #  ifdef OS2
  #    define MATCH shmatch
! #  else /* !OS2 */
  #    define MATCH dosmatch
! #  endif /* ?OS2 */
  #else /* !MSDOS */
     extern int errno;    /* error number from system functions */
  #  ifdef TOPS20
--- 56,66 ----
  #    endif
  #  endif /* ?__TURBOC__ */
  #  define link rename
! #  if defined(OS2) || defined(WIN32)
  #    define MATCH shmatch
! #  else
  #    define MATCH dosmatch
! #  endif
  #else /* !MSDOS */
     extern int errno;    /* error number from system functions */
  #  ifdef TOPS20
***************
*** 87,96 ****
  #  define RMDIR
  #endif /* UTS */
  
  
  /* Extra malloc() space in names for cutpath() */
  #if (defined(VMS) || defined(TOPS20))
! #  define PAD 3         /* may have to change .FOO] to ]FOO.DIR */
  #else
  #  define PAD 0
  #  define PATH_END '/'
--- 90,124 ----
  #  define RMDIR
  #endif /* UTS */
  
+ #ifdef AMIGA
+ #  define link rename
+ #  define utime FileDate
+ #  ifdef __SASC_60
+ #    include <dos.h>               /* SAS/C 6.x , pulled by wild() */
+ #    include <sys/dir.h>
+ #    define direct dirent
+ #    define disk_not_mounted 0  
+ #  else
+ #    define dirent direct
+ #  endif
+ #  ifdef MODERN
+ #    include <clib/exec_protos.h>
+ #    include <clib/dos_protos.h>
+ #  endif
+ #  ifdef AZTEC_C
+ #    include <pragmas/exec_lib.h>
+ #    include <pragmas/dos_lib.h>
+ #  endif
+ #endif 
+ 
+ #ifdef __human68k__
+ #  include <jctype.h>
+ #  define link rename
+ #endif
  
  /* Extra malloc() space in names for cutpath() */
  #if (defined(VMS) || defined(TOPS20))
! #  define PAD 5         /* may have to change .FOO] to ]FOO.DIR;1 */
  #else
  #  define PAD 0
  #  define PATH_END '/'
***************
*** 102,117 ****
  #  include <rms.h>
  #endif
  
! /* For directory access. (This is getting rather messy. Cleanup
!  * scheduled for version 17.9.)
!  */
  #ifndef UTIL
  
! #if defined(SYSV) || defined(__GO32__)   /* use readdir()  */
  #  include <dirent.h>
  #  define dstrm DIR
  #  define direct dirent
! #else /* !SYSV && !__GO32__ */
  
  #ifdef DIRENT                   /* use getdents() */
  #ifndef TOPS20
--- 130,149 ----
  #  include <rms.h>
  #endif
  
! /* For directory access. */
! 
  #ifndef UTIL
  
! #ifdef __human68k__
! #include <sys/dos.h>
! #endif
! 
! #if defined(SYSV) || defined(__GO32__) || defined(__386BSD__) || defined(__human68k__)
! /* use readdir() */
  #  include <dirent.h>
  #  define dstrm DIR
  #  define direct dirent
! #else /* !SYSV && !__GO32__ && !__386BSD__ && !__human68k__*/
  
  #ifdef DIRENT                   /* use getdents() */
  #ifndef TOPS20
***************
*** 139,153 ****
  #  define FALSE 0
  #  define O_RDONLY (0)
  #  define O_T20_WILD (1<<18)
! #  include <monsym.h>	/* Get amazing monsym() macro */
     extern int jsys(), fstat();
     extern char *getcwd();
     extern int _gtjfn(), _rljfn();
! #  define JSYS_CLASS	0070000000000
  #  define FLD(val,mask) (((unsigned)(val)*((mask)&(-(mask))))&(mask))
  #  define _DEFJS(name,class) (FLD(class, JSYS_CLASS) | (monsym(name)&0777777))
! #  define JFNS	_DEFJS("JFNS%", 1)
! #  define GNJFN	_DEFJS("GNJFN%", 0)
     static int wfopen(), wfnext(), strlower(), strupper();
     static char *wfname();
     typedef struct {
--- 171,185 ----
  #  define FALSE 0
  #  define O_RDONLY (0)
  #  define O_T20_WILD (1<<18)
! #  include <monsym.h>    /* Get amazing monsym() macro */
     extern int jsys(), fstat();
     extern char *getcwd();
     extern int _gtjfn(), _rljfn();
! #  define JSYS_CLASS    0070000000000
  #  define FLD(val,mask) (((unsigned)(val)*((mask)&(-(mask))))&(mask))
  #  define _DEFJS(name,class) (FLD(class, JSYS_CLASS) | (monsym(name)&0777777))
! #  define JFNS  _DEFJS("JFNS%", 1)
! #  define GNJFN _DEFJS("GNJFN%", 0)
     static int wfopen(), wfnext(), strlower(), strupper();
     static char *wfname();
     typedef struct {
***************
*** 171,199 ****
  #     ifdef OS2
  #      include "os2zip.h"
  #     else /* !OS2 */
  #      ifndef ATARI_ST
  #        include <dos.h>
  #      endif
  #      ifdef __TURBOC__
! #        define FATTR           FA_HIDDEN+FA_SYSTEM+FA_DIREC
! #        define FFIRST(n,d)     findfirst(n,(struct ffblk *)d,FATTR)
  #        define FNEXT(d)        findnext((struct ffblk *)d)
  #      else /* !__TURBOC__ */
! #        define FATTR           _A_HIDDEN+_A_SYSTEM+_A_SUBDIR
! #        define FFIRST(n,d)     _dos_findfirst(n,FATTR,(struct find_t *)d)
  #        define FNEXT(d)        _dos_findnext((struct find_t *)d)
  #      endif /* ?__TURBOC__ */
         typedef struct direct {
!          char d_reserved[30];
  #      ifndef WIN32
           char d_name[13];
! 	 int d_first;
  #      else
           char d_name[MAX_PATH];
! 	 int d_first;
           HANDLE d_hFindFile;
  #      endif /* WIN32 */
         } DIR;
  #     endif /* ?OS2 */
  #    else /* !MSDOS */
  #      ifdef VMS
--- 203,241 ----
  #     ifdef OS2
  #      include "os2zip.h"
  #     else /* !OS2 */
+ #      ifdef WIN32
+ #        include "ntzip.h"
+ #      endif
  #      ifndef ATARI_ST
  #        include <dos.h>
  #      endif
  #      ifdef __TURBOC__
! #        define FATTR (hidden_files ? FA_HIDDEN+FA_SYSTEM+FA_DIREC : FA_DIREC)
! #        define FFIRST(n,d,a)   findfirst(n,(struct ffblk *)d,a)
  #        define FNEXT(d)        findnext((struct ffblk *)d)
  #      else /* !__TURBOC__ */
! #        define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR :_A_SUBDIR)
! #        define FA_LABEL _A_VOLID
! #        define FFIRST(n,d,a)   _dos_findfirst(n,a,(struct find_t *)d)
  #        define FNEXT(d)        _dos_findnext((struct find_t *)d)
  #      endif /* ?__TURBOC__ */
         typedef struct direct {
!          char   reserved [21];
!          char   ff_attrib;
!          short  ff_ftime;
!          short  ff_fdate;
!          long   size;
  #      ifndef WIN32
           char d_name[13];
!          int d_first;
  #      else
           char d_name[MAX_PATH];
!          int d_first;
           HANDLE d_hFindFile;
  #      endif /* WIN32 */
         } DIR;
+        typedef DIR ff_dir;
+ #      define ff_name d_name /* ff_name is used by DJGPP */
  #     endif /* ?OS2 */
  #    else /* !MSDOS */
  #      ifdef VMS
***************
*** 212,241 ****
               char *d_name;
            } DIR;
  #        endif
! #        ifdef M_XENIX
  #          include <sys/ndir.h>
  #        else /* !M_XENIX */
! #          include <sys/dir.h>
  #        endif /* ?M_XENIX */
! #        ifdef NODIR                    /* for AT&T 3B1 */
  #          define dirent direct
             typedef FILE DIR;
- #          define dstrm DIR
  #        endif /* NODIR */
  #      endif /* ?VMS */
  #    endif /* ?MSDOS */
  #  endif /* ?NDIR */
  #  define dstrm DIR
! #  ifndef NODIR
!      DIR *opendir OF((char *));
! #  endif /* !NODIR */
! #  ifndef CONVEX
!      struct direct *readdir OF((DIR *));
! #  endif /* !CONVEX */
  #endif /* ?DIRENT */
  #endif /* ?SYSV */
  #endif /* !UTIL */
  
  
  /* Library functions not in (most) header files */
  
--- 254,293 ----
               char *d_name;
            } DIR;
  #        endif
! #        if defined(M_XENIX) || defined(SYSNDIR)
  #          include <sys/ndir.h>
  #        else /* !M_XENIX */
! #          ifndef AZTEC_C
! #            include <sys/dir.h>
! #          endif
  #        endif /* ?M_XENIX */
! #        ifdef NODIR                    /* for AT&T 3B1 + Amiga non SAS */
  #          define dirent direct
             typedef FILE DIR;
  #        endif /* NODIR */
  #      endif /* ?VMS */
  #    endif /* ?MSDOS */
  #  endif /* ?NDIR */
  #  define dstrm DIR
! #  if defined(MSDOS) && !defined(OS2)
! #    ifndef __GO32__
!        DIR *opendir OF((const char *));
!        struct direct *readdir OF((DIR *));
! #    endif
! #    ifndef WIN32
!        char *getVolumeLabel OF((int drive, ulg *vtime, ulg *vmode));
! #    endif
! #  endif
  #endif /* ?DIRENT */
  #endif /* ?SYSV */
  #endif /* !UTIL */
  
+ #ifdef __GO32__
+    typedef struct ffblk ff_dir;
+ #  define FFIRST(n,d,a)   findfirst(n,(struct ffblk *)d,a)
+ #endif
+ 
+ #define MSDOS_DIR_ATTR 0x10
  
  /* Library functions not in (most) header files */
  
***************
*** 248,283 ****
  #endif
  char *mktemp OF((char *));
  
! #ifndef __GO32__
!   int link OF((char *, char *));
!   int unlink OF((char *));
! # if defined(MSDOS)
!    int chmod OF((char *, int));
!    /* For many targets, chmod is already defined by sys/stat.h, and second
!     * parameter is an unsigned long.
!     */
! # endif
! #else
  #  include <dos.h>
  #endif
  
  
  #ifndef UTIL    /* the companion #endif is a bit of ways down ... */
  
! #ifndef __TURBOC__
     int utime OF((char *, time_t *));
! #endif /* !__TURBOC__ */
  #ifndef MSDOS
!    int open OF((char *, int, ...));
!    int close OF((int));
  #  ifndef RMDIR
!      int rmdir OF((char *));
  #  endif /* !RMDIR */
  #endif /* !MSDOS */
  
  
  /* Local globals (kinda like "military intelligence" or "broadcast quality") */
! local int exflag = 0;           /* Exclude flag */
  
  #ifdef VMS
    typedef int statime;
--- 300,339 ----
  #endif
  char *mktemp OF((char *));
  
! #ifdef __GO32__
  #  include <dos.h>
+ #else
+   /* int link OF((const char *, const char *)); */
+   /* int unlink OF((const char *)); */
+   /* int chmod OF((const char *, int)); */
+   /* For many targets, chmod is already defined by sys/stat.h, and second
+    * parameter is an unsigned long.
+    */
  #endif
  
  
  #ifndef UTIL    /* the companion #endif is a bit of ways down ... */
  
! #if !defined(__TURBOC__) && !defined(WIN32) && !defined(sgi)
     int utime OF((char *, time_t *));
! #endif
  #ifndef MSDOS
!    /* int open OF((char *, int, ...)); */
!    /* int close OF((int)); */
  #  ifndef RMDIR
!      /* int rmdir OF((const char *)); */
  #  endif /* !RMDIR */
  #endif /* !MSDOS */
  
  
  /* Local globals (kinda like "military intelligence" or "broadcast quality") */
! local struct stat zipstatb;
! local int zipstate = -1;
! /* -1 unknown, 0 old zip file exists, 1 new zip file */
! 
! local char *label = NULL;
! local ulg label_time = 0;
! local ulg label_mode = 0;
  
  #ifdef VMS
    typedef int statime;
***************
*** 295,309 ****
       local void closed(dstrm *);
  #  endif /* DIRENT */
     local char *readd(dstrm *);
!    local int fqcmp(voidp *, voidp *);
!    local int fqcmpz(voidp *, voidp *);
     local char *last(char *);
     local char *msname(char *);
  #  ifdef VMS
       local char *strlower(char *);
       local char *strupper(char *);
  #  endif /* VMS */
-    local char *ex2in(char *, int, int *);
     local int newname(char *, int);
     local void inctime(struct tm *);
     local ulg unix2dostime(statime *);
--- 351,364 ----
       local void closed(dstrm *);
  #  endif /* DIRENT */
     local char *readd(dstrm *);
!    local int fqcmp(const voidp *, const voidp *);
!    local int fqcmpz(const voidp *, const voidp *);
     local char *last(char *);
     local char *msname(char *);
  #  ifdef VMS
       local char *strlower(char *);
       local char *strupper(char *);
  #  endif /* VMS */
     local int newname(char *, int);
     local void inctime(struct tm *);
     local ulg unix2dostime(statime *);
***************
*** 316,366 ****
  
  #if defined(MSDOS) && !defined(OS2) && !defined(__GO32__)
  dstrm *opendir(n)
! char *n;                /* directory to open */
  /* Start searching for files in the MSDOS directory n */
  {
    dstrm *d;             /* malloc'd return value */
    char *p;              /* malloc'd temporary string */
  
    if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL ||
!       (p = malloc(strlen(n) + 5)) == NULL)
      return NULL;
    strcat(strcpy(p, n), "/");
    strcat(p, "*.*"); /* don't use strcat in one step, TOPS20 is confused */
  
  #ifdef WIN32
    {
!   WIN32_FIND_DATA fd;
!   DWORD dwAttr;
!   BOOL bAttr;
  
!   if ((HANDLE)0xFFFFFFFF == (d->d_hFindFile = FindFirstFile(p, &fd)))
      {
!     free((voidp *)p);
!     return NULL;
      }
-   else
      strcpy(d->d_name, fd.cFileName);
!   if (-1 != (dwAttr = GetFileAttributes(fd.cFileName)))
      {
!     bAttr = FALSE;
!     if (FILE_ATTRIBUTE_SYSTEM == (dwAttr & FILE_ATTRIBUTE_SYSTEM))
! 	bAttr = TRUE;
!     if (FILE_ATTRIBUTE_HIDDEN == (dwAttr & FILE_ATTRIBUTE_HIDDEN))
! 	bAttr = TRUE;
!     if (FILE_ATTRIBUTE_DIRECTORY == (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
! 	bAttr = TRUE;
!     if (!bAttr)
! 	{
! 	free ((voidp *)p);
! 	free ((void *) d);
! 	return NULL;
! 	}
      }
- 
    }
  #else
!   if (FFIRST(p, d))
    {
      free((voidp *)p);
      return NULL;
--- 371,416 ----
  
  #if defined(MSDOS) && !defined(OS2) && !defined(__GO32__)
  dstrm *opendir(n)
! const char *n;                /* directory to open */
  /* Start searching for files in the MSDOS directory n */
  {
    dstrm *d;             /* malloc'd return value */
    char *p;              /* malloc'd temporary string */
  
    if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL ||
!       (p = malloc(strlen(n) + 5)) == NULL) {
!     if (d != NULL) free((void *) d);
      return NULL;
+   }
    strcat(strcpy(p, n), "/");
    strcat(p, "*.*"); /* don't use strcat in one step, TOPS20 is confused */
  
  #ifdef WIN32
    {
!     WIN32_FIND_DATA fd;
!     DWORD dwAttr;
  
!     if ( INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd)))
      {
!       free((voidp *)p);
!       return NULL;
      }
      strcpy(d->d_name, fd.cFileName);
! 
!     if (-1 != (dwAttr = GetFileAttributes(fd.cFileName)))
      {
!       if (!hidden_files &&
!          (FILE_ATTRIBUTE_SYSTEM == (dwAttr & FILE_ATTRIBUTE_SYSTEM) ||
!           FILE_ATTRIBUTE_HIDDEN == (dwAttr & FILE_ATTRIBUTE_HIDDEN)))
!       {
!           free ((voidp *)p);
!           d->d_first = 0;
!           return d;
!       }
      }
    }
  #else
!   if (FFIRST(p, d, FATTR))
    {
      free((voidp *)p);
      return NULL;
***************
*** 379,399 ****
      d->d_first = 0;
    else
  #ifdef WIN32
!     {
      WIN32_FIND_DATA fd;
  
      if (!FindNextFile(d->d_hFindFile, &fd))
! 	return NULL;
!     else
! 	strcpy(d->d_name, fd.cFileName);
      }
  #else /* !WIN32 */
      if (FNEXT(d))
        return NULL;
  #endif
    return (struct direct *)d;
  }
  #  define closedir free
  
  #endif /* MSDOS && !OS2 && !__GO32__ */
  
--- 429,468 ----
      d->d_first = 0;
    else
  #ifdef WIN32
!   {
      WIN32_FIND_DATA fd;
+     DWORD dwAttr;
  
      if (!FindNextFile(d->d_hFindFile, &fd))
!         return NULL;
! 
!     strcpy(d->d_name, fd.cFileName);
! 
!     if (!hidden_files &&
!        (-1 != (dwAttr = GetFileAttributes(fd.cFileName))) &&
!        (FILE_ATTRIBUTE_SYSTEM == (dwAttr & FILE_ATTRIBUTE_SYSTEM) ||
!         FILE_ATTRIBUTE_HIDDEN == (dwAttr & FILE_ATTRIBUTE_HIDDEN)))
!     {
!         return (readdir(d));
      }
+   }
  #else /* !WIN32 */
      if (FNEXT(d))
        return NULL;
  #endif
    return (struct direct *)d;
+ 
+ }
+ #ifdef WIN32
+ void closedir(d)
+ dstrm *d;
+ {
+         FindClose(d->d_hFindFile);
+         free(d);
  }
+ #else
  #  define closedir free
+ #endif
  
  #endif /* MSDOS && !OS2 && !__GO32__ */
  
***************
*** 409,414 ****
--- 478,486 ----
      behavior of MS-DOS (MSC and Turbo C) findfirst and findnext functions.
  
    ---------------------------------------------------------------------------*/
+ 
+ static char wild_version_part[10]="\0";
+ 
  local void vms_wild(p, d)
  char *p;
  dstrm *d;
***************
*** 476,481 ****
--- 548,554 ----
      *c = '.';           /* "]" --> "." */
    }
    strcat(p, "*.*");
+   strcat(p, wild_version_part);
    vms_wild(p, d);       /* set up wildcard */
    free((voidp *)p);
    return d;
***************
*** 537,566 ****
     NULL if error. */
  {
      dstrm *d;             /* pointer to malloc'ed directory stream */
!     char    *c;				/* scans TOPS20 path */
!     int	    m;				/* length of name */
!     char    *p;				/* temp string */
  
      if (((d = (dstrm *)malloc(sizeof(dstrm))) == NULL) ||
! 	((p = (char *)malloc((m = strlen(n)) + 4)) == NULL)) {
! 	    return NULL;
      }
  
  /* Directory may be in form "<DIR.SUB1.SUB2>" or "<DIR.SUB1>SUB2.DIRECTORY".
  ** If latter, convert to former. */
  
      if ((m > 0)  &&  (*(c = strcpy(p,n) + m-1) != '>')) {
! 	c -= 10;
! 	*c-- = '\0';        /* terminate at "DIRECTORY.1" */
! 	*c = '>';           /* "." --> ">" */
! 	while ((c > p)  &&  (*--c != '>'));
! 	*c = '.';           /* ">" --> "." */
      }
      strcat(p, "*.*");
      if ((d->wfjfn = wfopen(p)) == 0) {
! 	free((voidp *)d);
! 	free((voidp *)p);
! 	return NULL;
      }
      free((voidp *)p);
      d->more = TRUE;
--- 610,639 ----
     NULL if error. */
  {
      dstrm *d;             /* pointer to malloc'ed directory stream */
!     char    *c;                         /* scans TOPS20 path */
!     int     m;                          /* length of name */
!     char    *p;                         /* temp string */
  
      if (((d = (dstrm *)malloc(sizeof(dstrm))) == NULL) ||
!         ((p = (char *)malloc((m = strlen(n)) + 4)) == NULL)) {
!             return NULL;
      }
  
  /* Directory may be in form "<DIR.SUB1.SUB2>" or "<DIR.SUB1>SUB2.DIRECTORY".
  ** If latter, convert to former. */
  
      if ((m > 0)  &&  (*(c = strcpy(p,n) + m-1) != '>')) {
!         c -= 10;
!         *c-- = '\0';        /* terminate at "DIRECTORY.1" */
!         *c = '>';           /* "." --> ">" */
!         while ((c > p)  &&  (*--c != '>'));
!         *c = '.';           /* ">" --> "." */
      }
      strcat(p, "*.*");
      if ((d->wfjfn = wfopen(p)) == 0) {
!         free((voidp *)d);
!         free((voidp *)p);
!         return NULL;
      }
      free((voidp *)p);
      d->more = TRUE;
***************
*** 618,624 ****
    d->p += ((struct direct *)(d->p))->d_reclen;  /* advance */
    return e->d_name;                             /* return name */
  # else /* !DIRENT */
!   return (e = readdir(d)) == NULL ? (char *)NULL : e->d_name;
  # endif /* ?DIRENT */
  #endif /* ?TOPS20 */
  }
--- 691,698 ----
    d->p += ((struct direct *)(d->p))->d_reclen;  /* advance */
    return e->d_name;                             /* return name */
  # else /* !DIRENT */
!   e = readdir(d);
!   return e == NULL ? (char *)NULL : e->d_name;
  # endif /* ?DIRENT */
  #endif /* ?TOPS20 */
  }
***************
*** 642,648 ****
  /* Wildcard filename routines */
  
  /* WFOPEN - open wild card filename
! **	Returns wild JFN for filespec, 0 if failure.
  */
  static int
  wfopen(name)
--- 716,722 ----
  /* Wildcard filename routines */
  
  /* WFOPEN - open wild card filename
! **      Returns wild JFN for filespec, 0 if failure.
  */
  static int
  wfopen(name)
***************
*** 652,658 ****
  }
  
  /* WFNAME - Return filename for wild JFN
! **	Returns pointer to dynamically allocated filename string
  */
  static char *
  wfname(jfn)
--- 726,732 ----
  }
  
  /* WFNAME - Return filename for wild JFN
! **      Returns pointer to dynamically allocated filename string
  */
  static char *
  wfname(jfn)
***************
*** 662,680 ****
      int ablock[5];
  
      ablock[1] = (int) (fname - 1);
!     ablock[2] = jfn & 0777777;	/* jfn, no flags */
!     ablock[3] = 0111110000001;	/* DEV+DIR+NAME+TYPE+GEN, punctuate */
      if (!jsys(JFNS, ablock))
! 	return NULL;		/* something bad happened */
      if ((fp = (char *)malloc(strlen(fname) + 1)) == NULL) {
! 	return NULL;
      }
!     strcpy(fp, fname);		/* copy the file name here */
      return fp;
  }
  
  /* WFNEXT - Make wild JFN point to next real file
! **	Returns success or failure (not JFN)
  */
  static int
  wfnext(jfn)
--- 736,754 ----
      int ablock[5];
  
      ablock[1] = (int) (fname - 1);
!     ablock[2] = jfn & 0777777;  /* jfn, no flags */
!     ablock[3] = 0111110000001;  /* DEV+DIR+NAME+TYPE+GEN, punctuate */
      if (!jsys(JFNS, ablock))
!         return NULL;            /* something bad happened */
      if ((fp = (char *)malloc(strlen(fname) + 1)) == NULL) {
!         return NULL;
      }
!     strcpy(fp, fname);          /* copy the file name here */
      return fp;
  }
  
  /* WFNEXT - Make wild JFN point to next real file
! **      Returns success or failure (not JFN)
  */
  static int
  wfnext(jfn)
***************
*** 682,700 ****
  {
      int ablock[5];
  
!     ablock[1] = jfn;		/* save jfn and flags */
      return jsys(GNJFN, ablock);
  }
  #endif /* TOPS20 */
    
  
! #if defined(MSDOS) && !defined(__GO32__)
  
  int wild(w)
  char *w;                /* path/pattern to match */
  /* If not in exclude mode, expand the pattern based on the contents of the
     file system.  Return an error code in the ZE_ class. */
  {
    char *a;              /* alloc'ed space for name */
    dstrm *d;             /* stream for reading directory */
    char *e;              /* name found in directory */
--- 756,837 ----
  {
      int ablock[5];
  
!     ablock[1] = jfn;            /* save jfn and flags */
      return jsys(GNJFN, ablock);
  }
  #endif /* TOPS20 */
    
  
! #ifdef __human68k__
! int wild(w)
! char *w;
! {
!   struct _filbuf inf;
!   int r;
!   extern int _hupair;
!   char name[FNMAX];
!   char *p;
! 
!   if (_hupair)
!     return procname(w);         /* if argv's passed hupair, don't glob */
!   strcpy(name, w);
!   _toslash(name);
!   if ((p = strrchr(name, '/')) == NULL && (p = strrchr(name, ':')) == NULL)
!     p = name;
!   else
!     p++;
!   if (_dos_files (&inf, w, 0xff) < 0)
!     return ZE_MISS;
!   do {
!     strcpy(p, inf.name);
!     r = procname(name);
!     if (r != ZE_OK)
!       return r;
!   } while (_dos_nfiles(&inf) >= 0);
! 
!   return ZE_OK;
! }
! #endif
  
+ #if defined(MSDOS) && !defined(OS2) && !defined(WIN32)
+ 
+ char *getVolumeLabel(drive, vtime, vmode)
+   int drive;  /* drive name: 'A' .. 'Z' or '\0' for current drive */
+   ulg *vtime; /* volume label creation time (DOS format) */
+   ulg *vmode; /* volume label file mode */
+ 
+ /* If a volume label exists for the given drive, return its name and
+    set its time and mode. The returned name must be static data. */
+ {
+   static char vol[14];
+   ff_dir d;
+ 
+   if (drive) {
+     vol[0] = (char)drive;
+     strcpy(vol+1, ":/");
+   } else {
+     strcpy(vol, "/");
+   }
+   strcat(vol, "*.*");
+   if (FFIRST(vol, &d, FA_LABEL) == 0) {
+     strncpy(vol, d.ff_name, sizeof(vol)-1);
+     *vtime = ((ulg)d.ff_fdate << 16) | ((ulg)d.ff_ftime & 0xffff);
+     *vmode = (ulg)d.ff_attrib;
+     return vol;
+   }
+   return NULL;
+ }
+ 
+ #endif /*  MSDOS && !OS2 && !WIN32 */
+ 
+ #if defined(MSDOS) || defined(OS2)
+ 
  int wild(w)
  char *w;                /* path/pattern to match */
  /* If not in exclude mode, expand the pattern based on the contents of the
     file system.  Return an error code in the ZE_ class. */
  {
+ # ifndef __GO32__
    char *a;              /* alloc'ed space for name */
    dstrm *d;             /* stream for reading directory */
    char *e;              /* name found in directory */
***************
*** 704,728 ****
    char *q;              /* name */
    int r;                /* temporary variable */
    char v[5];            /* space for device current directory */
  
    /* Allocate and copy pattern */
    if ((p = a = malloc(strlen(w) + 1)) == NULL)
      return ZE_MEM;
    strcpy(p, w);
  
!   /* Normalize pattern to upper case, path delimiter as '/'. */
    for (q = p; *q; q++)                  /* use / consistently */
      if (*q == '\\')
        *q = '/';
  
-   /* If excluding, don't bother with file system */
-   if (exflag)
-   {
-     r = procname(p);
-     free((voidp *)a);
-     return r;
-   }
- 
    /* Only name can have special matching characters */
    if ((q = isshexp(p)) != NULL &&
        (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL))
--- 841,873 ----
    char *q;              /* name */
    int r;                /* temporary variable */
    char v[5];            /* space for device current directory */
+ # endif /* __GO32__ */
  
+ # ifndef WIN32
+   if (volume_label == 1) {
+     volume_label = 2;
+     label = getVolumeLabel(w[1] == ':' ? to_up(w[0]) : '\0',
+                            &label_time, &label_mode);
+     if (label != NULL) {
+        newname(label, 0);
+     }
+     if (w[1] == ':' && w[2] == '\0') return ZE_OK;
+     /* "zip -$ foo a:" can be used to force drive name */
+   }
+ # endif
+ # ifdef __GO32__
+   return procname(w); /* expansion already done by DJGPP */
+ # else
    /* Allocate and copy pattern */
    if ((p = a = malloc(strlen(w) + 1)) == NULL)
      return ZE_MEM;
    strcpy(p, w);
  
!   /* Normalize path delimiter as '/'. */
    for (q = p; *q; q++)                  /* use / consistently */
      if (*q == '\\')
        *q = '/';
  
    /* Only name can have special matching characters */
    if ((q = isshexp(p)) != NULL &&
        (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL))
***************
*** 754,759 ****
--- 899,913 ----
      q = p;
      p = strcpy(v, ".");
    }
+   /* I can't understand Mark's code so I am adding a hack here to get
+    * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but
+    * reject "zip -rm foo ..".
+    */
+   if (recurse && (strcmp(q, ".") == 0 ||  strcmp(q, "..") == 0)) {
+      if (dispose && strcmp(q, "..") == 0)
+         err(ZE_PARMS, "cannot remove parent directory");
+      return procname(p);
+   }
  
    /* Search that level for matching names */
    if ((d = opend(p)) == NULL)
***************
*** 765,781 ****
        (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0))
      *(p + r - 1) = 0;
    f = 0;
!   while ((e = readd(d)) != NULL)
      if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e))
      {
        f = 1;
!       if (strcmp(p, ".") == 0)                  /* path is . */
!         procname(e);                            /* name is name */
!       else
        {
          if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL)
          {
            free((voidp *)a);
            return ZE_MEM;
          }
          n = strcpy(n, p);
--- 919,940 ----
        (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0))
      *(p + r - 1) = 0;
    f = 0;
!   while ((e = readd(d)) != NULL) {
      if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e))
      {
        f = 1;
!       if (strcmp(p, ".") == 0) {                /* path is . */
!         r = procname(e);                        /* name is name */
!         if (r) {
!            f = 0;
!            break;
!         }
!       } else
        {
          if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL)
          {
            free((voidp *)a);
+           closed(d);
            return ZE_MEM;
          }
          n = strcpy(n, p);
***************
*** 783,805 ****
            strcat(n, "/");
          r = procname(strcat(n, e));             /* name is path/name */
          free((voidp *)n);
!         if (r)
!         {
!           free((voidp *)a);
!           return r;
          }
        }
      }
    closed(d);
  
    /* Done */
    free((voidp *)a);
    return f ? ZE_OK : ZE_MISS;
  }
! #endif /* MSDOS && !__GO32__ */
  
! #if defined(MSDOS) && !defined(OS2)
! #  if (defined(__TURBOC__) || defined(__GO32__)) && !defined(__BORLANDC__)
  #   define GetFileMode(name) bdosptr(0x43, (name), 0)
  #  else
      int GetFileMode(char *name)
--- 942,965 ----
            strcat(n, "/");
          r = procname(strcat(n, e));             /* name is path/name */
          free((voidp *)n);
!         if (r) {
!           f = 0;
!           break;
          }
        }
      }
+   }
    closed(d);
  
    /* Done */
    free((voidp *)a);
    return f ? ZE_OK : ZE_MISS;
+ # endif /* __GO32__ */
  }
! #endif /* MSDOS || OS2 */
  
! #if defined(MSDOS) && !defined(OS2) && !defined(WIN32)
! #  if defined(__TURBOC__) || defined(__GO32__) || defined(__BORLANDC__)
  #   define GetFileMode(name) bdosptr(0x43, (name), 0)
  #  else
      int GetFileMode(char *name)
***************
*** 811,816 ****
--- 971,1088 ----
  #  endif/* __TURBOC__  || __GO32__ */
  # endif /* MSDOS && !OS2 */
  
+ #ifdef __human68k__
+ #  define GetFileMode(name) (_dos_chmod((name), -1) & 0x3f)
+ #endif
+ 
+ #ifdef AMIGA
+  
+ /* What we have here is a mostly-generic routine using opend()/readd() and */
+ /* isshexp()/MATCH() to find all the files matching a multi-part filespec  */
+ /* using the portable pattern syntax.  It shouldn't take too much fiddling */
+ /* to make it usable for any other platform that has directory hierarchies */
+ /* but no shell-level pattern matching.  It works for patterns throughout  */
+ /* the pathname, such as "foo:*.?/source/x*.[ch]".                         */
+ 
+ /* whole is a pathname with wildcards, wildtail points somewhere in the  */
+ /* middle of it.  All wildcards to be expanded must come AFTER wildtail. */
+ 
+ local int wild_recurse(whole, wildtail) char *whole; char *wildtail;
+ {
+     dstrm *dir;
+     char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
+     ush newlen, amatch = 0;
+     BPTR lok;
+     int e = ZE_MISS;
+ 
+     if (!isshexp(wildtail))
+         if (lok = Lock(whole, ACCESS_READ)) {       /* p exists? */
+             UnLock(lok);
+             return procname(whole);
+         } else
+             return ZE_MISS;                     /* woops, no wildcards! */
+ 
+     /* back up thru path components till existing dir found */
+     do {
+         name = wildtail + strlen(wildtail) - 1;
+         for (;;)
+             if (name-- <= wildtail || *name == '/') {
+                 subwild = name + 1;
+                 plug2 = *subwild;
+                 *subwild = 0;
+                 break;
+             }
+         if (glue)
+             *glue = plug;
+         glue = subwild;
+         plug = plug2;
+         dir = opend(whole);
+     } while (!dir && !disk_not_mounted && subwild > wildtail);
+     wildtail = subwild;                 /* skip past non-wild components */
+ 
+     if (subwild = strchr(wildtail + 1, '/')) {
+         /* this "+ 1" dodges the  ^^^ hole left by *glue == 0 */
+         *(subwild++) = 0;               /* wildtail = one component pattern */
+         newlen = strlen(whole) + strlen(subwild) + 32;
+     } else
+         newlen = strlen(whole) + 31;
+     if (!dir || !(newwhole = malloc(newlen))) {
+         if (glue)
+             *glue = plug;
+         e = dir ? ZE_MEM : ZE_MISS;
+         goto ohforgetit;
+     }
+     strcpy(newwhole, whole);
+     newlen = strlen(newwhole);
+     if (glue)
+         *glue = plug;                           /* repair damage to whole */
+     if (!isshexp(wildtail)) {
+         e = ZE_MISS;                            /* non-wild name not found */
+         goto ohforgetit;
+     }
+ 
+     while (name = readd(dir)) {
+         if (MATCH(wildtail, name)) {
+             strcpy(newwhole + newlen, name);
+             if (subwild) {
+                 name = newwhole + strlen(newwhole);
+                 *(name++) = '/';
+                 strcpy(name, subwild);
+                 e = wild_recurse(newwhole, name);
+             } else
+                 e = procname(newwhole);
+             newwhole[newlen] = 0;
+             if (e == ZE_OK)
+                 amatch = 1;
+             else if (e != ZE_MISS)
+                 break;
+         }
+     }
+ 
+   ohforgetit:
+     if (dir) closed(dir);
+     if (subwild) *--subwild = '/';
+     if (newwhole) free(newwhole);
+     if (e == ZE_MISS && amatch)
+         e = ZE_OK;
+     return e;
+ }
+ 
+ int wild(p) char *p;
+ {
+     char *use;
+ 
+     /* wild_recurse() can't handle colons in wildcard part: */
+     if (use = strchr(p, ':')) {
+         if (strchr(++use, ':'))
+             return ZE_PARMS;
+     } else
+         use = p;
+ 
+     return wild_recurse(p, use);
+ }
+ #endif /* AMIGA */
+                                           
  
  #ifdef VMS
  int wild(p)
***************
*** 826,831 ****
--- 1098,1111 ----
    if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL)
      return ZE_MEM;
    vms_wild(p, d);       /* pattern may be more than just directory name */
+ 
+   /*
+    * Save version specified by user to use in recursive drops into
+    * subdirectories.
+    */
+   strncpy(wild_version_part,d->nam.nam$l_ver,d->nam.nam$b_ver);
+   wild_version_part[d->nam.nam$b_ver] = 0;
+ 
    f = 0;
    while ((e = readd(d)) != NULL)        /* "dosmatch" is already built in */
      if (procname(e) == ZE_OK)
***************
*** 885,891 ****
  
  
  local int fqcmp(a, b)
! voidp *a, *b;           /* pointers to pointers to found entries */
  /* Used by qsort() to compare entries in the found list by name. */
  {
    return strcmp((*(struct flist far **)a)->name,
--- 1165,1171 ----
  
  
  local int fqcmp(a, b)
! const voidp *a, *b;           /* pointers to pointers to found entries */
  /* Used by qsort() to compare entries in the found list by name. */
  {
    return strcmp((*(struct flist far **)a)->name,
***************
*** 894,900 ****
  
  
  local int fqcmpz(a, b)
! voidp *a, *b;           /* pointers to pointers to found entries */
  /* Used by qsort() to compare entries in the found list by zname. */
  {
    return strcmp((*(struct flist far **)a)->zname,
--- 1174,1180 ----
  
  
  local int fqcmpz(a, b)
! const voidp *a, *b;           /* pointers to pointers to found entries */
  /* Used by qsort() to compare entries in the found list by zname. */
  {
    return strcmp((*(struct flist far **)a)->zname,
***************
*** 930,941 ****
  
    p = q = n;
    f = 0;
!   while ((c = *p++) != 0)
      if (c == '/')
      {
        *q++ = (char)c;
        f = 0;                            /* new component */
      }
      else if (c == '.')
        if (f < 9)
        {
--- 1210,1234 ----
  
    p = q = n;
    f = 0;
!   while ((c = (unsigned char)*p++) != 0)
      if (c == '/')
      {
        *q++ = (char)c;
        f = 0;                            /* new component */
      }
+ #ifdef __human68k__
+     else if (iskanji(c))
+     {
+       if (f == 7 || f == 11)
+         f++;
+       else if (*p != '\0' && f < 12 && f != 8)
+       {
+         *q++ = c;
+         *q++ = *p++;
+         f += 2;
+       }
+     }
+ #endif
      else if (c == '.')
        if (f < 9)
        {
***************
*** 981,987 ****
  }
  #endif /* VMS */
  
! local char *ex2in(x, isdir, pdosflag)
  char *x;                /* external file name */
  int isdir;              /* input: x is a directory */
  int *pdosflag;          /* output: force MSDOS file attributes? */
--- 1274,1280 ----
  }
  #endif /* VMS */
  
! char *ex2in(x, isdir, pdosflag)
  char *x;                /* external file name */
  int isdir;              /* input: x is a directory */
  int *pdosflag;          /* output: force MSDOS file attributes? */
***************
*** 999,1019 ****
  
    jfn = _gtjfn(x, (O_RDONLY));
    ablock[1] = (int) (fname - 1);
!   ablock[2] = jfn & 0777777;	/* jfn, no flags */
!   ablock[3] = 0111100000001;	/* DEV+DIR+NAME+TYPE, punctuate */
    if (!jsys(JFNS, ablock)) {
        _rljfn(jfn);
!       return NULL;		/* something bad happened */
    }
    _rljfn(jfn);
    if ((fp = (char *)malloc(strlen(fname) + 1)) == NULL) {
        return NULL;
    }
!   strcpy(fp, fname);		/* copy the file name here */
    x = fp;
  #endif /* TOPS20 */
  
! #ifdef OS2
    dosflag = dosify || IsFileSystemFAT(x);
    if (!dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL)
    {
--- 1292,1312 ----
  
    jfn = _gtjfn(x, (O_RDONLY));
    ablock[1] = (int) (fname - 1);
!   ablock[2] = jfn & 0777777;    /* jfn, no flags */
!   ablock[3] = 0111100000001;    /* DEV+DIR+NAME+TYPE, punctuate */
    if (!jsys(JFNS, ablock)) {
        _rljfn(jfn);
!       return NULL;              /* something bad happened */
    }
    _rljfn(jfn);
    if ((fp = (char *)malloc(strlen(fname) + 1)) == NULL) {
        return NULL;
    }
!   strcpy(fp, fname);            /* copy the file name here */
    x = fp;
  #endif /* TOPS20 */
  
! #if defined(OS2) || defined(WIN32)
    dosflag = dosify || IsFileSystemFAT(x);
    if (!dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL)
    {
***************
*** 1029,1035 ****
  #endif /* ?OS2 */
  
    /* Find starting point in name before doing malloc */
! #ifdef MSDOS                            /* msdos */
    t = *x && *(x + 1) == ':' ? x + 2 : x;
    while (*t == '/' || *t == '\\')
      t++;
--- 1322,1328 ----
  #endif /* ?OS2 */
  
    /* Find starting point in name before doing malloc */
! #if defined(MSDOS) || defined(__human68k__) /* msdos */
    t = *x && *(x + 1) == ':' ? x + 2 : x;
    while (*t == '/' || *t == '\\')
      t++;
***************
*** 1043,1055 ****
        t = x + 1;
      else
        t = n + 1;
! #  else /* !(VMS || TOPS20) */                      /* unix */
    for (t = x; *t == '/'; t++)
      ;
  #  endif /* ?(VMS || TOPS20) */
  #endif /* ?MSDOS */
  
    /* Make changes, if any, to the copied name (leave original intact) */
  #ifdef MSDOS
    for (n = t; *n; n++)
      if (*n == '\\')
--- 1336,1366 ----
        t = x + 1;
      else
        t = n + 1;
! #  else /* !(VMS || TOPS20) */
! #    ifdef AMIGA
!   if ((t = strrchr(x, ':')) != NULL)    /* reject ":" */
!     t++;
!   else
!     t = x;
!   {                                     /* reject "//" */
!     char *tt = t;
!     while (tt = strchr(tt, '/'))
!       while (*++tt == '/')
!         t = tt;
!   }
!   while (*t == '/')             /* reject leading "/" on what's left */
!     t++;
! #    else /* !AMIGA */                      /* unix */
    for (t = x; *t == '/'; t++)
      ;
+ #    endif /* ?AMIGA */
  #  endif /* ?(VMS || TOPS20) */
  #endif /* ?MSDOS */
  
    /* Make changes, if any, to the copied name (leave original intact) */
+ #ifdef __human68k__
+   _toslash(t);
+ #endif /* !__human68k__ */
  #ifdef MSDOS
    for (n = t; *n; n++)
      if (*n == '\\')
***************
*** 1131,1142 ****
  #endif /* VMS */
    }
  #else
!   isdir += 0;      /* avoid warning on unused variable */
  #endif /* ?(VMS || TOPS20) */
  
    if (dosify)
      msname(n);
! #if defined(MSDOS) && !defined(OS2)
    else
      strlwr(n);
  #endif
--- 1442,1453 ----
  #endif /* VMS */
    }
  #else
!   if (isdir == 42) return n;      /* avoid warning on unused variable */
  #endif /* ?(VMS || TOPS20) */
  
    if (dosify)
      msname(n);
! #if defined(MSDOS) && !defined(OS2) && !defined(WIN32)
    else
      strlwr(n);
  #endif
***************
*** 1179,1185 ****
    strupper(x);
  #endif /* ?(VMS || TOPS20) */
  
! #ifdef OS2
    if ( !IsFileNameValid(x) )
      ChangeNameForFAT(x);
  #endif /* !OS2 */
--- 1490,1496 ----
    strupper(x);
  #endif /* ?(VMS || TOPS20) */
  
! #if defined(OS2) || defined(WIN32)
    if ( !IsFileNameValid(x) )
      ChangeNameForFAT(x);
  #endif /* !OS2 */
***************
*** 1187,1195 ****
  }
  
  
! int exclude()
! /* Change from including to excluding names when procname() called.  Return
!    an error code in the ZE_ class. */
  {
    struct flist far *f;          /* steps through found linked list */
    extent j;                     /* index for s */
--- 1498,1506 ----
  }
  
  
! int check_dup()
! /* Sort the found list and remove duplicates.
!    Return an error code in the ZE_ class. */
  {
    struct flist far *f;          /* steps through found linked list */
    extent j;                     /* index for s */
***************
*** 1218,1232 ****
        }
      free((voidp *)s);
    }
-   exflag = 1;
    return ZE_OK;
  }
  
  
  local int newname(n, isdir)
  char *n;                /* name to add (or exclude) */
  int  isdir;             /* true for a directory */
! /* Add (or exclude) a name that is not in the zip file.  Return an error
     code in the ZE_ class. */
  {
    char *m;
--- 1529,1566 ----
        }
      free((voidp *)s);
    }
    return ZE_OK;
  }
  
+ int filter(name)
+   char *name;
+   /* Scan the -i and -x lists for matches to the given name.
+      Return true if the name must be included, false otherwise.
+      Give precedence to -x over -i.
+    */
+ {
+    int n;
+    int include = icount ? 0 : 1;
+ #ifdef MATCH_LASTNAME_ONLY
+    char *p = last(name);
+    if (*p) name = p;
+ #endif
+ 
+    if (pcount == 0) return 1;
+ 
+    for (n = 0; n < pcount; n++) {
+       if (MATCH(patterns[n].zname, name)) {
+          if (patterns[n].select == 'x') return 0;
+          include = 1;
+       }
+    }
+    return include;
+ }
  
  local int newname(n, isdir)
  char *n;                /* name to add (or exclude) */
  int  isdir;             /* true for a directory */
! /* Add (or exclude) the name of an existing disk file.  Return an error
     code in the ZE_ class. */
  {
    char *m;
***************
*** 1238,1300 ****
       list of new names to do (or remove from that list). */
    if ((m = ex2in(n, isdir, &dosflag)) == NULL)
      return ZE_MEM;
    /* Discard directory names with zip -rj */
    if (*m == '\0') {
      if (pathput) error("empty name without -j");
      return ZE_OK;
    }
!   if ((z = zsearch(m)) != NULL)
!     if (exflag)
!     {
!       z->mark = 0;
        free((voidp *)m);
        if (verbose)
          fprintf(mesg, "zip diagnostic: excluding %s\n", z->name);
!     }
!     else
!     {
        free((voidp *)(z->name));
-       free((voidp *)(z->zname));
        if ((z->name = malloc(strlen(n) + 1 + PAD)) == NULL)
          return ZE_MEM;
        strcpy(z->name, n);
        z->zname = m;
!       z->mark = 1;
        z->dosflag = dosflag;
        if (verbose)
          fprintf(mesg, "zip diagnostic: including %s\n", z->name);
      }
!   else
!     if (exflag)
!     {
!       /* search list for name--if there, remove it */
!       for (f = found; f != NULL; f = f->nxt)
!         if (namecmp(n, f->name) == 0)
!         {
!           fexpel(f);
!           break;
!         }
!       free((voidp *)m);
      }
!     else
      {
!       /* allocate space and add to list */
!       if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL ||
!           (f->name = malloc(strlen(n) + 1 + PAD)) == NULL)
!       {
!         if (f != NULL)
!           farfree((voidp far *)f);
!         return ZE_MEM;
!       }
!       strcpy(f->name, n);
!       f->zname = m;
!       f->dosflag = dosflag;
!       *fnxt = f;
!       f->lst = fnxt;
!       f->nxt = NULL;
!       fnxt = &f->nxt;
!       fcount++;
      }
    return ZE_OK;
  }
  
--- 1572,1657 ----
       list of new names to do (or remove from that list). */
    if ((m = ex2in(n, isdir, &dosflag)) == NULL)
      return ZE_MEM;
+ 
    /* Discard directory names with zip -rj */
    if (*m == '\0') {
+ #ifndef AMIGA
+ /* A null string is a legitimate external directory name in AmigaDOS; also,
+  * a command like "zip -r zipfile FOO:" produces an empty internal name.
+  */
      if (pathput) error("empty name without -j");
+ #endif
+     free((voidp *)m);
      return ZE_OK;
    }
!   if ((z = zsearch(m)) != NULL) {
!     z->mark = pcount ? filter(m) : 1;
!     if (z->mark == 0) {
        free((voidp *)m);
        if (verbose)
          fprintf(mesg, "zip diagnostic: excluding %s\n", z->name);
!     } else {
        free((voidp *)(z->name));
        if ((z->name = malloc(strlen(n) + 1 + PAD)) == NULL)
          return ZE_MEM;
        strcpy(z->name, n);
+ #ifdef FORCE_NEWNAME
+       free((voidp *)(z->zname));
        z->zname = m;
! #else
!       /* Better keep the old name. Useful when updating on MSDOS a zip file
!        * made on Unix.
!        */
!       free((voidp *)m);
! #endif
        z->dosflag = dosflag;
        if (verbose)
          fprintf(mesg, "zip diagnostic: including %s\n", z->name);
      }
!     if (n == label) {
!        label = z->name;
      }
!   } else if (pcount == 0 || filter(m)) {
! 
!     /* Check that we are not adding the zip file to itself. This
!      * catches cases like "zip -m foo ../dir/foo.zip".
!      */
!     struct stat statb;
!     if (zipstate == -1)
!        zipstate = strcmp(zipfile, "-") != 0 &&
!                    stat(zipfile, &zipstatb) == 0;
!     if (zipstate == 1 && (statb = zipstatb, stat(n, &statb) == 0
!       && zipstatb.st_mode  == statb.st_mode
!       && zipstatb.st_ino   == statb.st_ino
!       && zipstatb.st_dev   == statb.st_dev
!       && zipstatb.st_uid   == statb.st_uid
!       && zipstatb.st_gid   == statb.st_gid
!       && zipstatb.st_size  == statb.st_size
!       && zipstatb.st_mtime == statb.st_mtime
!       && zipstatb.st_ctime == statb.st_ctime))
!       /* Don't compare a_time since we are reading the file */
!          return ZE_OK;
! 
!     /* allocate space and add to list */
!     if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL ||
!         (f->name = malloc(strlen(n) + 1 + PAD)) == NULL)
      {
!       if (f != NULL)
!         farfree((voidp far *)f);
!       return ZE_MEM;
!     }
!     strcpy(f->name, n);
!     f->zname = m;
!     f->dosflag = dosflag;
!     *fnxt = f;
!     f->lst = fnxt;
!     f->nxt = NULL;
!     fnxt = &f->nxt;
!     fcount++;
!     if (n == label) {
!       label = f->name;
      }
+   }
    return ZE_OK;
  }
  
***************
*** 1309,1315 ****
  #endif
    dstrm *d;             /* directory stream from opend() */
    char *e;              /* pointer to name from readd() */
-   struct flist far *f;  /* steps through found list */
    int m;                /* matched flag */
    char *p;              /* path for recursion */
    struct stat s;        /* result of stat() */
--- 1666,1671 ----
***************
*** 1322,1329 ****
        linkput ? lstat(n, &s) :
  #endif /* S_IFLNK */
        SSTAT(n, &s)
! #if defined(__TURBOC__) || defined(VMS)
!        /* Borland and VMS C bug: stat() succeeds on wild card names! */
        || isshexp(n)
  #endif
       )
--- 1678,1685 ----
        linkput ? lstat(n, &s) :
  #endif /* S_IFLNK */
        SSTAT(n, &s)
! #if defined(__TURBOC__) || defined(VMS) || defined(__WATCOMC__)
!        /* For these 3 compilers, stat() succeeds on wild card names! */
        || isshexp(n)
  #endif
       )
***************
*** 1331,1429 ****
      /* Not a file or directory--search for shell expression in zip file */
      p = ex2in(n, 0, (int *)NULL);       /* shouldn't affect matching chars */
      m = 1;
!     for (z = zfiles; z != NULL; z = z->nxt)
        if (MATCH(p, z->zname))
        {
!         z->mark = !exflag;
          if (verbose)
!           fprintf(mesg, "zip diagnostic: %scluding %s\n",
!                  exflag ? "ex" : "in", z->name);
          m = 0;
        }
-     /* If excluding, also search for expression in found list */
-     if (exflag)
-     {
-       for (f = found; f != NULL;)
-         if (MATCH(p, f->zname))
-         {
-           f = fexpel(f);
-           m = 0;
-         }
-         else
-           f = f->nxt;
      }
      free((voidp *)p);
!     if (m)
!       return ZE_MISS;           /* no match */
    }
-   else
-   {
-     /* Live name--use if file, recurse if directory */
  
  #ifdef MSDOS
!     for (p = n; *p; p++)          /* use / consistently */
!       if (*p == '\\')
!         *p = '/';
  #endif /* MSDOS */
!     if ((s.st_mode & S_IFDIR) == 0)
      {
!       /* add or remove name of file */
!         if ((m = newname(n, 0)) != ZE_OK)
            return m;
      } else {
!         /* recurse into directory */
!         if (recurse && (d = opend(n)) != NULL)
          {
! #if (defined(VMS) || defined(TOPS20))
!           if ((m = newname(n, 1)) != ZE_OK)
            {
!             closed(d);    /* want just to set warning error and continue */
!             return m;
!           }
!           while ((e = readd(d)) != NULL)
!             if ((m = procname(e)) != ZE_OK)     /* recurse on name */
!             {
!               closed(d);
!               return m;
!             }
! #else /* (VMS || TOPS20) */
!           if ((p = malloc(strlen(n)+2)) == NULL)
              return ZE_MEM;
!           if (strcmp(n, ".") == 0)
!             *p = 0;  /* avoid "./" prefix and do not create zip entry */
!           else
            {
!             strcpy(p, n);
!             a = p + strlen(p);
!             if (a[-1] != '/')
!               strcpy(a, "/");
!             if ((m = newname(p, 1)) != ZE_OK)
!               return m;
            }
!           while ((e = readd(d)) != NULL)
!             if (strcmp(e, ".") && strcmp(e, ".."))
!             {
!               if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
!               {
!                 free((voidp *)p);
!                 closed(d);
!                 return ZE_MEM;
!               }
!               strcat(strcpy(a, p), e);
!               if ((m = procname(a)) != ZE_OK)   /* recurse on name */
!               {
!                 free((voidp *)a);  free((voidp *)p);
!                 closed(d);
!                 return m;
!               }
!               free((voidp *)a);
!             }
!           free((voidp *)p);
! #endif /* ? (VMS || TOPS20) */
!           closed(d);
          }
        }
      }
    return ZE_OK;
  }
  
--- 1687,1785 ----
      /* Not a file or directory--search for shell expression in zip file */
      p = ex2in(n, 0, (int *)NULL);       /* shouldn't affect matching chars */
      m = 1;
!     for (z = zfiles; z != NULL; z = z->nxt) {
        if (MATCH(p, z->zname))
        {
!         z->mark = pcount ? filter(z->zname) : 1;
          if (verbose)
!             fprintf(mesg, "zip diagnostic: %scluding %s\n",
!                z->mark ? "in" : "ex", z->name);
          m = 0;
        }
      }
      free((voidp *)p);
!     return m ? ZE_MISS : ZE_OK;
    }
  
+   /* Live name--use if file, recurse if directory */
+ #ifdef __human68k__
+   _toslash(n);
+ #endif
  #ifdef MSDOS
!   for (p = n; *p; p++)          /* use / consistently */
!     if (*p == '\\')
!       *p = '/';
  #endif /* MSDOS */
!   if ((s.st_mode & S_IFDIR) == 0)
!   {
!     /* add or remove name of file */
!     if ((m = newname(n, 0)) != ZE_OK)
!       return m;
!   } else {
! #if defined(VMS) || defined(TOPS20)
!     if (dirnames && (m = newname(n, 1)) != ZE_OK) {
!       return m;
!     }
!     /* recurse into directory */
!     if (recurse && (d = opend(n)) != NULL)
      {
!       while ((e = readd(d)) != NULL) {
!         if ((m = procname(e)) != ZE_OK)     /* recurse on name */
!         {
!           closed(d);
            return m;
+         }
+       }
+       closed(d);
+     }
+ #else /* (VMS || TOPS20) */
+     /* Add trailing / to the directory name */
+     if ((p = malloc(strlen(n)+2)) == NULL)
+       return ZE_MEM;
+     if (strcmp(n, ".") == 0) {
+       *p = 0;  /* avoid "./" prefix and do not create zip entry */
      } else {
!       strcpy(p, n);
!       a = p + strlen(p);
! #ifdef AMIGA
!       if (*p && a[-1] != '/' && a[-1] != ':')
! #else
!       if (a[-1] != '/')
! #endif
!         strcpy(a, "/");
!       if (dirnames && (m = newname(p, 1)) != ZE_OK) {
!         free((voidp *)p);
!         return m;
!       }
!     }
!     /* recurse into directory */
!     if (recurse && (d = opend(n)) != NULL)
!     {
!       while ((e = readd(d)) != NULL) {
!         if (strcmp(e, ".") && strcmp(e, ".."))
          {
!           if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
            {
!             free((voidp *)p);
!             closed(d);
              return ZE_MEM;
!           }
!           strcat(strcpy(a, p), e);
!           if ((m = procname(a)) != ZE_OK)   /* recurse on name */
            {
!             if (m == ZE_MISS)
!               warn("name not matched: ", a);
!             else
!               err(m, a);
            }
!           free((voidp *)a);
          }
        }
+       free((voidp *)p);
+       closed(d);
      }
+ #endif /* ? (VMS || TOPS20) */
+   } /* (s.st_mode & S_IFDIR) == 0) */
    return ZE_OK;
  }
  
***************
*** 1540,1546 ****
--- 1896,1906 ----
    SetFileTime(f, d);
  #else /* !OS2 */
    struct tm t;          /* argument for mktime() or invlocal() */
+ #if defined(WIN32) || defined(sgi)
+   struct utimbuf u;     /* argument for utime() */
+ #else
    time_t u[2];          /* argument for utime() */
+ #endif
  #ifndef __GO32__
    extern time_t mktime OF((struct tm *));
  #endif
***************
*** 1552,1569 ****
    t.tm_mday = (int)(d >> 16) & 0x1f;
    t.tm_mon = ((int)(d >> 21) & 0xf) - 1;
    t.tm_year = ((int)(d >> 25) & 0x7f) + 80;
! #if defined(MSDOS) || defined(OS2) || defined(CRAY)
    /* mktime() is more reliable than invlocal() because the time range is
     * wider on MSDOS than on Unix; required for Cray because invlocal assumes
     * 32-bit ints
     */
    u[0] = u[1] = mktime(&t);
! #else
    u[0] = u[1] = invlocal(&t);
  #endif
  
    /* Set updated and accessed times of f */
    utime(f, u);
  #endif /* ?OS2 */
  #endif /* ?VMS */
  #endif /* ?__TURBOC__ */
--- 1912,1937 ----
    t.tm_mday = (int)(d >> 16) & 0x1f;
    t.tm_mon = ((int)(d >> 21) & 0xf) - 1;
    t.tm_year = ((int)(d >> 25) & 0x7f) + 80;
! #if defined(WIN32) || defined (sgi)
!   u.actime = u.modtime = mktime(&t);
! #else
! # if defined(MSDOS) || defined(OS2) || defined(CRAY)
    /* mktime() is more reliable than invlocal() because the time range is
     * wider on MSDOS than on Unix; required for Cray because invlocal assumes
     * 32-bit ints
     */
    u[0] = u[1] = mktime(&t);
! # else
    u[0] = u[1] = invlocal(&t);
+ # endif
  #endif
  
    /* Set updated and accessed times of f */
+ #if defined(WIN32) || defined(sgi)
+   utime(f, &u);
+ #else
    utime(f, u);
+ #endif
  #endif /* ?OS2 */
  #endif /* ?VMS */
  #endif /* ?__TURBOC__ */
***************
*** 1654,1667 ****
--- 2022,2049 ----
    char name[FNMAX];
    int len = strlen(f);
  
+   if (f == label) {
+     if (a != NULL)
+       *a = label_mode;
+     if (n != NULL)
+       *n = -2L; /* convention for a label name */
+     return label_time;  /* does not work for unknown reason */
+   }
    strcpy(name, f);
    if (name[len - 1] == '/')
      name[len - 1] = 0; 
    /* not all systems allow stat'ing a file with / appended */
  
    if (strcmp(f, "-") == 0) {
+ #if defined(AMIGA) && !defined(__SASC_60)
+   /* forge stat values for stdin since Amiga has no fstat() */
+     s.st_mode = (S_IREAD|S_IWRITE|S_IFREG); 
+     s.st_size = -1;
+     s.st_mtime = time(&s.st_mtime);
+ #else /* !AMIGA */
      if (fstat(fileno(stdin), &s) != 0)
        error("fstat(stdin)");
+ #endif /* ?AMIGA */
    } else if ((
  #ifdef S_IFLNK
               linkput ? lstat(name, &s) :
***************
*** 1672,1685 ****
                */
      return 0;
  
!   if (a != NULL)
! #if defined(MSDOS) || defined(OS2)
      *a = ((ulg)s.st_mode << 16) | (ulg)GetFileMode(name);
  #else
      *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
  #endif
    if (n != NULL)
!     *n = (s.st_mode & S_IFREG) == 0 ? -1L : s.st_size;
  
  #ifdef OS2
    return GetFileTime(name);
--- 2054,2071 ----
                */
      return 0;
  
!   if (a != NULL) {
! #if defined(MSDOS) || defined(OS2) || defined(__human68k__)
      *a = ((ulg)s.st_mode << 16) | (ulg)GetFileMode(name);
  #else
      *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
+     if ((s.st_mode & S_IFDIR) != 0) {
+       *a |= MSDOS_DIR_ATTR;
+     }
  #endif
+   }
    if (n != NULL)
!     *n = (s.st_mode & S_IFMT) != S_IFREG ? -1L : s.st_size;
  
  #ifdef OS2
    return GetFileTime(name);
***************
*** 1690,1706 ****
  #    ifdef ATARI_ST
         return s.st_mtime; /* Turbo C doesn't use UNIX times */
  #    else
!        return unix2dostime(&s.st_mtime);
  #    endif
  #  endif /* ?VMS */
  #endif /* ?OS2 */
  }
  
  #ifdef TOPS20
! #  include <monsym.h>	/* Get amazing monsym() macro */
! #  define	_FBBYV	monsym(".FBBYV")
! #  define	  FBBSZ_S	-24	/* Obsolete, replace by FLDGET! */
! #  define	  FBBSZ_M	077	/* ditto */
  
  extern int _gtjfn(), _rljfn(), _gtfdb(), stat();
  
--- 2076,2096 ----
  #    ifdef ATARI_ST
         return s.st_mtime; /* Turbo C doesn't use UNIX times */
  #    else
! #      ifdef WIN32
!          return GetTheFileTime(name);
! #      else
!          return unix2dostime((statime*)&s.st_mtime);
! #      endif /* WIN32 */
  #    endif
  #  endif /* ?VMS */
  #endif /* ?OS2 */
  }
  
  #ifdef TOPS20
! #  include <monsym.h>   /* Get amazing monsym() macro */
! #  define       _FBBYV  monsym(".FBBYV")
! #  define         FBBSZ_S       -24     /* Obsolete, replace by FLDGET! */
! #  define         FBBSZ_M       077     /* ditto */
  
  extern int _gtjfn(), _rljfn(), _gtfdb(), stat();
  
***************
*** 1713,1719 ****
    translate_eol = 0;
    jfn = _gtjfn(z->name, O_RDONLY);
    z->att = (((_gtfdb (jfn, _FBBYV) << FBBSZ_S) & FBBSZ_M) != 8) ?
! 	   ASCII :BINARY;
    _rljfn(jfn);
    return 0;
  }
--- 2103,2109 ----
    translate_eol = 0;
    jfn = _gtjfn(z->name, O_RDONLY);
    z->att = (((_gtfdb (jfn, _FBBYV) << FBBSZ_S) & FBBSZ_M) != 8) ?
!            ASCII :BINARY;
    _rljfn(jfn);
    return 0;
  }
***************
*** 1724,1730 ****
    struct zlist *z;
    /* create extra field and change z->att if desired */
  {
!   return 0;
  }
  # endif /* !OS2 && !VMS */
  #endif /* TOPS20 */
--- 2114,2120 ----
    struct zlist *z;
    /* create extra field and change z->att if desired */
  {
!   return (int)(z-z);
  }
  # endif /* !OS2 && !VMS */
  #endif /* TOPS20 */
***************
*** 1747,1811 ****
  char *d;                /* directory to delete */
  /* Delete the directory *d if it is empty, do nothing otherwise.
     Return the result of rmdir(), delete(), or system().
   */
  {
  #if (defined(MACOS) || defined(TOPS20))
!   warn("deletedir not implemented yet", "");
!   return 127;
! #else
! #ifdef RMDIR
!   /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */
!   int r, len;
!   char *s;              /* malloc'd string for system command */
! 
!   len = strlen(d);
!   if ((s = malloc(len + 34)) == NULL)
      return 127;
  
! #ifdef VMS
!   {
!     char *c;            /* pointer into VMS path */
!     /* convert "DEV:[DIR.SUB1.SUB2]" form to "DEV:[DIR.SUB1]SUB2.DIR;1" */
!     strcat(strcpy(s, "set prot=(o:rwed) "), d);   /* d starts at s+18 */
!     if (*(c = s+17+len) != ']')
!     {
!       free(s);
!       return 127;
!     }
!     strcpy(c, ".DIR;1");        /* directories are always version 1 */
!     while (--c > s+18  &&  *c != '.'  &&  *c != '[') ;
!     if (c == s+18)
!     {
!       free(s);
!       return 127;
!     }
!     if (*c == '.')
!       *c = ']';
!     else if (*--c == ']')  /* presumably of form "DEV:[DIR.SUB1.][SUB2]" */
!     {                      /* (possible to have "DEV:[DIR.SUB1.][][SUB2]"?) */
!       char *b = c + 2;
!       c[-1] = ']';
!       while (*c++ = *b++) ;
!     }
!     else        /* must have reached device name:  can't delete top level */
!     {
!       free(s);
        return 127;
!     }
!   }
!   /* unprotect directory and delete it as a file.  May fail if exists 
!      normal file "foo.dir" on top of directory "foo.dir" */
!   system(s);
!   r = delete(s+18);
! #else /* !VMS */
!   sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d);
!   r = system(s);
! #endif /* ?VMS */
!   free(s);
!   return r;
! #else /* !RMDIR */
!   return rmdir(d);
! #endif /* ?RMDIR */
  #endif /* ? MACOS || TOPS20 */
  }
  
--- 2137,2170 ----
  char *d;                /* directory to delete */
  /* Delete the directory *d if it is empty, do nothing otherwise.
     Return the result of rmdir(), delete(), or system().
+    For VMS, d must be in format [x.y]z.dir;1  (not [x.y.z]).
   */
  {
  #if (defined(MACOS) || defined(TOPS20))
!     warn("deletedir not implemented yet", "");
      return 127;
+ #else
+ # ifdef RMDIR
+     /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */
+     int r, len;
+     char *s;              /* malloc'd string for system command */
  
!     len = strlen(d);
!     if ((s = malloc(len + 34)) == NULL)
        return 127;
! 
! #  ifdef VMS
!     system(strcat(strcpy(s, "set prot=(o:rwed) "), d));
!     r = delete(d);
! #  else /* !VMS */
!     sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d);
!     r = system(s);
! #  endif /* ?VMS */
!     free(s);
!     return r;
! # else /* !RMDIR */
!     return rmdir(d);
! # endif /* ?RMDIR */
  #endif /* ? MACOS || TOPS20 */
  }
  
***************
*** 1823,1831 ****
  int replace(d, s)
  char *d, *s;            /* destination and source file names */
  /* Replace file *d by file *s, removing the old *s.  Return an error code
!    in the ZE_ class. */
  {
    struct stat t;        /* results of stat() */
  
  #ifdef VMS
    /* stat() is broken on VMS remote files (accessed through Decnet).
--- 2182,2194 ----
  int replace(d, s)
  char *d, *s;            /* destination and source file names */
  /* Replace file *d by file *s, removing the old *s.  Return an error code
!    in the ZE_ class. This function need not preserve the file attributes,
!    this will be done by setfileattr() later.
!  */
  {
    struct stat t;        /* results of stat() */
+   int copy = 0;
+   int d_exists;
  
  #ifdef VMS
    /* stat() is broken on VMS remote files (accessed through Decnet).
***************
*** 1833,1878 ****
     * to update them or compress remote files */
    unlink(d);
  #else
!   if (SSTAT(d, &t) == 0 && unlink(d))
!     return ZE_CREAT;                    /* Can't erase zip file--give up */
! #endif
!   if (link(s, d))                       /* Just move s on top of d */
! #if !defined(VMS) && !defined(ATARI_ST)
!     /* For VMS & ATARI assume failure is EXDEV */
!     if (errno != EXDEV
  #  ifdef ENOTSAM
!        && errno != ENOTSAM /* Used at least on Turbo C */
  #  endif
!         ) return ZE_CREAT;
!     else
  #endif
-     {
-       FILE *f, *g;      /* source and destination files */
-       int r;            /* temporary variable */
- 
-       if ((f = fopen(s, FOPR)) == NULL) {
-         fprintf(stderr," replace: can't open %s\n", s);
-         return ZE_TEMP;
        }
!       if ((g = fopen(d, FOPW)) == NULL)
!       {
!         fclose(f);
!         return ZE_CREAT;
        }
!       r = fcopy(f, g, (ulg)-1L);
        fclose(f);
!       if (fclose(g) || r != ZE_OK)
!       {
!         unlink(d);
!         return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE;
!       }
! #ifdef VMS /* only delete if rename failed:  previous version may exist */
!       unlink(s);
      }
! #else /* !VMS */
      }
!   unlink(s);
! #endif /* !VMS */
    return ZE_OK;
  }
  
--- 2196,2267 ----
     * to update them or compress remote files */
    unlink(d);
  #else
!   d_exists = (LSTAT(d, &t) == 0);
!   if (d_exists)
!   {
!     /*
!      * respect existing soft and hard links!
!      */
!     if (t.st_nlink > 1
! # ifdef S_IFLNK
!         || (t.st_mode & S_IFMT) == S_IFLNK
! # endif
!         )
!        copy = 1;
!     else if (unlink(d))
!        return ZE_CREAT;                 /* Can't erase zip file--give up */
!   }
! #endif /* VMS */
!   if (!copy) {
!       if (link(s, d)) {               /* Just move s on top of d */
!           copy = 1;                     /* failed ? */
! #if !defined(VMS) && !defined(ATARI_ST) && !defined(AZTEC_C)
!     /* For VMS & ATARI & AMIGA Aztec assume failure is EXDEV */
!           if (errno != EXDEV
  #  ifdef ENOTSAM
!            && errno != ENOTSAM /* Used at least on Turbo C */
  #  endif
!               ) return ZE_CREAT;
  #endif
        }
! #ifndef link    /* UNIX link() */
!       /*
!        * Assuming a UNIX link(2), we still have to remove s.
!        * If link has been #defined to rename(), nothing to do.
!        */
!       else {
! # ifdef KEEP_OWNER
!           if (d_exists)
!               /* this will fail if the user isn't priviledged */
!               chown(d, t.st_uid, t.st_gid);
! # endif
!           unlink(s);
        }
! #endif          /* ?UNIX link() */
!   }
! 
!   if (copy) {
!     FILE *f, *g;      /* source and destination files */
!     int r;            /* temporary variable */
! 
!     if ((f = fopen(s, FOPR)) == NULL) {
!       fprintf(stderr," replace: can't open %s\n", s);
!       return ZE_TEMP;
!     }
!     if ((g = fopen(d, FOPW)) == NULL)
!     {
        fclose(f);
!       return ZE_CREAT;
      }
!     r = fcopy(f, g, (ulg)-1L);
!     fclose(f);
!     if (fclose(g) || r != ZE_OK)
!     {
!       unlink(d);
!       return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE;
      }
!     unlink(s);
!   }
    return ZE_OK;
  }
  
***************
*** 1892,1932 ****
  int a;                  /* attributes returned by getfileattr() */
  /* Give the file f the attributes a, return non-zero on failure */
  {
! #if defined (VMS) || defined(MACOS) || defined(TOPS20)
    return 0;
! #else /* !VMS */
    return chmod(f, a);
! #endif /* ?VMS */
  }
  
  
- #ifdef NO_MKTEMP
- 
- char *tempname(zip)
-   char *zip;              /* path name of zip file to generate temp name for */
- 
- /* Return a temporary file name in its own malloc'ed space.
-  * This function might accidentally destroy an existing file
-  * with extension .$z$ . Use mktemp below if you have it on your system.
-  */
- {
-   char *p;              /* temporary pointer */
-   char *t;              /* malloc'ed space for name */
- 
-   if ((t = malloc(strlen(zip)+5)) == NULL)
-     return NULL;
-   strcpy(t, zip);
-   if ((p = strrchr(t, '.')) != NULL &&
-       (!strncmp(p, ".zip", 4) || !strncmp(p, ".ZIP", 4)))
-       /* strncmp to avoid problems with VMS ';' */
-     strcpy(p, ".$z$");
-   else
-     strcat(t, ".$z$");
- 
-   return t;
- }
- #else /* !NO_MKTEMP */
- 
  char *tempname(zip)
    char *zip;              /* path name of zip file to generate temp name for */
  
--- 2281,2294 ----
  int a;                  /* attributes returned by getfileattr() */
  /* Give the file f the attributes a, return non-zero on failure */
  {
! #if defined(MACOS) || defined(TOPS20)
    return 0;
! #else
    return chmod(f, a);
! #endif
  }
  
  
  char *tempname(zip)
    char *zip;              /* path name of zip file to generate temp name for */
  
***************
*** 1936,1962 ****
  
    if (tempath != NULL)
    {
!     if ((t = malloc(strlen(tempath)+10)) == NULL)
        return NULL;
      strcpy(t, tempath);
  #if (!defined(VMS) && !defined(TOPS20))
      if (t[strlen(t)-1] != '/')
        strcat(t, "/");
  #endif
    }
    else
    {
!     if ((t = malloc(9)) == NULL)
        return NULL;
      *t = 0;
    }
    strcat(t, "_ZXXXXXX");
    return mktemp(t);
  }
  
- #endif /* NO_MKTEMP */
  
- 
  int fcopy(f, g, n)
  FILE *f, *g;            /* source and destination files */
  ulg n;                  /* number of bytes to copy or -1 for all */
--- 2298,2339 ----
  
    if (tempath != NULL)
    {
!     if ((t = malloc(strlen(tempath)+12)) == NULL)
        return NULL;
      strcpy(t, tempath);
  #if (!defined(VMS) && !defined(TOPS20))
+ #  ifdef AMIGA
+     {
+           char c = t[strlen(t)-1];
+           if (c != '/' && c != ':')
+             strcat(t, "/");
+     }
+ #  else /* !AMIGA */
+           
      if (t[strlen(t)-1] != '/')
        strcat(t, "/");
+ #  endif  /* ?AMIGA */            
  #endif
    }
    else
    {
!     if ((t = malloc(12)) == NULL)
        return NULL;
      *t = 0;
    }
+ #ifdef NO_MKTEMP
+   {
+     char *p = t + strlen(t);
+     sprintf(p, "%08lx", (ulg)time(NULL));
+     return t;
+   }
+ #else
    strcat(t, "_ZXXXXXX");
    return mktemp(t);
+ #endif
  }
  
  
  int fcopy(f, g, n)
  FILE *f, *g;            /* source and destination files */
  ulg n;                  /* number of bytes to copy or -1 for all */
***************
*** 2060,2088 ****
  #ifdef TOPS20
  
  int
! strupper(s)	/* Returns s in uppercase */
! char *s;	/* String to be uppercased */
  {
      char    *p;
  
      p = s;
      for (; *p; p++)
! 	*p = toupper (*p);
  }
  
  int
! strlower(s)	/* Returns s in lowercase. */
! char *s;	/* String to be lowercased */
  {
      char    *p;
  
      p = s;
      for (; *p; p++)
! 	*p = tolower (*p);
  }
  #endif /* TOPS20 */
  
! #ifdef __TURBOC__
  
  /************************/
  /*  Function fcalloc()  */
--- 2437,2465 ----
  #ifdef TOPS20
  
  int
! strupper(s)     /* Returns s in uppercase */
! char *s;        /* String to be uppercased */
  {
      char    *p;
  
      p = s;
      for (; *p; p++)
!         *p = toupper (*p);
  }
  
  int
! strlower(s)     /* Returns s in lowercase. */
! char *s;        /* String to be lowercased */
  {
      char    *p;
  
      p = s;
      for (; *p; p++)
!         *p = tolower (*p);
  }
  #endif /* TOPS20 */
  
! #if defined(__TURBOC__) && !defined(OS2)
  
  /************************/
  /*  Function fcalloc()  */
***************
*** 2091,2108 ****
  /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
   * and farmalloc(64K) returns a pointer with an offset of 8, so we
   * must fix the pointer. Warning: the pointer must be put back to its
!  * original form in order to free it.
   * For MSC, use halloc instead of this function (see tailor.h).
   */
! void far * fcalloc(items, size)
      unsigned items; /* number of items */
      unsigned size;  /* item size */
  {
!     void far * buf = farmalloc((ulg)items*size + 16L);
      /* Normalize the pointer to seg:0 */
!     *((int*)&buf+1) += ((unsigned)((uch*)buf-0) + 15) >> 4;
!     *(int*)&buf = 0;
!     return buf; /* buf stays NULL if alloc failed */
! }
  
! #endif /* __TURBOC__ */
--- 2468,2502 ----
  /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
   * and farmalloc(64K) returns a pointer with an offset of 8, so we
   * must fix the pointer. Warning: the pointer must be put back to its
!  * original form in order to free it, use fcfree().
   * For MSC, use halloc instead of this function (see tailor.h).
   */
! static ush ptr_offset = 0;
! 
! void * fcalloc(items, size)
      unsigned items; /* number of items */
      unsigned size;  /* item size */
  {
!     void * buf = farmalloc((ulg)items*size + 16L);
!     if (buf == NULL) return NULL;
      /* Normalize the pointer to seg:0 */
!     if (ptr_offset == 0) {
!         ptr_offset = (ush)((uch*)buf-0);
!     } else if (ptr_offset != (ush)((uch*)buf-0)) {
!         err(ZE_LOGIC, "inconsistent ptr_offset");
!     }
!     *((ush*)&buf+1) += (ptr_offset + 15) >> 4;
!     *(ush*)&buf = 0;
!     return buf;
! }
! 
! void fcfree(ptr)
!     void *ptr; /* region allocated with fcalloc() */
! {
!     /* Put the pointer back to its original form: */
!     *((ush*)&ptr+1) -= (ptr_offset + 15) >> 4;
!     *(ush*)&ptr = ptr_offset;
!     farfree(ptr);
!  }
  
! #endif /* __TURBOC__ && !OS2 */
diff -c ../zip19i/globals.c ./globals.c
*** ../zip19i/globals.c	Tue Nov  3 21:07:54 1992
--- ./globals.c	Fri Sep 10 00:03:42 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 14,19 ****
--- 13,20 ----
   */
  
  #define GLOBALS         /* include definition of errors[] in zip.h */
+ #define UTIL            /* do not declare the read_buf variable */
+ 
  #include "zip.h"
  
  
***************
*** 22,40 ****
  
  /* Argument processing globals */
  int recurse = 0;        /* 1=recurse into directories encountered */
  int pathput = 1;        /* 1=store path with name */
  int method = BEST;      /* one of BEST, DEFLATE (only), or STORE (only) */
  int dosify = 0;         /* 1=make new entries look like MSDOS */
  int verbose = 0;        /* 1=report oddities in zip file structure */
! int level = 5;          /* 0=fastest compression, 9=best compression */
  int translate_eol = 0;  /* Translate end-of-line LF -> CR LF */
  #ifdef VMS
     int vmsver = 0;      /* 1=append VMS version number to file names */
     int vms_native = 0;  /* 1=store in VMS format */
  #endif /* VMS */
! #ifdef OS2
     int use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
! #endif /* OS2 */
  int linkput = 0;        /* 1=store symbolic links as such */
  int noisy = 1;          /* 0=quiet operation */
  char *special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
--- 23,46 ----
  
  /* Argument processing globals */
  int recurse = 0;        /* 1=recurse into directories encountered */
+ int dispose = 0;        /* 1=remove files after put in zip file */
  int pathput = 1;        /* 1=store path with name */
  int method = BEST;      /* one of BEST, DEFLATE (only), or STORE (only) */
  int dosify = 0;         /* 1=make new entries look like MSDOS */
  int verbose = 0;        /* 1=report oddities in zip file structure */
! int fix = 0;            /* 1=fix the zip file */
! int level = 6;          /* 0=fastest compression, 9=best compression */
  int translate_eol = 0;  /* Translate end-of-line LF -> CR LF */
  #ifdef VMS
     int vmsver = 0;      /* 1=append VMS version number to file names */
     int vms_native = 0;  /* 1=store in VMS format */
  #endif /* VMS */
! #if defined(OS2) || defined(WIN32)
     int use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
! #endif
! int hidden_files = 0;   /* process hidden and system files */
! int volume_label = 0;   /* add volume label */
! int dirnames = 1;       /* include directory entries by default */
  int linkput = 0;        /* 1=store symbolic links as such */
  int noisy = 1;          /* 0=quiet operation */
  char *special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
***************
*** 58,60 ****
--- 64,71 ----
  struct flist far * far *fnxt = &found;
                          /* Where to put next name in found list */
  extent fcount;          /* Count of files in list */
+ 
+ /* Patterns to be matched */
+ struct plist *patterns = NULL; /* List of patterns to be matched */
+ int pcount = 0;                /* number of patterns */
+ int icount = 0;                /* number of include only patterns */
diff -c ../zip19i/history ./history
*** ../zip19i/history	Tue Nov  3 21:07:55 1992
--- ./history	Fri Sep 10 04:56:54 1993
***************
*** 1058,1080 ****
  7.  Use large model for BC++, _TEXT exceeds 64K (Onno)
  8.  Started cleanup by partial removal of "far" keyword.
  
! 
! Things to check or to be done (see also BUGS section in zip.1):
! 
! - Michael Regoli <mr@ogre.cica.indiana.edu> reports that zip 1.9g does
!   not compile on a Sun 4 with gcc 2.2.2 but I have the same configuration
!   and can't reproduce it.
! 
! - On VMS, "zip -rm" deletes too many directories and in the wrong
!   order. Greg is looking at this.
! 
! - On VMS, "zip -r foo [x.y]" does not work. "zip -r foo [x]y.dir" works.
! 
! - There is not (yet) a way to undo the effect of ZIPOPT
! 
! - it is possible in weird cases to add a zipfile to itself
! 
! - The -b option is ignored on OS/2.
! 
! - On OS/2, zip refuses to match some names, such as those beginning with an
!   exclamation mark. Same for names starting with #, possibly more.
--- 1058,1273 ----
  7.  Use large model for BC++, _TEXT exceeds 64K (Onno)
  8.  Started cleanup by partial removal of "far" keyword.
  
! ------------------------ Nov 21  1992   version 1.9j ------------------------
! 1.  Simplified trash() and deletedir() significantly, fixing the VMS zip -r
!     bug as a side effect (Greg).
! 2.  tailor.h: djgcc warns about using a char as array index (Onno)
! 3.  makefile.bor and match.asm: changed LARGE to __LARGE__ because LARGE
!     is a reserved word in tasm. (Onno)
! 4.  Added a workaround for a bug in latest version of OS/2 (Kai Uwe)
! 5.  Added -Z to CLFAGS in makefile.bor (Zachary Heilig)
! 6.  Quote "-T" in help screen for VMS (Greg)
! 7.  Added -c to CFLAGS in makefile.gcc (Bob Hardy)
! 9.  Added rs6000 makefile entry as in unzip (Michael Bernardi)
! 10. Renamed makefile as Makefile for unification with unzip
! 11. Added makefile entry for Pixel (Aubrey Jaffer)
! 12. Use nice_match in match.s to guarantee same output as C code.
! 13. Fixed "version made by" for OS/2 in zipup.c (Kai-Uwe)
! 14. Aligned messages with : as in unzip (Kai-Uwe)
! 15. New Amiga support (John Bush)
! 16. Forget the "#define const" which was source of trouble.
! 17. Do not use a directory time for -o (Onno)
! 
! 
! ------------------------ Nov 24  1992   version 1.9k ------------------------
! 1.  Define const for non ANSI compilers (Michael Lawler)
! 2.  Removed the .dif files from the amiga subdirectory (John Bush)
! 3.  Added automatic configuration with "make generic"
! 
! ------------------------ Jan 26  1993   version 1.9l ------------------------
! 1.  Add trap handler in configure
! 2.  Use readdir() for 386BSD (Onno)
! 3.  New work around for OS/2 bug in os2zip.c (Kai Uwe).
! 4.  Commented out declarations of opendir and readdir (was causing
!     problems with 'const'). (Mark).
! 5.  Process -@ only after the zip file is read (George Sipe)
! 6.  Added check for NeXT in configure (Mark)
! 7.  Define SYSV only if sys/termio.h exists
! 8.  Don't use gcc -c -c in msdos/makefile.gcc (Onno)
! 9.  Don't include sys/types.h for Amiga (John)
! 10. Added support for pgp in trees.c
! 11. Use nice_match in match.asm
! 12. Do not attempt matches beyond the window end (caused crash on 286 in
!     protected mode when attempting a word load at address DS:FFFF).
! 13. Fixed location of zcrypt19.zip in Where.
! 14. Do not check file size on MSDOS because of bug in DIET
! 15. Set 'version needed to extract' to 1.0 for stored files (Peter Gutmann)
! 16. Do not ignore the time of the first entry for -o (Mark).
! 17. Allow zip -r0 with output to a pipe (Mark)
! 18. Never include a zip file in itself or remove it at the end with -m.
! 19. Fix zip -r on VMS to include all versions (;*).  (Igor)
! 20. Don't forget closedir() on error (Kai Uwe)
! 21. Ignore ftell() error on pipes (Eric Backus)
! 22. Don't free() the literal string "-" (Eric Backus)
! 23. Don't call err() with a null pointer (Eric Backus)
! 24. Put back percent() arguments as ulg (Mark).
! 25. New os2/zip.def and os2zip.c (Kai Uwe)
! 26. Fixes in tailor.h for OS2 (Kai Uwe)
! 27. Fix for zero length indexed files (Igor)
! 
! ------------------------ Aug 20  1993   version 1.9m ------------------------
! 1.  1992->1993 in all copyright notices.
! 2.  Added "make bull" (doc@magna.com (Matthew J. D'Errico)
! 3.  Fixed vms_stat() to work across Decnet (Igor)
! 4.  Use ; instead of , in trees.c (confuses the SAS Amiga compiler).
! 5.  Added instructions for info-zip lists.
! 6.  Add the -F and -FF (zipfix) options.
! 7.  Documented the -v option.
! 8.  Use progress indicator also for zip -0 (Greg).
! 9.  Document /etc/magic line in install.doc.
! 10. Changed os2 stack size from 0x40000 to 0x80000 to avoid OS/2 bugs.
! 11. Don't use name foo.zip.$z$ on OS/2 FAT system.
! 12. Do not ignore the -l option with zip -0.
! 13. Updated Where file.
! 14. In zip.1, mention pkzip 2.04 instead of 1.93a.
! 15. Fix test for regular files in filetime().
! 16. In memcompress(), do not call deflate with compression level 0.
! 17. Display 0 instead of gargabe for negative compression ratios.
! 18. New amiga files. (diffs not yet applied, will be changed shortly)
! 19. Speed up zip -1 to -3 as in gzip, default changed to -6.
! 20. Fix problem of zip -r with symbolic link to non existent file.
! 21. Do not use _dos_getfileaddr() for Borland C++ (James W. Birdsall)
! 22. Fix compilation error in vms.c with GNU cc (Mike Freeman)
! 23. make the file that zipnote generates somewhat self-documenting, and allow
!     the zipnote -w input to be a little more free form. (Mark)
! 24. Added support for Borland C++ for OS/2 (32-bit) (Kai-Uwe).
! 25. Added makefile for Turbo C 2.0 (Andrew Cadach)
! 26. Added untested makefile entry for SCO Xenix on 286.
! 27. Add -S option to include hidden/system files on MSDOS/OS/2 (Kai Uwe).
! 28. Free the extra field as soon as it is written on disk.
! 29. Use -DSYSV for "make sun" so that it also works on Solaris. Add sun_bsd.
! 30. Added "make next-fat".
! 
! 
! ------------------------ Aug 21  1993   version 1.9n ------------------------
! 1.  Don't undef const in crypt.c (does not work on MSDOS).
! 2.  Fix some warnings with MSDOS compilers.
! 3.  Switch to large model for all 16 bit MSDOS compilers.
! 4.  New match.s with 68K support, and to avoid problems with DJGPP 1.10.
! 5.  When -b is used, do not create any file other than the final zipfile
!     in the final directory. (Don't leave junk on a WORM.)
! 
! ------------------------ Aug 29  1993   version 2.0a ------------------------
! 1.  Free local extra field only if different from central extra field (Kai Uwe)
! 2.  Use size_t instead of unsigned in os2/os2zip.c
! 3.  Fix for emx in os2/makefile.os2.
! 4.  Fix change 5 of zip 1.9n (was allowing destruction of a readonly file).
! 5.  next-fat -> nextfat to make Greg happy.
! 6.  Fix macros in vms/descrip.mms (Igor).
! 7.  Free the local extra field only after the second putlocal() (Igor).
! 8.  Add vms.obj in make_vaxc.com for zipsplit, zipnote, zipcloak (Mike Freeman)
! 9.  Don't use the constant (unsigned)2*32768 with 16-bit int (Piet Plomp).
! 10. Use syntax acceptable by ml in msdos/makefile.msc (Piet Plomp).
! 11. Use const if MODERN instead of __STDC__ (Greg).
! 12. Remove garbage at both ends of zip file with -F or -FF (Bill Davidsen)
! 13. Added support for Human68K (NIIMI Satoshi)
! 14. Preserve existing soft and hard links for the zip file (Martin Schulz)
! 15. Don't crash when no zip-file, with flag -o (Martin Schulz)
! 16. Ignore -y when -k is set (Martin Schulz)
! 17. Add the -D option (create entries for directories)
! 18. Free window and hash table (when -DDYN_ALLOC) before calling unzip for -T.
! 19. Remove -m4 from msdos/makefile.tc (not supported by TurboC 2.0)
! 20. Fix handling of system/hidden files for Windows/NT (Martin Schulz)
! 21. Get correct file times for Windows/NT (Martin Schulz)
! 22. Upper case conversion for Windows/NT depends on FAT (Martin Schulz)
! 23. Keep old internal name when updating on MSDOS a zipfile made on Unix:
!     "zip foo Makefile" no longer changes Makefile into makefile.
! 24. Do not recurse while excluding.
! 25. Add -i option. Simplify the -x code.
! 26. Include the volume label for the -S option.
! 
! ------------------------ Sep 1st  1993   version 2.0b ------------------------
! 1.  Do not use process.h in dummy/zipcloak.c
! 2.  Support volume labels for OS/2 (Kai Uwe)
! 3.  Include volume label even if file patterns do not include the root dir.
! 4.  Fixed copyright notice.
! 5.  Fixed zip -FF code (do not copy the bad compressed size)
! 6.  Add warning if -F would truncate the zip file.
! 7.  Use a specific option for volume label (-$ as in pkzip and arj).
! 8.  Better Amiga support (John Bush and Paul Kienitz).
! 9.  Define UNIX for Unix systems (Greg).
! 10. Link util_ for zipcloak (Mike Freeman)
! 11. Suppress all the TurboC .prj and .tc files; makefile.tc is more convenient.
! 12. Include only the dummy crypt routines. Full versions in zcryp20k.zip.
! 13. Fixed the contents file.
! 14. Untabify everything to make diffs easier.
! 15. When zip is used to archive stdin, read the archive comment (-z) from
!     stderr instead of stdin. (Bill Davisen)
! 
! ------------------------ Sep 2nd  1993   version 2.0c ------------------------
! 1.  Allow the full zipcloak.c to be compiled with the dummy crypt.[ch].
! 2.  Set the directory attribute when creating directory entries.
! 3.  Add -p option to zipsplit to wait between diskettes. (Mark).
! 4.  On OS/2, accept volume label on a drive other than the current drive.
! 5.  Fix fileio for SGI.
! 6.  Add err() to the dummy zipcloak.c.
! 7.  Get match.asm from msdos subdirectory in all msdos makefiles.
! 8.  Default to -DDYN_ALLOC for MSC to reduce memory usage for -T.
! 9.  Set up the Where and README files for a zip 2.0 release.
! 10. Check sys/dirent.h instead of dirent.h in configure (temporary
!     hack until the big fileio.c cleanup).
! 11. Use only strrchr (already defined as rindex for some BSD systems).
! 12. Little Amiga patches in fileio.c and SMakeFile (John Bush).
! 
! 
! ------------------------ Sep 6th  1993   version 2.0d ------------------------
! 1.  Need sys/dir.h for NODIR option (James Birdsall)
! 2.  Define OS_CODE and GetFileMode for Human68k (NIIMI Satoshi)
! 3.  Added the zipgrep shell script and zipgrep.1.
! 4.  Fix in crypt.c for Convex (Rafal Maszkowski)
! 5.  Added nt/nt.c and fixed makefile.nt (Martin Schulz)
! 6.  Fix opendir/readdir for NT (Martin Schulz)
! 7.  Reverse the meaning of -D. Directory attributes are saved by
!     default. Use -D to disable creation of directory entries.
! 8.  Remove empty directories with -rm even if directory entries are not
!     created (-D).
! 9.  Support volume labels with DJGPP (MSDOS version of gcc).
! 10. Added initialization for z->dosflag.
! 11. In Makefile, use "sh configure flags" instead of "./configure flags" to
!     deal with some buggy versions of make (SunOS 4.1 /bin/make).
! 12. Made zcrypt20m.zip compatible with unzip 5.0p1, unzip 5.1e and zip 2.0d.
!     (However funzip from unz50p1 cannot compile with the new crypt.)
! 
! ------------------------ Sep 7th  1993   version 2.0e ------------------------
! 1.  Avoid warnings for NT and fix IsFileNameValid() (Steve Salisbury).
! 2.  Use only comment after #endif in crypt.c (zcryp20n).
! 3.  Put the correct README in zcryp20n.
! 4.  Allow chars above 0x80 in recmatch (Paul Kienitz)
! 5.  In recmatch, Allow "^" as well as "!" at the beginning of a set
!     (for example "[^0-9]") as a negation (Paul Kienitz)
! 6.  Better msdos/makefile.tc.
! 
! ------------------------ Sep 7th  1993   version 2.0f ------------------------
! 1.  Call FindClose in fileio.c, add nt/ntzip.h (Martin Schulz)
! 2.  Added "Why doesn't zip do <something> just like PKZIP does?" in README.
! 
! 
! ------------------------ Sep 7th  1993   version 2.0g -------------------------
! 1.  Fix wild() for human68k, jstring.h not needed (NIIMI Satoshi)
! 2.  wild() is needed for OS2 also (Kai Uwe)
! 3.  New os2/makefile.os2 (Kai Uwe)
! 
! ------------------------ Sep 7th  1993   version 2.0 -------------------------
! 1.  Define MODERN for VMS on Alpha (Hunter)
! 2.  In vms/VMSmunch.c, deal with variant_unions under Alpha (Hunter)
! 3.  Define main with int result (Hunter)
! 4.  Do not return a garbage exit code for zipsplit -t.
! 5.  Restore file attributes of an existing zip file (Igor)
! 6.  Define UTIL in globals.c and vms.c to avoid declaring read_buf (Hunter)
! 7.  Renamed make_vaxc.com as make_vms.com, make it work on AXP (Hunter).
! 8.  Added warning about OpenVMS AXP in vms/make_gcc.com (Hunter)
! 9.  Support OpenVMS AXP in vms/descrip.mms (Hunter)
! 10. Do not perform sliding with MMAP or BIG_MEM (Martin Schulz)
! 11. Recommend -DMMAP in install.doc.
! 12. Avoid WATCOM C bug in stat("*") (Thomas Opheys)
! 13. Avoid temp file name > 8 chars for NO_MKTEMP (Thomas Opheys)
Only in .: human68k
diff -c ../zip19i/infozip.who ./infozip.who
*** ../zip19i/infozip.who	Tue Nov  3 21:07:55 1992
--- ./infozip.who	Fri Sep 10 04:54:36 1993
***************
*** 1,24 ****
  These members of the INFO-ZIP group contributed to the development and
! testing of portable Zip.  They are responsible for whatever works in Zip.
! Whatever doesn't work is solely the fault of the authors of Zip (Mark Adler,
! Rich Wales, Jean-loup Gailly, Kai Uwe Rommel and Igor Mandrichenko).
! Bill Davidsen provided the envargs code. If you have contributed and
! your name has been forgotten, please send a reminder to the zip-bugs
! address given in the Readme file.
  
  Mark Adler              madler@tybalt.caltech.edu       NeXT 2.x
  Glenn J. Andrews        oper1%drcv06.decnet@drcvax.af.mil       VAX VMS
  James Van Artsdalen     james@raid.dell.com             bug report
  Tom Betz                marob!upaya!tbetz@phri.nyu.edu  SCO Xenix 2.3.1
! James Birdsall          jwbirdsa@amc.com                AT&T 3B1
  Wim Bonner              27313853@WSUVM1.CSC.WSU.EDU     HP 9000/840a HPUX
  Paul Borman             prb@cray.com                    Cray-X/YMP,2 UNICOS 6-8
  Scott Briggs            briggs@nashua.progress.com      Windows NT
  Leslie C. Brown         lbrown@BRL.MIL                  Pyramid MIS-4
  Ralf Brown              ralf@b.gp.cs.cmu.edu            Pyramid MIS-4
  Pietro Caselli          zaphod@petruz.sublink.org       Minix 1.5.10
  Bill Davidsen           davidsen@crdos1.crd.ge.com      Xenix (on what?)
! Daniel Deimert          daniel@hexagon.se               zeus3.21 Zilog S8000
  James P. Dugal          jpd@usl.edu                     Pyramid 90X OSx4.1
  "Evil Ed"               esaffle@gmuvax2.gmu.edu         Ulrix-32 V3.1 (Rev. 9)
  David A. Feinleib       t-davefe@microsoft.com          Windows NT
--- 1,33 ----
  These members of the INFO-ZIP group contributed to the development and
! testing of portable Zip.  They are responsible for whatever works in
! Zip.  Whatever doesn't work is solely the fault of the authors of Zip
! (Mark Adler, Rich Wales, Jean-loup Gailly, Kai Uwe Rommel, Igor
! Mandrichenko and John Bush). If you have contributed and your name has
! been forgotten, please send a reminder to the zip-bugs address given
! in the Readme file. The names are given here in alphabetical order,
! because it's impossible to classify them by importance of the
! contribution. Some have made a complete port to a new target, some
! have provided a one line fix. All are to be thanked.
  
  Mark Adler              madler@tybalt.caltech.edu       NeXT 2.x
  Glenn J. Andrews        oper1%drcv06.decnet@drcvax.af.mil       VAX VMS
  James Van Artsdalen     james@raid.dell.com             bug report
+ Eric Backus             ericb@lsid.hp.com               bug report
+ Mark E. Becker          mbecker@cs.uml.edu              bug report
+ Michael Bernardi        mike@childsoc.demon.co.uk       RS6000
  Tom Betz                marob!upaya!tbetz@phri.nyu.edu  SCO Xenix 2.3.1
! James Birdsall          jwbirdsa@picarefy.com           AT&T 3B1
  Wim Bonner              27313853@WSUVM1.CSC.WSU.EDU     HP 9000/840a HPUX
  Paul Borman             prb@cray.com                    Cray-X/YMP,2 UNICOS 6-8
  Scott Briggs            briggs@nashua.progress.com      Windows NT
  Leslie C. Brown         lbrown@BRL.MIL                  Pyramid MIS-4
  Ralf Brown              ralf@b.gp.cs.cmu.edu            Pyramid MIS-4
+ Jeremy Daniel Buhler    jbuhler@owlnet.rice.edu         BC++
+ John Bush               john.bush@east.sun.com          Amiga (SAS/C)
  Pietro Caselli          zaphod@petruz.sublink.org       Minix 1.5.10
  Bill Davidsen           davidsen@crdos1.crd.ge.com      Xenix (on what?)
! Daniel Deimert          daniel@pkmab.se		        zeus3.21 Zilog S8000
! Matthew J. D'Errico     doc@magna.com                   Bull
  James P. Dugal          jpd@usl.edu                     Pyramid 90X OSx4.1
  "Evil Ed"               esaffle@gmuvax2.gmu.edu         Ulrix-32 V3.1 (Rev. 9)
  David A. Feinleib       t-davefe@microsoft.com          Windows NT
***************
*** 28,51 ****
--- 37,66 ----
  Kevin M. Fritz          kmfritz@apgea.army.mil          Turbo C++ 1.0
  Jean-loup Gailly        jloup@chorus.fr                 MS-DOS Microsoft C 5.1
  Scott D. Galloway       sgallowa@letterkenn-emh1.army.mil   Sperry 5000 SysV.3
+ Wayne R. Graves         graves@csa2.lbl.gov             Vax VMS
  George Grimes           grimes@netcom.com               Apollo Domain SR10.4
  Hunter Goatley          goathunter@WKUVX1.BITNET        Vax VMS
  Arnt Gulbrandsen        agulbra@pvv.unit.no             Linux
  David Gundlach          david@rolf.stat.uga.edu         Sun SS1+ SunOS 4.1
+ Peter Gutmann           pgut1@cs.aukuni.ac.nz           bug report
  Charles Hannum          mycroft@ai.mit.edu              bug report
  Bob Hardy               hardy@lucid.com                 Power C on MSDOS
+ Zachary Heilig          heilig@plains.nodak.edu         Turbo C++ 3.0
+ Aubrey Jaffer           jaffer@martigny.ai.mit.edu      Pixel
  Peter Jones             jones@info.uqam.ca              MIPS UMIPS 4.0
  Kjetil W. J{\o}rgensen  jorgens@lise.unit.no            OSF/1
  Bruce Kahn              bkahn@archive.webo.dg.com       MS-DOS Microsoft C 5.1
  Jonathan I. Kamens      jik@pit-manager.mit.edu         ultrix on DECstation
  Bob Kemp                Robert.V.Kemp@att.com           AT&T 3B2 SysV 3.2v2
  Earl Kiech              KIECH@utkvx.utk.edu             VAX VMS V5.4-1A
+ Paul Kienitz            Paul.Kienitz@f28.n125.z1.fidonet.org  Amiga (Manx Aztec)
  David Kirschbaum        kirsch@usasoc.soc.mil           He got us all in this
                                                          mess in the first place
  Bo Kullmar              bk@kullmar.se                   DNIX 5.3, SunOS 4.1
  Harry Langenbacher      harry@neuron6.Jpl.Nasa.Gov      Sun SS1+ SunOS 4.1
  Michael D. Lawler       mdlawler@bsu-cs.bsu.edu         Mt.Xinu BSD 4.3 on VAX
  Johnny Lee              johnnyl@microsoft.com           Microsoft C 7.0
+ Michael Lemke           michael@io.as.utexas.edu        VMS
  David Lemson            lemson@ux1.cso.uiuc.edu         Sequent Dynix 3.0.17
  Onno van der Linden     vdlinden@fwi.uva.nl             SCO Unix 3.2.0, 386/BSD
                                                          BC++ 3.0, djgcc 1.08
***************
*** 56,63 ****
  Fulvio Marino           fulvio@iconet.ico.olivetti.it   X/OS 2.3 & 2.4
  Bill Marsh              bmarsh@cod.nosc.mil             SGI Iris 4D35
  Peter Mauzey            ptm@mtdcc.att.com               AT&T 6300
! Rafal Z. Maszkowski     <rzm%pltumk11.bitnet@mvs.oac.ucla.edu> Convex
  Robert McBroom (?)      rm3@ornl.gov                    DECsystem 5810
  Humberto Ortiz-Zuazaga  zuazaga@ucunix.san.uc.edu       Linux
  James E. O'Dell         jim@fpr.com                     MacOS
  William O'Shaughnessy   williamo@hpcupt1.cup.hp.com     HPUX
--- 71,83 ----
  Fulvio Marino           fulvio@iconet.ico.olivetti.it   X/OS 2.3 & 2.4
  Bill Marsh              bmarsh@cod.nosc.mil             SGI Iris 4D35
  Peter Mauzey            ptm@mtdcc.att.com               AT&T 6300
! Rafal Z. Maszkowski     rzm@mat.torun.edu.pl            Convex
  Robert McBroom (?)      rm3@ornl.gov                    DECsystem 5810
+ Tom McConnell           tmcconne@sedona.intel.com       NCR SVR4
+ Frank P. McIngvale      frankm@eng.auburn.edu           Bug report
+ Michael                 kuch@mailserv.zdv.uni-tuebingen.de SGI
+ Dan Mick                dmick@pongo.west.sun.com        Solaris
+ Thomas S. Opheys        opheys@kirk.fmi.uni-passau.de   OS/2
  Humberto Ortiz-Zuazaga  zuazaga@ucunix.san.uc.edu       Linux
  James E. O'Dell         jim@fpr.com                     MacOS
  William O'Shaughnessy   williamo@hpcupt1.cup.hp.com     HPUX
***************
*** 67,72 ****
--- 87,93 ----
  Alan Phillips           postmaster@lancaster.ac.uk      Dynix/ptx 1.3
  Bruno Pillard           bp@chorus.fr                    SunOS 4.1
  Piet W. Plomp           piet@icce.rug.nl                MSC 7.0, SCO 3.2v4.0
+ Yuval Rakavy            yuval@cs.huji.ac.il             MSDOS
  David A Rasmussen       dave@convex.csd.uwm.edu         Convex C220 with 9.0 OS
  Michael Regoli          mr@cica.indiana.edu             Ultrix 3.1 VAX 8650
                                                          BSD 4.3 IBM RT/125
***************
*** 80,99 ****
                                                          VMS 5.2, 5.4 VAX 8600
                                                          Irix 3.3.2, SGI Iris 4D
                                                          UTS 1.2.4 Amdahl 5880
  Kai Uwe Rommel          rommel@informatik.tu-muenchen.de        OS/2
  Jon Saxton              jrs@panix.com                   Microsoft C 6.0
  Steve Salisbury         stevesa@microsoft.com           Microsoft C 6.0
  Timo Salmi              ts@uwasa.fi                     bug report
! Martin Schulz           martin@indian.cs.unb.ca         Atari ST
  W. T. Sidney            sidney@picard.med.ge.com        bug report
  Dave Sisson             daves@vtcosy.cns.vt.edu         AIX 1.1.1 PS/2 & 3090
  Fred Smith              fcshome!fredex@uunet.uu.net     Coherent
  Ron Srodawa             srodawa@vela.acs.oakland.edu    SCO Xenix/386 2.3.3
! Bertil Stenstr|m        stenis@heron.qz.se              HP-UX 7.0 HP9000/835
  Paul Telles             paul@pubnet.com                 SCO Xenix
  Robert F Tobler         rft@cs.stanford.edu             bug report
! Antoine Verheijen	antoine@sysmail.ucs.ualberta.ca envargs fix
  Arjan de Vet            devet@info.win.tue.nl           SunOS 4.1, MSC 5.1
  Johan Vromans           jv@mh.nl                        bug report
  Rich Wales              wales@cs.ucla.edu               SunOS 4.0.3 Sun-3/50
  Frank J. Wancho         wancho@wsmr-simtel20.army.mil   TOPS-20
--- 101,126 ----
                                                          VMS 5.2, 5.4 VAX 8600
                                                          Irix 3.3.2, SGI Iris 4D
                                                          UTS 1.2.4 Amdahl 5880
+ Phil Ritzenthaler       phil@cgrg.ohio-state.edu        SYSV
  Kai Uwe Rommel          rommel@informatik.tu-muenchen.de        OS/2
+ Markus Ruppel           m.ruppel@imperial.ac.uk         OS/2
  Jon Saxton              jrs@panix.com                   Microsoft C 6.0
  Steve Salisbury         stevesa@microsoft.com           Microsoft C 6.0
  Timo Salmi              ts@uwasa.fi                     bug report
! NIIMI Satoshi           a01309@cfi.waseda.ac.jp         Human68K
! Martin Schulz           martin.schulz@isltd.insignia.com Windows NT, Atari
  W. T. Sidney            sidney@picard.med.ge.com        bug report
  Dave Sisson             daves@vtcosy.cns.vt.edu         AIX 1.1.1 PS/2 & 3090
  Fred Smith              fcshome!fredex@uunet.uu.net     Coherent
  Ron Srodawa             srodawa@vela.acs.oakland.edu    SCO Xenix/386 2.3.3
! Bertil Stenstr|m        stenis@heron.dafa.se            HP-UX 7.0 HP9000/835
! Carl Streeter           streeter@oshkoshw.bitnet        OS/2
  Paul Telles             paul@pubnet.com                 SCO Xenix
+ Christopher C. Tjon     tjon@plains.nodak.edu           bug report
  Robert F Tobler         rft@cs.stanford.edu             bug report
! Antoine Verheijen       antoine@sysmail.ucs.ualberta.ca envargs fix
  Arjan de Vet            devet@info.win.tue.nl           SunOS 4.1, MSC 5.1
  Johan Vromans           jv@mh.nl                        bug report
  Rich Wales              wales@cs.ucla.edu               SunOS 4.0.3 Sun-3/50
  Frank J. Wancho         wancho@wsmr-simtel20.army.mil   TOPS-20
+                         oyvind@stavanger.sgp.slb.com    Bug report.
diff -c ../zip19i/install.doc ./install.doc
*** ../zip19i/install.doc	Tue Nov  3 21:07:55 1992
--- ./install.doc	Fri Sep 10 03:57:30 1993
***************
*** 1,53 ****
  HOW TO INSTALL ZIP
!      Zip is distributed as C source code that can be compiled on
!      a wide range of Unix machines, VAXes running VMS, and MSDOS
!      machines using Microsoft or Borland C++, and OS/2 machines
!      using Microsoft C.  You will need Unzip 5.0 (under Unix, MSDOS,
!      or VMS) or PKUNZIP 1.93a (under MSDOS) to unpack the distribution
!      file, zip19.zip. But since you read this, you have unpacked it
       already, or you cheated and got a tar.Z file...
  
       Let's assume however that you start from scratch and have not yet
       unpacked the sources. First, unpack the source as follows,
!      assuming that you have zip19.zip in the current directory.
  
            mkdir zipsrc
            cd zipsrc
!           unzip ../zip19
  
       This extracts all source files and documentation in the
       directory called "zipsrc". If you wish to build a version
       of zip with encryption capabilities, you must also get the
!      separate package zcrypt19.zip and uncomment the definition
       of MAKE at the beginning of the makefile.
  
       You then do:
  
            make system
  
!      where "system" is one of: 3b1, aix, att6300, aux, bsd, bsdold,
!      convex, cray, cray_v3, dec_osf1, dnix, dynix, hpux, isc, linux,
!      minix, next, next10, scodos, sun, sun_gcc, sysv, sysv_386, sysv_old,
!      ultrix, xenix, xos, zilog.  If you are using a NeXT running
!      version 2.0 or greater, then make next.  If you are using 1.0,
!      then make next10.  If you are using Sun OS 4.x, then make sun (or
!      sun_gcc if you have gcc). If you are using SVR4 on a 386, use
!      sysv_386 to get the optimized asm code.
! 
!      The other special systems are HPUX, DNIX 5.2 or 5.3, Cray Unicos,
!      AT&T 3B1 (also known as Unix PC or PC 7300), Zilog Zeus, A/UX,
!      Convex, AIX, MINIX, ISC System V/386, Dynix, Ultrix and DEC OSF/1.
! 
!      Otherwise, if you are using BSD Unix, try bsd.  If the linker
!      cannot find _memset or _memcpy, try bsdold.  If you are using
!      System V Unix or SCO Unix, try sysv or sysv_old.  Also use sysv
!      on a Silicon Graphics (SGI) machine.  You can also cross-compile
!      Zip for MSDOS under SCO 386 Unix using "make scodos". If you get
       error messages "constant expected" in deflate.c, add -DDYN_ALLOC
       to CFLAGS in your makefile entry.
  
       If none of these compiles, links, and functions properly on
!      your Unix system, see the file Readme for how to get help.
  
       If the appropriate system was selected, then the executables
       zip, zipnote and zipsplit will be created.  You can copy them
--- 1,59 ----
  HOW TO INSTALL ZIP
!      Zip is distributed as C source code that can be compiled on a
!      wide range of Unix machines, VAXes running VMS, and MSDOS
!      machines using Microsoft or Borland C++, and OS/2 machines using
!      Microsoft C.  You will need Unzip 5.0p1 (under Unix, MSDOS, or VMS)
!      or PKUNZIP 2.04g or later (under MSDOS) to unpack the distribution
!      file, zip20.zip. But since you read this, you have unpacked it
       already, or you cheated and got a tar.Z file...
  
       Let's assume however that you start from scratch and have not yet
       unpacked the sources. First, unpack the source as follows,
!      assuming that you have zip20.zip in the current directory.
  
            mkdir zipsrc
            cd zipsrc
!           unzip ../zip20
  
       This extracts all source files and documentation in the
       directory called "zipsrc". If you wish to build a version
       of zip with encryption capabilities, you must also get the
!      separate package zcrypt20.zip and uncomment the definition
       of MAKE at the beginning of the makefile.
  
       You then do:
  
            make system
  
!      where "system" is one of: generic, 386bsd, 3b1, aix, att6300, aux, bsd,
!      bsdold, bull, convex, coherent, cray, cray_v3, dec_osf1, dnix,
!      dynix, hpux, isc, linux, minix, next10, next2x, next3x, nextfat, pixel,
!      ptx, rs6000, scodos, sgi, sun, sun_gcc, sysv, sysv_gcc, sysv_386,
!      sys_386_gcc, sysv_old, ultrix, v7, xenix, xos, zilog.
!      Try "make generic" first, this works on most systems. If this
!      fails, then use one of the special targets given above.
! 
!      If you are using a NeXT, then make next for help about various
!      NeXT targets.  Among other special systems are HPUX, DNIX 5.2 or
!      5.3, Cray Unicos, AT&T 3B1 (also known as Unix PC or PC 7300),
!      Zilog Zeus, A/UX, Convex, AIX, MINIX, ISC System V/386, Dynix,
!      Ultrix and DEC OSF/1.
! 
!      If you are using BSD Unix, try bsd.  If the linker cannot find
!      _memset or _memcpy, try bsdold or v7.  If you are using System V
!      Unix or SCO Unix, try sysv or sysv_old.  Also use sysv on a
!      Silicon Graphics (SGI) machine.  You can also cross-compile Zip
!      for MSDOS under SCO 386 Unix using "make scodos". If you get
       error messages "constant expected" in deflate.c, add -DDYN_ALLOC
       to CFLAGS in your makefile entry.
  
+      If you have lots of memory, try compiling with -DBIG_MEM. If your
+      system supports mmap(), try compiling with -DMMAP. This generally
+      gives faster compression but uses more memory. See the Makefile
+      entry mmap_gcc for an example.
+ 
       If none of these compiles, links, and functions properly on
!      your Unix system, see the file README for how to get help.
  
       If the appropriate system was selected, then the executables
       zip, zipnote and zipsplit will be created.  You can copy them
***************
*** 75,83 ****
            rm -r zipsrc
  
       This will remove the directory zip and its contents created
!      by unzip.  You should keep the zip19.zip file around though,
       in case you need to build it again or want to give it to a
       colleague.
  
       The steps for installation under MSDOS, OS/2, and VMS are
       similar to the above: first unzip the distribution files
--- 81,99 ----
            rm -r zipsrc
  
       This will remove the directory zip and its contents created
!      by unzip.  You should keep the zip20.zip file around though,
       in case you need to build it again or want to give it to a
       colleague.
+ 
+      You can add the following lines to the file /etc/magic for
+      usage by the 'file' command:
+ 
+ 0	string		PK\003\004	Zip archive
+ >4	string		\011		(at least v0.9 to extract)
+ >4	string		\012		(at least v1.0 to extract)
+ >4	string		\013		(at least v1.1 to extract)
+ >4	string		\024		(at least v2.0 to extract)
+ 
  
       The steps for installation under MSDOS, OS/2, and VMS are
       similar to the above: first unzip the distribution files
Only in .: mac
diff -c ../zip19i/makecrc.c ./makecrc.c
*** ../zip19i/makecrc.c	Tue Nov  3 21:07:55 1992
--- ./makecrc.c	Sat Aug 21 01:57:28 1993
***************
*** 1,5 ****
--- 1,9 ----
  /* Not copyrighted 1990 Mark Adler */
  
+ #ifndef lint
+ static char rcsid[] = "$Id: zip.diff,v 1.1 1993/09/22 19:09:54 smace Exp $";
+ #endif
+ 
  #include <stdio.h>
  
  main()
***************
*** 37,43 ****
    /* terms of polynomial defining this crc (except x^32): */
    static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
  
!   /* Make exclusive-or pattern from polynomial */
    e = 0;
    for (i = 0; i < sizeof(p)/sizeof(int); i++)
      e |= 1L << (31 - p[i]);
--- 41,47 ----
    /* terms of polynomial defining this crc (except x^32): */
    static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
  
!   /* Make exclusive-or pattern from polynomial (0xedb88320) */
    e = 0;
    for (i = 0; i < sizeof(p)/sizeof(int); i++)
      e |= 1L << (31 - p[i]);
***************
*** 46,58 ****
    printf("  0x00000000L");
    for (i = 1; i < 256; i++)
    {
!     c = 0;
!     for (k = i | 256; k != 1; k >>= 1)
!     {
        c = c & 1 ? (c >> 1) ^ e : c >> 1;
-       if (k & 1)
-         c ^= e;
-     }
      printf(i % 5 ? ", 0x%08lxL" : ",\n  0x%08lxL", c);
    }
    putchar('\n');
--- 50,61 ----
    printf("  0x00000000L");
    for (i = 1; i < 256; i++)
    {
!     c = i;
!     /* The idea to initialize the register with the byte instead of
!      * zero was stolen from Haruhiko Okumura's ar002
!      */
!     for (k = 8; k; k--)
        c = c & 1 ? (c >> 1) ^ e : c >> 1;
      printf(i % 5 ? ", 0x%08lxL" : ",\n  0x%08lxL", c);
    }
    putchar('\n');
Only in ../zip19i: makefile
diff -c ../zip19i/match.s ./match.s
*** ../zip19i/match.s	Tue Nov  3 21:07:55 1992
--- ./match.s	Tue Aug 31 22:08:34 1993
***************
*** 1,50 ****
  /*
!  * Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   * Kai Uwe Rommel and Igor Mandrichenko.
   * Permission is granted to any individual or institution to use, copy, or
!  * redistribute this software so long as all of the original files are included
!  * unmodified, that it is not sold for profit, and that this copyright notice
!  * is retained.
   *
   * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel.
   
!  * match.s, optimized version of longest_match() in deflate.c
!  * This version is for 386 Unix or OS/2 in 32 bit mode.
!  * Warning: it uses the AT&T syntax: mov source,dest
!  * This file is only optional. If you want to force the C version,
!  * add -DNO_ASM to CFLAGS in makefile and remove match.o from OBJI).
!  * If you have reduced WSIZE in zip.h, then change its value below.
!  * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
   */
! 
! 	.file   "match.s"
! 
! #ifdef SYSV
  #  define _prev             prev
  #  define _window           window
! #  define _match_start	    match_start
! #  define _prev_length	    prev_length
! #  define _good_match	    good_match
! #  define _strstart	    strstart
  #  define _max_chain_length max_chain_length
  
  #  define _match_init       match_init
  #  define _longest_match    longest_match
  #endif
  
! #define MAX_MATCH 	258
! #define MAX_MATCH2      128     /* MAX_MATCH/2-1 */
! #define MIN_MATCH	3
! #define WSIZE 		32768
! #define MAX_DIST 	WSIZE - MAX_MATCH - MIN_MATCH - 1
  
! 	.globl	_match_init
! 	.globl  _longest_match
  
! 	.text
  
  _match_init:
! 	ret
  
  /*-----------------------------------------------------------------------
   * Set match_start to the longest match starting at the given string and
--- 1,64 ----
  /*
!  * Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   * Kai Uwe Rommel and Igor Mandrichenko.
   * Permission is granted to any individual or institution to use, copy, or
!  * redistribute this software so long as all of the original files are
!  * included, that it is not sold for profit, and that this copyright notice is
!  * retained.
   *
   * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel.
+  * The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
+  * with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
+  * Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
+  * Kristoffer Eriksson <ske@pkmab.se>
+  */
   
! /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
!  * external symbols with an underline character '_'.
   */
! #if defined(NO_UNDERLINE) || defined(SYSV)
  #  define _prev             prev
  #  define _window           window
! #  define _match_start      match_start
! #  define _prev_length      prev_length
! #  define _good_match       good_match
! #  define _nice_match       nice_match
! #  define _strstart         strstart
  #  define _max_chain_length max_chain_length
  
  #  define _match_init       match_init
  #  define _longest_match    longest_match
  #endif
  
! #ifdef DYN_ALLOC
!   error: DYN_ALLOC not yet supported in match.s
! #endif
! 
! #if defined(i386) || defined(_I386)
  
! /* This version is for 386 Unix or OS/2 in 32 bit mode.
!  * Warning: it uses the AT&T syntax: mov source,dest
!  * This file is only optional. If you want to force the C version,
!  * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
!  * If you have reduced WSIZE in gzip.h, then change its value below.
!  * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
!  */
  
!         .file   "match.S"
  
+ #define MAX_MATCH       258
+ #define MAX_MATCH2      $128 /* MAX_MATCH/2-1 */
+ #define MIN_MATCH       3
+ #define    WSIZE        $32768
+ #define MAX_DIST        WSIZE - MAX_MATCH - MIN_MATCH - 1
+ 
+         .globl  _match_init
+         .globl  _longest_match
+ 
+         .text
+ 
  _match_init:
!         ret
  
  /*-----------------------------------------------------------------------
   * Set match_start to the longest match starting at the given string and
***************
*** 55,68 ****
   *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
   */
  
! _longest_match:	/* int longest_match(cur_match) */
  
  #define cur_match   20(%esp)
       /* return address */               /* esp+16 */
          push    %ebp                    /* esp+12 */
          push    %edi                    /* esp+8  */
! 	push	%esi                    /* esp+4  */
! 	push    %ebx			/* esp    */
  
  /*
   *      match        equ esi
--- 69,82 ----
   *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
   */
  
! _longest_match: /* int longest_match(cur_match) */
  
  #define cur_match   20(%esp)
       /* return address */               /* esp+16 */
          push    %ebp                    /* esp+12 */
          push    %edi                    /* esp+8  */
!         push    %esi                    /* esp+4  */
!         push    %ebx                    /* esp    */
  
  /*
   *      match        equ esi
***************
*** 71,143 ****
   *      best_len     equ ebx
   *      limit        equ edx
   */
! 	mov 	cur_match,%esi
!         mov 	_max_chain_length,%ebp /* chain_length = max_chain_length */
! 	mov 	_strstart,%edi
! 	mov 	%edi,%edx
! 	sub	$ MAX_DIST,%edx        /* limit = strstart-MAX_DIST */
! 	jae	limit_ok
! 	sub	%edx,%edx              /* limit = NIL */
  limit_ok:
!         add	$_window+2,%edi        /* edi = offset(window + strstart + 2) */
!         mov	_prev_length,%ebx      /* best_len = prev_length */
!         movw 	-3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
!         movw 	-2(%edi),%cx           /* cx = scan[0..1] */
! 	cmp	_good_match,%ebx       /* do we have a good match already? */
          jb      do_scan
! 	shr 	$2,%ebp                /* chain_length >>= 2 */
          jmp     do_scan
  
          .align  4
  long_loop:
  /* at this point, edi == scan+2, esi == cur_match */
!         movw	-3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
          movw     -2(%edi),%cx           /* cx = scan[0..1] */
  short_loop:
-         dec     %ebp                    /* --chain_length */
-         jz      the_end
  /*
   * at this point, di == scan+2, si == cur_match,
   * ax = scan[best_len-1..best_len] and cx = scan[0..1]
   */
!         and     $ WSIZE-1, %esi
!         movw     _prev(%esi,%esi),%si   /* cur_match = prev[cur_match] */
                                          /* top word of esi is still 0 */
!         cmp     %edx,%esi		/* cur_match <= limit ? */
          jbe     the_end
  do_scan:
!         cmpw    _window-1(%ebx,%esi),%ax /* check match at best_len-1 */
          jne     short_loop
          cmpw    _window(%esi),%cx       /* check min_match_length match */
          jne     short_loop
  
          lea     _window+2(%esi),%esi    /* si = match */
          mov     %edi,%eax               /* ax = scan+2 */
!         mov 	$ MAX_MATCH2,%ecx       /* scan for at most MAX_MATCH bytes */
! #ifdef SYSV
!         repz;   cmpsw                   /* loop until mismatch */
! #else
!         repe;   cmpsw
! #endif
          je      maxmatch                /* match of length MAX_MATCH? */
  mismatch:
          movb    -2(%edi),%cl        /* mismatch on first or second byte? */
          subb    -2(%esi),%cl        /* cl = 0 if first bytes equal */
          xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
          sub     %edi,%eax           /* eax = len */
! 	sub	%eax,%esi           /* esi = cur_match + 2 + offset(window) */
! 	sub	$_window+2,%esi     /* esi = cur_match */
          subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
          adc     $0,%eax             /* eax = carry ? len+1 : len */
          cmp     %ebx,%eax           /* len > best_len ? */
          jle     long_loop
          mov     %esi,_match_start       /* match_start = cur_match */
          mov     %eax,%ebx               /* ebx = best_len = len */
!         cmp     $ MAX_MATCH,%eax        /* len >= MAX_MATCH ? */
          jl      long_loop
  the_end:
          mov     %ebx,%eax               /* result = eax = best_len */
! 	pop     %ebx
          pop     %esi
          pop     %edi
          pop     %ebp
--- 85,153 ----
   *      best_len     equ ebx
   *      limit        equ edx
   */
!         mov     cur_match,%esi
!         mov     _max_chain_length,%ebp /* chain_length = max_chain_length */
!         mov     _strstart,%edi
!         mov     %edi,%edx
!         sub     MAX_DIST,%edx          /* limit = strstart-MAX_DIST */
!         jae     limit_ok
!         sub     %edx,%edx              /* limit = NIL */
  limit_ok:
!         add     $2+_window,%edi        /* edi = offset(window+strstart+2) */
!         mov     _prev_length,%ebx      /* best_len = prev_length */
!         movw    -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
!         movw    -2(%edi),%cx           /* cx = scan[0..1] */
!         cmp     _good_match,%ebx       /* do we have a good match already? */
          jb      do_scan
!         shr     $2,%ebp                /* chain_length >>= 2 */
          jmp     do_scan
  
          .align  4
  long_loop:
  /* at this point, edi == scan+2, esi == cur_match */
!         movw    -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
          movw     -2(%edi),%cx           /* cx = scan[0..1] */
  short_loop:
  /*
   * at this point, di == scan+2, si == cur_match,
   * ax = scan[best_len-1..best_len] and cx = scan[0..1]
   */
!         and     WSIZE-1, %esi
!         movw    _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
                                          /* top word of esi is still 0 */
!         cmp     %edx,%esi               /* cur_match <= limit ? */
          jbe     the_end
+         dec     %ebp                    /* --chain_length */
+         jz      the_end
  do_scan:
!         cmpw    _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
          jne     short_loop
          cmpw    _window(%esi),%cx       /* check min_match_length match */
          jne     short_loop
  
          lea     _window+2(%esi),%esi    /* si = match */
          mov     %edi,%eax               /* ax = scan+2 */
!         mov     MAX_MATCH2,%ecx         /* scan for at most MAX_MATCH bytes */
!         rep;    cmpsw                   /* loop until mismatch */
          je      maxmatch                /* match of length MAX_MATCH? */
  mismatch:
          movb    -2(%edi),%cl        /* mismatch on first or second byte? */
          subb    -2(%esi),%cl        /* cl = 0 if first bytes equal */
          xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
          sub     %edi,%eax           /* eax = len */
!         sub     %eax,%esi           /* esi = cur_match + 2 + offset(window) */
!         sub     $2+_window,%esi     /* esi = cur_match */
          subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
          adc     $0,%eax             /* eax = carry ? len+1 : len */
          cmp     %ebx,%eax           /* len > best_len ? */
          jle     long_loop
          mov     %esi,_match_start       /* match_start = cur_match */
          mov     %eax,%ebx               /* ebx = best_len = len */
!         cmp     _nice_match,%eax        /* len >= nice_match ? */
          jl      long_loop
  the_end:
          mov     %ebx,%eax               /* result = eax = best_len */
!         pop     %ebx
          pop     %esi
          pop     %edi
          pop     %ebp
***************
*** 145,147 ****
--- 155,381 ----
  maxmatch:
          cmpsb
          jmp     mismatch
+ 
+ #else
+ 
+ /* ======================== 680x0 version ================================= */
+ 
+ #if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
+ #  ifndef mc68000
+ #    define mc68000
+ #  endif
+ #endif
+ 
+ #if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
+ #  ifndef mc68020
+ #    define mc68020
+ #  endif
+ #endif
+ 
+ #if defined(mc68020) || defined(mc68000)
+ 
+ #if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
+ #  define UNALIGNED_OK
+ #endif
+ 
+ #ifdef sysV68  /* Try Motorola Delta style */
+ 
+ #  define GLOBAL(symbol)        global  symbol
+ #  define TEXT                  text
+ #  define FILE(filename)        file    filename
+ #  define invert_maybe(src,dst) dst,src
+ #  define imm(data)             &data
+ #  define reg(register)         %register
+ 
+ #  define addl                  add.l
+ #  define addql                 addq.l
+ #  define blos                  blo.b
+ #  define bhis                  bhi.b
+ #  define bras                  bra.b
+ #  define clrl                  clr.l
+ #  define cmpmb                 cmpm.b
+ #  define cmpw                  cmp.w
+ #  define cmpl                  cmp.l
+ #  define lslw                  lsl.w
+ #  define lsrl                  lsr.l
+ #  define movel                 move.l
+ #  define movew                 move.w
+ #  define moveb                 move.b
+ #  define moveml                movem.l
+ #  define subl                  sub.l
+ #  define subw                  sub.w
+ #  define subql                 subq.l
+ 
+ #  define IndBase(bd,An)        (bd,An)
+ #  define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
+ #  define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
+ #  define predec(An)            -(An)
+ #  define postinc(An)           (An)+
+ 
+ #else /* default style (Sun 3, NeXT, Amiga, Atari) */
+ 
+ #  define GLOBAL(symbol)        .globl  symbol
+ #  define TEXT                  .text
+ #  define FILE(filename)        .even
+ #  define invert_maybe(src,dst) src,dst
+ #  if defined(sun) || defined(mc68k)
+ #    define imm(data)           #data
+ #  else
+ #    define imm(data)           \#data
+ #  endif
+ #  define reg(register)         register
+ 
+ #  define blos                  bcss
+ #  if defined(sun) || defined(mc68k)
+ #    define movel               movl
+ #    define movew               movw
+ #    define moveb               movb
+ #  endif
+ #  define IndBase(bd,An)        An@(bd)
+ #  define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l)
+ #  define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w)
+ #  define predec(An)            An@-
+ #  define postinc(An)           An@+
+ 
+ #endif  /* styles */
+ 
+ #define Best_Len        reg(d0)         /* unsigned */
+ #define Cur_Match       reg(d1)         /* Ipos */
+ #define Loop_Counter    reg(d2)         /* int */
+ #define Scan_Start      reg(d3)         /* unsigned short */
+ #define Scan_End        reg(d4)         /* unsigned short */
+ #define Limit           reg(d5)         /* IPos */
+ #define Chain_Length    reg(d6)         /* unsigned */
+ #define Scan_Test       reg(d7)
+ #define Scan            reg(a0)         /* *uch */
+ #define Match           reg(a1)         /* *uch */
+ #define Prev_Address    reg(a2)         /* *Pos */
+ #define Scan_Ini        reg(a3)         /* *uch */
+ #define Match_Ini       reg(a4)         /* *uch */
+ #define Stack_Pointer   reg(sp)
+ 
+ #define MAX_MATCH       258
+ #define MIN_MATCH       3
+ #define WSIZE           32768
+ #define MAX_DIST        (WSIZE - MAX_MATCH - MIN_MATCH - 1)
+ 
+         GLOBAL  (_match_init)
+         GLOBAL  (_longest_match)
+ 
+         TEXT
+ 
+         FILE    ("match.S")
+ 
+ _match_init:
+         rts
+ 
+ /*-----------------------------------------------------------------------
+  * Set match_start to the longest match starting at the given string and
+  * return its length. Matches shorter or equal to prev_length are discarded,
+  * in which case the result is equal to prev_length and match_start is
+  * garbage.
+  * IN assertions: cur_match is the head of the hash chain for the current
+  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+  */
+ 
+ /* int longest_match (cur_match) */
+ 
+ #ifdef UNALIGNED_OK
+ #  define pushreg       15928           /* d2-d6/a2-a4 */
+ #  define popreg        7292
+ #else
+ #  define pushreg       16184           /* d2-d7/a2-a4 */
+ #  define popreg        7420
+ #endif
+ 
+ _longest_match:
+         movel   IndBase(4,Stack_Pointer),Cur_Match
+         moveml  imm(pushreg),predec(Stack_Pointer)
+         movel   _max_chain_length,Chain_Length
+         movel   _prev_length,Best_Len
+         movel   imm(_prev),Prev_Address
+         movel   imm(_window+MIN_MATCH),Match_Ini
+         movel   _strstart,Limit
+         movel   Match_Ini,Scan_Ini
+         addl    Limit,Scan_Ini
+         subw    imm(MAX_DIST),Limit
+         bhis    L__limit_ok
+         clrl    Limit
+ L__limit_ok:
+         cmpl    invert_maybe(_good_match,Best_Len)
+         blos    L__length_ok
+         lsrl    imm(2),Chain_Length
+ L__length_ok:
+         subql   imm(1),Chain_Length
+ #ifdef UNALIGNED_OK
+         movew   IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+         movew   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+ #else
+         moveb   IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+         lslw    imm(8),Scan_Start
+         moveb   IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start
+         moveb   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+         lslw    imm(8),Scan_End
+         moveb   IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+ #endif
+         bras    L__do_scan
+ 
+ L__long_loop:
+ #ifdef UNALIGNED_OK
+         movew   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+ #else
+         moveb   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+         lslw    imm(8),Scan_End
+         moveb   IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+ #endif
+ 
+ L__short_loop:
+         lslw    imm(1),Cur_Match
+         movew   IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match
+         cmpw    invert_maybe(Limit,Cur_Match)
+         dbls    Chain_Length,L__do_scan
+         bras    L__return
+ 
+ L__do_scan:
+         movel   Match_Ini,Match
+         addl    Cur_Match,Match
+ #ifdef UNALIGNED_OK
+         cmpw    invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End)
+         bne     L__short_loop
+         cmpw    invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start)
+         bne     L__short_loop
+ #else
+         moveb   IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test
+         lslw    imm(8),Scan_Test
+         moveb   IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test
+         cmpw    invert_maybe(Scan_Test,Scan_End)
+         bne     L__short_loop
+         moveb   IndBase(-MIN_MATCH,Match),Scan_Test
+         lslw    imm(8),Scan_Test
+         moveb   IndBase(-MIN_MATCH+1,Match),Scan_Test
+         cmpw    invert_maybe(Scan_Test,Scan_Start)
+         bne     L__short_loop
+ #endif
+ 
+         movew   imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter
+         movel   Scan_Ini,Scan
+ L__scan_loop:
+         cmpmb   postinc(Match),postinc(Scan)
+         dbne    Loop_Counter,L__scan_loop
+ 
+         subl    Scan_Ini,Scan
+         addql   imm(MIN_MATCH-1),Scan
+         cmpl    invert_maybe(Best_Len,Scan)
+         bls     L__short_loop
+         movel   Scan,Best_Len
+         movel   Cur_Match,_match_start
+         cmpl    invert_maybe(_nice_match,Best_Len)
+         blos    L__long_loop
+ L__return:
+         moveml  postinc(Stack_Pointer),imm(popreg)
+         rts
+ 
+ #else
+  error: this asm version is for 386 or 680x0 only
+ #endif /* mc68000 || mc68020 */
+ #endif /* i386 || _I386   */
Only in .: msdos
Only in .: nt
Only in .: os2
diff -c ../zip19i/revision.h ./revision.h
*** ../zip19i/revision.h	Tue Nov  3 21:07:55 1992
--- ./revision.h	Tue Sep  7 02:40:26 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 13,22 ****
   *  revision.h by Mark Adler.
   */
  
! #define REVISION 19
! #define PATCHLEVEL 1
! #define VERSION "1.9i"
! #define REVDATE "Oct 30th 1992"
  
  /* Copyright notice for binary executables--this notice only applies to
   * those (zip, zipcloak, zipsplit, and zipnote), not to this file
--- 12,21 ----
   *  revision.h by Mark Adler.
   */
  
! #define REVISION 20
! #define PATCHLEVEL 0
! #define VERSION "2.0"
! #define REVDATE "Sept 7th 1993"
  
  /* Copyright notice for binary executables--this notice only applies to
   * those (zip, zipcloak, zipsplit, and zipnote), not to this file
***************
*** 26,37 ****
  #ifndef NOCPYRT
  char *copyright[] = {
  #ifdef VMS
! "Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,",
! "Kai Uwe Rommel and Igor Mandrichenko. Type '%s \"-L\"' for software license.",
  #else
! "Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly",
  "and Kai Uwe Rommel. Type '%s -L' for the software License.",
! #endif
  };
  char *disclaimer[] = {
  "",
--- 25,41 ----
  #ifndef NOCPYRT
  char *copyright[] = {
  #ifdef VMS
! "Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly",
! "and Igor Mandrichenko. Type '%s \"-L\"' for software license.",
  #else
! # ifdef AMIGA
! "Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,",
! "John Bush and Paul Kienitz. Type '%s -L' for the software License.",
! # else
! "Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly",
  "and Kai Uwe Rommel. Type '%s -L' for the software License.",
! # endif /* ?AMIGA */
! #endif /* ?VMS */
  };
  char *disclaimer[] = {
  "",
diff -c ../zip19i/tailor.h ./tailor.h
*** ../zip19i/tailor.h	Tue Nov  3 21:07:55 1992
--- ./tailor.h	Thu Sep  9 22:46:50 1993
***************
*** 1,10 ****
! /* tailor.h -- Not copyrighted 1992 Mark Adler */
  
- /* const's are inconsistently used across ANSI libraries--kill for all
-    header files.  */
- #define const
- 
- 
  /* Define MSDOS for Turbo C and Power C */
  #ifdef __POWERC
  #  define __TURBOC__
--- 1,5 ----
! /* tailor.h -- Not copyrighted 1993 Mark Adler */
  
  /* Define MSDOS for Turbo C and Power C */
  #ifdef __POWERC
  #  define __TURBOC__
***************
*** 20,52 ****
  #endif
  
  /* Use prototypes and ANSI libraries if _STDC__, or Microsoft or Borland C,
!  * or Silicon Graphics, or IBM C Set/2, or GNU gcc under emx.
   */
! #if (defined(__STDC__) || defined(MSDOS) || defined(sgi))
  #  ifndef PROTO
  #    define PROTO
  #  endif /* !PROTO */
  #  define MODERN
! #endif /* MSDOS */
  
! #if (defined(__IBMC__) || defined(__EMX__) || defined(ATARI_ST))
  #  ifndef PROTO
  #    define PROTO
  #  endif /* !PROTO */
  #  define MODERN
! #  ifdef far
! #    undef far
! #    undef near
! #    undef huge
! #  endif
  #endif
  
  #ifdef __IBMC__
  #  define S_IFMT 0xF000
  #endif /* __IBMC__ */
  
! #if (defined(__EMX__) || defined(__WATCOMC__)) && !defined(__32BIT__)
! #  define __32BIT__
  #endif
  
  #if (defined(__OS2__) && !defined(OS2))
--- 15,51 ----
  #endif
  
  /* Use prototypes and ANSI libraries if _STDC__, or Microsoft or Borland C,
!  * or Silicon Graphics, or IBM C Set/2, or Watcom C, or GNU gcc under emx.
   */
! #if defined(__STDC__) || defined(MSDOS) || defined(ATARI_ST) || defined(sgi)
  #  ifndef PROTO
  #    define PROTO
  #  endif /* !PROTO */
  #  define MODERN
! #endif
  
! #if defined(__IBMC__) || defined(__EMX__) || defined(__WATCOMC__)
  #  ifndef PROTO
  #    define PROTO
  #  endif /* !PROTO */
  #  define MODERN
! #endif
! 
! #if defined(__BORLANDC__) || (defined(__alpha) && defined(VMS))
! #  ifndef PROTO
! #    define PROTO
! #  endif /* !PROTO */
! #  define MODERN
  #endif
  
  #ifdef __IBMC__
  #  define S_IFMT 0xF000
  #endif /* __IBMC__ */
  
! #if defined(__EMX__) || defined(__WATCOMC__) || defined(__BORLANDC__)
! #  if (defined(OS2) && !defined(__32BIT__))
! #    define __32BIT__
! #  endif
  #endif
  
  #if (defined(__OS2__) && !defined(OS2))
***************
*** 54,60 ****
  #endif
  
  #ifdef __convexc__
! #	define CONVEX
  #endif /* __convexc__ */
  
  #ifdef __COMPILER_KCC__
--- 53,59 ----
  #endif
  
  #ifdef __convexc__
! #       define CONVEX
  #endif /* __convexc__ */
  
  #ifdef __COMPILER_KCC__
***************
*** 80,85 ****
--- 79,88 ----
  #  define OF(a) ()
  #endif /* ?PROTO */
  
+ /* Avoid using const if compiler does not support it */
+ #ifndef MODERN  /* if this fails, try: ifndef__STDC__ */
+ #  define const
+ #endif
  
  #ifdef MACOS
  #  define DYN_ALLOC
***************
*** 90,111 ****
  #    define DYN_ALLOC
       /* Turbo C 2.0 does not accept static allocations of large arrays */
       void far * fcalloc OF((unsigned items, unsigned size));
  #  else /* !__TURBOC__ */
  #    include <malloc.h>
  #    define farmalloc _fmalloc
  #    define farfree   _ffree
  #    define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
  #  endif /* ?__TURBOC__ */
  #else /* !MSDOS */
  #  if defined(WIN32)
  #    include <malloc.h>
  #  endif
! #  define huge
! #  define far
! #  define near
  #  define farmalloc malloc
  #  define farfree   free
  #  define fcalloc(items,size) calloc((unsigned)(items), (unsigned)(size))
  #  if (!defined(PROTO) && !defined(TOPS20))
       extern char *calloc(); /* essential for 16 bit systems (AT&T 6300) */
  #  endif
--- 93,124 ----
  #    define DYN_ALLOC
       /* Turbo C 2.0 does not accept static allocations of large arrays */
       void far * fcalloc OF((unsigned items, unsigned size));
+      void fcfree (void *ptr);
  #  else /* !__TURBOC__ */
  #    include <malloc.h>
  #    define farmalloc _fmalloc
  #    define farfree   _ffree
  #    define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
+ #    define fcfree(ptr) hfree((void huge *)(ptr))
  #  endif /* ?__TURBOC__ */
  #else /* !MSDOS */
  #  if defined(WIN32)
  #    include <malloc.h>
  #  endif
! #  ifdef __WATCOMC__
! #    undef huge
! #    undef far
! #    undef near
! #  endif
! #  ifndef __IBMC__
! #    define huge
! #    define far
! #    define near
! #  endif
  #  define farmalloc malloc
  #  define farfree   free
  #  define fcalloc(items,size) calloc((unsigned)(items), (unsigned)(size))
+ #  define fcfree    free
  #  if (!defined(PROTO) && !defined(TOPS20))
       extern char *calloc(); /* essential for 16 bit systems (AT&T 6300) */
  #  endif
***************
*** 120,126 ****
  #endif
      
  
! /* Define MSVMS if either MSDOS or VMS defined */
  #if defined(MSDOS) || defined(VMS)
  #  define MSVMS
  #endif
--- 133,139 ----
  #endif
      
  
! /* Define MSVMS if MSDOS or VMS defined -- ATARI also does, Amiga could */
  #if defined(MSDOS) || defined(VMS)
  #  define MSVMS
  #endif
***************
*** 128,136 ****
  /* case mapping functions. case_map is used to ignore case in comparisons,
   * to_up is used to force upper case even on Unix (for dosify option).
   */
! #if defined(OS2) || defined(MSDOS) || defined(VMS)
! #  define case_map(c) upper[c]
! #  define to_up(c)    upper[c]
  #else
  #  define case_map(c) (c)
  #  define to_up(c)    ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
--- 141,149 ----
  /* case mapping functions. case_map is used to ignore case in comparisons,
   * to_up is used to force upper case even on Unix (for dosify option).
   */
! #if defined(MSDOS) || defined(VMS) || defined(OS2) || defined(WIN32) || defined(AMIGA)
! #  define case_map(c) upper[(c) & 0xff]
! #  define to_up(c)    upper[(c) & 0xff]
  #else
  #  define case_map(c) (c)
  #  define to_up(c)    ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
***************
*** 143,149 ****
  #    include <stddef.h>
  #  endif /* !M_XENIX */
  #  include <stdlib.h>
! #  ifdef __386BSD__
  #    include <unistd.h>
  #  endif
     typedef size_t extent;
--- 156,162 ----
  #    include <stddef.h>
  #  endif /* !M_XENIX */
  #  include <stdlib.h>
! #  if defined(SYSV) || defined(__386BSD__)
  #    include <unistd.h>
  #  endif
     typedef size_t extent;
***************
*** 160,165 ****
--- 173,179 ----
  #  include <stat.h>
  #  define unlink delete
  #  define NO_SYMLINK
+ #  define SSTAT vms_stat
  #else /* !VMS */
  #  ifdef MACOS
  #    include <types.h>
***************
*** 176,185 ****
  #      include <ext.h>
  #      include <tos.h>
  #    else
! #      include <sys/types.h>
  #      include <sys/stat.h>
  #    endif
  #  endif
  #endif /* ?VMS */
  
  /* Some systems define S_IFLNK but do not support symbolic links */
--- 190,216 ----
  #      include <ext.h>
  #      include <tos.h>
  #    else
! #      ifdef AMIGA
!          int wild OF((char *));
!          /* default to MEDIUM_MEM, but allow makefile override */
! #        if ( (!defined(BIG_MEM)) && (!defined(SMALL_MEM)))
! #           define MEDIUM_MEM
! #        endif
! #        if defined(LATTICE) || defined(__SASC)
! #        include <sys/types.h>
! #          include <sys/stat.h>
!            extern int isatty(int);   /* SAS has no unistd.h */
! #      endif
! #        ifdef AZTEC_C
! #          include "amiga/z-stat.h"
! #          define RMDIR
! #        endif
! #      else /* !AMIGA */
! #        include <sys/types.h>
  #      include <sys/stat.h>
  #    endif
  #  endif
+ #  endif
  #endif /* ?VMS */
  
  /* Some systems define S_IFLNK but do not support symbolic links */
***************
*** 201,207 ****
  #  define FOPM  "r+","ctx=stm","rfm=fix","mrs=512"
  #  define FOPW  "w","ctx=stm","rfm=fix","mrs=512"
  #else /* !VMS */
! #  ifdef MODERN
  #    define FOPR "rb"
  #    define FOPM "r+b"
  #    ifdef TOPS20 /* TOPS20 MODERN? You kidding? */
--- 232,238 ----
  #  define FOPM  "r+","ctx=stm","rfm=fix","mrs=512"
  #  define FOPW  "w","ctx=stm","rfm=fix","mrs=512"
  #else /* !VMS */
! #  if defined(MODERN)
  #    define FOPR "rb"
  #    define FOPM "r+b"
  #    ifdef TOPS20 /* TOPS20 MODERN? You kidding? */
***************
*** 210,218 ****
--- 241,255 ----
  #      define FOPW "wb"
  #    endif
  #  else /* !MODERN */
+ #    ifdef AMIGA
+ #      define FOPR "rb"
+ #      define FOPM "rb+"
+ #      define FOPW "wb"
+ #    else /* !AMIGA */
  #    define FOPR "r"
  #    define FOPM "r+"
  #    define FOPW "w"
+ #    endif /* ?AMIGA */
  #  endif /* ?MODERN */
  #endif /* VMS */
  
***************
*** 229,238 ****
   * This is not mandatory, just a speed optimization. The compressed
   * output is strictly identical.
   */
! #if defined(MSDOS) || defined(i386) || defined(mc68020) || defined(vax)
! #   define UNALIGNED_OK
  #endif
! 
  
  /* Under MSDOS we may run out of memory when processing a large number
   * of files. Compile with MEDIUM_MEM to reduce the memory requirements or
--- 266,277 ----
   * This is not mandatory, just a speed optimization. The compressed
   * output is strictly identical.
   */
! #if (defined(MSDOS) && !defined(WIN32)) || defined(i386)
! #    define UNALIGNED_OK
  #endif
! #if defined(mc68020) || defined(vax)
! #    define UNALIGNED_OK
! #endif
  
  /* Under MSDOS we may run out of memory when processing a large number
   * of files. Compile with MEDIUM_MEM to reduce the memory requirements or
***************
*** 248,255 ****
  # else
  #  ifdef OS2
  #   ifdef __32BIT__
! #     define CBSZ 0x10000  /* 64k */
! #     define ZBSZ 0x40000  /* 256k */
  #   else
  #     define CBSZ 0xE000
  #     define ZBSZ 0x7F00 /* Some libraries do not allow a buffer size > 32K */
--- 287,294 ----
  # else
  #  ifdef OS2
  #   ifdef __32BIT__
! #     define CBSZ 0x40000
! #     define ZBSZ 0x40000
  #   else
  #     define CBSZ 0xE000
  #     define ZBSZ 0x7F00 /* Some libraries do not allow a buffer size > 32K */
***************
*** 270,275 ****
--- 309,322 ----
  #   define DYN_ALLOC
  #endif
  
+ #ifdef __human68k__
+ #  include <sys/xglob.h>
+ #  define MSVMS
+ #  define SSTAT h68_stat
+   int h68_stat OF((char *, struct stat *));
+ #  define OS_CODE  0x300  /* pretend it's Unix */
+ #endif
+ 
  #ifdef ATARI_ST
  #  define MSDOS  /* what? should be fixed */
  #  define MSVMS
***************
*** 302,309 ****
    int st_findfirst OF((char *, struct ffblk *, int));
    int st_rename    OF((char *, char *));
    int st_rmdir     OF((char *));
! #else
  #  define SSTAT      stat
  #endif
     
  /* end of tailor.h */
--- 349,403 ----
    int st_findfirst OF((char *, struct ffblk *, int));
    int st_rename    OF((char *, char *));
    int st_rmdir     OF((char *));
! #endif  /* ATARI */
! 
! #ifndef SSTAT
  #  define SSTAT      stat
  #endif
+ #ifdef S_IFLNK
+ #  define LSTAT      lstat
+ #else
+ #  define LSTAT      SSTAT
+ #endif
+ 
     
+ /* The following OS codes are defined in pkzip appnote.txt */
+ #ifdef AMIGA
+ #  define OS_CODE  0x100
+ #endif
+ #ifdef VMS
+ #  define OS_CODE  0x200
+ #endif
+ /* unix    3 */
+ /* vms/cms 4 */
+ #ifdef ATARI_ST
+ #  define OS_CODE  0x500
+ #endif
+ #ifdef OS2
+ #  define OS_CODE  0x600
+ #endif
+ #ifdef MACOS
+ #  define OS_CODE  0x700
+ #endif
+ /* z system 8 */
+ /* cp/m     9 */
+ #ifdef TOPS20
+ #  define OS_CODE  0xa00
+ #endif
+ #ifdef WIN32
+ #  define OS_CODE  0xb00
+ #endif
+ /* qdos 12 */
+ 
+ #if defined(MSDOS) && !defined(OS_CODE)
+ #  define OS_CODE  0x000
+ #endif
+ #ifndef OS_CODE
+ #  define OS_CODE  0x300  /* assume Unix */
+ #  ifndef UNIX
+ #    define UNIX
+ #  endif
+ #endif
+ 
+ 
  /* end of tailor.h */
Only in .: tops20
diff -c ../zip19i/trees.c ./trees.c
*** ../zip19i/trees.c	Tue Nov  3 21:07:56 1992
--- ./trees.c	Tue Aug 31 22:08:36 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 463,477 ****
  {
      int v = heap[k];
      int j = k << 1;  /* left son of k */
      while (j <= heap_len) {
          /* Set j to the smallest of the two sons: */
          if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++;
  
          /* Exit if v is smaller than both sons */
!         if (smaller(tree, v, heap[j])) break;
  
          /* Exchange v with the smallest son */
!         heap[k] = heap[j],  k = j;
  
          /* And continue down the tree, setting j to the left son of k */
          j <<= 1;
--- 462,480 ----
  {
      int v = heap[k];
      int j = k << 1;  /* left son of k */
+     int htemp;       /* required because of bug in SASC compiler */
+ 
      while (j <= heap_len) {
          /* Set j to the smallest of the two sons: */
          if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++;
  
          /* Exit if v is smaller than both sons */
!         htemp = heap[j];
!         if (smaller(tree, v, htemp)) break;
  
          /* Exchange v with the smallest son */
!         heap[k] = htemp;
!         k = j;
  
          /* And continue down the tree, setting j to the left son of k */
          j <<= 1;
***************
*** 838,844 ****
      Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
              "too many codes");
      Tracev((stderr, "\nbl counts: "));
!     send_bits(lcodes-257, 5); /* not +255 as stated in appnote.txt */
      send_bits(dcodes-1,   5);
      send_bits(blcodes-4,  4); /* not -3 as stated in appnote.txt */
      for (rank = 0; rank < blcodes; rank++) {
--- 841,848 ----
      Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
              "too many codes");
      Tracev((stderr, "\nbl counts: "));
!     send_bits(lcodes-257, 5);
!     /* not +255 as stated in appnote.txt 1.93a or -256 in 2.04c */
      send_bits(dcodes-1,   5);
      send_bits(blcodes-4,  4); /* not -3 as stated in appnote.txt */
      for (rank = 0; rank < blcodes; rank++) {
***************
*** 898,903 ****
--- 902,908 ----
  
      if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
  
+ #ifndef PGP /* PGP can't handle stored blocks */
      /* If compression failed and this is the first and last block,
       * and if the zip file can be seeked (to rewrite the local header),
       * the whole file is transformed into a stored file:
***************
*** 913,923 ****
          copy_block(buf, (unsigned)stored_len, 0); /* without header */
          compressed_len = stored_len << 3;
          *file_method = STORE;
  
  #ifdef FORCE_METHOD
!     } else if (level == 2 && buf != NULL) { /* force stored block */
  #else
!     } else if (stored_len+4 <= opt_lenb && buf != NULL) {
                         /* 4: two words for the lengths */
  #endif
          /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
--- 918,930 ----
          copy_block(buf, (unsigned)stored_len, 0); /* without header */
          compressed_len = stored_len << 3;
          *file_method = STORE;
+     } else
+ #endif /* PGP */
  
  #ifdef FORCE_METHOD
!     if (level == 2 && buf != (char*)NULL) { /* force stored block */
  #else
!     if (stored_len+4 <= opt_lenb && buf != (char*)NULL) {
                         /* 4: two words for the lengths */
  #endif
          /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
***************
*** 950,956 ****
--- 957,973 ----
      init_block();
  
      if (eof) {
+ #if defined(PGP) && !defined(MMAP)
+         /* Wipe out sensitive data for pgp */
+ # ifdef DYN_ALLOC
+         extern uch *window;
+ # else
+         extern uch window[];
+ # endif
+         memset(window, 0, (unsigned)(2*WSIZE-1)); /* -1 needed if WSIZE=32K */
+ #else /* !PGP */
          Assert (input_len == isize, "bad input size");
+ #endif
          bi_windup();
          compressed_len += 7;  /* align on byte boundary */
      }
***************
*** 1078,1084 ****
--- 1095,1103 ----
      while (n < 128)    ascii_freq += dyn_ltree[n++].Freq;
      while (n < LITERALS) bin_freq += dyn_ltree[n++].Freq;
      *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII;
+ #ifndef PGP
      if (*file_type == BINARY && translate_eol) {
          warn("-l used on binary file", "");
      }
+ #endif
  }
diff -c ../zip19i/util.c ./util.c
*** ../zip19i/util.c	Tue Nov  3 21:07:56 1992
--- ./util.c	Mon Sep  6 22:31:08 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 27,33 ****
  #ifndef UTIL /* UTIL picks out namecmp code (all utils) */
  
  /* Local functions */
! local int recmatch OF((char *, char *));
  
  #if (defined(MSDOS) && !defined(OS2) && !defined(__GO32__) && !defined(WIN32))
    local unsigned ident OF((unsigned chr));
--- 26,32 ----
  #ifndef UTIL /* UTIL picks out namecmp code (all utils) */
  
  /* Local functions */
! local int recmatch OF((uch *, uch *));
  
  #if (defined(MSDOS) && !defined(OS2) && !defined(__GO32__) && !defined(WIN32))
    local unsigned ident OF((unsigned chr));
***************
*** 52,65 ****
  
  
  local int recmatch(p, s)
! char *p;                /* sh pattern to match */
! char *s;                /* string to match it to */
  /* Recursively compare the sh pattern p with the string s and return 1 if
     they match, and 0 or 2 if they don't or if there is a syntax error in the
     pattern.  This routine recurses on itself no deeper than the number of
     characters in the pattern. */
  {
!   int c;                /* pattern char or start of range in [-] loop */ 
  
    /* Get first character, the pattern for new recmatch calls follows */
    c = *p++;
--- 51,64 ----
  
  
  local int recmatch(p, s)
! uch *p;       /* sh pattern to match */
! uch *s;       /* string to match it to */
  /* Recursively compare the sh pattern p with the string s and return 1 if
     they match, and 0 or 2 if they don't or if there is a syntax error in the
     pattern.  This routine recurses on itself no deeper than the number of
     characters in the pattern. */
  {
!   unsigned int c;       /* pattern char or start of range in [-] loop */ 
  
    /* Get first character, the pattern for new recmatch calls follows */
    c = *p++;
***************
*** 77,82 ****
--- 76,85 ----
      return *s ? recmatch(p, s + 1) : 0;
  
    /* '*' matches any number of characters, including zero */
+ #ifdef AMIGA
+   if (c == '#' && *p == '?')            /* "#?" is Amiga-ese for "*" */
+     c = '*', p++;
+ #endif /* AMIGA */
    if (c == '*')
    {
      if (*p == 0)
***************
*** 92,103 ****
    if (c == '[')
    {
      int e;              /* flag true if next char to be taken literally */
!     char *q;            /* pointer to end of [-] group */
      int r;              /* flag true to match anything but the range */
  
      if (*s == 0)                        /* need a character to match */
        return 0;
!     p += (r = *p == '!');               /* see if reverse */
      for (q = p, e = 0; *q; q++)         /* find closing bracket */
        if (e)
          e = 0;
--- 95,106 ----
    if (c == '[')
    {
      int e;              /* flag true if next char to be taken literally */
!     uch *q;   /* pointer to end of [-] group */
      int r;              /* flag true to match anything but the range */
  
      if (*s == 0)                        /* need a character to match */
        return 0;
!     p += (r = (*p == '!' || *p == '^')); /* see if reverse */
      for (q = p, e = 0; *q; q++)         /* find closing bracket */
        if (e)
          e = 0;
***************
*** 116,124 ****
          c = *(p-1);
        else
        {
          if (*(p+1) != '-')
            for (c = c ? c : *p; c <= *p; c++)    /* compare range */
!             if (case_map(c) == case_map(*s))
                return r ? 0 : recmatch(q + 1, s + 1);
          c = e = 0;                      /* clear range, escape flags */
        }
--- 119,128 ----
          c = *(p-1);
        else
        {
+         unsigned int cc = case_map(*s);
          if (*(p+1) != '-')
            for (c = c ? c : *p; c <= *p; c++)    /* compare range */
!             if (case_map(c) == cc)
                return r ? 0 : recmatch(q + 1, s + 1);
          c = e = 0;                      /* clear range, escape flags */
        }
***************
*** 143,153 ****
  /* Compare the sh pattern p with the string s and return true if they match,
     false if they don't or if there is a syntax error in the pattern. */
  {
!   return recmatch(p, s) == 1;
  }
  
  
! #ifdef MSDOS
  
  int dosmatch(p, s)
  char *p;                /* dos pattern to match */
--- 147,157 ----
  /* Compare the sh pattern p with the string s and return true if they match,
     false if they don't or if there is a syntax error in the pattern. */
  {
!   return recmatch((uch *) p, (uch *) s) == 1;
  }
  
  
! #if defined(MSDOS) && !defined(WIN32)
  
  int dosmatch(p, s)
  char *p;                /* dos pattern to match */
***************
*** 187,193 ****
  voidp *b;               /* pointer to value to search for */
  voidp far **a;          /* table of pointers to values, sorted */
  extent n;               /* number of pointers in a[] */
! int (*cmp) OF((voidp *, voidp far *));  /* comparison function for search */
  /* Search for b in the pointer list a[0..n-1] using the compare function
     cmp(b, c) where c is an element of a[i] and cmp() returns negative if
     *b < *c, zero if *b == *c, or positive if *b > *c.  If *b is found,
--- 191,198 ----
  voidp *b;               /* pointer to value to search for */
  voidp far **a;          /* table of pointers to values, sorted */
  extent n;               /* number of pointers in a[] */
! int (*cmp) OF((const voidp *, const voidp far *)); /* comparison function */
! 
  /* Search for b in the pointer list a[0..n-1] using the compare function
     cmp(b, c) where c is an element of a[i] and cmp() returns negative if
     *b < *c, zero if *b == *c, or positive if *b > *c.  If *b is found,
***************
*** 368,375 ****
  
    for (;;)
    {
!     d = (int) (unsigned char) case_map(*string1)
!       - (int) (unsigned char) case_map(*string2);
      
      if (d || *string1 == 0 || *string2 == 0)
        return d;
--- 373,380 ----
  
    for (;;)
    {
!     d = (int) (uch) case_map(*string1)
!       - (int) (uch) case_map(*string2);
      
      if (d || *string1 == 0 || *string2 == 0)
        return d;
Only in .: vms
diff -c ../zip19i/zip.1 ./zip.1
*** ../zip19i/zip.1	Tue Nov  3 21:07:56 1992
--- ./zip.1	Mon Sep  6 03:41:42 1993
***************
*** 1,24 ****
! .\" Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
! .\" Kai Uwe Rommel and Igor Mandrichenko.
  .\" Permission is granted to any individual or institution to use, copy, or
! .\" redistribute this software so long as all of the original files are included
! .\" unmodified, that it is not sold for profit, and that this copyright notice
  .\" is retained.
  .\" zip.1 by Mark Adler, Jean-loup Gailly and  R. P. C. Rodgers
  .\"
! .TH ZIP 1L "17 October 1992"
  .SH NAME
  zip, zipcloak, zipnote, zipsplit \- package and compress (archive) files
  .SH SYNOPSIS
  .B zip
! .RB [ \-cdeEfghijklLmoqrTuwyz@ ]
  .RB [ \-b\ path ]
  .RB [ \-n\ suffixes ]
  .RB [ \-t\ mmddyy ]
- .RB [ \-x\ list ]
  .I [ zipfile
  .I [ file1
  .IR file2 " .\|.\|." ]]
  .PP
  .B zipcloak
  .RB [ \-dhL ]
--- 1,24 ----
! .\" Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
! .\" Kai Uwe Rommel, Igor Mandrichenko and John Bush.
  .\" Permission is granted to any individual or institution to use, copy, or
! .\" redistribute this software so long as all of the original files are
! .\" included, that it is not sold for profit, and that this copyright notice
  .\" is retained.
  .\" zip.1 by Mark Adler, Jean-loup Gailly and  R. P. C. Rodgers
  .\"
! .TH ZIP 1L "2 Sept 1993"
  .SH NAME
  zip, zipcloak, zipnote, zipsplit \- package and compress (archive) files
  .SH SYNOPSIS
  .B zip
! .RB [ \-cdDeEfFghjklLmoqrSTuvVwyz@$ ]
  .RB [ \-b\ path ]
  .RB [ \-n\ suffixes ]
  .RB [ \-t\ mmddyy ]
  .I [ zipfile
  .I [ file1
  .IR file2 " .\|.\|." ]]
+ .RB [ \-xi\ list ]
  .PP
  .B zipcloak
  .RB [ \-dhL ]
***************
*** 57,69 ****
  and PKZIP and PKUNZIP can work with archives produced by
  .IR zip .
  .I zip
! version 1.9 is compatible with PKZIP 1.93a.
! Note that PKUNZIP 1.10 cannot extract files produced by PKZIP 1.93a
  or
  .I zip
! 1.9. You must use PKUNZIP 1.93a or
  .I unzip
! 5.0 (or later versions) to extract them.
  .PP
  For a brief help on
  .I zip
--- 57,69 ----
  and PKZIP and PKUNZIP can work with archives produced by
  .IR zip .
  .I zip
! version 2.0 is compatible with PKZIP 2.04
! Note that PKUNZIP 1.10 cannot extract files produced by PKZIP 2.04
  or
  .I zip
! 2.0. You must use PKUNZIP 2.04g or
  .I unzip
! 5.0p1 (or later versions) to extract them.
  .PP
  For a brief help on
  .I zip
***************
*** 194,199 ****
--- 194,203 ----
  .I funzip
  which is provided in the
  .I unzip
+ package, or by
+ .I gunzip
+ which is provided in the
+ .I gzip
  package. For example:
  .LP
  \fPdd if=/dev/nrst0  ibs=16k | funzip | tar xvf -\fC
***************
*** 205,210 ****
--- 209,222 ----
  will write a temporary file with the new contents,
  and only replace the old one when the process of creating the new version
  has been completed without error.
+ .LP
+ If the name of the
+ .I zip
+ archive does not contain an extension, the extension
+ .IR .zip
+ is added. If the name already contains an extension other than
+ .IR .zip
+ the existing extension is kept unchanged.
  .SH "OPTIONS"
  .TP
  .BI \-b\ path
***************
*** 270,275 ****
--- 282,311 ----
  This requires that file names be entered in upper case if they were
  zipped by PKZIP on an MSDOS system.
  .TP
+ .B \-D
+ Do not create entries in the
+ .I zip
+ archive for directories.  Directory entries are created by default so that
+ their attributes can be saved in the zip archive.
+ The environment variable ZIPOPT can be used to change the default options. For
+ example under Unix with sh:
+ .RS
+ .IP
+ ZIPOPT="-D"; export ZIPOPT
+ .RE
+ .IP
+ (The variable ZIPOPT can be used for any option except
+ .B \-i
+ and
+ .B \-x
+ and can include several options.) The option
+ .B \-D
+ is a shorthand
+ for
+ .B \-x
+ "*/" but the latter cannot be set as default in the ZIPOPT environment
+ variable.
+ .TP
  .B \-e
  Encrypt the contents of the
  .I zip
***************
*** 309,314 ****
--- 345,377 ----
  .I zip
  archives are always relative.
  .TP
+ .B \-F
+ Fix the
+ .I zip
+ archive. This option can be used if some portions of the archive
+ are missing. It is not guaranteed to work, so you MUST make a backup
+ of the original archive first.
+ .IP
+ When doubled as in
+ .B \-FF
+ the compressed sizes given inside the damaged archive are not trusted
+ and zip scans for special signatures to identify the limits between
+ the archive members. The single
+ .B \-F
+ is more reliable if the archive is not too much damaged, for example
+ if it has only been truncated, so try this option first.
+ .IP
+ Neither option will recover archives that have been incorrectly
+ transferred in ascii mode instead of binary. After the repair, the
+ .B \-t
+ option of
+ .I unzip
+ may show that some files have a bad CRC. Such files cannot be recovered;
+ you can remove them from the archive using the
+ .B \-d
+ option of
+ .I zip.
+ .TP
  .B \-g
  Grow (append to) the specified
  .I zip
***************
*** 324,331 ****
  .I zip
  is run with no arguments).
  .TP
  .B \-j
! Store just the name of a saved file (junk the path). By default,
  .I zip
  will store the full path (relative to the current path).
  .TP
--- 387,417 ----
  .I zip
  is run with no arguments).
  .TP
+ .BI \-i\ files
+ Include only the specified files, as in:
+ .RS
+ .IP
+ \fCzip -r foo . -i \\*.c\fP
+ .RE
+ .IP
+ which will include only the files that end in
+ .IR \& .c
+ in the current directory and its subdirectories. (Note for PKZIP
+ users: the equivalent command is
+ .RS
+ .IP
+ \fCpkzip -r foo *.c\fP
+ .RE
+ .IP
+ PKZIP does not allow recursion in directories other than the current one.)
+ The backslash avoids the shell filename substitution, so that the
+ name matching is performed by
+ .I zip
+ at all directory levels.
+ .TP
  .B \-j
! Store just the name of a saved file (junk the path), and do not store
! directory names. By default,
  .I zip
  will store the full path (relative to the current path).
  .TP
***************
*** 333,339 ****
  Attempt to convert the names and paths to conform to MSDOS,
  store only the MSDOS attribute (just the user write attribute from UNIX),
  and mark the entry as made under MSDOS (even though it was not);
! for compatibility with PKUNZIP under MSDOS.
  .TP
  .B \-l
  Translate the Unix end-of-line character LF into the
--- 419,426 ----
  Attempt to convert the names and paths to conform to MSDOS,
  store only the MSDOS attribute (just the user write attribute from UNIX),
  and mark the entry as made under MSDOS (even though it was not);
! for compatibility with PKUNZIP under MSDOS which cannot handle certain
! names such as those with two dots.
  .TP
  .B \-l
  Translate the Unix end-of-line character LF into the
***************
*** 368,374 ****
  .I zip
  has created the archive without error.
  This is useful for conserving disk space,
! but is potentially dangerous and should be used with care.
  .TP
  .BI \-n\ suffixes
  Do not attempt to compress files named with the given
--- 455,464 ----
  .I zip
  has created the archive without error.
  This is useful for conserving disk space,
! but is potentially dangerous so it is recommended to use it in
! combination with
! .B \-T
! to test the archive before removing all input files.
  .TP
  .BI \-n\ suffixes
  Do not attempt to compress files named with the given
***************
*** 379,385 ****
  doesn't waste its time trying to compress them.
  The suffixes are separated by
  either colons or semicolons.  For example:
- For example,
  .RS
  .IP
  \fCzip -rn .Z:.zip:.tiff:.gif:.snd  foo foo\fP
--- 469,474 ----
***************
*** 410,417 ****
  setenv ZIPOPT "-n .gif:.zip"
  .RE
  .IP
- (The variable ZIPOPT can be used for any option and can include several
- options.)
  To attempt compression on all files, use:
  .RS
  .IP
--- 499,504 ----
***************
*** 442,448 ****
  .B \-q
  Quiet mode;
  eliminate informational messages and comment prompts.
! (useful, for example, in shell scripts and background tasks).
  .TP
  .B \-r
  Travel the directory structure recursively;
--- 529,535 ----
  .B \-q
  Quiet mode;
  eliminate informational messages and comment prompts.
! (Useful, for example, in shell scripts and background tasks).
  .TP
  .B \-r
  Travel the directory structure recursively;
***************
*** 458,465 ****
  .I zip
  archive named
  .IR foo.zip ,
! including files with named starting with ".",
  since the recursion does not use the shell's file-name substitution mechanism.
  You should not use
  .B \-r
  with the name ".*",
--- 545,557 ----
  .I zip
  archive named
  .IR foo.zip ,
! including files with names starting with ".",
  since the recursion does not use the shell's file-name substitution mechanism.
+ If you wish to include only a specific subset of the files in directory
+ .I foo
+ and its subdirectories, use the
+ .B \-i
+ option to the specify the pattern of files to be included.
  You should not use
  .B \-r
  with the name ".*",
***************
*** 467,472 ****
--- 559,568 ----
  which will attempt to zip up the parent directory
  (probably not what was intended).
  .TP
+ .B \-S
+ Include system and hidden files. This option is
+ effective on some systems only; it is ignored on Unix.
+ .TP
  .BI \-t\ mmddyy
  Do not operate on files modified prior to the specified date,
  where
***************
*** 527,532 ****
--- 623,637 ----
  .B \-f
  (freshen) option.
  .TP
+ .B \-v
+ Verbose mode. Display a progress indicator during compression.
+ .TP
+ .B \-V
+ Save VMS file attributes. This option is available on VMS only;
+ .I zip
+ archives created with this option will generally not be usable
+ on other systems.
+ .TP
  .B \-w
  Append the version number of the files to the name,
  including multiple versions of files.
***************
*** 546,556 ****
  .I foo.zip
  while excluding all the files that end in
  .IR \& .o .
! The backslash causes
  .I zip
! to match file names that were found when
! .I foo
! was searched.
  .TP
  .B \-y
  Store symbolic links as such in the
--- 651,660 ----
  .I foo.zip
  while excluding all the files that end in
  .IR \& .o .
! The backslash avoids the shell filename substitution, so that the
! name matching is performed by
  .I zip
! at all directory levels.
  .TP
  .B \-y
  Store symbolic links as such in the
***************
*** 583,592 ****
  .B \-9
  indicates the slowest compression method (optimal compression, ignores
  the suffix list). The default compression level is
! .BR \-5.
  .TP
  .B \-@
  Take the list of input files from standard input.
  .SH "EXAMPLES"
  The simplest example:
  .IP
--- 687,708 ----
  .B \-9
  indicates the slowest compression method (optimal compression, ignores
  the suffix list). The default compression level is
! .BR \-6.
  .TP
  .B \-@
  Take the list of input files from standard input.
+ .TP
+ .B \-$
+ Include the volume label for the the drive holding the first file to be
+ compressed.  If you want to include only the volume label or to force a
+ specific drive, use the drive name as first file name, as in:
+ .RS
+ .IP
+ \fCzip -$ foo a: c:bar\fP
+ .RE
+ .IP
+ This option is effective on some systems only (MSDOS and OS/2); it is
+ ignored on Unix.
  .SH "EXAMPLES"
  The simplest example:
  .IP
***************
*** 700,708 ****
  archive being modified or,
  in the case of the
  .B \-x
! (exclude) option,
! on the list of files to be operated on,
! by using backslashes or quotes to tell the shell not to do the name expansion.
  In general, when
  .I zip
  encounters a name in the list of files to do, it first looks for the name in
--- 816,825 ----
  archive being modified or,
  in the case of the
  .B \-x
! (exclude) or
! .B \-i
! (include) options, on the list of files to be operated on, by using
! backslashes or quotes to tell the shell not to do the name expansion.
  In general, when
  .I zip
  encounters a name in the list of files to do, it first looks for the name in
***************
*** 711,719 ****
  .I zip
  archive being modified (if it exists), using the pattern matching characters
  described above, if present.  For each match, it will add that name to the
! list of files to be processed.  File names following the
  .B \-x
! (exclude) option are removed from the processing list instead of being added.
  .LP
  The pattern matching includes the path,
  and so patterns like \\*.o match names that end in ".o",
--- 828,839 ----
  .I zip
  archive being modified (if it exists), using the pattern matching characters
  described above, if present.  For each match, it will add that name to the
! list of files to be processed, unless this name matches one given
! with the
  .B \-x
! option, or does not match any name given with the
! .B \-i
! option.
  .LP
  The pattern matching includes the path,
  and so patterns like \\*.o match names that end in ".o",
***************
*** 735,753 ****
  .BR \-f ,
  or
  .BR \-d ).
- The
- .I zip
- program will never use pattern matching to search the file system.
- If it has recursively travelled a directory,
- all files (and all directories) found there are fair game.
  .SH "SEE ALSO"
  compress(1),
  shar(1L),
  tar(1),
! unzip(1L)
  .SH BUGS
  .I zip
! 1.9 is not compatible with PKUNZIP 1.10. Use
  .I zip
  1.1 to produce
  .I zip
--- 855,869 ----
  .BR \-f ,
  or
  .BR \-d ).
  .SH "SEE ALSO"
  compress(1),
  shar(1L),
  tar(1),
! unzip(1L),
! gzip(1L)
  .SH BUGS
  .I zip
! 2.0 is not compatible with PKUNZIP 1.10. Use
  .I zip
  1.1 to produce
  .I zip
***************
*** 756,766 ****
  .I zip
  files produced by
  .I zip
! 1.9 must not be
  .I updated
  by
  .I zip
! 1.1 or PKZIP 1.10 or PKZIP 1.93a, if they contain
  encrypted members, or if they have been produced in a pipe or on a non
  seekable device. The old versions of
  .I zip
--- 872,882 ----
  .I zip
  files produced by
  .I zip
! 2.0 must not be
  .I updated
  by
  .I zip
! 1.1 or PKZIP 1.10, if they contain
  encrypted members, or if they have been produced in a pipe or on a non
  seekable device. The old versions of
  .I zip
***************
*** 770,792 ****
  If you do not use encryption and use regular disk files, you do
  not have to care about this problem.
  .LP
- .I zip
- 1.9 is compatible with PKZIP 1.93a, except when two features
- are used: encryption or
- .I zip
- file created in a pipe or on a non
- seekable device. PKZIP versions above 2.0 will support such files, and
- .I unzip
- 5.0 already supports them.
- .LP
- Without
- .B \-y
- when
- .I zip
- must compress a symbolic link to an non existing file,
- it only displays a warning "name not matched". A better warning should be
- given.
- .LP
  Under VMS,
  not all of the odd file formats are treated properly.
  Only stream-LF format
--- 886,891 ----
***************
*** 805,810 ****
--- 904,914 ----
  Under VMS, zip hangs for file specification that uses DECnet syntax
  .I foo::*.*.
  .LP
+ On OS/2, zip cannot match some names, such as those including an
+ exclamation mark or a hash sign.  This is a bug in OS/2 itself: the
+ 32-bit DosFindFirst/Next don't find such names.  Other programs such
+ as GNU tar are also affected by this bug.
+ .LP
  Under OS/2, the amount of External Attributes displayed by DIR is (for
  compatibility) the amount returned by the 16-bit version of
  DosQueryPathInfo(). Otherwise OS/2 1.3 and 2.0 would report different
***************
*** 820,830 ****
  MS-C-compiled version running on OS/2 1.3, so even this one shows the
  32-bit-mode size.
  .SH AUTHORS
! Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
! Kai Uwe Rommel and Igor Mandrichenko.
  Permission is granted to any individual or institution to use, copy, or
! redistribute this software so long as all of the original files are included
! unmodified, that it is not sold for profit, and that this copyright notice
  is retained.
  .LP
  LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE
--- 924,934 ----
  MS-C-compiled version running on OS/2 1.3, so even this one shows the
  32-bit-mode size.
  .SH AUTHORS
! Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
! Kai Uwe Rommel, Igor Mandrichenko and John Bush.
  Permission is granted to any individual or institution to use, copy, or
! redistribute this software so long as all of the original files are included,
! that it is not sold for profit, and that this copyright notice
  is retained.
  .LP
  LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE
***************
*** 832,838 ****
  IMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
  RESULTING FROM THE USE OF THIS SOFTWARE.
  .LP
! Please send bug reports and comments to:
  .IR zip\-bugs@wkuvx1.bitnet.
  For bug reports, please include the version of
  .IR zip ,
--- 936,942 ----
  IMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
  RESULTING FROM THE USE OF THIS SOFTWARE.
  .LP
! Please send bug reports and comments by email to:
  .IR zip\-bugs@wkuvx1.bitnet.
  For bug reports, please include the version of
  .IR zip ,
***************
*** 846,862 ****
  and from which the shrink algorithm was stolen;
  to Phil Katz for placing in the public domain the
  .I zip
! file format,
! compression format,
! and .ZIP filename extension, and for accepting minor changes
! to the file format;
! to Steve Burg for clarifications on the deflate format; to Keith Petersen,
! Rich Wales and Hunter Goatley for providing a mailing list and
  .I ftp
! site for the INFO-ZIP group to use;
! and most importantly,
! to the INFO-ZIP group itself
! (listed in the file
  .IR infozip.who )
  without whose tireless testing and bug-fixing efforts a portable
  .I zip
--- 950,964 ----
  and from which the shrink algorithm was stolen;
  to Phil Katz for placing in the public domain the
  .I zip
! file format, compression format, and .ZIP filename extension, and for
! accepting minor changes to the file format; to Steve Burg for
! clarifications on the deflate format; to Haruhiko Okumura and Leonid
! Broukhis for providing some useful ideas for the compression
! algorithm; to Keith Petersen, Rich Wales, Hunter Goatley and Mark
! Adler for providing a mailing list and
  .I ftp
! site for the INFO-ZIP group to use; and most importantly, to the
! INFO-ZIP group itself (listed in the file
  .IR infozip.who )
  without whose tireless testing and bug-fixing efforts a portable
  .I zip
diff -c ../zip19i/zip.c ./zip.c
*** ../zip19i/zip.c	Tue Nov  3 21:07:56 1992
--- ./zip.c	Fri Sep 10 03:16:44 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 19,25 ****
  #ifdef VMS
  #  include "VMSmunch.h"
  #endif
! #if defined(MSDOS) && !defined(__GO32__)
  #  include <process.h>
  #endif
  #include <signal.h>
--- 18,24 ----
  #ifdef VMS
  #  include "VMSmunch.h"
  #endif
! #if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
  #  include <process.h>
  #endif
  #include <signal.h>
***************
*** 39,54 ****
  local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
  local int comadd = 0;   /* 1=add comments for new files */
  local int zipedit = 0;  /* 1=edit zip comment and all file comments */
- local int dispose = 0;  /* 1=remove files after put in zip file */
  local int latest = 0;   /* 1=set zip file time to time of latest file */
  local ulg before = 0;   /* 0=ignore, else exclude files before this time */
  local int test = 0;     /* 1=test zip file with unzip -t */
  
  /* Temporary zip file name and file pointer */
  local char *tempzip;
  local FILE *tempzf;
  
- 
  /* Local functions */
  
  local void freeup  OF((void));
--- 38,52 ----
  local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
  local int comadd = 0;   /* 1=add comments for new files */
  local int zipedit = 0;  /* 1=edit zip comment and all file comments */
  local int latest = 0;   /* 1=set zip file time to time of latest file */
  local ulg before = 0;   /* 0=ignore, else exclude files before this time */
  local int test = 0;     /* 1=test zip file with unzip -t */
+ local int tempdir = 0;  /* 1=use temp directory (-b) */
  
  /* Temporary zip file name and file pointer */
  local char *tempzip;
  local FILE *tempzf;
  
  /* Local functions */
  
  local void freeup  OF((void));
***************
*** 58,64 ****
  local void help    OF((void));
  local void zipstdout OF((void));
  local void check_zipfile OF((char *zipname));
!       void  main     OF((int, char **));
  local int count_args OF((char *s));
  local void envargs   OF((int *Pargc, char ***Pargv, char *envstr));
  
--- 56,63 ----
  local void help    OF((void));
  local void zipstdout OF((void));
  local void check_zipfile OF((char *zipname));
! local void get_filters OF((int argc, char **argv));
!       int  main     OF((int, char **));
  local int count_args OF((char *s));
  local void envargs   OF((int *Pargc, char ***Pargv, char *envstr));
  
***************
*** 101,120 ****
    struct zlist far *z;  /* pointer into zfile list */
  
    /* If latest, set time to zip file to latest file in zip file */
!   if (latest && strcmp(zipfile, "-"))
    {
      diag("changing time of zip file to time of latest file in it");
      /* find latest time in zip file */
      if (zfiles == NULL)
         warn("zip file is empty, can't make it as old as latest entry", "");
      else {
!       t = zfiles->tim;
!       for (z = zfiles->nxt; z != NULL; z = z->nxt)
          /* Ignore directories in time comparisons */
          if (t < z->tim && z->zname[z->nam-1] != '/')
            t = z->tim;
        /* set modified time of zip file to that time */
!       stamp(zipfile, t);
      }
    }
    if (tempath != NULL)
--- 100,124 ----
    struct zlist far *z;  /* pointer into zfile list */
  
    /* If latest, set time to zip file to latest file in zip file */
!   if (latest && zipfile && strcmp(zipfile, "-"))
    {
      diag("changing time of zip file to time of latest file in it");
      /* find latest time in zip file */
      if (zfiles == NULL)
         warn("zip file is empty, can't make it as old as latest entry", "");
      else {
!       t = 0;
!       for (z = zfiles; z != NULL; z = z->nxt)
          /* Ignore directories in time comparisons */
          if (t < z->tim && z->zname[z->nam-1] != '/')
            t = z->tim;
        /* set modified time of zip file to that time */
!       if (t != 0)
!         stamp(zipfile, t);
!       else
!         warn(
!          "zip file has only directories, can't make it as old as latest entry",
!          "");
      }
    }
    if (tempath != NULL)
***************
*** 156,164 ****
    static int error_level;
    if (error_level++ > 0) exit(0);  /* avoid recursive err() */
  
!   if (PERR(c))
!     perror("zip error");
!   fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
    if (tempzip != NULL)
    {
      if (tempzip != zipfile) {
--- 160,171 ----
    static int error_level;
    if (error_level++ > 0) exit(0);  /* avoid recursive err() */
  
!   if (h != NULL) {
!     if (PERR(c))
!       perror("zip error");
!     fflush(mesg);
!     fprintf(stderr, "\nzip error: %s (%s)\n", errors[c-1], h);
!   }
    if (tempzip != NULL)
    {
      if (tempzip != zipfile) {
***************
*** 215,221 ****
  /* Upon getting a user interrupt, turn echo back on for tty and abort
     cleanly using err(). */
  {
! #ifndef MSDOS
    echon();
    putc('\n', stderr);
  #endif /* !MSDOS */
--- 222,228 ----
  /* Upon getting a user interrupt, turn echo back on for tty and abort
     cleanly using err(). */
  {
! #if !defined(MSDOS) && !defined(__human68k__)
    echon();
    putc('\n', stderr);
  #endif /* !MSDOS */
***************
*** 228,234 ****
  char *a, *b;            /* message strings juxtaposed in output */
  /* Print a warning message to stderr and return. */
  {
!   fprintf(stderr, "zip warning: %s%s\n", a, b);
  }
  
  
--- 235,241 ----
  char *a, *b;            /* message strings juxtaposed in output */
  /* Print a warning message to stderr and return. */
  {
!   if (noisy) fprintf(stderr, "zip warning: %s%s\n", a, b);
  }
  
  
***************
*** 255,287 ****
    static char *text[] = {
  "",
  "Zip %s (%s). Usage:",
! "zip [-options] [-b path] [-t mmddyy] [-n suffixes] [zipfile list] [-x list]",
  "  The default action is to add or replace zipfile entries from list, which",
  "  can include the special name - to compress standard input.",
  "  If zipfile and list are omitted, zip compresses stdin to stdout.",
  "  -f   freshen: only changed files  -u   update: only changed or new files",
  "  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
  "  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
- #ifdef VMS
- "  -h   show this help              \"-L\"  show software license",
- #else
- "  -h   show this help               -L   show software license",
- #endif
  "  -r   recurse into directories     -j   junk (don't record) directory names",
  "  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)",
  "  -1   compress faster              -9   compress better",
! "  -q   quiet operation              -n   don't compress these suffixes",
  "  -c   add one-line comments        -z   add zipfile comment",
! "  -b   use \"path\" for temp files    -t   only do files after \"mmddyy\"",
  "  -@   read names from stdin        -o   make zipfile as old as latest entry",
! #ifdef CRYPT
! "  -e   encrypt  (-ee verify key)    -T   test zipfile integrity",
! #else
! "  -T   test zipfile integrity",
! #endif
  #ifdef VMS
  "  -w   append the VMS version number to the name stored in the zip file",
  " \"-V\"  save VMS file attributes",
  #endif /* VMS */
  #ifdef OS2
  "  -E   use the .LONGNAME Extended attribute (if found) as filename",
--- 262,290 ----
    static char *text[] = {
  "",
  "Zip %s (%s). Usage:",
! "zip [-options] [-b path] [-t mmddyy] [-n suffixes] [zipfile list] [-xi list]",
  "  The default action is to add or replace zipfile entries from list, which",
  "  can include the special name - to compress standard input.",
  "  If zipfile and list are omitted, zip compresses stdin to stdout.",
  "  -f   freshen: only changed files  -u   update: only changed or new files",
  "  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
  "  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
  "  -r   recurse into directories     -j   junk (don't record) directory names",
  "  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)",
  "  -1   compress faster              -9   compress better",
! "  -q   quiet operation              -v   verbose operation",
  "  -c   add one-line comments        -z   add zipfile comment",
! "  -b   use \"path\" for temp file     -t   only do files after \"mmddyy\"",
  "  -@   read names from stdin        -o   make zipfile as old as latest entry",
! "  -x   exclude the following names  -i   include only the following names",
  #ifdef VMS
+ " \"-F\"  fix zipfile(-FF try harder) \"-D\"  do not add directory entries",
+ " \"-T\"  test zipfile integrity      \"-L\"  show software license",
  "  -w   append the VMS version number to the name stored in the zip file",
  " \"-V\"  save VMS file attributes",
+ #else
+ "  -F   fix zipfile (-FF try harder) -D   do not add directory entries",
+ "  -T   test zipfile integrity       -L   show software license",
  #endif /* VMS */
  #ifdef OS2
  "  -E   use the .LONGNAME Extended attribute (if found) as filename",
***************
*** 289,295 ****
  #ifdef S_IFLNK
  "  -y   store symbolic links as the link instead of the referenced file",
  #endif /* !S_IFLNK */
! "  -x   exclude the names that follow from those operated on"
    };
  
    for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
--- 292,305 ----
  #ifdef S_IFLNK
  "  -y   store symbolic links as the link instead of the referenced file",
  #endif /* !S_IFLNK */
! #if defined(MSDOS) || defined(OS2)
! "  -$   include volume label         -S   include system and hidden files",
! #endif
! #ifdef CRYPT
! "  -e   encrypt  (-ee verify key)    -n   don't compress these suffixes"
! #else
! "  -h   show this help               -n   don't compress these suffixes"
! #endif
    };
  
    for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
***************
*** 305,312 ****
  }
  
  
! /* Do command line expansion for MSDOS and VMS */
! #if defined(MSVMS) && !defined(__GO32__)
  #  define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
  #else /* !MSVMS */
  #  define PROCNAME(n) procname(n)
--- 315,322 ----
  }
  
  
! /* Do command line expansion for MSDOS, VMS, ATARI, and AMIGA but not OS/2 */
! #if defined(MSVMS) || defined(AMIGA)
  #  define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
  #else /* !MSVMS */
  #  define PROCNAME(n) procname(n)
***************
*** 331,339 ****
    char *zipname;
    /* Invoke unzip -t on the given zip file */
  {
! #if defined(MSDOS) && !defined(__GO32__)
     if (spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
! 	       zipname, NULL)) {
  #else
     char cmd[128];
     strcpy(cmd, "unzip -t ");
--- 341,349 ----
    char *zipname;
    /* Invoke unzip -t on the given zip file */
  {
! #if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
     if (spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
!                zipname, NULL)) {
  #else
     char cmd[128];
     strcpy(cmd, "unzip -t ");
***************
*** 346,359 ****
  # endif
  #endif
       fprintf(mesg, "test of %s FAILED\n", zipfile);
!      err(ZE_FORM, "original files unmodified");
     }
     if (noisy)
       fprintf(mesg, "test of %s OK\n", zipfile);
  }
  
  
! void main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Add, update, freshen, or delete zip entries in a zip file.  See the
--- 356,403 ----
  # endif
  #endif
       fprintf(mesg, "test of %s FAILED\n", zipfile);
!      err(ZE_TEST, "original files unmodified");
     }
     if (noisy)
       fprintf(mesg, "test of %s OK\n", zipfile);
  }
  
+ local void get_filters(argc, argv)
+   int argc;               /* number of tokens in command line */
+   char **argv;            /* command line tokens */
+ /* Counts number of -i or -x patterns, sets patterns and pcount */
+ {
+   int i;
+   int flag = 0;
+ 
+   pcount = 0;
+   for (i = 1; i < argc; i++) {
+     if (argv[i][0] == '-') {
+       if (strrchr(argv[i], 'i') != NULL) {
+         flag = 'i';
+       } else if (strrchr(argv[i], 'x') != NULL) {
+         flag = 'x';
+       } else {
+         flag = 0;
+       }
+     } else if (flag) {
+       if (patterns != NULL) {
+         patterns[pcount].zname = ex2in(argv[i], 0, (int *)NULL);
+         patterns[pcount].select = flag;
+         if (flag == 'i') icount++;
+       }
+       pcount++;
+     }
+   }
+   if (pcount == 0 || patterns != NULL) return;
+   patterns = (struct plist*) malloc(pcount * sizeof(struct plist));
+   if (patterns == NULL)
+     err(ZE_MEM, "was creating pattern list");
+   get_filters(argc, argv);
+ }
+ 
  
! int main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Add, update, freshen, or delete zip entries in a zip file.  See the
***************
*** 372,385 ****
--- 416,440 ----
    char *p;              /* steps through option arguments */
    char *pp;             /* temporary pointer */
    int r;                /* temporary variable */
+   int s;                /* flag to read names from stdin */
    ulg t;                /* file time, length of central directory */
    struct zlist far *v;  /* temporary variable */
    struct zlist far * far *w;    /* pointer to last link in zfiles list */
    FILE *x, *y;          /* input and output zip files */
    struct zlist far *z;  /* steps through zfiles linked list */
    char *zipbuf;         /* stdio buffer for the zip file */
+   FILE *comment_stream; /* set to stderr if anything is read from stdin */
+ 
+ #if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
+   {
+     extern void DebugMalloc(void);
+     atexit(DebugMalloc);
+   }
+ #endif
  
    mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
+   comment_stream = (FILE *)stdin;
+ 
    init_upper();           /* build case map table */
  
  #ifdef MACOS
***************
*** 399,406 ****
--- 454,467 ----
    tempzf = NULL;
    d = 0;                        /* disallow adding to a zip file */
    signal(SIGINT, handler);
+ #ifdef SIGTERM                  /* AMIGADOS and others have no SIGTERM */
    signal(SIGTERM, handler);
+ #endif
    k = 0;                        /* Next non-option argument type */
+   s = 0;                        /* set by -@ if -@ is early */
+ 
+   get_filters(argc, argv);      /* scan first the -x and -i patterns */
+ 
    for (i = 1; i < argc; i++)
    {
      if (argv[i][0] == '-')
***************
*** 415,420 ****
--- 476,482 ----
                          /* Set the compression efficacy */
                level = *p - '0';  break;
              case 'b':   /* Specify path for temporary file */
+               tempdir = 1;
                if (k != 0)
                  err(ZE_PARMS, "use -b before zip file name");
                else
***************
*** 427,432 ****
--- 489,496 ----
                  err(ZE_PARMS, "specify just one action");
                action = DELETE;
                break;
+             case 'D':   /* Do not add directory entries */
+               dirnames = 0; break;
              case 'e':   /* Encrypt */
  #ifndef CRYPT
                err(ZE_PARMS, "encryption not supported");
***************
*** 446,451 ****
--- 510,517 ----
                }
  #endif /* ?CRYPT */
                break;
+             case 'F':   /* fix the zip file */
+               fix++; latest = 1; break;
              case 'f':   /* Freshen zip file--overwrite only */
                if (action != ADD)
                  err(ZE_PARMS, "specify just one action");
***************
*** 478,483 ****
--- 544,552 ----
                noisy = 0;  break;
              case 'r':   /* Recurse into subdirectories */
                recurse = 1;  break;
+             case 'S':
+               hidden_files = 1;
+               break;
              case 't':   /* Exclude files earlier than specified date */
                if (before)
                  err(ZE_PARMS, "can only have one -t");
***************
*** 493,516 ****
                verbose++;
                break;
  #ifdef VMS
-             case 'w':   /* Append the VMS version number */
-               vmsver = 1;  break;
              case 'V':   /* Store in VMS format */
                vms_native = 1; break;
  #endif /* VMS */
              case 'x':   /* Exclude following files */
                if (k != 4 &&
                    (k != 3 || (action != UPDATE && action != FRESHEN)))
!                 err(ZE_PARMS, "nothing to exclude (-x) from");
!               if (k == 3)       /* must be -u or -f */
!                 for (z = zfiles; z != NULL; z = z->nxt)
!                   z->mark = 1;  /* mark all of them */
                k = 5;
-               if ((r = exclude()) != ZE_OK)
-                 if (r == ZE_PARMS)
-                   err(r, "cannot repeat names in zip file");
-                 else
-                   err(r, "was processing list of files");
                break;
  #ifdef S_IFLNK
              case 'y':   /* Store symbolic links as such */
--- 562,578 ----
                verbose++;
                break;
  #ifdef VMS
              case 'V':   /* Store in VMS format */
                vms_native = 1; break;
+             case 'w':   /* Append the VMS version number */
+               vmsver = 1;  break;
  #endif /* VMS */
+             case 'i':   /* Include only the following files */
              case 'x':   /* Exclude following files */
                if (k != 4 &&
                    (k != 3 || (action != UPDATE && action != FRESHEN)))
!                 err(ZE_PARMS, "nothing to select from");
                k = 5;
                break;
  #ifdef S_IFLNK
              case 'y':   /* Store symbolic links as such */
***************
*** 518,532 ****
  #endif /* S_IFLNK */
              case 'z':   /* Edit zip file comment */
                zipedit = 1;  break;
              case '@':   /* read file names from stdin */
!               while ((pp = getnam(errbuf)) != NULL)
!               {
!                 if ((r = PROCNAME(pp)) != ZE_OK)
!                   if (r == ZE_MISS)
!                     warn("name not matched: ", pp);
!                   else
!                     err(r, pp);
!               }
                break;
  #ifdef OS2
              case 'E':
--- 580,604 ----
  #endif /* S_IFLNK */
              case 'z':   /* Edit zip file comment */
                zipedit = 1;  break;
+ #if defined(MSDOS) || defined(OS2)
+             case '$':   /* Include volume label */
+               volume_label = 1; break;
+ #endif
              case '@':   /* read file names from stdin */
!               comment_stream = NULL;
!               if (k < 3)        /* zip file not read yet */
!                 s = 1;          /* defer -@ until after zipfile read */
!               else if (strcmp(zipfile, "-") == 0)
!                 err(ZE_PARMS, "can't use - and -@ together");
!               else              /* zip file read--do it now */
!                 while ((pp = getnam(errbuf)) != NULL)
!                 {
!                   if ((r = PROCNAME(pp)) != ZE_OK)
!                     if (r == ZE_MISS)
!                       warn("name not matched: ", pp);
!                     else
!                       err(r, pp);
!                 }
                break;
  #ifdef OS2
              case 'E':
***************
*** 546,551 ****
--- 618,625 ----
          case 0:
            zipstdout();
            k = 3;
+           if (s)
+             err(ZE_PARMS, "can't use - and -@ together");
            break;
          case 1:
            err(ZE_PARMS, "invalid path");
***************
*** 553,559 ****
          case 2:
            err(ZE_PARMS, "invalid time");
            break;
!         case 3:  case 4:  case 5:
            if ((r = PROCNAME(argv[i])) != ZE_OK)
              if (r == ZE_MISS)
                warn("name not matched: ", argv[i]);
--- 627,634 ----
          case 2:
            err(ZE_PARMS, "invalid time");
            break;
!         case 3:  case 4:
!           comment_stream = NULL;
            if ((r = PROCNAME(argv[i])) != ZE_OK)
              if (r == ZE_MISS)
                warn("name not matched: ", argv[i]);
***************
*** 566,573 ****
      {
        if (special == NULL)
          special = argv[i];
!       else
!         switch (k)
        {
          case 0:
            if ((zipfile = ziptyp(argv[i])) == NULL)
--- 641,649 ----
      {
        if (special == NULL)
          special = argv[i];
!       else if (k == 5)
!         break; /* -i and -x arguments already scanned */
!       else switch (k)
        {
          case 0:
            if ((zipfile = ziptyp(argv[i])) == NULL)
***************
*** 575,580 ****
--- 651,668 ----
            if ((r = readzipfile()) != ZE_OK)
              err(r, zipfile);
            k = 3;
+           if (s)
+           {
+             while ((pp = getnam(errbuf)) != NULL)
+             {
+               if ((r = PROCNAME(pp)) != ZE_OK)
+                 if (r == ZE_MISS)
+                   warn("name not matched: ", pp);
+                 else
+                   err(r, pp);
+             }
+             s = 0;
+           }
            break;
          case 1:
            if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL)
***************
*** 593,599 ****
            k = 0;
            break;
          }
!         case 3:  case 4:  case 5:
            if ((r = PROCNAME(argv[i])) != ZE_OK)
              if (r == ZE_MISS)
                warn("name not matched: ", argv[i]);
--- 681,687 ----
            k = 0;
            break;
          }
!         case 3:  case 4:
            if ((r = PROCNAME(argv[i])) != ZE_OK)
              if (r == ZE_MISS)
                warn("name not matched: ", argv[i]);
***************
*** 606,630 ****
    }
    if (k < 3) {               /* zip used as filter */
      zipstdout();
      if ((r = procname("-")) != ZE_OK)
        if (r == ZE_MISS)
          warn("name not matched: ", "-");
        else
          err(r, "-");
      k = 4;
    }
  
!   if (k != 5)                   /* Clean up selections */
!   {
!     if (k == 3 && (action == UPDATE || action == FRESHEN))
!       for (z = zfiles; z != NULL; z = z->nxt)
!         z->mark = 1;                    /* if -u or -f with no args, do all */
!     if ((r = exclude()) != ZE_OK)       /* remove duplicates in found list */
!       if (r == ZE_PARMS)
!         err(r, "cannot repeat names in zip file");
!       else
!         err(r, "was processing list of files");
    }
    if (zcount)
      free((voidp *)zsort);
  
--- 694,723 ----
    }
    if (k < 3) {               /* zip used as filter */
      zipstdout();
+     comment_stream = NULL;
      if ((r = procname("-")) != ZE_OK)
        if (r == ZE_MISS)
          warn("name not matched: ", "-");
        else
          err(r, "-");
      k = 4;
+     if (s)
+       err(ZE_PARMS, "can't use - and -@ together");
    }
  
!   /* Clean up selections */
!   if (k == 3 && (action == UPDATE || action == FRESHEN)) {
!     for (z = zfiles; z != NULL; z = z->nxt) {
!       /* if -u or -f with no args, do all */
!       z->mark = pcount ? filter(z->zname) : 1;
!     }
    }
+   if ((r = check_dup()) != ZE_OK)     /* remove duplicates in found list */
+     if (r == ZE_PARMS)
+       err(r, "cannot repeat names in zip file");
+     else
+       err(r, "was processing list of files");
+ 
    if (zcount)
      free((voidp *)zsort);
  
***************
*** 638,646 ****
        key != NULL || comadd || zipedit))
      err(ZE_PARMS, "invalid option(s) used with -d");
    if (linkput && dosify)
!     err(ZE_PARMS, "can't use -y with -k");
!   if ((action != ADD || d || test) && !strcmp(zipfile, "-"))
!     err(ZE_PARMS, "can't use -d,-f,-u, -g or -T\n  on standard output");
  #ifdef VMS
    if (vms_native && translate_eol)
      err(ZE_PARMS, "can't use -V with -l");
--- 731,745 ----
        key != NULL || comadd || zipedit))
      err(ZE_PARMS, "invalid option(s) used with -d");
    if (linkput && dosify)
!     {
!       warn("can't use -y with -k, -y ignored", "");
!       linkput = 0;
!     }
!   if (test && !strcmp(zipfile, "-")) {
!     warn("can't use -T on stdout, -T ignored", "");
!   }
!   if ((action != ADD || d) && !strcmp(zipfile, "-"))
!     err(ZE_PARMS, "can't use -d,-f,-u or -g on stdout\n");
  #ifdef VMS
    if (vms_native && translate_eol)
      err(ZE_PARMS, "can't use -V with -l");
***************
*** 650,666 ****
  
  
    /* If -b not specified, make temporary path the same as the zip file */
! #ifdef MSDOS
    if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
                            (p = strrchr(zipfile, '\\')) != NULL ||
                            (p = strrchr(zipfile, ':')) != NULL))
    {
      if (*p == ':')
        p++;
! #else /* !MSDOS */
    if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
    {
! #endif /* ?MSDOS */
      if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
        err(ZE_MEM, "was processing arguments");
      r = *p;  *p = 0;
--- 749,767 ----
  
  
    /* If -b not specified, make temporary path the same as the zip file */
! #if defined(MSDOS) || defined(__human68k__) || defined(AMIGA)
    if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
+ #  ifdef MSDOS
                            (p = strrchr(zipfile, '\\')) != NULL ||
+ #  endif
                            (p = strrchr(zipfile, ':')) != NULL))
    {
      if (*p == ':')
        p++;
! #else
    if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
    {
! #endif
      if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
        err(ZE_MEM, "was processing arguments");
      r = *p;  *p = 0;
***************
*** 674,680 ****
    diag("stating marked entries");
    k = 0;                        /* Initialize marked count */
    for (z = zfiles; z != NULL; z = z->nxt)
!     if (z->mark)
        if (action != DELETE &&
                  ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
                   t < before ||
--- 775,781 ----
    diag("stating marked entries");
    k = 0;                        /* Initialize marked count */
    for (z = zfiles; z != NULL; z = z->nxt)
!     if (z->mark) {
        if (action != DELETE &&
                  ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
                   t < before ||
***************
*** 682,694 ****
        {
          z->mark = 0;
          z->trash = t && t >= before;    /* delete if -um or -fm */
!         if (verbose)
            fprintf(mesg, "zip diagnostic: %s %s\n", z->name,
                   z->trash ? "up to date" : "missing or early");
        }
        else
          k++;
! 
  
    /* Remove entries from found list that do not exist or are too old */
    diag("stating new entries");
--- 783,800 ----
        {
          z->mark = 0;
          z->trash = t && t >= before;    /* delete if -um or -fm */
!         if (verbose) {
            fprintf(mesg, "zip diagnostic: %s %s\n", z->name,
                   z->trash ? "up to date" : "missing or early");
+         }
        }
        else
          k++;
! #if 0
!       fprintf(mesg, "t %ld, z->tim %ld, t-tim %ld\n", t, z->tim,
!               t-z->tim); /* ??? */
! #endif
!     }
  
    /* Remove entries from found list that do not exist or are too old */
    diag("stating new entries");
***************
*** 716,737 ****
    d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
  
  
!   /* Before we get carried away, make sure zip file is writeable */
    if (strcmp(zipfile, "-"))
    {
!     x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) : 
!                                         fopen(zipfile, FOPM);
!     /* Note: FOPW and FOPM expand to several parameters for VMS */
!     if (x == NULL)
!       err(ZE_CREAT, zipfile);
!     fclose(x);
!     a = getfileattr(zipfile);
!     if (zfiles == NULL && zipbeg == 0)
!       destroy(zipfile);
    }
    else
      a = 0;
  
  
    /* Open zip file and temporary output file */
    diag("opening zip file and creating temporary zip file");
--- 822,853 ----
    d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
  
  
!   /* Before we get carried away, make sure zip file is writeable. This
!    * has the undesired side effect of leaving one empty junk file on a WORM,
!    * so when the zipfile does not exist already and when -b is specified,
!    * the writability check is made in replace().
!    */
    if (strcmp(zipfile, "-"))
    {
!     if (tempdir && zfiles == NULL && zipbeg == 0) {
!       a = 0;
!     } else {
!        x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) : 
!                                            fopen(zipfile, FOPM);
!       /* Note: FOPW and FOPM expand to several parameters for VMS */
!       if (x == NULL)
!         err(ZE_CREAT, zipfile);
!       fclose(x);
!       a = getfileattr(zipfile);
!       if (zfiles == NULL && zipbeg == 0)
!         destroy(zipfile);
!     }
    }
    else
      a = 0;
  
+   /* Throw away the garbage in front of the zip file for -F */
+   if (fix) zipbeg = 0;
  
    /* Open zip file and temporary output file */
    diag("opening zip file and creating temporary zip file");
***************
*** 739,752 ****
    tempzn = 0;
    if (strcmp(zipfile, "-") == 0)
    {
! #ifdef MSDOS
      /* Set stdout mode to binary for MSDOS systems */
      setmode(fileno(stdout), O_BINARY);
      tempzf = y = fdopen(fileno(stdout), FOPW);
  #else
      tempzf = y = stdout;
  #endif
!     tempzip = "-";
    }
    else if (d) /* d true if just appending (-g) */
    {
--- 855,872 ----
    tempzn = 0;
    if (strcmp(zipfile, "-") == 0)
    {
! #if defined(MSDOS) || defined(__human68k__)
      /* Set stdout mode to binary for MSDOS systems */
      setmode(fileno(stdout), O_BINARY);
      tempzf = y = fdopen(fileno(stdout), FOPW);
  #else
      tempzf = y = stdout;
  #endif
!     /* tempzip must be malloced so a later free won't barf */
!     tempzip = malloc(4);
!     if (tempzip == NULL)
!       err(ZE_MEM, "allocating temp filename");
!     strcpy(tempzip, "-");
    }
    else if (d) /* d true if just appending (-g) */
    {
***************
*** 763,769 ****
      if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL)
        err(ZE_NAME, zipfile);
      if ((tempzip = tempname(zipfile)) == NULL)
!       err(ZE_MEM, tempzip);
      if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
        err(ZE_TEMP, tempzip);
      if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
--- 883,889 ----
      if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL)
        err(ZE_NAME, zipfile);
      if ((tempzip = tempname(zipfile)) == NULL)
!       err(ZE_MEM, "allocating temp filename");
      if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
        err(ZE_TEMP, tempzip);
      if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
***************
*** 796,802 ****
        {
          if (noisy)
          {
!           fprintf(mesg, "updating %s", z->zname);
            fflush(mesg);
          }
          if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
--- 916,922 ----
        {
          if (noisy)
          {
!           fprintf(mesg, "updating: %s", z->zname);
            fflush(mesg);
          }
          if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
***************
*** 833,839 ****
        {
          if (noisy)
          {
!           fprintf(mesg, "deleting %s\n", z->zname);
            fflush(mesg);
          }
          v = z->nxt;                     /* delete entry from list */
--- 953,959 ----
        {
          if (noisy)
          {
!           fprintf(mesg, "deleting: %s\n", z->zname);
            fflush(mesg);
          }
          v = z->nxt;                     /* delete entry from list */
***************
*** 880,886 ****
      /* zip it up */
      if (noisy)
      {
!       fprintf(mesg, "adding %s", z->zname);
        fflush(mesg);
      }
      if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN)
--- 1000,1006 ----
      /* zip it up */
      if (noisy)
      {
!       fprintf(mesg, "  adding: %s", z->zname);
        fflush(mesg);
      }
      if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN)
***************
*** 924,929 ****
--- 1044,1052 ----
    /* Get one line comment for each new entry */
    if (comadd)
    {
+     if (comment_stream == NULL) {
+       comment_stream = fdopen(fileno(stderr), "r");
+     }
      if ((e = malloc(MAXCOM + 1)) == NULL)
        err(ZE_MEM, "was reading comment lines");
      for (z = zfiles; z != NULL; z = z->nxt)
***************
*** 931,940 ****
        {
          if (noisy)
            fprintf(mesg, "Enter comment for %s:\n", z->name);
!         /* ??? reopen /dev/tty if one file was zipped from stdin
!          * or if file names were read from stdin.
!          */
!         if (fgets(e, MAXCOM+1, stdin) != NULL)
          {
            if ((p = malloc((k = strlen(e))+1)) == NULL)
            {
--- 1054,1060 ----
        {
          if (noisy)
            fprintf(mesg, "Enter comment for %s:\n", z->name);
!         if (fgets(e, MAXCOM+1, comment_stream) != NULL)
          {
            if ((p = malloc((k = strlen(e))+1)) == NULL)
            {
***************
*** 954,959 ****
--- 1074,1082 ----
    /* Get multi-line comment for the zip file */
    if (zipedit)
    {
+     if (comment_stream == NULL) {
+       comment_stream = fdopen(fileno(stderr), "r");
+     }
      if ((e = malloc(MAXCOM + 1)) == NULL)
        err(ZE_MEM, "was reading comment lines");
      if (noisy && zcomlen)
***************
*** 968,977 ****
      *zcomment = 0;
      if (noisy)
        fputs("enter new zip file comment (end with .):\n", mesg);
!      /* ??? reopen /dev/tty if one file was zipped from stdin
!       * or if file names were read from stdin.
!       */
!     while (fgets(e, MAXCOM+1, stdin) != NULL && strcmp(e, ".\n"))
      {
        if (e[(r = strlen(e)) - 1] == '\n')
          e[--r] = 0;
--- 1091,1100 ----
      *zcomment = 0;
      if (noisy)
        fputs("enter new zip file comment (end with .):\n", mesg);
! #if (defined(AMIGA) && (defined(LATTICE)||defined(__SASC)))
!       flushall();  /* tty input/output is out of sync here */
! #endif
!     while (fgets(e, MAXCOM+1, comment_stream) != NULL && strcmp(e, ".\n"))
      {
        if (e[(r = strlen(e)) - 1] == '\n')
          e[--r] = 0;
***************
*** 1021,1026 ****
--- 1144,1152 ----
    if (x != NULL)
      fclose(x);
  
+   /* Free some memory before spawning unzip */
+   lm_free();
+ 
    /* Test new zip file before overwriting old one or removing input files */
    if (test) {
      check_zipfile(tempzip);
***************
*** 1039,1045 ****
      free((voidp *)tempzip);
    }
    tempzip = NULL;
!   if (strcmp(zipfile, "-")) {
      setfileattr(zipfile, a);
  #ifdef VMS
      /* If the zip file existed previously, restore its record format: */
--- 1165,1171 ----
      free((voidp *)tempzip);
    }
    tempzip = NULL;
!   if (a && strcmp(zipfile, "-")) {
      setfileattr(zipfile, a);
  #ifdef VMS
      /* If the zip file existed previously, restore its record format: */
***************
*** 1050,1055 ****
--- 1176,1182 ----
  
    /* Finish up (process -o, -m, clean up).  Exit code depends on o. */
    leave(o ? ZE_OPEN : ZE_OK);
+   return 0; /* just to avoid compiler warning */
  }
  
  /*****************************************************************
Only in .: zip.diff
diff -c ../zip19i/zip.doc ./zip.doc
*** ../zip19i/zip.doc	Tue Nov  3 21:07:57 1992
--- ./zip.doc	Mon Sep  6 03:45:08 1993
***************
*** 1,13 ****
- 
- ZIP(1L)           MISC. REFERENCE MANUAL PAGES            ZIP(1L)
- 
  NAME
       zip, zipcloak, zipnote,  zipsplit  -  package  and  compress
       (archive) files
  
  SYNOPSIS
!      zip   [-cdeEfghijklLmoqrTuwyz@]   [-b path]    [-n suffixes]
!      [-t mmddyy] [-x list] [ zipfile [ file1 file2 ...]]
  
       zipcloak [-dhL] [-b path] zipfile
  
--- 1,10 ----
  NAME
       zip, zipcloak, zipnote,  zipsplit  -  package  and  compress
       (archive) files
  
  SYNOPSIS
!      zip [-cdDeEfFghjklLmoqrSTuvVwyz@$]  [-b path]  [-n suffixes]
!      [-t mmddyy] [ zipfile [ file1 file2 ...]] [-xi list]
  
       zipcloak [-dhL] [-b path] zipfile
  
***************
*** 25,34 ****
       A companion program (unzip(1L)), unpacks zip archives.   The
       zip  and  unzip(1L) programs can work with archives produced
       by PKZIP, and PKZIP and PKUNZIP can work with archives  pro-
!      duced  by  zip.   zip  version  1.9 is compatible with PKZIP
!      1.93a.  Note that PKUNZIP 1.10 cannot extract files produced
!      by  PKZIP  1.93a  or  zip 1.9. You must use PKUNZIP 1.93a or
!      unzip 5.0 (or later versions) to extract them.
  
       For a brief help on zip and unzip, run each without specify-
       ing any parameters on the command line.
--- 22,31 ----
       A companion program (unzip(1L)), unpacks zip archives.   The
       zip  and  unzip(1L) programs can work with archives produced
       by PKZIP, and PKZIP and PKUNZIP can work with archives  pro-
!      duced by zip.  zip version 2.0 is compatible with PKZIP 2.04
!      Note that PKUNZIP 1.10  cannot  extract  files  produced  by
!      PKZIP  2.04  or zip 2.0. You must use PKUNZIP 2.04g or unzip
!      5.0p1 (or later versions) to extract them.
  
       For a brief help on zip and unzip, run each without specify-
       ing any parameters on the command line.
***************
*** 106,113 ****
            tar cf - . | zip - - | dd of=/dev/nrst0 obs=16k
  
       zip archives created in this manner can  be  extracted  with
!      the  program  funzip which is provided in the unzip package.
!      For example:
  
       dd if=/dev/nrst0  ibs=16k | funzip | tar xvf -
  
--- 103,111 ----
            tar cf - . | zip - - | dd of=/dev/nrst0 obs=16k
  
       zip archives created in this manner can  be  extracted  with
!      the  program  funzip which is provided in the unzip package,
!      or by gunzip which is provided  in  the  gzip  package.  For
!      example:
  
       dd if=/dev/nrst0  ibs=16k | funzip | tar xvf -
  
***************
*** 116,121 ****
--- 114,124 ----
       one when the process of creating the new  version  has  been
       completed without error.
  
+      If the name of the zip archive does not  contain  an  exten-
+      sion,  the extension .zip is added. If the name already con-
+      tains an extension other than .zip the existing extension is
+      kept unchanged.
+ 
  OPTIONS
       -b path
            Use the specified path for the temporary  zip  archive.
***************
*** 154,159 ****
--- 157,175 ----
            entered in upper case if they were zipped by  PKZIP  on
            an MSDOS system.
  
+      -D   Do not create entries in the  zip  archive  for  direc-
+           tories.   Directory  entries  are created by default so
+           that their attributes can be saved in the zip  archive.
+           The  environment  variable ZIPOPT can be used to change
+           the default options. For example under Unix with sh:
+ 
+                ZIPOPT="-D"; export ZIPOPT
+ 
+           (The variable ZIPOPT can be used for any option  except
+           -i  and -x and can include several options.) The option
+           -D is a shorthand for -x "*/" but the latter cannot  be
+           set as default in the ZIPOPT environment variable.
+ 
       -e   Encrypt the contents of the zip archive using  a  pass-
            word  which is entered on the terminal in response to a
            prompt (this will not be echoed; if standard  error  is
***************
*** 175,180 ****
--- 191,216 ----
            which  the  original  zip  command was run, since paths
            stored in zip archives are always relative.
  
+      -F   Fix the zip archive. This option can be  used  if  some
+           portions   of  the  archive  are  missing.  It  is  not
+           guaranteed to work, so you MUST make a  backup  of  the
+           original archive first.
+ 
+           When doubled as  in  -FF  the  compressed  sizes  given
+           inside  the  damaged  archive  are  not trusted and zip
+           scans for special signatures  to  identify  the  limits
+           between  the  archive  members.  The  single -F is more
+           reliable if the archive is not too  much  damaged,  for
+           example  if  it  has  only  been truncated, so try this
+           option first.
+ 
+           Neither option will recover  archives  that  have  been
+           incorrectly   transferred  in  ascii  mode  instead  of
+           binary. After the repair, the -t option  of  unzip  may
+           show  that some files have a bad CRC. Such files cannot
+           be recovered; you can  remove  them  from  the  archive
+           using the -d option of zip.
+ 
       -g   Grow (append to) the specified zip archive, instead  of
            creating  a  new  one.  If  this  operation  fails, zip
            attempts to restore the archive to its original  state.
***************
*** 184,198 ****
       -h   Display the zip help information (this also appears  if
            zip is run with no arguments).
  
!      -j   Store just the name of a saved file (junk the path). By
!           default,  zip will store the full path (relative to the
!           current path).
  
       -k   Attempt to convert the names and paths  to  conform  to
            MSDOS,  store  only  the MSDOS attribute (just the user
            write attribute from UNIX), and mark the entry as  made
            under MSDOS (even though it was not); for compatibility
!           with PKUNZIP under MSDOS.
  
       -l   Translate the Unix end-of-line character  LF  into  the
            MSDOS  convention CR LF. This option should not be used
--- 220,251 ----
       -h   Display the zip help information (this also appears  if
            zip is run with no arguments).
  
!      -i files
!           Include only the specified files, as in:
! 
!                zip -r foo . -i \*.c
! 
!           which will include only the files that end in .c in the
!           current  directory  and  its  subdirectories. (Note for
!           PKZIP users: the equivalent command is
  
+                pkzip -r foo *.c
+ 
+           PKZIP does not allow  recursion  in  directories  other
+           than  the  current one.) The backslash avoids the shell
+           filename substitution, so that  the  name  matching  is
+           performed by zip at all directory levels.
+ 
+      -j   Store just the name of a saved file  (junk  the  path),
+           and  do not store directory names. By default, zip will
+           store the full path (relative to the current path).
+ 
       -k   Attempt to convert the names and paths  to  conform  to
            MSDOS,  store  only  the MSDOS attribute (just the user
            write attribute from UNIX), and mark the entry as  made
            under MSDOS (even though it was not); for compatibility
!           with PKUNZIP under MSDOS which  cannot  handle  certain
!           names such as those with two dots.
  
       -l   Translate the Unix end-of-line character  LF  into  the
            MSDOS  convention CR LF. This option should not be used
***************
*** 216,223 ****
            becomes empty after removal of the files, the directory
            is also removed. No deletions are done  until  zip  has
            created  the archive without error.  This is useful for
!           conserving disk space, but is potentially dangerous and
!           should be used with care.
  
       -n suffixes
            Do not attempt to compress files named with  the  given
--- 269,277 ----
            becomes empty after removal of the files, the directory
            is also removed. No deletions are done  until  zip  has
            created  the archive without error.  This is useful for
!           conserving disk space, but is potentially dangerous  so
!           it  is  recommended to use it in combination with -T to
!           test the archive before removing all input files.
  
       -n suffixes
            Do not attempt to compress files named with  the  given
***************
*** 225,231 ****
            in the output zip file, so that zip doesn't  waste  its
            time   trying  to  compress  them.   The  suffixes  are
            separated by either colons or semicolons.  For example:
-           For example,
  
                 zip -rn .Z:.zip:.tiff:.gif:.snd  foo foo
  
--- 279,284 ----
***************
*** 241,249 ****
  
                 setenv ZIPOPT "-n .gif:.zip"
  
!           (The variable ZIPOPT can be used for any option and can
!           include several options.) To attempt compression on all
!           files, use:
  
                 zip -n : foo
  
--- 294,300 ----
  
                 setenv ZIPOPT "-n .gif:.zip"
  
!           To attempt compression on all files, use:
  
                 zip -n : foo
  
***************
*** 261,267 ****
            latest time of the entries in foo.zip.
  
       -q   Quiet mode; eliminate informational messages  and  com-
!           ment  prompts.   (useful, for example, in shell scripts
            and background tasks).
  
       -r   Travel the directory structure recursively;  for  exam-
--- 312,318 ----
            latest time of the entries in foo.zip.
  
       -q   Quiet mode; eliminate informational messages  and  com-
!           ment  prompts.   (Useful, for example, in shell scripts
            and background tasks).
  
       -r   Travel the directory structure recursively;  for  exam-
***************
*** 271,282 ****
  
            In this case, all the files and directories in foo  are
            saved  in  a zip archive named foo.zip, including files
!           with named starting with ".", since the recursion  does
            not  use  the shell's file-name substitution mechanism.
!           You should not use -r with the name  ".*",  since  that
!           matches  ".."  which  will attempt to zip up the parent
!           directory (probably not what was intended).
  
       -t mmddyy
            Do not operate on files modified prior to the specified
            date,  where  mm  is the month (0-12), dd is the day of
--- 322,339 ----
  
            In this case, all the files and directories in foo  are
            saved  in  a zip archive named foo.zip, including files
!           with names starting with ".", since the recursion  does
            not  use  the shell's file-name substitution mechanism.
!           If you wish to include only a specific  subset  of  the
!           files  in directory foo and its subdirectories, use the
!           -i option to the specify the pattern  of  files  to  be
!           included.   You  should  not use -r with the name ".*",
!           since that matches ".." which will attempt  to  zip  up
!           the parent directory (probably not what was intended).
  
+      -S   Include system and hidden files. This option is  effec-
+           tive on some systems only; it is ignored on Unix.
+ 
       -t mmddyy
            Do not operate on files modified prior to the specified
            date,  where  mm  is the month (0-12), dd is the day of
***************
*** 308,313 ****
--- 365,377 ----
            Note that the -u option with no arguments acts like the
            -f (freshen) option.
  
+      -v   Verbose  mode.  Display  a  progress  indicator  during
+           compression.
+ 
+      -V   Save VMS file attributes. This option is  available  on
+           VMS  only;  zip  archives created with this option will
+           generally not be usable on other systems.
+ 
       -w   Append the version number of the  files  to  the  name,
            including  multiple  versions  of  files.   (VMS  only;
            default: use only the most recent version of  a  speci-
***************
*** 320,327 ****
  
            which will include the contents of foo in foo.zip while
            excluding  all the files that end in .o.  The backslash
!           causes zip to match file names that were found when foo
!           was searched.
  
       -y   Store symbolic  links  as  such  in  the  zip  archive,
            instead of compressing and storing the file referred to
--- 384,392 ----
  
            which will include the contents of foo in foo.zip while
            excluding  all the files that end in .o.  The backslash
!           avoids the shell filename  substitution,  so  that  the
!           name matching is performed by zip at all directory lev-
!           els.
  
       -y   Store symbolic  links  as  such  in  the  zip  archive,
            instead of compressing and storing the file referred to
***************
*** 340,349 ****
            files), -1 indicates  the  fastest  compression  method
            (less   compression)   and  -9  indicates  the  slowest
            compression method (optimal  compression,  ignores  the
!           suffix list). The default compression level is -5.
  
       -@   Take the list of input files from standard input.
  
  EXAMPLES
       The simplest example:
  
--- 405,424 ----
            files), -1 indicates  the  fastest  compression  method
            (less   compression)   and  -9  indicates  the  slowest
            compression method (optimal  compression,  ignores  the
!           suffix list). The default compression level is -6.
  
       -@   Take the list of input files from standard input.
  
+      -$   Include the volume label for the the drive holding  the
+           first  file  to  be compressed.  If you want to include
+           only the volume label or to force a specific drive, use
+           the drive name as first file name, as in:
+ 
+                zip -$ foo a: c:bar
+ 
+           This option is effective on some  systems  only  (MSDOS
+           and OS/2); it is ignored on Unix.
+ 
  EXAMPLES
       The simplest example:
  
***************
*** 414,431 ****
  
       The zip program can do the same matching on names  that  are
       in  the zip archive being modified or, in the case of the -x
!      (exclude) option, on the list of files to be operated on, by
!      using  backslashes or quotes to tell the shell not to do the
!      name expansion.  In general, when zip encounters a  name  in
!      the  list of files to do, it first looks for the name in the
!      file system.  If it finds it, it then adds it to the list of
!      files  to do.  If it does not find it, it looks for the name
!      in the zip archive being modified (if it exists), using  the
!      pattern  matching  characters  described  above, if present.
!      For each match, it will add that name to the list  of  files
!      to  be  processed.   File  names  following the -x (exclude)
!      option are removed from the processing list instead of being
!      added.
  
       The pattern matching includes the path, and so patterns like
       \*.o  match  names that end in ".o", no matter what the path
--- 489,506 ----
  
       The zip program can do the same matching on names  that  are
       in  the zip archive being modified or, in the case of the -x
!      (exclude) or -i (include) options, on the list of  files  to
!      be  operated  on, by using backslashes or quotes to tell the
!      shell not to do the name expansion.  In  general,  when  zip
!      encounters a name in the list of files to do, it first looks
!      for the name in the file system.  If it finds  it,  it  then
!      adds it to the list of files to do.  If it does not find it,
!      it looks for the name in the zip archive being modified  (if
!      it  exists), using the pattern matching characters described
!      above, if present.  For each match, it will add that name to
!      the  list of files to be processed, unless this name matches
!      one given with the -x option, or does  not  match  any  name
!      given with the -i option.
  
       The pattern matching includes the path, and so patterns like
       \*.o  match  names that end in ".o", no matter what the path
***************
*** 436,471 ****
       In general, use backslash to make zip do the pattern  match-
       ing with the -f (freshen) and -d (delete) options, and some-
       times after the  -x  (exclude)  option  when  used  with  an
!      appropriate operation (add, -u, -f, or -d).  The zip program
!      will never use pattern matching to search the  file  system.
!      If  it has recursively travelled a directory, all files (and
!      all directories) found there are fair game.
  
  SEE ALSO
!      compress(1), shar(1L), tar(1), unzip(1L)
  
  BUGS
!      zip 1.9 is not compatible with PKUNZIP 1.10. Use zip 1.1  to
       produce zip files which can be extracted by PKUNZIP 1.10.
  
!      zip files produced by zip 1.9 must not be updated by zip 1.1
!      or  PKZIP  1.10  or  PKZIP  1.93a, if they contain encrypted
!      members, or if they have been produced in a pipe or on a non
!      seekable  device.  The  old  versions  of zip or PKZIP would
!      create an archive with an incorrect format.   The  old  ver-
!      sions  can  list  the  contents  of  the zip file but cannot
!      extract it anyway (because  of  the  new  compression  algo-
!      rithm).   If  you do not use encryption and use regular disk
!      files, you do not have to care about this problem.
! 
!      zip 1.9 is compatible with  PKZIP  1.93a,  except  when  two
!      features  are used: encryption or zip file created in a pipe
!      or on a non seekable device. PKZIP versions above  2.0  will
!      support such files, and unzip 5.0 already supports them.
! 
!      Without -y when zip must compress a symbolic link to an  non
!      existing   file,  it  only  displays  a  warning  "name  not
!      matched". A better warning should be given.
  
       Under VMS, not all of the odd file formats are treated prop-
       erly.   Only stream-LF format zip files are expected to work
--- 511,534 ----
       In general, use backslash to make zip do the pattern  match-
       ing with the -f (freshen) and -d (delete) options, and some-
       times after the  -x  (exclude)  option  when  used  with  an
!      appropriate operation (add, -u, -f, or -d).
  
  SEE ALSO
!      compress(1), shar(1L), tar(1), unzip(1L), gzip(1L)
  
  BUGS
!      zip 2.0 is not compatible with PKUNZIP 1.10. Use zip 1.1  to
       produce zip files which can be extracted by PKUNZIP 1.10.
  
!      zip files produced by zip 2.0 must not be updated by zip 1.1
!      or PKZIP 1.10, if they contain encrypted members, or if they
!      have been produced in a pipe or on a  non  seekable  device.
!      The  old  versions  of  zip or PKZIP would create an archive
!      with an incorrect format.  The old  versions  can  list  the
!      contents  of  the  zip  file  but  cannot  extract it anyway
!      (because of the new compression algorithm).  If you  do  not
!      use  encryption  and use regular disk files, you do not have
!      to care about this problem.
  
       Under VMS, not all of the odd file formats are treated prop-
       erly.   Only stream-LF format zip files are expected to work
***************
*** 480,485 ****
--- 543,554 ----
       Under VMS, zip hangs for file specification that uses DECnet
       syntax foo::*.*.
  
+      On OS/2, zip cannot match some names, such as those  includ-
+      ing  an  exclamation  mark or a hash sign.  This is a bug in
+      OS/2 itself: the 32-bit DosFindFirst/Next  don't  find  such
+      names.   Other programs such as GNU tar are also affected by
+      this bug.
+ 
       Under OS/2, the amount of External Attributes  displayed  by
       DIR is (for compatibility) the amount returned by the 16-bit
       version of DosQueryPathInfo(). Otherwise OS/2  1.3  and  2.0
***************
*** 495,505 ****
       this one shows the 32-bit-mode size.
  
  AUTHORS
!      Copyright (C) 1990-1992 Mark Adler, Richard B. Wales,  Jean-
!      loup  Gailly, Kai Uwe Rommel and Igor Mandrichenko.  Permis-
!      sion is granted to any individual  or  institution  to  use,
!      copy,  or  redistribute  this software so long as all of the
!      original files are included unmodified, that it is not  sold
       for profit, and that this copyright notice is retained.
  
       LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTIL-
--- 564,574 ----
       this one shows the 32-bit-mode size.
  
  AUTHORS
!      Copyright (C) 1990-1993 Mark Adler, Richard B. Wales,  Jean-
!      loup  Gailly,  Kai  Uwe  Rommel,  Igor Mandrichenko and John
!      Bush.  Permission is granted to any individual  or  institu-
!      tion  to use, copy, or redistribute this software so long as
!      all of the original files are included, that it is not  sold
       for profit, and that this copyright notice is retained.
  
       LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTIL-
***************
*** 508,514 ****
       COPYRIGHT  HOLDERS  BE LIABLE FOR ANY DAMAGES RESULTING FROM
       THE USE OF THIS SOFTWARE.
  
!      Please    send    bug    reports    and     comments     to:
       zip-bugs@wkuvx1.bitnet.  For bug reports, please include the
       version of zip, the make options used  to  compile  it,  the
       machine  and operating system in use, and as much additional
--- 577,583 ----
       COPYRIGHT  HOLDERS  BE LIABLE FOR ANY DAMAGES RESULTING FROM
       THE USE OF THIS SOFTWARE.
  
!      Please  send  bug  reports  and  comments   by   email   to:
       zip-bugs@wkuvx1.bitnet.  For bug reports, please include the
       version of zip, the make options used  to  compile  it,  the
       machine  and operating system in use, and as much additional
***************
*** 521,532 ****
       the  zip  file format, compression format, and .ZIP filename
       extension, and for accepting minor changes to the file  for-
       mat; to Steve Burg for clarifications on the deflate format;
!      to  Keith  Petersen,  Rich  Wales  and  Hunter  Goatley  for
!      providing a mailing list and ftp site for the INFO-ZIP group
!      to use; and most importantly, to the INFO-ZIP  group  itself
!      (listed  in  the  file  infozip.who)  without whose tireless
!      testing and bug-fixing efforts a portable zip would not have
!      been  possible.   Finally  we should thank (blame) the first
!      INFO-ZIP moderator, David Kirschbaum, for  getting  us  into
!      this mess in the first place.  The manual page was rewritten
!      for UNIX by R. P. C. Rodgers.
--- 590,603 ----
       the  zip  file format, compression format, and .ZIP filename
       extension, and for accepting minor changes to the file  for-
       mat; to Steve Burg for clarifications on the deflate format;
!      to Haruhiko Okumura and Leonid Broukhis for  providing  some
!      useful  ideas for the compression algorithm; to Keith Peter-
!      sen, Rich Wales, Hunter Goatley and Mark Adler for providing
!      a  mailing  list and ftp site for the INFO-ZIP group to use;
!      and most importantly, to the INFO-ZIP group  itself  (listed
!      in  the file infozip.who) without whose tireless testing and
!      bug-fixing efforts a portable zip would not have been possi-
!      ble.   Finally  we  should  thank (blame) the first INFO-ZIP
!      moderator, David Kirschbaum, for getting us into  this  mess
!      in  the first place.  The manual page was rewritten for UNIX
!      by R. P. C. Rodgers.
diff -c ../zip19i/zip.h ./zip.h
*** ../zip19i/zip.h	Tue Nov  3 21:07:57 1992
--- ./zip.h	Fri Sep  3 03:10:36 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 46,58 ****
  #  ifdef __GO32__
       char *strlwr(char *); /* not in include files of djgcc */
  #  endif
- #  if defined(NeXT) /* no way to disable precompiled headers */
- #    undef const
- #  endif
  #  include <string.h>
- #  if defined(NeXT)
- #    define const
- #  endif
  #else /* !MODERN */
     voidp *malloc();
     char *getenv();
--- 45,51 ----
***************
*** 79,93 ****
  
  
  /* Forget FILENAME_MAX (incorrectly = 14 on some System V) */
! #ifdef MSDOS
  #  define FNMAX 256
! #else /* !MSDOS */
  #  define FNMAX 1024
! #endif /* ?MSDOS */
  
  
  /* For setting stdout to binary */
! #ifdef MSDOS
  #  include <io.h>
  #  include <fcntl.h>
  #  ifdef __GO32__
--- 72,86 ----
  
  
  /* Forget FILENAME_MAX (incorrectly = 14 on some System V) */
! #if defined(MSDOS) && !defined(WIN32) && !defined(OS2)
  #  define FNMAX 256
! #else
  #  define FNMAX 1024
! #endif
  
  
  /* For setting stdout to binary */
! #if defined(MSDOS) || defined(__human68k__)
  #  include <io.h>
  #  include <fcntl.h>
  #  ifdef __GO32__
***************
*** 133,138 ****
--- 126,135 ----
    struct flist far * far *lst;  /* Pointer to link pointing here */
    struct flist far *nxt;        /* Link to next name */
  };
+ struct plist {
+   char *zname;                  /* Name used for zip file headers */
+   int select;                   /* Selection flag ('i' or 'x') */
+ };
  
  /* internal file attribute */
  #define UNKNOWN (-1)
***************
*** 148,153 ****
--- 145,151 ----
  extern uch lower[256];
  extern char errbuf[];           /* Handy place to build error messages */
  extern int recurse;             /* Recurse into directories encountered */
+ extern int dispose;             /* Remove files after put in zip file */
  extern int pathput;             /* Store path with name */
  
  #define BEST -1                 /* Use best method (deflation or store) */
***************
*** 158,172 ****
  extern int dosify;              /* Make new entries look like MSDOS */
  extern char *special;           /* Don't compress special suffixes */
  extern int verbose;             /* Report oddities in zip file structure */
  extern int level;               /* Compression level */
  extern int translate_eol;       /* Translate end-of-line LF -> CR LF */
  #ifdef VMS
     extern int vmsver;           /* Append VMS version number to file names */
     extern int vms_native;       /* Store in VMS formait */
  #endif /* VMS */
! #ifdef OS2
     extern int use_longname_ea;   /* use the .LONGNAME EA as the file's name */
! #endif /* OS2 */
  extern int linkput;             /* Store symbolic links as such */
  extern int noisy;               /* False for quiet operation */
  extern char *key;               /* Scramble password or NULL */
--- 156,174 ----
  extern int dosify;              /* Make new entries look like MSDOS */
  extern char *special;           /* Don't compress special suffixes */
  extern int verbose;             /* Report oddities in zip file structure */
+ extern int fix;                 /* Fix the zip file */
  extern int level;               /* Compression level */
  extern int translate_eol;       /* Translate end-of-line LF -> CR LF */
  #ifdef VMS
     extern int vmsver;           /* Append VMS version number to file names */
     extern int vms_native;       /* Store in VMS formait */
  #endif /* VMS */
! #if defined(OS2) || defined(WIN32)
     extern int use_longname_ea;   /* use the .LONGNAME EA as the file's name */
! #endif
! extern int hidden_files;        /* process hidden and system files */
! extern int volume_label;        /* add volume label */
! extern int dirnames;            /* include directory names */
  extern int linkput;             /* Store symbolic links as such */
  extern int noisy;               /* False for quiet operation */
  extern char *key;               /* Scramble password or NULL */
***************
*** 185,190 ****
--- 187,195 ----
  extern struct flist far * far *fnxt;    /* Where to put next in found list */
  extern extent fcount;           /* Count of names in found list */
  
+ extern struct plist *patterns;  /* List of patterns to be matched */
+ extern int pcount;              /* number of patterns */
+ extern int icount;              /* number of include only patterns */
  
  /* Diagnostic functions */
  #ifdef DEBUG
***************
*** 220,226 ****
          /* in zipup.c */
  int zipcopy OF((struct zlist far *, FILE *, FILE *));
  #ifndef UTIL
!    int percent OF((long, long));
     int zipup OF((struct zlist far *, FILE *));
     int file_read OF((char *buf, unsigned size));
  #endif /* !UTIL */
--- 225,231 ----
          /* in zipup.c */
  int zipcopy OF((struct zlist far *, FILE *, FILE *));
  #ifndef UTIL
!    int percent OF((ulg, ulg));
     int zipup OF((struct zlist far *, FILE *));
     int file_read OF((char *buf, unsigned size));
  #endif /* !UTIL */
***************
*** 239,254 ****
  
          /* in fileio.c */
  #ifndef UTIL
! #  ifdef MSDOS
       int wild OF((char *));
! #  endif /* MSDOS */
! #  ifdef VMS
!      int wild OF((char *));
! #  endif /* VMS */
     char *getnam OF((char *));
     struct flist far *fexpel OF((struct flist far *));
     char *in2ex OF((char *));
!    int exclude OF((void));
     int procname OF((char *));
     void stamp OF((char *, ulg));
     ulg dostime OF((int, int, int, int, int, int));
--- 244,258 ----
  
          /* in fileio.c */
  #ifndef UTIL
! #  if defined(MSDOS) || defined(VMS) || defined(__human68k__)
       int wild OF((char *));
! #  endif
     char *getnam OF((char *));
     struct flist far *fexpel OF((struct flist far *));
     char *in2ex OF((char *));
!    char *ex2in OF((char *, int, int *));
!    int check_dup OF((void));
!    int filter OF((char *name));
     int procname OF((char *));
     void stamp OF((char *, ulg));
     ulg dostime OF((int, int, int, int, int, int));
***************
*** 257,263 ****
     int issymlnk OF((ulg a));
  #  ifdef S_IFLNK
  #    define rdsymlnk(p,b,n) readlink(p,b,n)
!      extern int readlink OF((char *, char *, int));
  #  else /* !S_IFLNK */
  #    define rdsymlnk(p,b,n) (0)
  #  endif /* !S_IFLNK */
--- 261,267 ----
     int issymlnk OF((ulg a));
  #  ifdef S_IFLNK
  #    define rdsymlnk(p,b,n) readlink(p,b,n)
! /*   extern int readlink OF((char *, char *, int)); */
  #  else /* !S_IFLNK */
  #    define rdsymlnk(p,b,n) (0)
  #  endif /* !S_IFLNK */
***************
*** 284,290 ****
  void     init_upper OF((void));
  int      namecmp    OF((char *string1, char *string2));
  voidp far **search  OF((voidp *, voidp far **, extent,
!                        int (*)(voidp *, voidp far *)));
  ulg updcrc OF((char *, extent));
  
  extern ulg crc_32_tab[];
--- 288,294 ----
  void     init_upper OF((void));
  int      namecmp    OF((char *string1, char *string2));
  voidp far **search  OF((voidp *, voidp far **, extent,
!                        int (*)(const voidp *, const voidp far *)));
  ulg updcrc OF((char *, extent));
  
  extern ulg crc_32_tab[];
***************
*** 293,298 ****
--- 297,303 ----
  #ifndef UTIL
          /* in deflate.c */
  void lm_init OF((int pack_level, ush *flags));
+ void lm_free OF((void));
  ulg  deflate OF((void));
  
          /* in trees.c */
Only in ../zip19i: zip19i.zip
diff -c ../zip19i/zipcloak.c ./zipcloak.c
*** ../zip19i/zipcloak.c	Tue Nov  3 21:07:58 1992
--- ./zipcloak.c	Thu Sep  9 23:30:02 1993
***************
*** 1,316 ****
  /*
!    This code is not copyrighted and is put in the public domain. It
!    was originally written in Europe and can be freely distributed from
!    any country except the U.S.A. If this code is imported in the U.S.A,
!    it cannot be re-exported from the U.S.A to another country. (This
!    restriction might seem curious but this is what US law requires.)
   */
  
! #define UTIL
! #include "revision.h"
! #include "zip.h"
! #include "crypt.h"
! #include <signal.h>
! #ifdef MSDOS
! #  include <stdlib.h>
! #endif
  
  
- #ifdef CRYPT  /* defined (or not) in crypt.h */
- 
- /* Temporary zip file name and file pointer */
- local char *tempzip;
- local FILE *tempzf;
- 
- 
- /* Local functions */
- void err OF((int code, char *msg));
- local void handler OF((int sig));
- local void license OF((void));
- local void help OF((void));
- void main OF((int argc, char **argv));
- 
- 
- 
- /***********************************************************************
-  * Issue a message for the error, clean up files and memory, and exit.
-  */
- void err(code, msg)
-     int code;               /* error code from the ZE_ class */
-     char *msg;              /* message about how it happened */
- {
-     if (PERR(code)) perror("zipcloak error");
-     fprintf(stderr, "zipcloak error: %s (%s)\n", errors[code-1], msg);
-     if (tempzf != NULL) fclose(tempzf);
-     if (tempzip != NULL) {
-         destroy(tempzip);
-         free((voidp *)tempzip);
-     }
-     if (zipfile != NULL) free((voidp *)zipfile);
- #ifdef VMS
-     exit(0);
- #else
-     exit(code);
- #endif
- }
- 
- 
- /***********************************************************************
-  * Upon getting a user interrupt, turn echo back on for tty and abort
-  * cleanly using err().
-  */
- local void handler(sig)
-     int sig;                  /* signal number (ignored) */
- {
- #ifndef MSDOS
-     echon();
-     putc('\n', stderr);
- #endif
-     err(ZE_ABORT +sig-sig, "aborting");
-     /* dummy usage of sig to avoid compiler warnings */
- }
- 
- 
- /***********************************************************************
-  * Print a warning message to stderr and return.
-  */
  void warn(msg1, msg2)
      char *msg1, *msg2;        /* message strings juxtaposed in output */
  {
      fprintf(stderr, "zipcloak warning: %s%s\n", msg1, msg2);
  }
  
! 
! static char *public[] = {
! "The encryption code of this program is not copyrighted and is put in the",
! "public domain. It was originally written in Europe and can be freely",
! "distributed from any country except the U.S.A. If this program is imported",
! "in the U.S.A, it cannot be re-exported from the U.S.A to another country.",
! "The copyright notice of the zip program applies to the rest of the code."
! };
! 
! /***********************************************************************
!  * Print license information to stdout.
!  */
! local void license()
! {
!     extent i;             /* counter for copyright array */
! 
!     for (i = 0; i < sizeof(public)/sizeof(char *); i++) {
!         puts(public[i]);
!     }
!     for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++) {
!         puts(disclaimer[i]);
!     }
! }
! 
! 
! static char *help_info[] = {
! "",
! "ZipCloak %s (%s)",
! "Usage:  zipcloak [-d] [-b path] zipfile",
! "  the default action is to encrypt all unencrypted entries in the zip file",
! "  -d   decrypt--decrypt encrypted entries (copy if given wrong password)",
! "  -b   use \"path\" for the temporary zip file",
! "  -h   show this help               -L   show software license"
!   };
! 
! /***********************************************************************
!  * Print help (along with license info) to stdout.
!  */
! local void help()
  {
!     extent i;             /* counter for help array */
! 
!     for (i = 0; i < sizeof(public)/sizeof(char *); i++) {
!         puts(public[i]);
!     }
!     for (i = 0; i < sizeof(help_info)/sizeof(char *); i++) {
!         printf(help_info[i], VERSION, REVDATE);
!         putchar('\n');
!     }
  }
  
! #endif /* CRYPT */
! 
! 
! /***********************************************************************
!  * Encrypt or decrypt all of the entries in a zip file.  See the command
!  * help in help() above.
!  */
! 
! void main(argc, argv)
!     int argc;             /* number of tokens in command line */
!     char **argv;          /* command line tokens */
  {
- #ifdef CRYPT
-     int attr;             /* attributes of zip file */
-     ulg start_offset;     /* start of central directory */
-     int decrypt;          /* decryption flag */
-     int temp_path;        /* 1 if next argument is path for temp files */
-     char passwd[PWLEN+1]; /* password for encryption or decryption */
-     char *q;              /* steps through option arguments */
-     int r;                /* arg counter */
-     int res;              /* result code */
-     ulg length;           /* length of central directory */
-     FILE *inzip, *outzip; /* input and output zip files */
-     struct zlist far *z;  /* steps through zfiles linked list */
- 
- 
-     /* If no args, show help */
-     if (argc == 1) {
-         help();
-         exit(0);
-     }
- 
-     init_upper();           /* build case map table */
- 
-     /* Go through args */
-     zipfile = tempzip = NULL;
-     tempzf = NULL;
-     signal(SIGINT, handler);
-     signal(SIGTERM, handler);
-     temp_path = decrypt = 0;
-     for (r = 1; r < argc; r++) {
-         if (*argv[r] == '-') {
-             if (!argv[r][1]) err(ZE_PARMS, "zip file cannot be stdin");
-             for (q = argv[r]+1; *q; q++) {
-                 switch(*q) {
-                 case 'b':   /* Specify path for temporary file */
-                     if (temp_path) {
-                         err(ZE_PARMS, "use -b before zip file name");
-                     }
-                     temp_path = 1;          /* Next non-option is path */
-                     break;
-                 case 'd':
-                     decrypt = 1;  break;
-                 case 'h':   /* Show help */
-                     help();
-                     exit(0);
-                 case 'l': case 'L':  /* Show copyright and disclaimer */
-                     license();
-                     exit(0);
-                 default:
-                     err(ZE_PARMS, "unknown option");
-                 } /* switch */
-             } /* for */
- 
-         } else if (temp_path == 0) {
-             if (zipfile != NULL) {
-                 err(ZE_PARMS, "can only specify one zip file");
- 
-             } else if ((zipfile = ziptyp(argv[r])) == NULL) {
-                 err(ZE_MEM, "was processing arguments");
-             }
-         } else {
-             tempath = argv[r];
-             temp_path = 0;
-         } /* if */
-     } /* for */
- 
-     if (zipfile == NULL) err(ZE_PARMS, "need to specify zip file");
- 
-     /* Read zip file */
-     if ((res = readzipfile()) != ZE_OK) err(res, zipfile);
-     if (zfiles == NULL) err(ZE_NAME, zipfile);
- 
-     /* Check for something to do */
-     for (z = zfiles; z != NULL; z = z->nxt) {
-         if (decrypt ? z->flg & 1 : !(z->flg & 1)) break;
-     }
-     if (z == NULL) {
-         err(ZE_NONE, decrypt ? "no encrypted files"
-                        : "all files encrypted already");
-     }
- 
-     /* Before we get carried away, make sure zip file is writeable */
-     if ((inzip = fopen(zipfile, "a")) == NULL) err(ZE_CREAT, zipfile);
-     fclose(inzip);
-     attr = getfileattr(zipfile);
- 
-     /* Open output zip file for writing */
-     if ((tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) {
-         err(ZE_TEMP, tempzip);
-     }
- 
-     /* Get password */
-     if (getp("Enter password: ", passwd, PWLEN+1) == NULL) {
-         err(ZE_PARMS, "stderr is not a tty (you may never see this message!)");
-     }
- 
-     /* Open input zip file again, copy preamble if any */
-     if ((inzip = fopen(zipfile, FOPR)) == NULL) err(ZE_NAME, zipfile);
- 
-     if (zipbeg && (res = fcopy(inzip, outzip, zipbeg)) != ZE_OK) {
-         err(res, res == ZE_TEMP ? tempzip : zipfile);
-     }
-     /* Go through local entries, copying, encrypting, or decrypting */
-     for (z = zfiles; z != NULL; z = z->nxt) {
-         if (decrypt && (z->flg & 1)) {
-             printf("decrypting %s", z->zname);
-             fflush(stdout);
-             if ((res = zipbare(z, inzip, outzip, passwd)) != ZE_OK) {
-                 if (res != ZE_MISS) err(res, "was decrypting an entry");
-                 printf(" (wrong password--just copying)");
-             }
-             putchar('\n');
- 
-         } else if ((!decrypt) && !(z->flg & 1)) {
-             printf("encrypting %s\n", z->zname);
-             fflush(stdout);
-             if ((res = zipcloak(z, inzip, outzip, passwd)) != ZE_OK) {
-                 err(res, "was encrypting an entry");
-             }
-         } else {
-             printf("copying %s\n", z->zname);
-             fflush(stdout);
-             if ((res = zipcopy(z, inzip, outzip)) != ZE_OK) {
-                 err(res, "was copying an entry");
-             }
-         } /* if */
-     } /* for */
-     fclose(inzip);
- 
-     /* Write central directory and end of central directory */
- 
-     /* get start of central */
-     if ((start_offset = ftell(outzip)) == -1L) err(ZE_TEMP, tempzip);
- 
-     for (z = zfiles; z != NULL; z = z->nxt) {
-         if ((res = putcentral(z, outzip)) != ZE_OK) err(res, tempzip);
-     }
- 
-     /* get end of central */
-     if ((length = ftell(outzip)) == -1L) err(ZE_TEMP, tempzip);
- 
-     length -= start_offset;               /* compute length of central */
-     if ((res = putend((int)zcount, length, start_offset, zcomlen,
-                        zcomment, outzip)) != ZE_OK) {
-         err(res, tempzip);
-     }
-     tempzf = NULL;
-     if (fclose(outzip)) err(ZE_TEMP, tempzip);
-     if ((res = replace(zipfile, tempzip)) != ZE_OK) {
-         warn("new zip file left as: ", tempzip);
-         free((voidp *)tempzip);
-         tempzip = NULL;
-         err(res, "was replacing the original zip file");
-     }
-     free((voidp *)tempzip);
-     tempzip = NULL;
-     setfileattr(zipfile, attr);
-     free((voidp *)zipfile);
-     zipfile = NULL;
- 
-     /* Done! */
-     exit(0);
- 
- #else /* !CRYPT */
- 
      fprintf(stderr, "\
  This version of ZipCloak does not support encryption.  Get zcrypt20.zip (or\n\
  a later version) and recompile.  The Info-ZIP file `Where' lists sites.\n");
      exit(1);
! 
! #endif /* ?CRYPT */
  }
--- 1,32 ----
  /*
!    Dummy version of Info-ZIP zipcloak.c encryption code.  See "Where"
!    file for sites from which to obtain full encryption sources.
   */
  
! #include "tailor.h"
  
+ void warn  OF((char *msg1, char *msg2));
+ void err   OF((int code, char *msg));
+ int  main  OF((void));
  
  void warn(msg1, msg2)
      char *msg1, *msg2;        /* message strings juxtaposed in output */
  {
      fprintf(stderr, "zipcloak warning: %s%s\n", msg1, msg2);
  }
  
! void err(code, msg)
!     int code;               /* error code from the ZE_ class */
!     char *msg;              /* message about how it happened */
  {
!     if (code) warn(msg, "");
  }
  
! int main()
  {
      fprintf(stderr, "\
  This version of ZipCloak does not support encryption.  Get zcrypt20.zip (or\n\
  a later version) and recompile.  The Info-ZIP file `Where' lists sites.\n");
      exit(1);
!     return 1; /* avoid warning */
  }
diff -c ../zip19i/ziperr.h ./ziperr.h
*** ../zip19i/ziperr.h	Tue Nov  3 21:07:58 1992
--- ./ziperr.h	Tue Aug 31 22:08:40 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 24,29 ****
--- 23,29 ----
  #define ZE_LOGIC        5       /* internal logic error */
  #define ZE_BIG          6       /* entry too large to split */
  #define ZE_NOTE         7       /* invalid comment format */
+ #define ZE_TEST         8       /* zip test (-T) failed or out of memory */
  #define ZE_ABORT        9       /* user interrupt or termination */
  #define ZE_TEMP         10      /* error using a temp file */
  #define ZE_READ         11      /* read or seek error */
***************
*** 46,52 ****
  /*  5 */  "Internal logic error",
  /*  6 */  "Entry too big to split",
  /*  7 */  "Invalid comment format",
! /*  8 */  "",
  /*  9 */  "Interrupted",
  /* 10 */  "Temporary file failure",
  /* 11 */  "Input file read failure",
--- 46,52 ----
  /*  5 */  "Internal logic error",
  /*  6 */  "Entry too big to split",
  /*  7 */  "Invalid comment format",
! /*  8 */  "Zip file invalid or insufficient memory",
  /*  9 */  "Interrupted",
  /* 10 */  "Temporary file failure",
  /* 11 */  "Input file read failure",
diff -c ../zip19i/zipfile.c ./zipfile.c
*** ../zip19i/zipfile.c	Tue Nov  3 21:07:58 1992
--- ./zipfile.c	Mon Sep  6 04:18:50 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 13,19 ****
--- 12,20 ----
   *  zipfile.c by Mark Adler.
   */
  
+ #define NOCPYRT         /* this is not a main module */
  #include "zip.h"
+ #include "revision.h"
  
  #ifdef VMS
  #  include "VMSmunch.h"
***************
*** 26,33 ****
  #define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16))
  
  /* Macros for writing machine integers to little-endian format */
! #define PUTSH(a,f) {putc((char)(a),(f)); putc((char)((a) >> 8),(f));}
! #define PUTLG(a,f) {PUTSH(a,f) PUTSH((a) >> 16,f)}
  
  
  /* -- Structure of a ZIP file -- */
--- 27,34 ----
  #define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16))
  
  /* Macros for writing machine integers to little-endian format */
! #define PUTSH(a,f) {putc((char)(a) & 0xff,(f)); putc((char)((a) >> 8),(f));}
! #define PUTLG(a,f) {PUTSH((a) & 0xffff,f) PUTSH((a) >> 16,f)}
  
  
  /* -- Structure of a ZIP file -- */
***************
*** 50,55 ****
--- 51,60 ----
  #define LOCNAM  22              /* length of filename */
  #define LOCEXT  24              /* length of extra field */
  
+ #define EXTCRC  0               /* uncompressed crc-32 for file */
+ #define EXTSIZ  4               /* compressed size in zip file */
+ #define EXTLEN  8               /* uncompressed size */
+ 
  #define CENVEM  0               /* version made by */
  #define CENVER  2               /* version needed to extract */
  #define CENFLG  4               /* encrypt, deflate flags */
***************
*** 78,93 ****
  
  /* Local functions */
  
! local int zqcmp OF((voidp *, voidp *));
  #  ifndef UTIL
!      local int rqcmp OF((voidp *, voidp *));
!      local int zbcmp OF((voidp *, voidp far *));
!      local char *cutpath OF((char *));
  #  endif /* !UTIL */
  
  
  local int zqcmp(a, b)
! voidp *a, *b;           /* pointers to pointers to zip entries */
  /* Used by qsort() to compare entries in the zfile list.
   * Compares the internal names z->zname */
  {
--- 83,98 ----
  
  /* Local functions */
  
! local int zqcmp OF((const voidp *, const voidp *));
  #  ifndef UTIL
!      local int rqcmp OF((const voidp *, const voidp *));
!      local int zbcmp OF((const voidp *, const voidp far *));
!      local void cutpath OF((char *p));
  #  endif /* !UTIL */
  
  
  local int zqcmp(a, b)
! const voidp *a, *b;           /* pointers to pointers to zip entries */
  /* Used by qsort() to compare entries in the zfile list.
   * Compares the internal names z->zname */
  {
***************
*** 98,104 ****
  #ifndef UTIL
  
  local int rqcmp(a, b)
! voidp *a, *b;           /* pointers to pointers to zip entries */
  /* Used by qsort() to compare entries in the zfile list.
   * Compare the internal names z->zname, but in reverse order. */
  {
--- 103,109 ----
  #ifndef UTIL
  
  local int rqcmp(a, b)
! const voidp *a, *b;           /* pointers to pointers to zip entries */
  /* Used by qsort() to compare entries in the zfile list.
   * Compare the internal names z->zname, but in reverse order. */
  {
***************
*** 108,115 ****
  
  
  local int zbcmp(n, z)
! voidp *n;               /* string to search for */
! voidp far *z;           /* pointer to a pointer to a zip entry */
  /* Used by search() to compare a target to an entry in the zfile list. */
  {
    return namecmp((char *)n, ((struct zlist far *)z)->zname);
--- 113,120 ----
  
  
  local int zbcmp(n, z)
! const voidp *n;         /* string to search for */
! const voidp far *z;     /* pointer to a pointer to a zip entry */
  /* Used by search() to compare a target to an entry in the zfile list. */
  {
    return namecmp((char *)n, ((struct zlist far *)z)->zname);
***************
*** 147,162 ****
    if ((t = malloc(strlen(s) + 5)) == NULL)
      return NULL;
    strcpy(t, s);
  #ifdef MSDOS
    for (q = t; *q; q++)
      if (*q == '\\')
        *q = '/';
  #endif /* MSDOS */
    if (strrchr((q = strrchr(t, PATHCUT)) == NULL ? t : q + 1, '.') == NULL)
      strcat(t, ".zip");
- #if defined(FORCE_UPPER) && defined(MSDOS) && !defined(OS2)
-   strupr(t);
- #endif
    return t;
  }
  
--- 152,173 ----
    if ((t = malloc(strlen(s) + 5)) == NULL)
      return NULL;
    strcpy(t, s);
+ #ifdef __human68k__
+   _toslash(t);
+ #endif
  #ifdef MSDOS
    for (q = t; *q; q++)
      if (*q == '\\')
        *q = '/';
  #endif /* MSDOS */
+ #ifdef AMIGA
+   if ((q = strrchr(t, '/')) == NULL)
+     q = strrchr(t, ':');
+   if (strrchr((q ? q + 1 : t), '.') == NULL)
+ #else /* !AMIGA */
    if (strrchr((q = strrchr(t, PATHCUT)) == NULL ? t : q + 1, '.') == NULL)
+ #endif /* ?AMIGA */
      strcat(t, ".zip");
    return t;
  }
  
***************
*** 230,235 ****
--- 241,247 ----
     Return an error code in the ZE_ class.
  */
  {
+   ulg a = 0L;           /* attributes returned by filetime() */
    char b[CENHEAD];      /* buffer for central headers */
    FILE *f;              /* zip file */
    ush flg;              /* general purpose bit flag */
***************
*** 270,275 ****
--- 282,294 ----
        (f = fopen(zipfile, FOPR)) != NULL)
  #endif /* ?VMS */
    {
+     /* Get any file attribute valid for this OS, to set in the central
+      * directory when fixing the archive:
+      */
+ #ifndef UTIL
+     if (fix)
+       filetime(zipfile, &a, (long*)&s);
+ #endif
      x = &zfiles;                        /* first link */
      p = 0;                              /* starting file offset */
      zcount = 0;                         /* number of files */
***************
*** 294,319 ****
           be greater than or equal to LOCHEAD) */
        if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
          return ZE_MEM;
!       if (fread(b, LOCHEAD, 1, f) != 1)
!         return ferror(f) ? ZE_READ : ZE_EOF;
!       t = b;  u = (char far *)z;  n = LOCHEAD;
!       do {
!         *u++ = *t++;
!       } while (--n);
! 
        /* Link into list */
        *x = z;
        z->nxt = NULL;
        x = &z->nxt;
  
        /* Read file name and extra field and skip data */
-       n = SH(LOCNAM + (uch far *)z);
-       z->ext = SH(LOCEXT + (uch far *)z);
- #ifdef ZIPFIX
-       s = 0;
- #else
-       s = LG(LOCSIZ + (uch far *)z);
- #endif
        if (n == 0)
        {
          sprintf(errbuf, "%d", zcount + 1);
--- 313,359 ----
           be greater than or equal to LOCHEAD) */
        if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
          return ZE_MEM;
!       if (fread(b, LOCHEAD, 1, f) != 1) {
!         if (fix)
!           break;
!         else
!           return ferror(f) ? ZE_READ : ZE_EOF;
!       }
!       if (fix) {
!         z->ver = SH(LOCVER + b);
!         z->vem = dosify ? 20 : OS_CODE + REVISION;
!         z->dosflag = dosify;
!         flg = z->flg = z->lflg = SH(LOCFLG + b);
!         z->how = SH(LOCHOW + b);
!         z->tim = LG(LOCTIM + b);          /* time and date into one long */
!         z->crc = LG(LOCCRC + b);
!         z->siz = LG(LOCSIZ + b);
!         z->len = LG(LOCLEN + b);
!         n = z->nam = SH(LOCNAM + b);
!         z->cext = z->ext = SH(LOCEXT + b);
!         z->com = 0;
!         z->dsk = 0;
!         z->att = 0;
!         z->atx = dosify ? a & 0xff : a;     /* Attributes from filetime() */
!         z->mark = 0;
!         z->trash = 0;
!         s = fix > 1 ? 0L : z->siz; /* discard compressed size with -FF */
!       } else {
!         t = b;  u = (char far *)z;  n = LOCHEAD;
!         do {
!           *u++ = *t++;
!         } while (--n);
!         z->ext = SH(LOCEXT + (uch far *)z);
!         n = SH(LOCNAM + (uch far *)z);
!         flg = SH(b+LOCFLG);
!         s = LG(LOCSIZ + (uch far *)z);
!       }
        /* Link into list */
        *x = z;
        z->nxt = NULL;
        x = &z->nxt;
  
        /* Read file name and extra field and skip data */
        if (n == 0)
        {
          sprintf(errbuf, "%d", zcount + 1);
***************
*** 333,338 ****
--- 373,382 ----
         * the correct compressed size.
         */
        z->zname[n] = 0;                  /* terminate name */
+       if (fix) {
+         z->cextra = z->extra;
+         if (noisy) fprintf(mesg, "zip: reading %s\n", z->zname);
+       }
  #ifdef UTIL
        z->name = z->zname;               /* !!! to be checked */
  #else /* !UTIL */
***************
*** 347,354 ****
        zcount++;
  
        /* Skip extended local header if there is one */
-       flg = SH(b+LOCFLG);
- 
        if ((flg & 8) != 0) {
          /* Skip the compressed data if compressed size is unknown.
           * For safety, we should use the central directory.
--- 391,396 ----
***************
*** 362,368 ****
              if (fseek(f, -15L, SEEK_CUR))
                return ferror(f) ? ZE_READ : ZE_EOF;
            }
!           s = LG(b+8);
            p += s;
            if ((ulg) ftell(f) != p+16L) {
              warn("bad extended local header for ", z->zname);
--- 404,410 ----
              if (fseek(f, -15L, SEEK_CUR))
                return ferror(f) ? ZE_READ : ZE_EOF;
            }
!           s = LG(4 + EXTSIZ + b);
            p += s;
            if ((ulg) ftell(f) != p+16L) {
              warn("bad extended local header for ", z->zname);
***************
*** 380,420 ****
            }
          }
          /* overwrite the unknown values of the local header: */
!         t = b+4;  u = (char far *)z+LOCCRC;  n = 12;
!         do {
!           *u++ = *t++;
!         } while (--n);
          p += 16L;
        }
! #ifdef ZIPFIX
!       /* Don't trust the compressed size */
!       else {
! 	for (;;) {
! 	  while ((m = getc(f)) != EOF && m != 'P') p++;
! 	  b[0] = (char) m;
! 	  if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG || s == CENSIG)
! 	    break;
! 	  if (fseek(f, -3L, SEEK_CUR))
! 	    return ferror(f) ? ZE_READ : ZE_EOF;
! 	  p++;
! 	}
! 	s = p - (z->off + 4 + LOCHEAD + n + z->ext);
! 	if (s != LG(LOCSIZ + (uch far *)z)) {
! 	  fprintf(stderr, " compressed size %ld, actual size %ld for %s\n",
! 		  LG(LOCSIZ + (uch far *)z), s, z->zname);
! 	}
        }
! #else
        /* Read next signature */
!       if (fread(b, 4, 1, f) != 1)
!         return ferror(f) ? ZE_READ : ZE_EOF;
! #endif /* ZIPFIX */
      }
  
      /* Point to start of header list and read central headers */
      z = zfiles;
      s = p;                              /* save start of central */
!     while (LG(b) == CENSIG)
      {
        if (z == NULL)
        {
--- 422,486 ----
            }
          }
          /* overwrite the unknown values of the local header: */
!         if (fix) {
!             /* already in host format */
!             z->crc = LG(4 + EXTCRC + b);
!             z->siz = s;
!             z->len = LG(4 + EXTLEN + b);
!         } else {
!             /* Keep in Intel format for comparison with central header */
!             t = b+4;  u = (char far *)z+LOCCRC;  n = 12;
!             do {
!               *u++ = *t++;
!             } while (--n);
!         }
          p += 16L;
        }
!       else if (fix > 1) {
!         /* Don't trust the compressed size */
!         for (;;) {
!           while ((m = getc(f)) != EOF && m != 'P') p++;
!           b[0] = (char) m;
!           if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG || s == CENSIG)
!             break;
!           if (fseek(f, -3L, SEEK_CUR))
!             return ferror(f) ? ZE_READ : ZE_EOF;
!           p++;
!         }
!         s = p - (z->off + 4 + LOCHEAD + n + z->ext);
!         if (s != z->siz) {
!           fprintf(stderr, " compressed size %ld, actual size %ld for %s\n",
!                   z->siz, s, z->zname);
!           z->siz = s;
!         }
!         /* next LOCSIG already read at this point, don't read it again: */
!         continue;
        }
! 
        /* Read next signature */
!       if (fread(b, 4, 1, f) != 1) {
!         if (fix)
!           break;
!         else
!           return ferror(f) ? ZE_READ : ZE_EOF;
!       }
      }
  
      /* Point to start of header list and read central headers */
      z = zfiles;
      s = p;                              /* save start of central */
!     if (fix) {
!       if (LG(b) != CENSIG && noisy) {
!         fprintf(mesg, "zip warning: %s %s truncated.\n", zipfile,
!                 fix > 1 ? "has been" : "would be");
! 
!         if (fix == 1) {
!           fprintf(mesg,
!    "Retry with option -qF to truncate, with -FF to attempt full recovery\n");
!           err(ZE_FORM, NULL);
!         }
!       }
!     } else while (LG(b) == CENSIG)
      {
        if (z == NULL)
        {
***************
*** 437,448 ****
        for (m = 0, u = (char far *)z, n = 0; n < LOCHEAD - 2; n++)
          if (u[n] != b[n+2])
          {
!           if (!m)
              warn("local and central headers differ for ", z->zname);
            m = 1;
            sprintf(errbuf, " offset %d--local = %02x, central = %02x",
                    n, (uch)u[n], (uch)b[n+2]);
!           warn(errbuf, "");
          }
        if (m)
          return ZE_FORM;
--- 503,515 ----
        for (m = 0, u = (char far *)z, n = 0; n < LOCHEAD - 2; n++)
          if (u[n] != b[n+2])
          {
!           if (!m && noisy)
              warn("local and central headers differ for ", z->zname);
            m = 1;
            sprintf(errbuf, " offset %d--local = %02x, central = %02x",
                    n, (uch)u[n], (uch)b[n+2]);
!           if (noisy) warn(errbuf, "");
!           b[n+2] = u[n]; /* fix the zipfile */
          }
        if (m)
          return ZE_FORM;
***************
*** 463,468 ****
--- 530,536 ----
        z->dsk = SH(CENDSK + b);
        z->att = SH(CENATT + b);
        z->atx = LG(CENATX + b);
+       z->dosflag = (z->vem & 0xff00) == 0;
        if (z->off != LG(CENOFF + b))
        {
          warn("local offset in central header incorrect for ", z->zname);
***************
*** 590,624 ****
      }
      
      /* Read end header */
!     if (z != NULL || LG(b) != ENDSIG)
!     {
!       warn("missing end signature--probably not a zip file (did you", "");
!       warn("remember to use binary mode when you transferred it?)", "");
!       return ZE_FORM;
!     }
!     if (fread(b, ENDHEAD, 1, f) != 1)
!       return ferror(f) ? ZE_READ : ZE_EOF;
!     if (SH(ENDDSK + b) || SH(ENDBEG + b) ||
!         SH(ENDSUB + b) != SH(ENDTOT + b))
!       warn("multiple disk information ignored", "");
!     if (zcount != SH(ENDSUB + b))
!     {
!       warn("count in end of central directory incorrect", "");
!       return ZE_FORM;
!     }
!     if (LG(ENDSIZ + b) != p - s)
!     {
!       warn("central directory size is incorrect (made by stzip?)", "");
!       /* stzip 0.9 gets this wrong, so be tolerant */
!       /* return ZE_FORM; */
!     }
!     if (LG(ENDOFF + b) != s)
!     {
!       warn("central directory start is incorrect", "");
!       return ZE_FORM;
      }
      cenbeg = s;
!     zcomlen = SH(ENDCOM + b);
      if (zcomlen)
      {
        if ((zcomment = malloc(zcomlen)) == NULL)
--- 658,694 ----
      }
      
      /* Read end header */
!     if (!fix) {
!       if (z != NULL || LG(b) != ENDSIG)
!       {
!         warn("missing end signature--probably not a zip file (did you", "");
!         warn("remember to use binary mode when you transferred it?)", "");
!         return ZE_FORM;
!       }
!       if (fread(b, ENDHEAD, 1, f) != 1)
!         return ferror(f) ? ZE_READ : ZE_EOF;
!       if (SH(ENDDSK + b) || SH(ENDBEG + b) ||
!           SH(ENDSUB + b) != SH(ENDTOT + b))
!         warn("multiple disk information ignored", "");
!       if (zcount != SH(ENDSUB + b))
!       {
!         warn("count in end of central directory incorrect", "");
!         return ZE_FORM;
!       }
!       if (LG(ENDSIZ + b) != p - s)
!       {
!         warn("central directory size is incorrect (made by stzip?)", "");
!         /* stzip 0.9 gets this wrong, so be tolerant */
!         /* return ZE_FORM; */
!       }
!       if (LG(ENDOFF + b) != s)
!       {
!         warn("central directory start is incorrect", "");
!         return ZE_FORM;
!       }
      }
      cenbeg = s;
!     zcomlen = fix ? 0 : SH(ENDCOM + b);
      if (zcomlen)
      {
        if ((zcomment = malloc(zcomlen)) == NULL)
***************
*** 634,640 ****
        sprintf(errbuf, " has a preamble of %ld bytes", zipbeg);
        warn(zipfile, errbuf);
      }
!     if (getc(f) != EOF)
        warn("garbage at end of zip file ignored", "");
  
      /* Done with zip file for now */
--- 704,710 ----
        sprintf(errbuf, " has a preamble of %ld bytes", zipbeg);
        warn(zipfile, errbuf);
      }
!     if (!fix && getc(f) != EOF)
        warn("garbage at end of zip file ignored", "");
  
      /* Done with zip file for now */
***************
*** 723,729 ****
  
  int putend(n, s, c, m, z, f)
  int n;                  /* number of entries in central directory */
! ulg s, c;               /* size and offset of central directory */
  extent m;               /* length of zip file comment (0 if none) */
  char *z;                /* zip file comment if m != 0 */
  FILE *f;                /* file to write to */
--- 793,800 ----
  
  int putend(n, s, c, m, z, f)
  int n;                  /* number of entries in central directory */
! ulg s;                  /* size of central directory */
! ulg c;                  /* offset of central directory */
  extent m;               /* length of zip file comment (0 if none) */
  char *z;                /* zip file comment if m != 0 */
  FILE *f;                /* file to write to */
***************
*** 746,842 ****
  
  #ifndef UTIL
  
! local char *cutpath(p)
  char *p;                /* path string */
! /* Cut the last path component off the name *p in place.  Return p.
!  * For a directory name ending with /, just remove the /.
!  * For VMS, keep directory names intact. This function can be called
!  * on both internal names a/b and external names [a.b].
   */
  {
!   char *r;                   /* pointer to last path delimiter */
  
! #ifdef VMS                   /* change [w.x.y]z to [w.x.y] */
    if ((r = strrchr(p, ']')) != NULL)
    {
!     if (r[1] == '\0')
!       return p;              /* keep directory name intact */
!     r[1] = '\0';             /* [w.x.y]z -> [w.x.y] */
    }
!   else
! #endif /* VMS */             /* change w/x/y/z to w/x/y */
    if ((r = strrchr(p, '/')) != NULL)
      *r = 0;
    else
      *p = 0;
-   return p;
  }
  
- 
  int trash()
  /* Delete the compressed files and the directories that contained the deleted
     files, if empty.  Return an error code in the ZE_ class.  Failure of
     destroy() or deletedir() is ignored. */
  {
    extent i;             /* counter on deleted names */
!   extent n;             /* number of deleted names left to handle */
    struct zlist far **s; /* table of zip entries to handle, sorted */
    struct zlist far *z;  /* current zip entry */
  
!   /* Count and delete marked names */
    n = 0;
    for (z = zfiles; z != NULL; z = z->nxt)
      if (z->mark || z->trash)
      {
        z->mark = 1;
-       n++;
        if (z->zname[z->nam - 1] != '/') { /* don't unlink directory */
          if (verbose)
            fprintf(mesg, "zip diagnostic: trashing file %s\n", z->name);
          destroy(z->name);
        }
      }
  
!   /* Try to delete all paths that lead up to marked names */
    if (n)
    {
!     if ((s = (struct zlist far **)malloc((n+1)*sizeof(struct zlist far *))) ==
!         NULL ||
!         (s[0] = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
        return ZE_MEM;
-     s[0]->name = s[0]->zname = "";
-     s++;
      n = 0;
!     for (z = zfiles; z != NULL; z = z->nxt)
!       if (z->mark && *cutpath(z->zname)) {
! 	cutpath(z->name);
!         if (strcmp(z->zname, s[n-1]->zname)) /* just to optimize qsort */
!           s[n++] = z;
      }
- 
      /* Sort the files in reverse order to get subdirectories first.
       * To avoid problems with strange naming conventions as in VMS,
       * we sort on the internal names, so x/y/z will always be removed
       * before x/y. On VMS, x/y/z > x/y but [x.y.z] < [x.y]
       */
- #ifdef VMS_BUG
-   printf("before qsort\n");
-   for (i = 0; i < n; i++) printf("%s\t%s\n", s[i]->zname, s[i]->name);
- #endif
      qsort((char *)s, n, sizeof(struct zlist far *), rqcmp);
! #ifdef VMS_BUG
!   printf("after qsort\n");
!   for (i = 0; i < n; i++) printf("%s\t%s\n", s[i]->zname, s[i]->name);
! #endif
!     for (i = 0; i < n; i++)
!       if (strcmp(s[i]->zname, s[i-1]->zname))
!       {
!         if (verbose)
            fprintf(mesg, "zip diagnostic: trashing directory %s (if empty)\n",
!                  s[i]->name);
          deletedir(s[i]->name);
        }
!     farfree((voidp far *)((--s)[0]));
      free((voidp *)s);
    }
    return ZE_OK;
--- 817,924 ----
  
  #ifndef UTIL
  
! local void cutpath(p)
  char *p;                /* path string */
! /* Cut the last path component off the name *p in place.
!  * This should work on both internal and external names.
   */
  {
!   char *r;              /* pointer to last path delimiter */
  
! #ifdef VMS                      /* change [w.x.y]z to [w.x]y.DIR */
    if ((r = strrchr(p, ']')) != NULL)
    {
!     *r = 0;
!     if ((r = strrchr(p, '.')) != NULL)
!     {
!       *r = ']';
!       strcat(r, ".DIR;1");     /* this assumes a little padding--see PAD */
!     } else {
!       *p = 0;
!     }
!   } else {
!     *p = 0;
    }
! #endif /* ?VMS */
    if ((r = strrchr(p, '/')) != NULL)
      *r = 0;
    else
      *p = 0;
  }
  
  int trash()
  /* Delete the compressed files and the directories that contained the deleted
     files, if empty.  Return an error code in the ZE_ class.  Failure of
     destroy() or deletedir() is ignored. */
  {
    extent i;             /* counter on deleted names */
!   extent n;             /* number of directories to delete */
    struct zlist far **s; /* table of zip entries to handle, sorted */
    struct zlist far *z;  /* current zip entry */
  
!   /* Delete marked names and count directories */
    n = 0;
    for (z = zfiles; z != NULL; z = z->nxt)
      if (z->mark || z->trash)
      {
        z->mark = 1;
        if (z->zname[z->nam - 1] != '/') { /* don't unlink directory */
          if (verbose)
            fprintf(mesg, "zip diagnostic: trashing file %s\n", z->name);
          destroy(z->name);
+         /* Try to delete all paths that lead up to marked names. This is
+          * necessary only without the -D option.
+          */
+         if (!dirnames) {
+           cutpath(z->name);
+           cutpath(z->zname);
+           if (z->zname[0] != '\0') {
+             strcat(z->zname, "/");
+           }
+           z->nam = strlen(z->zname);
+           if (z->nam > 0) n++;
+         }
+       } else {
+         n++;
        }
      }
  
!   /* Construct the list of all marked directories. Some may be duplicated
!    * if -D was used.
!    */
    if (n)
    {
!     if ((s = (struct zlist far **)malloc(n*sizeof(struct zlist far *))) ==
!         NULL)
        return ZE_MEM;
      n = 0;
!     for (z = zfiles; z != NULL; z = z->nxt) {
!       if (z->mark && z->nam > 0 && z->zname[z->nam - 1] == '/'
!           && (n == 0 || strcmp(z->zname, s[n-1]->zname) != 0)) {
!         s[n++] = z;
!       }
      }
      /* Sort the files in reverse order to get subdirectories first.
       * To avoid problems with strange naming conventions as in VMS,
       * we sort on the internal names, so x/y/z will always be removed
       * before x/y. On VMS, x/y/z > x/y but [x.y.z] < [x.y]
       */
      qsort((char *)s, n, sizeof(struct zlist far *), rqcmp);
! 
!     for (i = 0; i < n; i++) {
!       char *p = s[i]->name;
!       if (*p == '\0') continue;
!       if (p[strlen(p) - 1] == '/') { /* keep VMS [x.y]z.dir;1 intact */
!         p[strlen(p) - 1] = '\0';
!       }
!       if (i == 0 || strcmp(s[i]->zname, s[i-1]->zname) != 0) {
!         if (verbose) {
            fprintf(mesg, "zip diagnostic: trashing directory %s (if empty)\n",
!                   s[i]->name);
!         }
          deletedir(s[i]->name);
        }
!     }
      free((voidp *)s);
    }
    return ZE_OK;
Only in .: zipgrep
Only in .: zipgrep.1
diff -c ../zip19i/zipnote.c ./zipnote.c
*** ../zip19i/zipnote.c	Tue Nov  3 21:07:58 1992
--- ./zipnote.c	Thu Sep  9 23:25:26 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 21,26 ****
--- 20,27 ----
  
  /* Character to mark zip entry names in the comment file */
  #define MARK '@'
+ #define MARKE " (comment above this line)"
+ #define MARKZ " (zip file comment below this line)"
  
  /* Temporary zip file name and file pointer */
  local char *tempzip;
***************
*** 34,40 ****
     local void help(void);
     local void putclean(char *, int);
     local int catalloc(char * far *, char *);
!    void main(int, char **);
  #endif /* PROTO */
  
  
--- 35,41 ----
     local void help(void);
     local void putclean(char *, int);
     local int catalloc(char * far *, char *);
!    int main(int, char **);
  #endif /* PROTO */
  
  
***************
*** 159,165 ****
      if (c == MARK || c == '\\')
        putchar('\\');
      if (c >= ' ' || c == '\t' || c == '\n')
!       putchar(e = c);
    }
    if (e != '\n')
      putchar('\n');
--- 160,166 ----
      if (c == MARK || c == '\\')
        putchar('\\');
      if (c >= ' ' || c == '\t' || c == '\n')
!       { e=c; putchar(e); }
    }
    if (e != '\n')
      putchar('\n');
***************
*** 188,194 ****
  }
  
  
! void main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Write the comments in the zipfile to stdout, or read them from stdin. */
--- 189,195 ----
  }
  
  
! int main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Write the comments in the zipfile to stdout, or read them from stdin. */
***************
*** 218,224 ****
--- 219,227 ----
    zipfile = tempzip = NULL;
    tempzf = NULL;
    signal(SIGINT, handler);
+ #ifdef SIGTERM              /* AMIGA has no SIGTERM */
    signal(SIGTERM, handler);
+ #endif
    k = w = 0;
    for (r = 1; r < argc; r++)
      if (*argv[r] == '-')
***************
*** 273,281 ****
      {
        printf("%c %s\n", MARK, z->zname);
        putclean(z->comment, z->com);
!       putchar(MARK);  putchar('\n');
      }
!     putchar(MARK);  putchar('\n');
      putclean(zcomment, zcomlen);
      exit(ZE_OK);
    }
--- 276,284 ----
      {
        printf("%c %s\n", MARK, z->zname);
        putclean(z->comment, z->com);
!       printf("%c%s\n", MARK, MARKE);
      }
!     printf("%c%s\n", MARK, MARKZ);
      putclean(zcomment, zcomlen);
      exit(ZE_OK);
    }
***************
*** 287,314 ****
    t = getfileattr(zipfile);
  
    /* Process stdin, replacing comments */
!   for (z = zfiles; z != NULL; z = z->nxt)
!   {
!     if (gets(a) == NULL || a[0] != MARK || a[1] != ' ' ||
!         strcmp(a + 2, z->zname))
!       err(ZE_NOTE, "missing entry name");
!     if (z->com)
        free((voidp *)z->comment);
      z->comment = malloc(1);  *(z->comment) = 0;
      while (gets(a) != NULL && *a != MARK)
        if ((r = catalloc(&(z->comment), a)) != ZE_OK)
          err(r, "was building new comments");
-     if (a[1])
-       err(ZE_NOTE, "missing comment end line");
      z->com = strlen(z->comment);
    }
-   if (gets(a) == NULL || a[0] != MARK || a[1])
-     err(ZE_NOTE, "missing zip file comment marker line");
-   zcomment = malloc(1);  *zcomment = 0;
-   while (gets(a) != NULL)
-     if ((r = catalloc(&zcomment, a)) != ZE_OK)
-       err(r, "was building new comments");
-   zcomlen = strlen(zcomment);
  
    /* Open output zip file for writing */
    if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
--- 290,321 ----
    t = getfileattr(zipfile);
  
    /* Process stdin, replacing comments */
!   z = zfiles;
!   while (gets(a) != NULL && (a[0] != MARK || strcmp(a + 1, MARKZ)))
!   {                                     /* while input and not file comment */
!     if (a[0] != MARK || a[1] != ' ')    /* better be "@ name" */
!       err(ZE_NOTE, "unexpected input");
!     while (z != NULL && strcmp(a + 2, z->zname))
!       z = z->nxt;                       /* allow missing entries in order */
!     if (z == NULL)
!       err(ZE_NOTE, "unknown entry name");
!     if (z->com)                         /* change zip entry comment */
        free((voidp *)z->comment);
      z->comment = malloc(1);  *(z->comment) = 0;
      while (gets(a) != NULL && *a != MARK)
        if ((r = catalloc(&(z->comment), a)) != ZE_OK)
          err(r, "was building new comments");
      z->com = strlen(z->comment);
+     z = z->nxt;                         /* point to next entry */
+   }
+   if (a != NULL)                        /* change zip file comment */
+   {
+     zcomment = malloc(1);  *zcomment = 0;
+     while (gets(a) != NULL)
+       if ((r = catalloc(&zcomment, a)) != ZE_OK)
+         err(r, "was building new comments");
+     zcomlen = strlen(zcomment);
    }
  
    /* Open output zip file for writing */
    if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
***************
*** 355,358 ****
--- 362,366 ----
  
    /* Done! */
    exit(ZE_OK);
+   return 0; /* avoid warning */
  }
diff -c ../zip19i/zipsplit.c ./zipsplit.c
*** ../zip19i/zipsplit.c	Tue Nov  3 21:07:59 1992
--- ./zipsplit.c	Thu Sep  9 23:28:38 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 19,25 ****
  #include <signal.h>
  
  #define DEFSIZ 36000L   /* Default split size (change in help() too) */
! #ifdef MSDOS
  #  define NL 2          /* Number of bytes written for a \n */
  #else /* !MSDOS */
  #  define NL 1          /* Number of bytes written for a \n */
--- 18,24 ----
  #include <signal.h>
  
  #define DEFSIZ 36000L   /* Default split size (change in help() too) */
! #if defined(MSDOS) || defined(__human68k__)
  #  define NL 2          /* Number of bytes written for a \n */
  #else /* !MSDOS */
  #  define NL 1          /* Number of bytes written for a \n */
***************
*** 33,41 ****
     local void license(void);
     local void help(void);
     local extent simple(ulg *, extent, ulg, ulg);
!    local int descmp(voidp *, voidp *);
     local extent greedy(ulg *, extent, ulg, ulg);
!    void main(int, char **);
  #endif /* PROTO */
  
  
--- 32,40 ----
     local void license(void);
     local void help(void);
     local extent simple(ulg *, extent, ulg, ulg);
!    local int descmp(const voidp *, const voidp *);
     local extent greedy(ulg *, extent, ulg, ulg);
!    int main(int, char **);
  #endif /* PROTO */
  
  
***************
*** 126,131 ****
--- 125,131 ----
  "  -i   make index (zipsplit.idx) and count its size against first zip file",
  "  -n   make zip files no larger than \"size\" (default = 36000)",
  "  -b   use \"path\" for the output zip files",
+ "  -p   pause between output zip files",
  "  -s   do a sequential split even if it takes more zip files",
  "  -h   show this help               -L   show software license"
    };
***************
*** 171,177 ****
  
  
  local int descmp(a, b)
! voidp *a, *b;           /* pointers to pointers to ulg's to compare */
  /* Used by qsort() in greedy() to do a descending sort. */
  {
    return **(ulg **)a < **(ulg **)b ? 1 : (**(ulg **)a > **(ulg **)b ? -1 : 0);
--- 171,177 ----
  
  
  local int descmp(a, b)
! const voidp *a, *b;           /* pointers to pointers to ulg's to compare */
  /* Used by qsort() in greedy() to do a descending sort. */
  {
    return **(ulg **)a < **(ulg **)b ? 1 : (**(ulg **)a > **(ulg **)b ? -1 : 0);
***************
*** 269,275 ****
  }
  
  
! void main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Split a zip file into several zip files less than a specified size.  See
--- 269,275 ----
  }
  
  
! int main(argc, argv)
  int argc;               /* number of tokens in command line */
  char **argv;            /* command line tokens */
  /* Split a zip file into several zip files less than a specified size.  See
***************
*** 291,301 ****
    int r;                /* temporary variable, counter */
    extent s;             /* number of bins needed */
    ulg t;                /* total of sizes, end of central directory */
    struct zlist far **w; /* malloc'ed table for zfiles linked list */
    int x;                /* if true, make an index file */
    struct zlist far *z;  /* steps through zfiles linked list */
  
- 
    /* If no args, show help */
    if (argc == 1)
    {
--- 291,304 ----
    int r;                /* temporary variable, counter */
    extent s;             /* number of bins needed */
    ulg t;                /* total of sizes, end of central directory */
+   int u;                /* flag to wait for user on output files */
    struct zlist far **w; /* malloc'ed table for zfiles linked list */
    int x;                /* if true, make an index file */
    struct zlist far *z;  /* steps through zfiles linked list */
+ #ifdef AMIGA
+   char tailchar;         /* temporary variable used in name generation below */
+ #endif
  
    /* If no args, show help */
    if (argc == 1)
    {
***************
*** 307,314 ****
  
    /* Go through args */
    signal(SIGINT, handler);
    signal(SIGTERM, handler);
!   k = h = x = d = 0;
    c = DEFSIZ;
    for (r = 1; r < argc; r++)
      if (*argv[r] == '-')
--- 310,319 ----
  
    /* Go through args */
    signal(SIGINT, handler);
+ #ifdef SIGTERM                 /* Amiga has no SIGTERM */
    signal(SIGTERM, handler);
! #endif
!   k = h = x = d = u = 0;
    c = DEFSIZ;
    for (r = 1; r < argc; r++)
      if (*argv[r] == '-')
***************
*** 335,340 ****
--- 340,347 ----
                else
                  k = 2;          /* Next non-option is size */
                break;
+             case 'p':
+               u = 1;
              case 's':
                h = 1;    /* Only try simple */
                break;
***************
*** 342,348 ****
                d = 1;
                break;
              default:
!               err(ZE_PARMS, "unknown option");
            }
        else
          err(ZE_PARMS, "zip file cannot be stdin");
--- 349,355 ----
                d = 1;
                break;
              default:
!               err(ZE_PARMS, "Use option -h for help.");
            }
        else
          err(ZE_PARMS, "zip file cannot be stdin");
***************
*** 363,369 ****
        else              /* k must be 2 */
        {
          if ((c = (ulg)atol(argv[r])) < 100)     /* 100 is smallest zip file */
!           err(ZE_PARMS, "invalid size given");
          k = 0;
        }
    if (zipfile == NULL)
--- 370,376 ----
        else              /* k must be 2 */
        {
          if ((c = (ulg)atol(argv[r])) < 100)     /* 100 is smallest zip file */
!           err(ZE_PARMS, "invalid size given. Use option -h for help.");
          k = 0;
        }
    if (zipfile == NULL)
***************
*** 386,392 ****
      if (a != NULL)
        free((voidp *)a);
      err(ZE_MEM, "was computing split");
!     return;
    }
    i = t = 0;
    for (j = 0, z = zfiles; j < zcount; j++, z = z->nxt)
--- 393,399 ----
      if (a != NULL)
        free((voidp *)a);
      err(ZE_MEM, "was computing split");
!     return 1;
    }
    i = t = 0;
    for (j = 0, z = zfiles; j < zcount; j++, z = z->nxt)
***************
*** 432,438 ****
      free((voidp *)w);  free((voidp *)a);
      free((voidp *)zipfile);
      zipfile = NULL;
!     return;
    }
  
    /* Set up path for output files */
--- 439,445 ----
      free((voidp *)w);  free((voidp *)a);
      free((voidp *)zipfile);
      zipfile = NULL;
!     exit(0);
    }
  
    /* Set up path for output files */
***************
*** 443,458 ****
    else
    {
      strcpy(path, tempath);
      if (path[0] && path[strlen(path) - 1] != '/')
        strcat(path, "/");
      name = path + strlen(path);
    }
  
    /* Write the index file */
    if (x)
    {
      strcpy(name, INDEX);
!     printf("creating %s\n", path);
      indexmade = 1;
      if ((f = fopen(path, "w")) == NULL)
      {
--- 450,478 ----
    else
    {
      strcpy(path, tempath);
+ #ifdef AMIGA
+     tailchar = path[strlen(path) - 1];  /* last character */
+     if (path[0] && (tailchar != '/') && (tailchar != ':'))
+       strcat(path, "/");
+     name = path + strlen(path);
+ #else
      if (path[0] && path[strlen(path) - 1] != '/')
        strcat(path, "/");
      name = path + strlen(path);
+ #endif /* ?AMIGA */
    }
  
    /* Write the index file */
+   if (u)
+   {
+     char m[10];
+     fputs("Insert first disk and hit return: ", stderr);
+     fgets(m, 10, stdin);
+   }
    if (x)
    {
      strcpy(name, INDEX);
!     printf("creating: %s\n", path);
      indexmade = 1;
      if ((f = fopen(path, "w")) == NULL)
      {
***************
*** 498,504 ****
--- 518,529 ----
  #ifdef VMS
    if ((q = strrchr(zipfile, ']')) != NULL)
  #else /* !VMS */
+ #  ifdef AMIGA
+   if (((q = strrchr(zipfile, '/')) != NULL)
+                        || ((q = strrchr(zipfile, ':'))) != NULL)
+ #  else /* !AMIGA */
    if ((q = strrchr(zipfile, '/')) != NULL)
+ #  endif /* ?AMIGA */
  #endif /* ?VMS */
      q++;
    else
***************
*** 522,529 ****
    zipfile = NULL;
    for (j = 0; j < s; j++)
    {
      sprintf(name, template, j + 1);
!     printf("creating %s\n", path);
      zipsmade = j + 1;
      if ((f = fopen(path, FOPW)) == NULL)
      {
--- 547,560 ----
    zipfile = NULL;
    for (j = 0; j < s; j++)
    {
+     if (u && j)
+     {
+       char m[10];
+       fputs("Insert next disk and hit return: ", stderr);
+       fgets(m, 10, stdin);
+     }
      sprintf(name, template, j + 1);
!     printf("creating: %s\n", path);
      zipsmade = j + 1;
      if ((f = fopen(path, FOPW)) == NULL)
      {
***************
*** 579,582 ****
--- 610,614 ----
  
    /* Done! */
    exit(0);
+   return 0; /* avoid warning */
  }
diff -c ../zip19i/zipup.c ./zipup.c
*** ../zip19i/zipup.c	Tue Nov  3 21:07:59 1992
--- ./zipup.c	Fri Sep 10 05:34:50 1993
***************
*** 1,11 ****
  /*
  
!  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included
!  unmodified, that it is not sold for profit, and that this copyright notice
!  is retained.
  
  */
  
--- 1,10 ----
  /*
  
!  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
   Kai Uwe Rommel and Igor Mandrichenko.
   Permission is granted to any individual or institution to use, copy, or
!  redistribute this software so long as all of the original files are included,
!  that it is not sold for profit, and that this copyright notice is retained.
  
  */
  
***************
*** 30,71 ****
  #  endif
  #endif
  
- /* The following OS codes are defined in pkzip appnote.txt */
- #ifdef AMIGA
- #  define OS_CODE  0x100
- #endif
- #ifdef VMS
- #  define OS_CODE  0x200
- #endif
- /* unix    3 */
- /* vms/cms 4 */
- #ifdef ATARI_ST
- #  define OS_CODE  0x500
- #endif
- #ifdef OS2
- #  define OS_CODE  0x600
- #endif
- #ifdef MACOS
- #  define OS_CODE  0x700
- #endif
- /* z system 8 */
- /* cp/m     9 */
- #ifdef TOPS20
- #  define OS_CODE  0xa00
- #endif
- #ifdef WIN32
- #  define OS_CODE  0xb00
- #endif
- /* qdos 12 */
- 
- #if defined(MSDOS) && !defined(OS_CODE)
- #  define OS_CODE  0x000
- #endif
- #ifndef OS_CODE
- #  define OS_CODE  0x300  /* assume Unix */
- #endif
  
- 
  /* Use the raw functions for MSDOS and Unix to save on buffer space.
     They're not used for VMS since it doesn't work (raw is weird on VMS).
     (This sort of stuff belongs in fileio.c, but oh well.) */
--- 29,35 ----
***************
*** 83,111 ****
     int vms_close OF((ftype));
     int vms_error OF((ftype));
  #else /* !VMS */
! #  if defined(MSDOS) && !defined(ATARI_ST)
  #    include <io.h>
  #    include <fcntl.h>
  #    define fhow (O_RDONLY|O_BINARY)
  #  else /* !MSDOS */
  #    if defined(SYSV) || defined(__386BSD__)
! #      include <fcntl.h>
! #    else
!        int open OF((char *, int));
!        int read OF((int, char *, int));
!        int close OF((int));
!        int lseek OF((int, long, int));
  #    endif
  #    ifdef TOPS20
  #      define O_RDONLY (0)
! #      define O_UNCONVERTED	(0400) /* Forced NO conversion requested */
  #      define fhow (O_RDONLY | O_UNCONVERTED)
  #    else
! #      define fhow 0
  #    endif
  #  endif /* ?MSDOS */
     typedef int ftype;
! #  define fbad (-1)
  #  define zopen(n,p) open(n,p)
  #  define zread(f,b,n) read(f,b,n)
  #  define zclose(f) close(f)
--- 47,81 ----
     int vms_close OF((ftype));
     int vms_error OF((ftype));
  #else /* !VMS */
! #  if (defined(MSDOS) && !defined(ATARI_ST)) || defined(__human68k__)
  #    include <io.h>
  #    include <fcntl.h>
  #    define fhow (O_RDONLY|O_BINARY)
  #  else /* !MSDOS */
  #    if defined(SYSV) || defined(__386BSD__)
! #      include <fcntl.h>  /* open(), read(), close(), lseek() */
  #    endif
  #    ifdef TOPS20
  #      define O_RDONLY (0)
! #      define O_UNCONVERTED     (0400) /* Forced NO conversion requested */
  #      define fhow (O_RDONLY | O_UNCONVERTED)
  #    else
! #      ifdef AMIGA
! #        include <fcntl.h>
! #        define fhow (O_RDONLY | O_RAW)
! #        define fbad (-1)
! #        ifdef AZTEC_C
! #          define O_RAW 0
! #        endif
! #      else
! #        define fhow 0
! #      endif
  #    endif
  #  endif /* ?MSDOS */
     typedef int ftype;
! #  ifndef fbad
! #    define fbad (-1)
! #  endif
  #  define zopen(n,p) open(n,p)
  #  define zread(f,b,n) read(f,b,n)
  #  define zclose(f) close(f)
***************
*** 113,126 ****
  #  define zstdin 0
  #endif /* ?VMS */
  
  #if defined(MMAP) || defined(BIG_MEM)
    extern uch * window;          /* Used to read all input file at once */
-   extern ulg window_size;       /* size of said window */
  #endif
  
  /* Local data */
  
- #ifndef UTIL
    local ulg crc;       /* crc on uncompressed file data */
    local ftype ifile;   /* file to compress */
    local long remain;
--- 83,97 ----
  #  define zstdin 0
  #endif /* ?VMS */
  
+ #ifndef UTIL
+ 
  #if defined(MMAP) || defined(BIG_MEM)
    extern uch * window;          /* Used to read all input file at once */
  #endif
+ extern ulg window_size;         /* size of said window */
  
  /* Local data */
  
    local ulg crc;       /* crc on uncompressed file data */
    local ftype ifile;   /* file to compress */
    local long remain;
***************
*** 147,157 ****
  {
    ulg n;                /* holds local header offset */
  
!   if (fseek(x, z->off, SEEK_SET))
!     return ferror(x) ? ZE_READ : ZE_EOF;
!   z->off = tempzn;
!   n = 4 + LOCHEAD + (long)z->nam + (long)z->ext + z->siz;
!   /* copy the extended local header if there is one */
    if (z->lflg & 8) n += 16;
    tempzn += n;
    return fcopy(x, y, n);
--- 118,145 ----
  {
    ulg n;                /* holds local header offset */
  
!   Trace((stderr, "zipcopy %s\n", z->zname));
!   n = 4 + LOCHEAD + (long)z->nam + (long)z->ext;
! 
!   if (fix > 1) {
!     /* do not trust the old compressed size */
!     if (putlocal(z, y) != ZE_OK)
!       return ZE_TEMP;
! 
!     if (fseek(x, z->off + n, SEEK_SET)) /* seek to compressed data */
!       return ferror(x) ? ZE_READ : ZE_EOF;
! 
!     z->off = tempzn;
!     tempzn += n;
!     n = z->siz;
!   } else {
!     if (fseek(x, z->off, SEEK_SET))     /* seek to local header */
!       return ferror(x) ? ZE_READ : ZE_EOF;
! 
!     z->off = tempzn;
!     n += z->siz;
!   }
!   /* copy the compressed data and the extended local header if there is one */
    if (z->lflg & 8) n += 16;
    tempzn += n;
    return fcopy(x, y, n);
***************
*** 161,167 ****
  #ifndef UTIL
  
  int percent(n, m)
! long n, m;               /* n is the original size, m is the new size */
  /* Return the percentage compression from n to m using only integer
     operations */
  {
--- 149,156 ----
  #ifndef UTIL
  
  int percent(n, m)
! ulg n;
! ulg m;               /* n is the original size, m is the new size */
  /* Return the percentage compression from n to m using only integer
     operations */
  {
***************
*** 170,176 ****
      n += 0x80;  n >>= 8;
      m += 0x80;  m >>= 8;
    }
!   return n ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;
  }
  
  local int suffixes(a, s)
--- 159,165 ----
      n += 0x80;  n >>= 8;
      m += 0x80;  m >>= 8;
    }
!   return n > m ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;
  }
  
  local int suffixes(a, s)
***************
*** 228,234 ****
    int l = 0;            /* true if this file is a symbolic link */
    int m;                /* method for this entry */
    ulg o, p;             /* offsets in zip file */
!   long q = -2L;         /* size returned by filetime */
    int r;                /* temporary variable */
    ulg s = 0L;           /* size of compressed data */
    int isdir;            /* set for a directory name */
--- 217,223 ----
    int l = 0;            /* true if this file is a symbolic link */
    int m;                /* method for this entry */
    ulg o, p;             /* offsets in zip file */
!   long q = -3L;         /* size returned by filetime */
    int r;                /* temporary variable */
    ulg s = 0L;           /* size of compressed data */
    int isdir;            /* set for a directory name */
***************
*** 238,248 ****
    isdir = z->zname[z->nam-1] == '/';
    z->att = (ush)UNKNOWN; /* will be changed later */
  
!   if ((z->tim = filetime(z->name, &a, &q)) == 0 || q < -1L)
      return ZE_OPEN;
!   /* q is set to -1 if the input file is a device */
! 
    remain = -1L; /* changed only for BIG_MEM */
  
    /* Select method based on the suffix and the global method */
    m = special != NULL && suffixes(z->name, special) ? STORE : method;
--- 227,241 ----
    isdir = z->zname[z->nam-1] == '/';
    z->att = (ush)UNKNOWN; /* will be changed later */
  
!   if ((z->tim = filetime(z->name, &a, &q)) == 0 || q < -2L)
      return ZE_OPEN;
!   /* q is set to -1 if the input file is a device, -2 for a volume label */
!   if (q == -2L) {
!      isdir = 1;
!      q = 0;
!   }
    remain = -1L; /* changed only for BIG_MEM */
+   window_size = 0L;
  
    /* Select method based on the suffix and the global method */
    m = special != NULL && suffixes(z->name, special) ? STORE : method;
***************
*** 251,257 ****
    if (strcmp(z->name, "-") == 0)
    {
      ifile = (ftype)zstdin;
! #ifdef MSDOS
      setmode(zstdin, O_BINARY);
  #endif
    }
--- 244,250 ----
    if (strcmp(z->name, "-") == 0)
    {
      ifile = (ftype)zstdin;
! #if defined(MSDOS) || defined(__human68k__)
      setmode(zstdin, O_BINARY);
  #endif
    }
***************
*** 264,269 ****
--- 257,263 ----
      else if (isdir) { /* directory */
        ifile = fbad;
        m = STORE;
+       q = 0;
      }
      else if ((ifile = zopen(z->name, fhow)) == fbad)
        return ZE_OPEN;
***************
*** 272,282 ****
      /* Map ordinary files but not devices. This code should go in fileio.c */
      if (q > 0 && !translate_eol) {
        if (window != NULL)
! 	free(window);  /* window can't be a mapped file here */
        window_size = q + MIN_LOOKAHEAD;
        window = (uch*)mmap(0, window_size, PROT_READ, MAP_SHARED, ifile, 0);
        if (window == (uch*)(-1)) {
! 	window = NULL;
          return ZE_OPEN;
        }
        /* If we can't touch the page beyond the end of file, remap
--- 266,276 ----
      /* Map ordinary files but not devices. This code should go in fileio.c */
      if (q > 0 && !translate_eol) {
        if (window != NULL)
!         free(window);  /* window can't be a mapped file here */
        window_size = q + MIN_LOOKAHEAD;
        window = (uch*)mmap(0, window_size, PROT_READ, MAP_SHARED, ifile, 0);
        if (window == (uch*)(-1)) {
!         window = NULL;
          return ZE_OPEN;
        }
        /* If we can't touch the page beyond the end of file, remap
***************
*** 290,297 ****
           * we would have enough space in the first page (assuming a page
           * size of at least 512 bytes)
           */
! 	fprintf(mesg, " cannot extend mmap on %s", z->name);
! 	window = NULL;
          return ZE_OPEN;
        }
        remain = q;
--- 284,291 ----
           * we would have enough space in the first page (assuming a page
           * size of at least 512 bytes)
           */
!         fprintf(mesg, " cannot extend mmap on %s", z->name);
!         window = NULL;
          return ZE_OPEN;
        }
        remain = q;
***************
*** 302,315 ****
      if (q > 0 && !translate_eol) {
        window_size = q + MIN_LOOKAHEAD;
        window = window ? (uch*) realloc(window, (unsigned)window_size)
! 		      : (uch*) malloc((unsigned)window_size);
        /* Just use normal code if big malloc or realloc fails: */
        if (window != NULL) {
! 	remain = zread(ifile, (char*)window, q+1);
! 	if (remain != q) {
! 	  fprintf(mesg, " q=%ld, remain=%ld ", q, remain);
! 	  error("can't read whole file at once");
! 	}
        }
      }
  # endif /* BIG_MEM */
--- 296,311 ----
      if (q > 0 && !translate_eol) {
        window_size = q + MIN_LOOKAHEAD;
        window = window ? (uch*) realloc(window, (unsigned)window_size)
!                       : (uch*) malloc((unsigned)window_size);
        /* Just use normal code if big malloc or realloc fails: */
        if (window != NULL) {
!         remain = zread(ifile, (char*)window, q+1);
!         if (remain != q) {
!           fprintf(mesg, " q=%ld, remain=%ld ", q, remain);
!           error("can't read whole file at once");
!         }
!       } else {
!         window_size = 0L;
        }
      }
  # endif /* BIG_MEM */
***************
*** 336,351 ****
     */
  
    /* (Assume ext, cext, com, and zname already filled in.) */
! #ifdef OS2
!   z->vem = z->dosflag ? 20 :            /* Made under MSDOS by PKZIP 2.0 */
!   /* For a FAT file system, we must cheat and pretend that the file
     * was not made on OS2 but under DOS. unzip is confused otherwise.
     */
  #else
    z->vem = dosify ? 20 : OS_CODE + REVISION;
  #endif
  
!   z->ver = 20;                          /* Need PKUNZIP 2.0 */
    z->crc = 0;  /* to be updated later */
    /* Assume first that we will need an extended local header: */
    z->flg = 8;  /* to be updated later */
--- 332,348 ----
     */
  
    /* (Assume ext, cext, com, and zname already filled in.) */
! #if defined(OS2) || defined(WIN32)
!   z->vem = z->dosflag ? 20       /* Made under MSDOS by PKZIP 2.0 */
!          : OS_CODE + REVISION;
!   /* For a FAT file system, we cheat and pretend that the file
     * was not made on OS2 but under DOS. unzip is confused otherwise.
     */
  #else
    z->vem = dosify ? 20 : OS_CODE + REVISION;
  #endif
  
!   z->ver = m == STORE ? 10 : 20;     /* Need PKUNZIP 2.0 except for store */
    z->crc = 0;  /* to be updated later */
    /* Assume first that we will need an extended local header: */
    z->flg = 8;  /* to be updated later */
***************
*** 380,386 ****
      tempzn += RAND_HEAD_LEN;
    }
  #endif
!   o = ftell(y); /* for debugging only */
  
    /* Write stored or deflated file to zip file */
    isize = 0L;
--- 377,387 ----
      tempzn += RAND_HEAD_LEN;
    }
  #endif
!   if (ferror(y))
!     err(ZE_WRITE, "unexpected error on zip file");
!   o = ftell(y); /* for debugging only, ftell can fail on pipes */
!   if (ferror(y))
!     clearerr(y); 
  
    /* Write stored or deflated file to zip file */
    isize = 0L;
***************
*** 399,413 ****
         return ZE_MEM;
  
      if (!isdir) /* no read for directories */
!     while ((k = l ? rdsymlnk(z->name, b, CBSZ) : zread(ifile, b, CBSZ)) > 0)
      {
-       isize += k;
-       crc = updcrc(b, k);
        if (zfwrite(b, 1, k, y) != k)
        {
          free((voidp *)b);
          return ZE_TEMP;
        }
  #ifdef MINIX
        if (l)
          q = k;
--- 400,413 ----
         return ZE_MEM;
  
      if (!isdir) /* no read for directories */
!     while ((k = l ? rdsymlnk(z->name, b, CBSZ) : file_read(b, CBSZ)) > 0)
      {
        if (zfwrite(b, 1, k, y) != k)
        {
          free((voidp *)b);
          return ZE_TEMP;
        }
+       if (verbose) putc('.', stderr);
  #ifdef MINIX
        if (l)
          q = k;
***************
*** 432,445 ****
    tempzn += s;
    p = tempzn; /* save for future fseek() */
  
! #ifndef VMS
!   /* Check input size (but not in VMS--variable record lengths mess it up) */
    if (q >= 0 && isize != (ulg)q && !translate_eol)
    {
!     fprintf(mesg, " i=%ld, q=%ld ", isize, q);
!     error("incorrect input size");
    }
! #endif /* !VMS */
  
    /* Try to rewrite the local header with correct information */
    z->crc = crc;
--- 432,447 ----
    tempzn += s;
    p = tempzn; /* save for future fseek() */
  
! #if !defined(MSDOS) && !defined(VMS)
!   /* Check input size (but not in VMS -- variable record lengths mess it up)
!    * and not on MSDOS -- diet in TSR mode reports an incorrect file size)
!    */
    if (q >= 0 && isize != (ulg)q && !translate_eol)
    {
!     Trace((mesg, " i=%ld, q=%ld ", isize, q));
!     warn(" file size changed while zipping ", z->name);
    }
! #endif
  
    /* Try to rewrite the local header with correct information */
    z->crc = crc;
***************
*** 467,472 ****
--- 469,475 ----
      }
  #endif
      z->how = m;
+     z->ver = m == STORE ? 10 : 20;     /* Need PKUNZIP 2.0 except for store */
      if ((z->flg & 1) == 0)
        z->flg &= ~8; /* clear the extended local header flag */
      z->lflg = z->flg;
***************
*** 482,487 ****
--- 485,496 ----
        tempzn += 16L;
      }
    }
+   /* Free the local extra field which is no longer needed */
+   if (z->ext) {
+     if (z->extra != z->cextra)
+       free((voidp *)(z->extra));
+     z->ext = 0;
+   }
  
    /* Display statistics */
    if (noisy)
***************
*** 526,539 ****
  #endif
    if (translate_eol == 0) {
      len = zread(ifile, buf, size);
!     if (len == (unsigned)EOF || len == 0) return len;
  
    } else if (translate_eol == 1) {
      /* Transform LF to CR LF */
      size >>= 1;
      b = buf+size;
      size = len = zread(ifile, b, size);
!     if (len == (unsigned)EOF || len == 0) return len;
      do {
         if ((*buf++ = *b++) == '\n') *(buf-1) = '\r', *buf++ = '\n', len++;
      } while (--size != 0);
--- 535,548 ----
  #endif
    if (translate_eol == 0) {
      len = zread(ifile, buf, size);
!     if (len == (unsigned)EOF || len == 0) return (int)len;
  
    } else if (translate_eol == 1) {
      /* Transform LF to CR LF */
      size >>= 1;
      b = buf+size;
      size = len = zread(ifile, b, size);
!     if (len == (unsigned)EOF || len == 0) return (int)len;
      do {
         if ((*buf++ = *b++) == '\n') *(buf-1) = '\r', *buf++ = '\n', len++;
      } while (--size != 0);
***************
*** 543,549 ****
      /* Transform CR LF to LF and suppress final ^Z */
      b = buf;
      size = len = zread(ifile, buf, size-1);
!     if (len == (unsigned)EOF || len == 0) return len;
      buf[len] = '\n'; /* I should check if next char is really a \n */
      do {
         if ((*buf++ = *b++) == '\r' && *b == '\n') buf--, len--;
--- 552,558 ----
      /* Transform CR LF to LF and suppress final ^Z */
      b = buf;
      size = len = zread(ifile, buf, size-1);
!     if (len == (unsigned)EOF || len == 0) return (int)len;
      buf[len] = '\n'; /* I should check if next char is really a \n */
      do {
         if ((*buf++ = *b++) == '\r' && *b == '\n') buf--, len--;
***************
*** 557,562 ****
    }
    crc = updcrc(buf, len);
    isize += (ulg)len;
!   return len;
  }
  #endif /* !UTIL */
--- 566,571 ----
    }
    crc = updcrc(buf, len);
    isize += (ulg)len;
!   return (int)len;
  }
  #endif /* !UTIL */
