Imported Upstream version 610c21 98/182798/1 upstream/610c21
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 28 Jun 2018 05:25:25 +0000 (14:25 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 28 Jun 2018 05:25:31 +0000 (14:25 +0900)
Change-Id: I321618a57ba40e1148d34bad72caf19a4a8c6f4d
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
182 files changed:
Contents
History.610
INSTALL
README
acorn/riscos.c
acorn/riscos.h
acorn/swiven.c
acorn/swiven.h
aes_wg/LICENSE [new file with mode: 0644]
aes_wg/README_AES_WG.txt [new file with mode: 0644]
aes_wg/USexport_AES_WG.msg [new file with mode: 0644]
aes_wg/aes.h [new file with mode: 0644]
aes_wg/aescrypt.c [new file with mode: 0644]
aes_wg/aeskey.c [new file with mode: 0644]
aes_wg/aesopt.h [new file with mode: 0644]
aes_wg/aestab.c [new file with mode: 0644]
aes_wg/brg_endian.h [new file with mode: 0644]
aes_wg/fileenc.c [new file with mode: 0644]
aes_wg/fileenc.h [new file with mode: 0644]
aes_wg/hmac.c [new file with mode: 0644]
aes_wg/hmac.h [new file with mode: 0644]
aes_wg/iz_aes_wg.h [new file with mode: 0644]
aes_wg/main.c [new file with mode: 0644]
aes_wg/orig/aes.h_orig [new file with mode: 0644]
aes_wg/orig/aesopt.h_orig [new file with mode: 0644]
aes_wg/orig/brg_endian.h_orig [new file with mode: 0644]
aes_wg/orig/fileenc.c_orig [new file with mode: 0644]
aes_wg/orig/hmac.c_orig [new file with mode: 0644]
aes_wg/orig/hmac.h_orig [new file with mode: 0644]
aes_wg/orig/prng.c_orig [new file with mode: 0644]
aes_wg/orig/pwd2key.c_orig [new file with mode: 0644]
aes_wg/orig/sha1.c_orig [new file with mode: 0644]
aes_wg/prng.c [new file with mode: 0644]
aes_wg/prng.h [new file with mode: 0644]
aes_wg/pwd2key.c [new file with mode: 0644]
aes_wg/pwd2key.h [new file with mode: 0644]
aes_wg/sha1.c [new file with mode: 0644]
aes_wg/sha1.h [new file with mode: 0644]
aes_wg/zip-comment.txt [new file with mode: 0644]
amiga/amiga.h
amiga/crc_68.a
amiga/filedate.c
amiga/flate.a
amiga/makesfx.c
amiga/stat.c
amiga/z-stat.h
aosvs/aosvs.h
api.c
apihelp.c
atheos/athcfg.h
atheos/atheos.h
beos/beos.h
beos/beosmain.cpp
consts.h
crc32.c
crc32.h
crypt.c
docs/Contents
docs/UNZIP.HTX [new file with mode: 0644]
docs/UNZIP_CLI.HTX [new file with mode: 0644]
docs/unzip.txt
ebcdic.h
envargs.c
explode.c
extract.c
fileio.c
flexos/flxcfg.h
gbloffs.c
globals.c
globals.h
human68k/crc_68.s
human68k/flate.s
inflate.h
libiz/izunzip_example.c
list.c
macos/README.TXT
macos/UnZp.h
macos/UnZpLib.h
macos/UnZpSFX.h
macos/UnZpSx.h
macos/source/charmap.h
macos/source/getenv.c
macos/source/helpers.c
macos/source/helpers.h
macos/source/maccfg.h
macos/source/macdir.c
macos/source/macdir.h
macos/source/macscreen.c
macos/source/macstat.c
macos/source/macstat.h
macos/source/macstuff.h
macos/source/mactime.c
macos/source/mactime.h
macos/source/macunzip.c
macos/source/pathname.c
macos/source/pathname.h
macos/source/sxunzip.c
man/man1/unzip.1
match.c
mod/win32/w32cfg.h [deleted file]
mod/win32/win32.c [deleted file]
msdos/crc_i86.asm
msdos/doscfg.h
netware/nlmcfg.h
os2/os2acl.c
os2/os2acl.h
os2/os2cfg.h
os2/os2data.h
os2/rexxapi.c
os2/rexxhelp.c
process.c
qdos/callstub.c
qdos/config.S
qdos/crc68.s
qdos/izqdos.h
qdos/makesfx.c
query.c [deleted file]
tandem/tandem.c
tandem/tandem.h
tandem/tannsk.h
theos/_fprintf.c
theos/_isatty.c
theos/_setargv.c
theos/_sprintf.c
theos/_stat.c
theos/charconv.h
theos/oldstat.h
theos/stat.h
theos/theos.c
theos/thscfg.h
timezone.c
timezone.h
tops20/tops20.c
ubz2err.c
unix/Makefile
unix/macosx.h
unreduce.c
unshrink.c
unzip.c
unzip.h
unzpriv.h
unzvers.h
vms/INSTALL_VMS.txt
vms/build_unzip.com
vms/cmdline.c
vms/descrip_src.mms
vms/unz_cli.cld
vms/vms.c
vms/vmsdefs.h
win32/crc_i386.asm
win32/crc_i386.c
win32/crc_lcc.asm
win32/rsxntwin.h
win32/test_unzip.cmd
win32/vc10/funzip/funzip.vcxproj
win32/vc10/unzip/unzip.vcxproj
win32/vc10/unzipsfx/unzipsfx.vcxproj
win32/win32.c
wince/intrface.h
wince/punzip.h
wince/punzip.rcv
wince/wince.cpp
wince/winmain.cpp
wince/winmain.h
windll/decs.h
windll/guisfx/dialog.h
windll/unzipstb.c
windll/vc10/unzip32_dll/unzip32_dll.vcxproj
windll/windll.h
winlib/vc10/izunzip_example/izunzip_example.vcxproj [new file with mode: 0644]
winlib/vc10/izunzip_example/izunzip_example.vcxproj.filters [new file with mode: 0644]
winlib/vc10/libbz2/libbz2.vcxproj [new file with mode: 0644]
winlib/vc10/libbz2/libbz2.vcxproj.filters [new file with mode: 0644]
winlib/vc10/winlib.sln [new file with mode: 0644]
winlib/vc10/winlib/winlib.vcxproj [new file with mode: 0644]
winlib/vc10/winlib/winlib.vcxproj.filters [new file with mode: 0644]
zip-comment.txt
zip.h
zipinfo.c
zos/vmmvs.c
zos/vmmvs.h
zvm/vmstat.h

index 315c2bc..1169167 100644 (file)
--- a/Contents
+++ b/Contents
@@ -42,7 +42,7 @@ man/man1/       nroff "man" sources for the main user documentation
 
    Miscellaneous
 file_id.diz     BBS-oriented file describing this archive  [?]
-testmake.zip    Test archive for checking whether newly built UnZip works
+testmake.zip    Test archive for checking an UnZip program
 testmake_ppmd.zip  Test archive with PPMd compression
 
    Source Code
@@ -69,6 +69,7 @@ inflate.c       Deflate compression (method 8)
 inflate.h       Header file for inflate.c
 list.c          UnZip (not ZipInfo) listing
 match.c         Pattern-matching for filename wildcards
+memdiag.c       Memory diagnostics
 process.c       Multiple archives, memory management, extra field
 timezone.c      Timezone and timestamp supplement
 timezone.h      Header file for timezone.c
@@ -106,6 +107,7 @@ vms/            VMS/OpenVMS
 win32/          Windows 9x and Windows NT
 wince/          Windows CE (GUI version)
 windll/         Windows 3.x/9x/NT DLLs
+winlib/         Windows NT object library
 zos/            z/OS
 zvm/            VM/CMS and MVS
 
index bbc5944..7d8b044 100644 (file)
@@ -1,4 +1,4 @@
-UnZip, version 6.1c, ?? ??? 2014
+UnZip, version 6.1c, ?? ??? 2016
 
 These changes occurred in beta versions 6.10a through 6.1c.
 
@@ -651,6 +651,16 @@ Features added (or removed):
    theos/theos.c, tops20/tops20.c, unix/unix.c, vms/vms.c,
    win32/win32.c, zos/vmmvs.c) [sanvila, SMS]
 
+6.1c21 (30 Oct 2016):
+ - Changed the command-line syntax of the Windows test command script to
+   allow the user to specify a particular UnZip program name, instead of
+   "unzip".  This allows the test script to be used with the UnZip-like
+   example programs supplied with DLL (windll/unzipstb.c) or static
+   library (winlib/izunzip_example.c).  (win32/test_unzip.cmd) [SMS]
+ - Revised Usage text, and, on VMS, the DCL foreign-command symbol
+   suggestions.  Other related, minor code tidying.  (unzip.c, unzip.h,
+   unzpriv.h, vms/cmdline.c) [SMS]
+
 
 Bugs fixed:
 
@@ -861,12 +871,12 @@ Bugs fixed:
  - Add comment about disk number == 1.  (process.c) [EG]
 
 6.10c04 (05 Aug 2011):
- - Replace some Mac-specific AppleDouble-related code which got omitted
+ - Restore some Mac-specific AppleDouble-related code which got omitted
    between 6.10a and 6.10b(?)  (extract.c) [SMS]
- - Replace lost code for enhanced "apparent file type" message in
+ - Restore lost code for enhanced "apparent file type" message in
    ZipInfo.  A hex value is now included, to show useful info for
    unexpected values (not "binary", "ebcdic", or "text").  zipinfo.c [SMS]
- - Replace lost change enabling "-s" everywhere.  Replace lost change to
+ - Restore lost change enabling "-s" everywhere.  Restore lost change to
    VMS usage text.  (unzip.c, unzip.h) [SMS]
  - Remove an unused variable (aes_strngth).  (zipinfo.c) [EG, SMS]
  - Reform a defective ZCRYPT version test, now handling version 3.0 case.
@@ -1356,7 +1366,7 @@ Bugs fixed:
    large values should be displayed properly when space allows.  Forum
    topics: http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=267
    http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=437
-   (zipinfo.c) [quanww, sanvila, SMS]
+   CVE-2014-9913.  (zipinfo.c) [quanww, sanvila, SMS]
  - Added some crude, optional, dynamic memory tracing diagnostic
    capability for use by developers.  (api.c, crypt.c, envargs.c,
    extract.c, fileio.c, funzip.c, globals.c, inflate.c, match.c,
@@ -1760,5 +1770,151 @@ Bugs fixed:
    fake "compression method" of 99, and the actual compression method is
    stored in an AES_WG extra block.  In some cases, the AES_WG "99"
    value was being used instead of the actual value from the extra
-   block.)  (extract.c)  [Elvis Angelaccio, SMS] 
+   block.)  (extract.c)  [Elvis Angelaccio, SMS]
  - Revised some "UT"-related comments.  (process.c) [SMS]
+
+6.1c21 (12 May 2017):
+ - Changed the Windows DLL UnZip-like example program to send its
+   example-specific messages to stderr instead of stdout.  This allows
+   the ZipInfo test in the Windows test command script
+   (win32/test_unzip.cmd) to pass.  (windll/unzipstb.c) [SMS]
+ - Extended the crude, optional, dynamic memory tracing diagnostic
+   capability for use by developers to some VMS-specific modules.
+   (vms/cmdline.c, vms/vms.c) [SMS]
+ - The -da/--auto-extract-dir (/[NO]AUTO_DIRECTORY) option, to create a
+   destination directory based on the archive name, was truncating the
+   archive name at the leftmost dot, not the rightmost dot, leading to a
+   truncated directory name if the archive name included multiple dots.
+   (fileio.c) [SMS]
+ - Updated the LICENSE notice in source files to "version 2009-Jan-02".
+   Updated the copyright date in the LICENSE file itself.  (apihelp.c,
+   consts.h, crc32.c, crc32.h, ebcdic.h, envargs.c, explode.c,
+   gbloffs.c, globals.c, inflate.h, LICENSE, timezone.c, timezone.h,
+   ubz2err.c, unreduce.c, unshrink.c, zip.h, acorn/riscos.c,
+   acorn/riscos.h, acorn/swiven.c, acorn/swiven.h, amiga/amiga.h,
+   amiga/crc_68.a, amiga/filedate.c, amiga/flate.a, amiga/makesfx.c,
+   amiga/stat.c, amiga/z-stat.h, aosvs/aosvs.h, atheos/athcfg.h,
+   atheos/atheos.h, beos/beos.h, beos/beosmain.cpp, flexos/flxcfg.h,
+   human68k/crc_68.s, human68k/flate.s, macos/README.TXT, macos/UnZp.h,
+   macos/UnZpLib.h, macos/UnZpSFX.h, macos/UnZpSx.h,
+   macos/source/charmap.h, macos/source/getenv.c,
+   macos/source/helpers.c, macos/source/helpers.h,
+   macos/source/maccfg.h, macos/source/macdir.c, macos/source/macdir.h,
+   macos/source/macscreen.c, macos/source/macstat.c,
+   macos/source/macstat.h, macos/source/macstuff.h,
+   macos/source/mactime.c, macos/source/mactime.h,
+   macos/source/macunzip.c, macos/source/pathname.c,
+   macos/source/pathname.h, macos/source/sxunzip.c, msdos/crc_i86.asm,
+   msdos/doscfg.h, netware/nlmcfg.h, os2/os2acl.c, os2/os2acl.h,
+   os2/os2cfg.h, os2/os2data.h, os2/rexxapi.c, os2/rexxhelp.c,
+   qdos/callstub.c, qdos/config.S, qdos/crc68.s, qdos/izqdos.h,
+   qdos/makesfx.c, tandem/tandem.c, tandem/tandem.h, tandem/tannsk.h,
+   theos/charconv.h, theos/oldstat.h, theos/stat.h, theos/theos.c,
+   theos/thscfg.h, theos/_fprintf.c, theos/_isatty.c, theos/_setargv.c,
+   theos/_sprintf.c, theos/_stat.c, tops20/tops20.c, unix/macosx.h,
+   vms/vmsdefs.h, win32/crc_i386.asm, win32/crc_i386.c,
+   win32/crc_lcc.asm, win32/rsxntwin.h, wince/intrface.h,
+   wince/punzip.h, wince/punzip.rcv, wince/wince.cpp, wince/winmain.cpp,
+   wince/winmain.h, windll/decs.h, windll/windll.h,
+   windll/guisfx/dialog.h, zos/vmmvs.c, zos/vmmvs.h, zvm/vmstat.h)
+   [EG, SMS]
+ - The new command-line parser was not properly handling a double hyphen
+   ("--") token, which should stop option interpretation.  When that was
+   changed, some loose global variables were moved into the main globals
+   structure.
+   Forum topic: http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=526
+   (globals.c, globals.h, unzip.c, zipinfo.c) [SMS]
+ - In the VMS CLI UnZip program (UNZIP_CLI.EXE) in /ZIPINFO mode, the
+   /LICENSE qualifier was not recognized.  (vms/cmdline.c,
+   vms/unz_cli.cld) [SMS]
+ - Simplified handling of the different option lists for UnZip and
+   ZipInfo modes.  (unzip.c, unzpriv.h, zipinfo.c) [SMS]
+ - Moved some global variables for user-progress messages into the main
+   globals structure.  (globals.c, globals.h, unzip.c) [SMS]
+ - On Unix, file date-time values in a "UT" (0x5455) extra field block
+   could be ignored if a modern "ux" (0x7875) UID/GID block followed it
+   (which would be usual for an archive created bu Zip 3.x).  The DOS
+   (local) modification date-time (which is always present) would then
+   used instead, but it has a two-second resolution and no timezone
+   information.  The result was a file modification date-time with an
+   even number of seconds, even if the original value was odd, and
+   unexpected hours/date caused by the loss of timezone information.
+   (process.c) [Andries van Bergen, SMS]
+ - In ZipInfo ("-Z", /ZIPINFO) short-format ("-s", /SHORT, default)
+   reports, an unexpectedly large compression method value (>999) caused
+   a (mostly harmless) buffer overflow, and spoiled the report format.
+   Now, values less than 1000 are displayed as before, using a
+   three-digit decimal format, "uDDD", but larger values are displayed
+   using a four-digit (unlabled) hexadecimal format, "XXXX".
+   https://launchpad.net/bugs/1643750  CVE-2016-9844.
+   (zipinfo.c) [Alexis Vanden Eijnde, Tyler Hicks, SMS]
+ - On VMS, a "%" character in an archive name, or in an archive member
+   directory or file name, could cause spurious error/warning messages
+   when a caret-escaped percent sign ("^%") was erroneously interpreted
+   as a one-character wildcard.  Typical messages included:
+      (unzip -T name_with_^%_sign.zip):
+   [ Modify file QIO failed. ]
+   [ %SYSTEM-W-NOMOREFILES, no more files ]
+   warning:  cannot set time for: dev:[dir]name_with_^%_sign.zip;1
+      (extracting/creating a directory with a "%"):
+   warning:  set-dir-attributes failed ($qiow mod) for dev:[dir]x.DIR;1.
+   [ %SYSTEM-W-NOMOREFILES, no more files ]
+   warning:  set times/attribs failed for dev:[dir]
+     failed setting times/attribs for 1 dir entries
+      (extracting a regular file with a "%"):
+   [ Cannot create (QIO) output file dev:[dir]name_with^%_sign.txt ]
+   [ %SYSTEM-W-BADFILENAME, bad file name syntax ]
+   and so on.  In a related problem, on VMS, match.c:iswild() ignored
+   caret escapes, causing many non-wildcard names to be considered
+   wildcard names.  Also, since VMS V7.2 on non-VAX, "?" is a
+   one-character wildcard, equivalent to "%", but was not treated as
+   such.  (Correcting this problem makes possible the first of the
+   problems shown above.)  For example:
+      ($unzip -T name_with_^%_sign.zip)
+   unzip:  cannot find any matches for wildcard specification
+    "name_with_^%_sign.zip".
+   (match.c, vms/vms.c) [Jouk Jansen, SMS]
+ - Added "ZCONST" to an argument declaration in action_msg() to clear a
+   GCC compiler warning on AIX.  (extract.c) [SMS]
+ - Changed some archive data buffer types from "char" to "unsigned
+   char".  (extract.c, globals.c, globals.h, fileio.c, process.c,
+   unzpriv.h) [SMS]
+ - Added code to detect (and, for now, mostly ignore) a Central
+   Directory Digital Signature.  Previously, its presence could cause a
+   spurious informational message: "note:  didn't find
+   end-of-central-dir signature at end of central dir."  Now, it
+   triggers an informational message saying that the digital signature
+   data were detected but ignored.  (consts.h, extract.c, globals.c,
+   globals.h, list.c, process.c, unzpriv.h, zipinfo.c) [Jakub Martisko,
+   SMS]
+ - When processing a Zip64 (large-file) archive, "unzip -T" could
+   generate a spurious informational message, "note:  didn't find
+   end-of-central-dir signature at end of central dir."  Otherwise, the
+   results seem to have been correct.  (list.c) [SMS]
+ - Added a Windows-specific "#pragma comment" directive for the bzip2
+   object library in the UnZip object library example program, solving a
+   build failure on Windows.  (libiz/izunzip_example.c) [SMS]
+ - In the Unix builder, added "LANG=C" to the generation rules ("man",
+   nroff) for the ".txt[r]" plain-text formatted "man" files.  This
+   prevents a Unicode locale at build time from affecting the results.
+   (unix/Makefile) [SMS]
+ - Changed a variable type, and added type casts to clear some (VS 2017)
+   compiler warnings involving AES_WG encryption on x64 (using
+   aes_wg/fileenc.c:fcrypt_init()).  (api.c, crypt.c) [SMS]
+ - Tidied Windows vc10 builders, mostly for x64, but some more generally.
+   The bzip2 code (bzip2\compress.c) may trigger a harmless warning on
+   x64.  Made AES_WG support the default (C macro: CRYPT_AES_WG).
+   (win32/vc10/funzip/funzip.vcxproj,
+   win32/vc10/unzipsfx/unzipsfx.vcxproj,
+   windll/vc10/unzip32_dll/unzip32_dll.vcxproj, winlib/vc10/winlib.sln,
+   winlib/vc10/izunzip_example/izunzip_example.vcxproj,
+   winlib/vc10/winlib/winlib.vcxproj) [SMS]
+ - Build failed with an old C compiler (HP-UX PA-RISC bundled).  In
+   process.c:process_zipfiles(), an insufficiently primitve variable
+   declaration.  In unzip.c:UzpVersionStr(), a defective array
+   declaration/initialization.  (process.c, unzip.c) [SMS]
+ - Sloppy code caused various run-time errors when built with an old C
+   compiler (HP-UX PA-RISC bundled).  Typical error messages included:
+    "zipinfo:  Streaming input archive not supported in ZipInfo mode."
+    "End-of-central-directory signature not found."
+   (fileio.c, process.c) [SMS]
diff --git a/INSTALL b/INSTALL
index 4e6abaa..20cf4ae 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
       INSTALL -- Info-ZIP UnZip Installation Instructions
       ===================================================
 
-   UnZip version 6.1.  Revised: 2015-11-13
+   UnZip version 6.1.  Revised: 2017-01-27
 
 ------------------------------------------------------------------------
 
@@ -32,12 +32,13 @@ user-selected options.
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-   For Macintosh Mac OS X, follow the Unix procedures.
+   For Macintosh macOS (Mac OS X), follow the Unix procedures.
 
    For VMS instructions, see also [.vms]INSTALL_VMS.txt.
 
-   For Windows, using Cygwin or MinGW, follow the Unix procedures.  (For
-   Windows using native tools, see the Windows section below.)
+   For Windows, using native tools (Visual Studio), see the Windows
+section below.  For Windows, using Cygwin or MinGW, follow the Unix
+procedures.
 
    +-------------------------------------------------------------------+
    | Many system types have a system-specific directory ("unix/",      |
@@ -114,35 +115,22 @@ or not "unzip -a" is used to extract them.  (Unix users could use "unzip
    Advanced Encryption Standard (AES) Encryption
    ---------------------------------------------
 
-   To enable support for AES encryption, a separate IZ_AES_WG source kit
-is needed.  On the Info-ZIP FTP server, the IZ_AES_WG source kit should
-be found in:
+   All the source files needed to enable support for AES encryption are
+included in a normal UnZip source kit.  Information about AES encryption
+in Info-ZIP programs can normally be found in the file
+aes_wg/README_AES_WG.txt.
 
-      ftp://ftp.info-zip.org/pub/infozip/crypt/
+      For export control reasons, it may be possible to find an UnZip
+      source kit from which these files have been removed.  If the files
+      in the "aes_wg" subdirectory are missing, then the simplest
+      solution is to fetch a complete source kit from any of the usual
+      places.  For more information if the aes_wg/README_AES_WG.txt
+      file is missing, it should also be available at:
 
-The latest kit should be:
-
-      ftp://ftp.info-zip.org/pub/infozip/crypt/iz_aes_wg.zip
-
-but other, older kits may also be available there.  Version
-compatibility information should be included in the IZ_AES_WG
-documentation.  The latest version of that should be:
-
-      ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
-
-It might be wise to read that before downloading any particular
-IZ_AES_WG kit.
-
-   The IZ_AES_WG kit should be unpacked in the main UnZip directory,
-where it should populate the "aes_wg" subdirectory.  For example, if
-the proper IZ_AES_WG kit is "iz_aes_wg13.zip", then use commands like
-the following:
-
-      cd unzip61                        # (If not already there.)
-      unzip ../iz_aes_wg13.zip
+            ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
 
    See the "Build" section, below, for details on how to build UnZip
-with AES encryption support.
+with or without AES encryption support.
 
 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
@@ -177,15 +165,15 @@ by UnZip builders.
       -------------------------------------------
 
    Beginning with UnZip version 6.10c (beta), support for optional
-compression methods bzip2, LZMA, and PPMd is enabled by default.  The
-code used to implement these compression methods and the code in the
-optional source kit for AES_WG encryption are generally written to newer
-C language standards than the base Info-ZIP code, so some very old
-compilers may be unable to build UnZip if these features are enabled.
-In other cases, some special build options must be specified to get a
-particular feature to work properly.  The build instructions below (and
-in other, system-specific, supplementary documents) show how to disable
-these optional features and/or how work around specific build problems.
+compression methods bzip2, LZMA, and PPMd, and for AES_WG encryption is
+enabled by default.  The code used to implement these compression and
+encryption methods and is generally written to newer C language
+standards than the base Info-ZIP code, so some very old compilers may be
+unable to build UnZip if these features are enabled.  In other cases,
+some special build options must be specified to get a particular feature
+to work properly.  The build instructions below (and in other,
+system-specific, supplementary documents) show how to disable these
+optional features and/or how work around specific build problems.
 
 ------------------------------------------------------------------------
 
@@ -252,12 +240,10 @@ the popular "make" options):
    When using "make generic", add the "make" macros listed below to
 control the corresponding optional features:
 
-      NO_AES_WG=1       Disable support for WinZip-compatible AES
-                        (strong) encryption (if the optional source kit
-                        is present).  Support requires a separate
-                        IZ_AES_WG source kit, as described above
-                        ("Optional Source Kits"), but is enabled by
-                        default if that source kit is present.
+      NO_AES_WG=1       Disable support for AES_WG (WinZip-compatible
+                        AES (strong)) encryption.  By default, this
+                        support is enabled, if the AES_WG source files
+                        are present in the "aes_wg" subdirectory.
 
       BINS=[L][M][U]    Binaries build list:
                          L: object library (libizunzip.a)
@@ -543,7 +529,7 @@ instead of specifying many options using the LOCAL_UNZIP "make" macro.
 
    The Info-ZIP developers do not have access to all the system types
 for which support has been included (or suggested) in the various "make"
-files. so non-"generic" targets are less well tested, and may need
+files, so non-"generic" targets are less well tested, and may need
 considerable help from the user to get optimal results (or any success
 at all).  Feedback from users of these system types would be gratefully
 received.  To get a list of all possible system targets, use a command
@@ -576,10 +562,10 @@ built without some expected features enabled.
    Build Suggestions for Various Non-"generic" Targets
    ---------------------------------------------------
 
-Macintosh (Mac OS X)
-   On Mac OS X, use the Unix build procedure, described above.  Our
-   testing has been done using the Command Line Tools for Xcode.  (In
-   some Xcode versions, the Command Line Tools may not be enabled by
+Macintosh (macOS, Mac OS X)
+   On macOS (Mac OS X), use the Unix build procedure, described above.
+   Our testing has been done using the Command Line Tools for Xcode.
+   (In some Xcode versions, the Command Line Tools may not be enabled by
    default.)  Currently, installing the (separate, much smaller) Command
    Line Tools package (without the whole Xcode package) is all that is
    needed.  For pre-Mac-OS-X Macintosh, see below for old infomation.
@@ -646,60 +632,17 @@ Windows (XP, Vista, 7, and so on)
    for the "unz32dll" and "uzexampl" projects.
 
    Currently, Microsoft Visual Studio 2010 (Visual C++ v10.0), VS 2012
-   (VC++ v11.0), and VS 2013 (VC++ 12.0) are the only tested versions.
-   Newer Visual Studio versions may work, but have not been tested.
-   Builder files for older Visual Studio versions have not been removed
-   from the kit, and may work in limited ways, but they have not been
-   updated to handle the latest optional features (optional compression
-   and encryption methods, and so on).  The Unix-like Windows
-   environments, Cygwin and MinGW, use the Unix builders, not the Visual
-   Studio builders.  Other, non-Microsoft compilers (like Borland or
-   Watcom) have not been tested.  Obsolete information for older Visual
-   Studio versions and other compilers follows:
-
-   For creating Windows executables, the Microsoft Visual C++ compiler
-   platforms from version 2.x up to 8.0 (Visual Studio .Net C++ 2005)
-   should work.  Recent build tests have been run on VC++ 6.0, 7.1 and
-   8.0.  The linker of newer Microsoft Visual C++ versions (beginning
-   with Visual C++ 2008 - [VC++ 9.0]) create executables that are marked
-   to run on Windows 2000 and newer, only.  Although these Visual C++
-   environments may succeed in building Windows Info-ZIP executables,
-   they cannot (and must not) be used to create binaries for public
-   distribution, if support for older systems is intended.
-
-   Alternative compilers for the Intel platforms are OpenWatcom C++,
-   GNU C (Cygwin and MinGW32 have been tested, others, such as emx/rsxnt
-   may also work), Borland C++, or lcc-win32.  DEC C/C++ for NT/Alpha
-   may or may not still work.
-
-   For the Watcom compiler, use WMAKE and win32\makefile.wat.
-
-   For the Microsoft compilers, use NMAKE and win32\Makefile.
-
-   For Cygwin or MinGW, use unix/Makefile and the "generic" target.
-   (An old win32\Makefile.gcc may still be included in the kit, but it
-   lacks support for many features, and may be of little value.)
-
-   With emx+gcc, a good choice is GNUMake 3.75 (or higher) from the
-   djgpp V2 distribution used on win32\Makefile.emx.
-
-   The unzip32.dll WinDLL executables can be built using the appropriate
-   Makefile in the win32\ subdirectory, or by using the Microsoft Visual
-   C++ project files supplied below the windll\ subdirectory.  Besides
-   the MSC compilers, gcc-mingw32, Watcom C and Borland C allow to build
-   the Windows UnZip DLL.  By default, the Makefiles for compilers that
-   use the Microsoft C runtime are configured to link against the shared
-   multithreading C runtime DLL.  Depending on the intended usage for
-   unzip32.dll, a statically linked dll might be more suitable.  The
-   "make" scripts for MSC support build variants with static linking; you
-   should look up the configuration switch DLLSTANDALONE in the MSC
-   Makefile or the "Static..." build configurations in the Visual Studio
-   project files.
-
-Windows CE
-   Only Microsoft Visual C++ 5.0, 6.0 or Visual C++ embedded 3.0 or later
-   are supported.  Use the appropriate version of the included project
-   files and check wince\README for details.
+   (VC++ v11.0), VS 2013 (VC++ 12.0), and VS 2015 (VC++ 14.0) are the
+   only tested versions.  Newer Visual Studio versions may work, but
+   have not been tested.  Builder files for older Visual Studio versions
+   have not been removed from the kit, and may work in limited ways, but
+   they have not been updated to handle the latest optional features
+   (optional compression and encryption methods, and so on).  The
+   Unix-like Windows environments, Cygwin and MinGW, use the Unix
+   builders, not the Visual Studio builders.  Other, non-Microsoft
+   compilers (like Borland or Watcom) have not been tested.  Obsolete
+   information for older Visual Studio versions and other compilers may
+   be found below.
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -743,9 +686,9 @@ Human68K
    This port has not been tested since the 5.12 release.
 
 Macintosh (Pre-Mac-OS-X)
-   On Mac OS X, use the Unix build procedure.  The following information
-   for pre-Mac-OS-X Macintosh is old, obsolete, and probably useless,
-   and is included for completeness only.
+   On macOS (Mac OS X), use the Unix build procedure.  The following
+   information for pre-Mac-OS-X Macintosh is old, obsolete, and probably
+   useless, and is included for completeness only.
 
    Metrowerks CodeWarrior Pro 4 with Universal Interfaces 3.1 is the only
    currently supported compiler, although the Mac Programmer's Workbench
@@ -774,6 +717,51 @@ TOPS-20
    directory only (including those in the kit's tops20 directory), then
    use make.mic and "do make".
 
+Obsolete Windows Versions/Tools
+   For creating Windows executables, the Microsoft Visual C++ compiler
+   platforms from version 2.x up to 8.0 (Visual Studio .Net C++ 2005)
+   should work.  Recent build tests have been run on VC++ 6.0, 7.1 and
+   8.0.  The linker of newer Microsoft Visual C++ versions (beginning
+   with Visual C++ 2008 - [VC++ 9.0]) create executables that are marked
+   to run on Windows 2000 and newer, only.  Although these Visual C++
+   environments may succeed in building Windows Info-ZIP executables,
+   they cannot (and must not) be used to create binaries for public
+   distribution, if support for older systems is intended.
+
+   Alternative compilers for the Intel platforms are OpenWatcom C++,
+   GNU C (Cygwin and MinGW32 have been tested, others, such as emx/rsxnt
+   may also work), Borland C++, or lcc-win32.  DEC C/C++ for NT/Alpha
+   may or may not still work.
+
+   For the Watcom compiler, use WMAKE and win32\makefile.wat.
+
+   For the Microsoft compilers, use NMAKE and win32\Makefile.
+
+   For Cygwin or MinGW, use unix/Makefile and the "generic" target.
+   (An old win32\Makefile.gcc may still be included in the kit, but it
+   lacks support for many features, and may be of little value.)
+
+   With emx+gcc, a good choice is GNUMake 3.75 (or higher) from the
+   djgpp V2 distribution used on win32\Makefile.emx.
+
+   The unzip32.dll WinDLL executables can be built using the appropriate
+   Makefile in the win32\ subdirectory, or by using the Microsoft Visual
+   C++ project files supplied below the windll\ subdirectory.  Besides
+   the MSC compilers, gcc-mingw32, Watcom C and Borland C allow to build
+   the Windows UnZip DLL.  By default, the Makefiles for compilers that
+   use the Microsoft C runtime are configured to link against the shared
+   multithreading C runtime DLL.  Depending on the intended usage for
+   unzip32.dll, a statically linked dll might be more suitable.  The
+   "make" scripts for MSC support build variants with static linking; you
+   should look up the configuration switch DLLSTANDALONE in the MSC
+   Makefile or the "Static..." build configurations in the Visual Studio
+   project files.
+
+Windows CE
+   Only Microsoft Visual C++ 5.0, 6.0 or Visual C++ embedded 3.0 or later
+   are supported.  Use the appropriate version of the included project
+   files and check wince\README for details.
+
 ------------------------------------------------------------------------
 
       Test
diff --git a/README b/README
index 712f685..b720319 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
                         ------------------------
 
    Program version: 6.1c (BETA).
-   Document date: 2015-04-15
+   Document date: 2016-04-07
 
 ------------------------------------------------------------------------
 
@@ -132,8 +132,8 @@ TOPS-20.  A DLL is available for OS/2 and Windows.
    - New option "-so"/"--options" lists all available options.
    - New option "-sc"/"--commandline" shows the input command line and
      exits.
-   - New "--license" option lists the license.  This allows distribution
-     without additional documentation.
+   - New "--license" option displays the license.  This allows program
+     distribution without additional documentation.
 
 - Behavior change: Now, by default, date-time information is restored on
   extracted files only, not on created directories.  Use "-D" to restore
@@ -169,7 +169,7 @@ TOPS-20.  A DLL is available for OS/2 and Windows.
   query should always show the file-system path/name which has the
   conflict (including the effects of any "-d exdir" or "-j[=N]"
   options), and a user-specified "rename" (file-system) path/name should
-  be used as-specified.
+  be used as specified.
 
 - New -da/--auto-extract-dir option to specify a destination directory
   for extracted files which is derived from the base name of the
@@ -271,6 +271,9 @@ welcome, as are feature requests and other suggestions, and even general
 usage questions (ideally on topics which are not already well explained
 in the existing documentation).
 
+   This is especially true for UnZip 6.1c, because of the extent of the
+changes made since UnZip 6.10b.
+
    The developers also use an internal e-mail discussion forum, with a
 Web-form submission gateway ("Info-ZIP Bug Report") at:
       http://info-zip.org/zip-bug.html
@@ -323,4 +326,19 @@ place to start for anyone wishing to contribute.  There are many
 projects, small and large (some, _very_ large), listed there.  New
 contributors are welcome.
 
+   We try to acknowledge contributions in the release notes (History.*,
+and so on), but sometimes we fail.  If you deserve credit for some
+contribution but don't see it, please let us know, and we'll try again
+in the next release.
+
+------------------------------------------------------------------------
+
+      Apology
+      -------
+
+   Too much time has passed between the releases of UnZip versions 6.10b
+and 6.1c.  UnZip 6.1c lacks support for some new features in Zip 3.1d. 
+We'll try to get the missing features into UnZip 6.1d, and to get the
+final UnZip 6.1 released in a more timely way.
+
 ------------------------------------------------------------------------
index e746ad5..e3fdde9 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2010 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 519f06c..7569b2f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2010 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index ceba284..c116537 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2010 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 1999-Oct-05 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, both of these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.cdrom.com/pub/infozip/license.html
index 836fccf..4f125f4 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2010 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/aes_wg/LICENSE b/aes_wg/LICENSE
new file mode 100644 (file)
index 0000000..a5d2fea
--- /dev/null
@@ -0,0 +1,62 @@
+This is version 2009-Jan-02 of the Info-ZIP license.
+The definitive version of this document should be available at
+ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and
+a copy at http://www.info-zip.org/pub/infozip/license.html.
+
+
+Copyright (c) 1990-2010 Info-ZIP.  All rights reserved.
+
+For the purposes of this copyright and license, "Info-ZIP" is defined as
+the following set of individuals:
+
+   Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
+   Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth,
+   Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
+   David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
+   Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
+   Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda,
+   Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren,
+   Rich Wales, Mike White.
+
+This software is provided "as is," without warranty of any kind, express
+or implied.  In no event shall Info-ZIP or its contributors be held liable
+for any direct, indirect, incidental, special or consequential damages
+arising out of the use of or inability to use this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the above disclaimer and the following restrictions:
+
+    1. Redistributions of source code (in whole or in part) must retain
+       the above copyright notice, definition, disclaimer, and this list
+       of conditions.
+
+    2. Redistributions in binary form (compiled executables and libraries)
+       must reproduce the above copyright notice, definition, disclaimer,
+       and this list of conditions in documentation and/or other materials
+       provided with the distribution.  Additional documentation is not needed
+       for executables where a command line license option provides these and
+       a note regarding this option is in the executable's startup banner.  The
+       sole exception to this condition is redistribution of a standard
+       UnZipSFX binary (including SFXWiz) as part of a self-extracting archive;
+       that is permitted without inclusion of this license, as long as the
+       normal SFX banner has not been removed from the binary or disabled.
+
+    3. Altered versions--including, but not limited to, ports to new operating
+       systems, existing ports with new graphical interfaces, versions with
+       modified or added functionality, and dynamic, shared, or static library
+       versions not from Info-ZIP--must be plainly marked as such and must not
+       be misrepresented as being the original source or, if binaries,
+       compiled from the original source.  Such altered versions also must not
+       be misrepresented as being Info-ZIP releases--including, but not
+       limited to, labeling of the altered versions with the names "Info-ZIP"
+       (or any variation thereof, including, but not limited to, different
+       capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the
+       explicit permission of Info-ZIP.  Such altered versions are further
+       prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP
+       e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP
+       will provide support for the altered versions.
+
+    4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
+       "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its
+       own source and binary releases.
diff --git a/aes_wg/README_AES_WG.txt b/aes_wg/README_AES_WG.txt
new file mode 100644 (file)
index 0000000..c67ea52
--- /dev/null
@@ -0,0 +1,211 @@
+                        README_AES_WG.txt
+                        -----------------
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+      Introduction
+      ------------
+
+   The Info-ZIP programs UnZip (version 6.1 and later) and Zip (version
+3.1 and later) include optional support for Advanced Encryption Standard
+(AES) encryption, a relatively strong encryption method.  This document
+describes the Info-ZIP AES implementation, and provides its terms of
+use.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+         WARNING
+         -------
+
+      The Info-ZIP AES_WG source kit (iz_aes_wg.zip), and the UnZip and
+      Zip source kits which include it, are subject to US export control
+      laws.  BEFORE downloading or using any version of any of these
+      kits, read the following Encryption Notice.  You agree to follow
+      these terms (as well as the terms of the Info-ZIP license) when
+      you download and/or use any of these source kits.
+
+         Encryption Notice
+         -----------------
+
+      This software kit includes encryption software.  The country or
+      other jurisdiction where you are may restrict the import,
+      possession, use, and/or re-export to another country, of
+      encryption software.  BEFORE using any encryption software, please
+      check all applicable laws, regulations, and policies concerning
+      the import, possession, use, and re-export of encryption software,
+      to see if these are permitted.  Some helpful information may be
+      found at: http://www.wassenaar.org/
+
+      Export and re-export of this software from the US are governed by
+      the US Department of Commerce, Bureau of Industry and Security
+      (BIS).  This is open-source ("publicly available") software.
+      Info-ZIP has submitted the required notification to the BIS.  The
+      details are:
+         Export Commodity Control Number (ECCN) 5D002
+         License Exception: Technology Software Unrestricted (TSU)
+         (Export Administration Regulations (EAR) Section 740.13)
+
+      A copy of the required BIS notification is available in the file
+      aes_wg/USexport_aes_wg.msg in the source kits, and at:
+         ftp://ftp.info-zip.org/pub/infozip/crypt/USexport_AES_WG.msg
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+      Description
+      -----------
+
+   The Info-ZIP programs UnZip (version 6.1 and later) and Zip (version
+3.1 and later) include optional support for Advanced Encryption Standard
+(AES) encryption, a relatively strong encryption method.  Traditional
+zip encryption, in contrast, is now considered relatively weak and easy
+to crack.
+
+   The Info-ZIP AES implementation is based on the WinZip AES
+specification, and uses AES encryption code supplied by Brian Gladman.
+We refer to it as IZ_AES_WG (Info-ZIP AES WinZip/Gladman) or simply
+AES_WG.  The WinZip AES scheme is described in:
+
+      http://www.winzip.com/aes_info.htm
+
+   Briefly, the WinZip AES scheme uses compression method 99 to flag an
+AES-encrypted archive member.  (In contrast, PKZIP AES encryption uses
+an incompatible scheme with different archive data structures.  However,
+current versions of PKZIP may also be able to process WinZip AES
+encrypted archive entries.)
+
+   The IZ_AES_WG implementation supports 128-, 192-, and 256-bit keys.
+See the various discussions of WinZip AES encryption on the Internet for
+more on the security of the WinZip AES encryption implementation.
+
+   The IZ_AES_WG source kit is based on an AES source kit provided by
+Brian Gladman, which we obtained at:
+
+      http://gladman.plushost.co.uk/oldsite/cryptography_technology/
+      fileencrypt/files.zip
+
+with one header file ("brg_endian.h") from a newer kit:
+
+      http://gladman.plushost.co.uk/oldsite/AES/aes-src-11-01-11.zip
+
+(Non-Windows users should use "unzip -a" when unpacking those kits.)
+
+   That site is no longer active, so the only independent sources for
+those kits may be Internet archive providers.  Dr. Gladman's current AES
+material may be found at:
+
+      http://www.gladman.me.uk/AES
+      https://github.com/BrianGladman/AES
+
+   We chose the code from the older Gladman code kits primarily to
+ensure compatibility with WinZip.  We made some changes to it to improve
+its portability to different hardware and operating systems.
+
+   The portability-related changes to the original Gladman code include:
+
+      Use of <string.h> instead of <memory.h>.
+
+      Use of "brg_endian.h" for endian determination.
+
+      Changing "brg_endian.h" to work with GNU C on non-Linux systems,
+      and on SunOS 4.x systems.
+
+      #include <limits.h> instead of "limits.h" in aes.h.
+
+      Changing some "long" types to "int" or "sha1_32t" in hmac.c and
+      hmac.h to accommodate systems (like Mac OS X on Intel) where a
+      64-bit "long" type caused bad results.
+
+   Comments in the code identify the changes.  (Look for "Info-ZIP".)
+The IZ_AES_WG kit includes the original files from those kits, as well
+as files which we have modified.  The original forms of modified files
+are preserved in an "orig" subdirectory, for reference.
+
+   The name "IZ_AES_WG" (Info-ZIP AES WinZip/Gladman) is used by
+Info-ZIP to identify our implementation of WinZip AES encryption of Zip
+archive members, using encryption code supplied by Dr. Gladman.  WinZip
+is a registered trademark of WinZip International LLC.  PKZIP is a
+registered trademark of PKWARE, Inc.
+
+   The source code files from Dr. Gladman are subject to the LICENSE
+TERMS at the top of each source file.  The entire IZ_AES_WG kit is
+provided under the Info-ZIP license, a copy of which is included in the
+file LICENSE in the source kits.  The latest version of the Info-ZIP
+license should be available at:
+
+      http://www.info-zip.org/license.html
+
+   NOTE: The IZ_AES_WG source kit is intended for use with the Info-ZIP
+         UnZip and Zip programs ONLY.  Any other use is unsupported and
+         not recommended.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+      Building UnZip and Zip with AES_WG Encryption Support
+      -----------------------------------------------------
+
+   The IZ_AES_WG source kit is normally included in the basic UnZip and
+Zip source kits, and its files should be found in an "aes_wg"
+subdirectory.
+
+   The build instructions (INSTALL) in the UnZip and Zip source kits
+describe how to build UnZip and Zip with (or without) support for AES_WG
+encryption.
+
+   The UnZip and Zip README files have additional general information on
+AES encryption, and the UnZip and Zip manual pages provide the details
+on how to use AES encryption in these programs.
+
+   Be aware that some countries or jurisdictions may restrict who may
+download or use strong encryption source code and binaries. Prospective
+users are responsible for determining whether they are legally allowed
+to download or use this encryption software.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+      Acknowledgements
+      ----------------
+
+   We're grateful to Dr. Gladman for providing the AES encryption code.
+Any problems involving AES_WG encryption in Info-ZIP programs should be
+reported to the Info-ZIP team, not to Dr. Gladman.  However, any questions
+on AES encryption or decryption algorithms, or regarding Gladman's code
+(except as we modified and use it) should be addressed to Dr. Gladman.
+
+   We're grateful to WinZip for making the WinZip AES specification
+available, and providing the detailed information needed to implement
+it.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+      IZ_AES_WG Version History
+      -------------------------
+
+      1.6  2017-01-23  Revised to reflect the inclusion of the IZ_AES_WG
+                       sources in the UnZip and Zip source kits.  [SMS]
+      1.5  2016-07-15  Updated USexport_AES_WG.msg to current version.
+                       Updated zip-comment.txt.  Updated this file
+                       (README_AES_WG.txt) to include legal notices
+                       and updates.  [EG]
+      1.4  2015-04-03  Changed "long" types to "int" for counters, and
+                       to "sha1_32t" for apparent 32-bit byte groups,
+                       where a 64-bit "long" type caused bad results (on
+                       Mac OS X, Intel).  (hmac.c, hmac.h) [SMS]
+      1.3  2013-11-18  Renamed USexport.msg to USexport_AES_WG.msg to
+                       distinguish it from the Traditional encryption
+                       notice, USexport.msg.  [SMS]
+      1.2  2013-04-12  Avoid <sys/isa_defs.h> on __sun systems with
+                       __sparc defined (for SunOS 4.x).  (brg_endian.h)
+                       [SMS]
+      1.1  2012-12-31  #include <limits.h> instead of "limits.h" in
+                       aes.h (for VAX C).  [SMS]
+      1.0  2011-07-07  Minor documentation changes.  [SMS, EG]
+                       Compatible with UnZip 6.10 and Zip 3.1.
+                       US Department of Commerce BIS notified.
+      0.5  2011-07-07  Minor documentation changes.  [SMS, EG]
+                       Compatible with UnZip 6.10 and Zip 3.1.
+      0.4  2011-06-25  Minor documentation changes.  [SMS, EG]
+                       Compatible with UnZip 6.10 and Zip 3.1.
+      0.3  2011-06-22  Initial beta version.  [SMS, EG]
+      0.2  2011-06-20  Minor documentation updates.  [EG]
+      0.1  2011-06-17  Initial alpha version.  [SMS]
+
diff --git a/aes_wg/USexport_AES_WG.msg b/aes_wg/USexport_AES_WG.msg
new file mode 100644 (file)
index 0000000..ffff546
--- /dev/null
@@ -0,0 +1,19 @@
+To: crypt (at) bis.doc.gov, enc (at) nsa.gov, web_site (at) bis.doc.gov
+Cc: Zip-Bugs (at) goatley.com
+Subject: TSU NOTIFICATION - Encryption   (Info-ZIP iz_aes_wg.zip)
+
+   SUBMISSION TYPE:       TSU
+   SUBMITTED BY:          Edward Gordon
+   SUBMITTED FOR:         The Info-ZIP group (an informal, Internet-based
+                          collection of software developers with the contact
+                          address given in next item)
+   POINT OF CONTACT:      Zip-Bugs (at) goatley.com
+   PHONE and/or FAX:      n/a
+   MANUFACTURER:          n/a
+   PRODUCT NAME/MODEL #:  iz_aes_wg
+   ECCN:                  5D002
+
+   NOTIFICATION:
+
+           ftp://ftp.info-zip.org/pub/infozip/crypt/iz_aes_wg.zip
+
diff --git a/aes_wg/aes.h b/aes_wg/aes.h
new file mode 100644 (file)
index 0000000..764f66f
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the definitions required to use AES and Rijndael in C.
+*/
+
+#ifndef _AES_H
+#define _AES_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* If a table pointer is needed in the AES context, include the define  */
+/* #define AES_TABLE_PTR                                                */
+
+/*  This include is used to find 8 and 32 bit unsigned integer types    */
+/***********************************************************************
+ * 2012-12-31 SMS for Info-ZIP.
+ * Changed "limits.h" to <limits.h> for VAX C (and general consistency).
+ *
+ * #include "limits.h"
+ ***********************************************************************
+ */
+#include <limits.h>
+
+#if UCHAR_MAX == 0xff                       /* an unsigned 8 bit type   */
+  typedef unsigned char      aes_08t;
+#else
+#error Please define aes_08t as an 8-bit unsigned integer type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff                  /* an unsigned 32 bit type  */
+  typedef   unsigned int     aes_32t;
+#elif ULONG_MAX == 0xffffffff
+  typedef   unsigned long    aes_32t;
+#else
+#error Please define aes_32t as a 32-bit unsigned integer type in aes.h
+#endif
+
+/* This BLOCK_SIZE is in BYTES.  It can have the values 16, 24, 32 or   */
+/* undefined for use with aescrypt.c and aeskey.c, or 16, 20, 24, 28,   */
+/* 32 or undefined for use with aescrypp.c and aeskeypp.c.   When the   */
+/* BLOCK_SIZE is left undefined a version that provides a dynamically   */
+/* variable block size is produced but this is MUCH slower.             */
+
+#define BLOCK_SIZE  16
+
+/* key schedule length (in 32-bit words)                                */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH   128
+#else
+#define KS_LENGTH   (4 * BLOCK_SIZE)
+#endif
+
+typedef unsigned int aes_fret;   /* type for function return value      */
+#define aes_bad      0           /* bad function return value           */
+#define aes_good     1           /* good function return value          */
+#ifndef AES_DLL                  /* implement normal or DLL functions   */
+#define aes_rval     aes_fret
+#else
+#define aes_rval     aes_fret __declspec(dllexport) _stdcall
+#endif
+
+typedef struct                     /* the AES context for encryption    */
+{   aes_32t    k_sch[KS_LENGTH];   /* the encryption key schedule       */
+    aes_32t    n_rnd;              /* the number of cipher rounds       */
+    aes_32t    n_blk;              /* the number of bytes in the state  */
+#if defined(AES_TABLE_PTR)         /* where global variables are not    */
+    void      *t_ptr;              /* available this pointer is used    */
+#endif                             /* to point to the fixed tables      */
+} aes_ctx;
+
+/* The block length (blen) is input in bytes when it is in the range    */
+/* 16 <= blen <= 32 or in bits when in the range 128 <= blen <= 256     */
+/* Only 16 bytes (128 bits) is legal for AES but the files aescrypt.c   */
+/* and aeskey.c provide support for 16, 24 and 32 byte (128, 192 and    */
+/* 256 bit) blocks while aescrypp.c and aeskeypp.c provide support for  */
+/* 16, 20, 24, 28 and 32 byte (128, 160, 192, 224 and 256 bit) blocks.  */
+/* The value aes_good is returned if the requested block size is legal, */
+/* otherwise aes_bad is returned.                                       */
+
+#if !defined(BLOCK_SIZE)
+aes_rval aes_set_block_size(unsigned int blen, aes_ctx cx[1]);
+#endif
+
+/* The key length (klen) is input in bytes when it is in the range      */
+/* 16 <= klen <= 32 or in bits when in the range 128 <= klen <= 256     */
+/* The files aescrypt.c and aeskey.c provide support for 16, 24 and     */
+/* 32 byte (128, 192 and 256 bit) keys while aescrypp.c and aeskeypp.c  */
+/* provide support for 16, 20, 24, 28 and 32 byte (128, 160, 192, 224   */
+/* and 256 bit) keys.  The value aes_good is returned if the requested  */
+/* key size is legal, otherwise aes_bad is returned.                    */
+
+aes_rval aes_set_encrypt_key(const unsigned char in_key[],
+                                        unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_encrypt_block(const unsigned char in_blk[],
+                            unsigned char out_blk[], const aes_ctx cx[1]);
+
+aes_rval aes_set_decrypt_key(const unsigned char in_key[],
+                                        unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_decrypt_block(const unsigned char in_blk[],
+                            unsigned char out_blk[], const aes_ctx cx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/aescrypt.c b/aes_wg/aescrypt.c
new file mode 100644 (file)
index 0000000..4e6e771
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the code for implementing encryption and decryption
+ for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
+ can optionally be replaced by code written in assembler using NASM.
+*/
+
+#include "aesopt.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+#define unused  77  /* Sunset Strip */
+
+#define si(y,x,k,c) (s(y,c) = word_in(x + 4 * c) ^ k[c])
+#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x)     x[4],y[4]
+#else
+#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+ /*
+   the following defines prevent the compiler requiring the declaration
+   of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
+                        s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x)     x[6],y[6]
+#else
+#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5, \
+                        y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
+                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
+                        s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
+                        so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x)     x[8],y[8]
+#else
+#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+                        y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
+                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
+                        s(y,4) = s(x,4); s(y,5) = s(x,5); \
+                        s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+                        si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+                        so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+                        rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{   case 8: si(y,x,k,7); si(y,x,k,6); \
+    case 6: si(y,x,k,5); si(y,x,k,4); \
+    case 4: si(y,x,k,3); si(y,x,k,2); \
+            si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{   case 8: so(y,x,7); so(y,x,6); \
+    case 6: so(y,x,5); so(y,x,4); \
+    case 4: so(y,x,3); so(y,x,2); \
+            so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
+            rm(y,x,k,5); rm(y,x,k,4); \
+            rm(y,x,k,3); rm(y,x,k,2); \
+            rm(y,x,k,1); rm(y,x,k,0); \
+            break; \
+    case 6: rm(y,x,k,5); rm(y,x,k,4); \
+            rm(y,x,k,3); rm(y,x,k,2); \
+            rm(y,x,k,1); rm(y,x,k,0); \
+            break; \
+    case 4: rm(y,x,k,3); rm(y,x,k,2); \
+            rm(y,x,k,1); rm(y,x,k,0); \
+            break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
+    case 6: rm(y,x,k,5); rm(y,x,k,4); \
+    case 4: rm(y,x,k,3); rm(y,x,k,2); \
+            rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION) && !defined(AES_ASM)
+
+/* Given the column (c) of the output state variable, the following
+   macros give the input state variables which are needed in its
+   computation for each row (r) of the state. All the alternative
+   macros give the same end values but expand into different ways
+   of calculating these values.  In particular the complex macro
+   used for dynamically variable block sizes is designed to expand
+   to a compile time constant whenever possible but will expand to
+   conditional clauses on some branches (I am grateful to Frank
+   Yellin for this construction)
+*/
+
+#if defined(BLOCK_SIZE)
+#if BLOCK_SIZE == 16
+# define fwd_var(x,r,c) s(x,((r+c)%nc))
+#else
+#define fwd_var(x,r,c) s(x,(r+c+(((r>1)&&(nc>9-r))?1:0))%nc)
+#endif
+#else
+#define fwd_var(x,r,c)\
+ ( r == 0 ?    s(x,c) \
+ : r == 1 ?           \
+    ( c == 0 ? s(x,1) \
+    : c == 1 ? s(x,2) \
+    : c == 2 ? s(x,3) \
+    : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
+    : c == 4 ? s(x,5) \
+    : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
+    : c == 6 ? s(x,7) : s(x,0)) \
+ : r == 2 ? \
+    ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
+    : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
+    : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+    : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+    : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
+    : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
+    : c == 6 ? s(x,1) : s(x,2)) \
+ : \
+    ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
+    : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+    : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+    : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
+    : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+    : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+    : c == 6 ? s(x,2) : s(x,3)))
+#endif
+
+#if defined(FT4_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
+#elif defined(FT1_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
+#else
+#define fwd_rnd(y,x,k,c)    (s(y,c) = fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)) ^ (k)[c])
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
+#elif defined(FL1_SET)
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
+#else
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = no_table(x,t_use(s,box),fwd_var,rf1,c) ^ (k)[c])
+#endif
+
+aes_rval aes_encrypt_block(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{   aes_32t        locals(b0, b1);
+    const aes_32t  *kp = cx->k_sch;
+    dec_fmvars  /* declare variables for fwd_mcol() if needed */
+
+    if(!(cx->n_blk & 1)) return aes_bad;
+
+    state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == FULL)
+
+    kp += (cx->n_rnd - 9) * nc;
+
+    /*lint -e{616} control flows into case/default */
+    switch(cx->n_rnd)
+    {
+    case 14:
+        round(fwd_rnd,  b1, b0, kp - 4 * nc);
+        round(fwd_rnd,  b0, b1, kp - 3 * nc);
+    case 12:
+        round(fwd_rnd,  b1, b0, kp - 2 * nc);
+        round(fwd_rnd,  b0, b1, kp -     nc);
+    case 10:
+        round(fwd_rnd,  b1, b0, kp         );
+        round(fwd_rnd,  b0, b1, kp +     nc);
+        round(fwd_rnd,  b1, b0, kp + 2 * nc);
+        round(fwd_rnd,  b0, b1, kp + 3 * nc);
+        round(fwd_rnd,  b1, b0, kp + 4 * nc);
+        round(fwd_rnd,  b0, b1, kp + 5 * nc);
+        round(fwd_rnd,  b1, b0, kp + 6 * nc);
+        round(fwd_rnd,  b0, b1, kp + 7 * nc);
+        round(fwd_rnd,  b1, b0, kp + 8 * nc);
+        round(fwd_lrnd, b0, b1, kp + 9 * nc);
+    default:
+        ;
+    }
+#else
+
+#if (ENC_UNROLL == PARTIAL)
+    {   aes_32t    rnd;
+        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+        {
+            kp += nc;
+            round(fwd_rnd, b1, b0, kp);
+            kp += nc;
+            round(fwd_rnd, b0, b1, kp);
+        }
+        kp += nc;
+        round(fwd_rnd,  b1, b0, kp);
+#else
+    {   aes_32t    rnd, *p0 = b0, *p1 = b1, *pt;
+        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+        {
+            kp += nc;
+            round(fwd_rnd, p1, p0, kp);
+            pt = p0, p0 = p1, p1 = pt;
+        }
+#endif
+        kp += nc;
+        round(fwd_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION) && !defined(AES_ASM)
+
+/* Given the column (c) of the output state variable, the following
+   macros give the input state variables which are needed in its
+   computation for each row (r) of the state. All the alternative
+   macros give the same end values but expand into different ways
+   of calculating these values.  In particular the complex macro
+   used for dynamically variable block sizes is designed to expand
+   to a compile time constant whenever possible but will expand to
+   conditional clauses on some branches (I am grateful to Frank
+   Yellin for this construction)
+*/
+
+#if defined(BLOCK_SIZE)
+#if BLOCK_SIZE == 16
+#define inv_var(x,r,c) s(x,((4+c-r)%nc))
+#else
+#define inv_var(x,r,c) s(x,(840+c-r-(((r>1)&&(nc>9-r))?1:0))%nc)
+#endif
+#else
+#define inv_var(x,r,c)\
+ ( r == 0 ?    s(x,c) \
+ : r == 1 ?           \
+    ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
+    : c == 1 ? s(x,0) \
+    : c == 2 ? s(x,1) \
+    : c == 3 ? s(x,2) \
+    : c == 4 ? s(x,3) \
+    : c == 5 ? s(x,4) \
+    : c == 6 ? s(x,5) : s(x,6)) \
+ : r == 2 ? \
+    ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+    : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+    : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
+    : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
+    : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
+    : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
+    : c == 6 ? s(x,3) : s(x,4)) \
+ : \
+    ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
+    : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+    : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+    : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
+    : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+    : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+    : c == 6 ? s(x,2) : s(x,3)))
+#endif
+
+#if defined(IT4_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
+#elif defined(IT1_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
+#else
+#define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol(no_table(x,t_use(i,box),inv_var,rf1,c) ^ (k)[c]))
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
+#elif defined(IL1_SET)
+#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
+#else
+#define inv_lrnd(y,x,k,c)   (s(y,c) = no_table(x,t_use(i,box),inv_var,rf1,c) ^ (k)[c])
+#endif
+
+aes_rval aes_decrypt_block(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{   aes_32t        locals(b0, b1);
+    const aes_32t  *kp = cx->k_sch + nc * cx->n_rnd;
+    dec_imvars  /* declare variables for inv_mcol() if needed */
+
+    if(!(cx->n_blk & 2)) return aes_bad;
+
+    state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == FULL)
+
+    kp = cx->k_sch + 9 * nc;
+
+    /*lint -e{616} control flows into case/default */
+    switch(cx->n_rnd)
+    {
+    case 14:
+        round(inv_rnd,  b1, b0, kp + 4 * nc);
+        round(inv_rnd,  b0, b1, kp + 3 * nc);
+    case 12:
+        round(inv_rnd,  b1, b0, kp + 2 * nc);
+        round(inv_rnd,  b0, b1, kp + nc    );
+    case 10:
+        round(inv_rnd,  b1, b0, kp         );
+        round(inv_rnd,  b0, b1, kp -     nc);
+        round(inv_rnd,  b1, b0, kp - 2 * nc);
+        round(inv_rnd,  b0, b1, kp - 3 * nc);
+        round(inv_rnd,  b1, b0, kp - 4 * nc);
+        round(inv_rnd,  b0, b1, kp - 5 * nc);
+        round(inv_rnd,  b1, b0, kp - 6 * nc);
+        round(inv_rnd,  b0, b1, kp - 7 * nc);
+        round(inv_rnd,  b1, b0, kp - 8 * nc);
+        round(inv_lrnd, b0, b1, kp - 9 * nc);
+    default:
+        ;
+    }
+#else
+
+#if (DEC_UNROLL == PARTIAL)
+    {   aes_32t    rnd;
+        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+        {
+            kp -= nc;
+            round(inv_rnd, b1, b0, kp);
+            kp -= nc;
+            round(inv_rnd, b0, b1, kp);
+        }
+        kp -= nc;
+        round(inv_rnd, b1, b0, kp);
+#else
+    {   aes_32t    rnd, *p0 = b0, *p1 = b1, *pt;
+        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+        {
+            kp -= nc;
+            round(inv_rnd, p1, p0, kp);
+            pt = p0, p0 = p1, p1 = pt;
+        }
+#endif
+        kp -= nc;
+        round(inv_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/aeskey.c b/aes_wg/aeskey.c
new file mode 100644 (file)
index 0000000..5bb39d4
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the code for implementing the key schedule for AES and
+ Rijndael for block and key sizes of 16, 24, and 32 bytes.
+*/
+
+#include "aesopt.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+/* Subroutine to set the block size (if variable). The value can be
+   in bytes, with legal values of 16, 24 and 32, or in bits, with
+   legal values of 128, 192 and 256.
+*/
+
+#if !defined(BLOCK_SIZE)
+
+aes_rval aes_set_block_size(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+#ifdef GLOBALS
+    if(!t_use(in,it)) gen_tabs();
+#else
+    if(!cx->t_ptr || !t_use(in,it)) gen_tabs(cx);
+#endif
+#endif
+    if(((blen & 7) || blen < 16 || blen > 32) && ((blen & 63) || blen < 128 || blen > 256))
+    {
+        cx->n_blk = 0; return aes_bad;
+    }
+    else
+    {
+        cx->n_blk = blen >> (blen < 128 ? 0 : 3); return aes_good;
+    }
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+   length can be specified in bytes, with legal values of 16, 24
+   and 32, or in bits, with legal values of 128, 192 and 256. These
+   values correspond with Nk values of 4, 6 and 8 respectively.
+
+   The following macros implement a single cycle in the key
+   schedule generation process. The number of cycles needed
+   for each cx->n_col and nk value is:
+
+    nk =             4  5  6  7  8
+    ------------------------------
+    cx->n_col = 4   10  9  8  7  7
+    cx->n_col = 5   14 11 10  9  9
+    cx->n_col = 6   19 15 12 11 11
+    cx->n_col = 7   21 19 16 13 14
+    cx->n_col = 8   29 23 19 17 14
+*/
+
+#define ke4(k,i) \
+{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+#define kel4(k,i) \
+{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+
+#define ke6(k,i) \
+{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+    k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
+}
+#define kel6(k,i) \
+{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+}
+
+#define ke8(k,i) \
+{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
+    k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
+}
+#define kel8(k,i) \
+{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+}
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_set_encrypt_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{   aes_32t    ss[8];
+
+#if !defined(FIXED_TABLES)
+#ifdef GLOBALS
+    if(!t_use(in,it)) gen_tabs();
+#else
+    if(!cx->t_ptr || !t_use(in,it)) gen_tabs(cx);
+#endif
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if(!cx->n_blk) cx->n_blk = 16;
+#else
+    cx->n_blk = BLOCK_SIZE;
+#endif
+
+    if(((klen & 7) || klen < 16 || klen > 32) && ((klen & 63) || klen < 128 || klen > 256))
+    {
+        cx->n_rnd = 0; return aes_bad;
+    }
+
+    klen >>= (klen < 128 ? 2 : 5);
+    cx->n_blk = (cx->n_blk & ~3) | 1;
+
+    cx->k_sch[0] = ss[0] = word_in(in_key     );
+    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
+    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
+    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
+
+    switch(klen)
+    {
+    case 4:
+        ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
+        ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
+        ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
+        ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
+        ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
+        cx->n_rnd = 10; break;
+    case 6:
+        cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+        cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+        ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
+        ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
+        ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
+        ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
+        cx->n_rnd = 12; break;
+    case 8:
+        cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+        cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+        cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+        cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+        ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
+        ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
+        ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
+        kel8(cx->k_sch, 6);
+        cx->n_rnd = 14; break;
+    default:
+        ;
+    }
+#else
+    cx->n_rnd = (klen > nc ? klen : nc) + 6;
+    {   aes_32t i, l;
+        l = (nc * cx->n_rnd + nc - 1) / klen;
+
+        switch(klen)
+        {
+        case 4:
+            for(i = 0; i < l; ++i)
+                ke4(cx->k_sch, i);
+            break;
+        case 6:
+            cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+            for(i = 0; i < l; ++i)
+                ke6(cx->k_sch, i);
+            break;
+        case 8:
+            cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+            cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+            cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+            for(i = 0; i < l; ++i)
+                ke8(cx->k_sch,  i);
+            break;
+        default:
+            ;
+        }
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+#if (DEC_ROUND != NO_TABLES)
+#define d_vars  dec_imvars
+#define ff(x)   inv_mcol(x)
+#else
+#define ff(x)   (x)
+#define d_vars
+#endif
+
+#if 1
+#define kdf4(k,i) \
+{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
+    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
+    ss[4] ^= k[4*(i)];   k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
+    ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
+}
+#define kd4(k,i) \
+{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
+    k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
+    k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
+}
+#define kdl4(k,i) \
+{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
+    k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
+    k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
+}
+#else
+#define kdf4(k,i) \
+{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
+}
+#define kd4(k,i) \
+{   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
+    ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
+    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
+    ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
+}
+#define kdl4(k,i) \
+{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
+    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
+}
+#endif
+
+#define kdf6(k,i) \
+{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
+    ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
+}
+#define kd6(k,i) \
+{   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
+    ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
+    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
+    ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
+    ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
+    ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
+}
+#define kdl6(k,i) \
+{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
+    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
+}
+
+#define kdf8(k,i) \
+{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
+    ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
+    ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
+}
+#define kd8(k,i) \
+{   aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
+    ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
+    ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
+    ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
+    g = ls_box(ss[3],0); \
+    ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
+    ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
+    ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
+    ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
+}
+#define kdl8(k,i) \
+{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
+    ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
+}
+
+aes_rval aes_set_decrypt_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{   aes_32t    ss[8];
+    d_vars
+
+#if !defined(FIXED_TABLES)
+#ifdef GLOBALS
+    if(!t_use(in,it)) gen_tabs();
+#else
+    if(!cx->t_ptr || !t_use(in,it)) gen_tabs(cx);
+#endif
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if(!cx->n_blk) cx->n_blk = 16;
+#else
+    cx->n_blk = BLOCK_SIZE;
+#endif
+
+    if(((klen & 7) || klen < 16 || klen > 32) && ((klen & 63) || klen < 128 || klen > 256))
+    {
+        cx->n_rnd = 0; return aes_bad;
+    }
+
+    klen >>= (klen < 128 ? 2 : 5);
+    cx->n_blk = (cx->n_blk & ~3) | 2;
+
+    cx->k_sch[0] = ss[0] = word_in(in_key     );
+    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
+    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
+    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
+
+    switch(klen)
+    {
+    case 4:
+        kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
+        kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
+        kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
+        kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
+        kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
+        cx->n_rnd = 10; break;
+    case 6:
+        cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+        cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+        kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
+        kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
+        kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
+        kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
+        cx->n_rnd = 12; break;
+    case 8:
+        cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+        cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+        cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24));
+        cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28));
+        kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
+        kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
+        kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
+        kdl8(cx->k_sch, 6);
+        cx->n_rnd = 14; break;
+    default:
+        ;
+    }
+#else
+    cx->n_rnd = (klen > nc ? klen : nc) + 6;
+    {   aes_32t i, l;
+        l = (nc * cx->n_rnd + nc - 1) / klen;
+
+        switch(klen)
+        {
+        case 4:
+            for(i = 0; i < l; ++i)
+                ke4(cx->k_sch, i);
+            break;
+        case 6:
+            cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+            for(i = 0; i < l; ++i)
+                ke6(cx->k_sch, i);
+            break;
+        case 8:
+            cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+            cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+            cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+            for(i = 0; i < l; ++i)
+                ke8(cx->k_sch,  i);
+            break;
+        default:
+            ;
+        }
+#if (DEC_ROUND != NO_TABLES)
+        for(i = nc; i < nc * cx->n_rnd; ++i)
+            cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+#endif
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/aesopt.h b/aes_wg/aesopt.h
new file mode 100644 (file)
index 0000000..72fc1a7
--- /dev/null
@@ -0,0 +1,933 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
+
+    OPERATION
+
+    These source code files implement the AES algorithm Rijndael designed by
+    Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+    block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+    that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+    and 256 bits (16, 20, 24, 28 and 32 bytes).  This file is a common header
+    file for these two implementations and for aesref.c, which is a reference
+    implementation.
+
+    This version is designed for flexibility and speed using operations on
+    32-bit words rather than operations on bytes.  It provides aes_both fixed
+    and  dynamic block and key lengths and can also run with either big or
+    little endian internal byte order (see aes.h).  It inputs block and key
+    lengths in bytes with the legal values being  16, 24 and 32 for aes.c and
+    16, 20, 24, 28 and 32 for aespp.c
+
+    THE CIPHER INTERFACE
+
+    aes_08t         (an unsigned  8-bit type)
+    aes_32t         (an unsigned 32-bit type)
+    aes_fret        (a signed 16 bit type for function return values)
+    aes_good        (value != 0, a good return)
+    aes_bad         (value == 0, an error return)
+    struct aes_ctx  (structure for the cipher encryption context)
+    struct aes_ctx  (structure for the cipher decryption context)
+    aes_rval        the function return type (aes_fret if not DLL)
+
+    C subroutine calls:
+
+      aes_rval aes_set_block_size(unsigned int blen, aes_ctx cx[1]);
+      aes_rval aes_set_encrypt_key(const unsigned char in_key[],
+                                            unsigned int klen, aes_ctx cx[1]);
+      aes_rval aes_encrypt_block(const unsigned char in_blk[],
+                                unsigned char out_blk[], const aes_ctx cx[1]);
+
+      aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+      aes_rval aes_set_decrypt_key(const unsigned char in_key[],
+                                            unsigned int klen, aes_ctx cx[1]);
+      aes_rval aes_decrypt_block(const unsigned char in_blk[],
+                                unsigned char out_blk[], const aes_ctx cx[1]);
+
+    IMPORTANT NOTE: If you are using this C interface and your compiler does
+    not set the memory used for objects to zero before use, you will need to
+    ensure that cx.n_blk is set to zero before using these subroutine calls.
+
+    C++ aes class subroutines:
+
+      class AESclass    for encryption
+      class AESclass    for decryption
+
+      aes_rval len(unsigned int blen = 16);
+      aes_rval key(const unsigned char in_key[], unsigned int klen);
+      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+      aes_rval len(unsigned int blen = 16);
+      aes_rval key(const unsigned char in_key[], unsigned int klen);
+      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+    The block length inputs to set_block and set_key are in numbers of
+    BYTES, not bits.  The calls to subroutines must be made in the above
+    order but multiple calls can be made without repeating earlier calls
+    if their parameters have not changed. If the cipher block length is
+    variable but set_blk has not been called before cipher operations a
+    value of 16 is assumed (that is, the AES block size). In contrast to
+    earlier versions the block and key length parameters are now checked
+    for correctness and the encryption and decryption routines check to
+    ensure that an appropriate key has been set before they are called.
+
+    COMPILATION
+
+    The files used to provide AES (Rijndael) are
+
+    a. aes.h for the definitions needed for use in C.
+    b. aescpp.h for the definitions needed for use in C++.
+    c. aesopt.h for setting compilation options (also includes common
+       code).
+    d. aescrypt.c for encryption and decrytpion, or
+    e. aescrypt.asm for encryption and decryption using assembler code.
+    f. aeskey.c for key scheduling.
+    g. aestab.c for table loading or generation.
+
+    The assembler code uses the NASM assembler. The above files provice
+    block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+    If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+    aeskey.c respectively, the block and key lengths can then be 16, 20,
+    24, 28 or 32 bytes. However this code has not been optimised to the
+    same extent and is hence slower (esepcially for the AES block size
+    of 16 bytes).
+
+    To compile AES (Rijndael) for use in C code use aes.h and exclude
+    the AES_DLL define in aes.h
+
+    To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+    exclude the AES_DLL define in aes.h
+
+    To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+    aes.h, include the AES_DLL define and compile the DLL.  If using
+    the test files to test the DLL, exclude aes.c from the test build
+    project and compile it with the same defines as used for the DLL
+    (ensure that the DLL path is correct)
+
+    CONFIGURATION OPTIONS (here and in aes.h)
+
+    a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+       or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+       extended code) or leave this undefined for dynamically variable
+       block size (this will result in much slower code).
+    b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+    c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+    d. If you want the code to run in a specific internal byte order, then
+       INTERNAL_BYTE_ORDER must be set accordingly.
+    e. set other configuration options decribed below.
+*/
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*  START OF CONFIGURATION OPTIONS
+
+    USE OF DEFINES
+
+    Later in this section there are a number of defines that control the
+    operation of the code.  In each section, the purpose of each define is
+    explained so that the relevant form can be included or excluded by
+    setting either 1's or 0's respectively on the branches of the related
+    #if clauses.
+*/
+
+/*  DO NOT CHANGE THE FOLLOWING EIGHT DEFINES   */
+
+#define NO_TABLES              0
+#define ONE_TABLE              1
+#define FOUR_TABLES            4
+#define NONE                   0
+#define PARTIAL                1
+#define FULL                   2
+#define AES_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+/*  1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
+#include "crypt/aes.h"
+#else
+#  include "aes.h"
+#endif
+
+/***********************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed to use (a modified) "brg_endian.h" for endian determination
+ * instead of the code below.
+ ***********************************************************************
+ */
+#include "brg_endian.h"
+
+#if 0
+
+#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#  include <endian.h>
+#  include <byteswap.h>
+#elif defined(__CRYPTLIB__)
+#  if defined( INC_ALL )
+#    include "crypt.h"
+#  elif defined( INC_CHILD )
+#    include "../crypt.h"
+#  else
+#    include "crypt.h"
+#  endif
+#  if defined(DATA_LITTLEENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  else
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_MSC_VER)
+#  include <stdlib.h>
+#elif !defined(WIN32)
+#  include <stdlib.h>
+#  if !defined (_ENDIAN_H)
+#    include <sys/param.h>
+#  else
+#    include _ENDIAN_H
+#  endif
+#endif
+
+#endif /* 0 */
+
+
+/*  2. BYTE ORDER IN 32-BIT WORDS
+
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the order in which bytes are packed into such words.
+    The following block of code is an attempt to capture the most obvious
+    ways in which various environemnts define byte order. It may well fail,
+    in which case the definitions will need to be set by editing at the
+    points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 241 or 243 of aesopt.h).
+#endif
+
+/*  3. FUNCTIONS REQUIRED
+
+    This implementation provides five main subroutines which provide for
+    setting block length, setting encryption and decryption keys and for
+    encryption and decryption. When the assembler code is not being used
+    the following definition blocks allow the selection of the routines
+    that are to be included in the compilation.
+*/
+#if 1
+#define ENCRYPTION
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+
+#if 0
+#define DECRYPTION
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+/*  4. ASSEMBLER SUPPORT
+
+    This define (which can be on the command line) enables the use of the
+    assembler code routines for encryption and decryption with the C code
+    only providing key scheduling
+*/
+#if 0
+#define AES_ASM
+#endif
+
+/*  5. BYTE ORDER WITHIN 32 BIT WORDS
+
+    The fundamental data processing units in Rijndael are 8-bit bytes. The
+    input, output and key input are all enumerated arrays of bytes in which
+    bytes are numbered starting at zero and increasing to one less than the
+    number of bytes in the array in question. This enumeration is only used
+    for naming bytes and does not imply any adjacency or order relationship
+    from one byte to another. When these inputs and outputs are considered
+    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+    In this implementation bits are numbered from 0 to 7 starting at the
+    numerically least significant end of each byte (bit n represents 2^n).
+
+    However, Rijndael can be implemented more efficiently using 32-bit
+    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+    into word[n]. While in principle these bytes can be assembled into words
+    in any positions, this implementation only supports the two formats in
+    which bytes in adjacent positions within words also have adjacent byte
+    numbers. This order is called big-endian if the lowest numbered bytes
+    in words have the highest numeric significance and little-endian if the
+    opposite applies.
+
+    This code can work in either order irrespective of the order used by the
+    machine on which it runs. Normally the internal byte order will be set
+    to the order of the processor on which the code is to be run but this
+    define can be used to reverse this in special situations
+*/
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif 0
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#else
+#error The internal byte order is not defined
+#endif
+
+/*  6. FAST INPUT/OUTPUT OPERATIONS.
+
+    On some machines it is possible to improve speed by transferring the
+    bytes in the input and output arrays to and from the internal 32-bit
+    variables by addressing these arrays as if they are arrays of 32-bit
+    words.  On some machines this will always be possible but there may
+    be a large performance penalty if the byte arrays are not aligned on
+    the normal word boundaries. On other machines this technique will
+    lead to memory access errors when such 32-bit word accesses are not
+    properly aligned. The option SAFE_IO avoids such problems but will
+    often be slower on those machines that support misaligned access
+    (especially so if care is taken to align the input  and output byte
+    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+    assumed that access to byte arrays as if they are arrays of 32-bit
+    words will not cause problems when such accesses are misaligned.
+*/
+#if 1 && !defined(_MSC_VER)
+#define SAFE_IO
+#endif
+
+/*  7. LOOP UNROLLING
+
+    The code for encryption and decrytpion cycles through a number of rounds
+    that can be implemented either in a loop or by expanding the code into a
+    long sequence of instructions, the latter producing a larger program but
+    one that will often be much faster. The latter is called loop unrolling.
+    There are also potential speed advantages in expanding two iterations in
+    a loop with half the number of iterations, which is called partial loop
+    unrolling.  The following options allow partial or full loop unrolling
+    to be set independently for encryption and decryption
+*/
+#if 1
+#define ENC_UNROLL  FULL
+#elif 0
+#define ENC_UNROLL  PARTIAL
+#else
+#define ENC_UNROLL  NONE
+#endif
+
+#if 1
+#define DEC_UNROLL  FULL
+#elif 0
+#define DEC_UNROLL  PARTIAL
+#else
+#define DEC_UNROLL  NONE
+#endif
+
+/*  8. FAST FINITE FIELD OPERATIONS
+
+    If this section is included, tables are used to provide faster finite
+    field arithmetic (this has no effect if FIXED_TABLES is defined).
+*/
+#if 1
+#define FF_TABLES
+#endif
+
+/*  9. INTERNAL STATE VARIABLE FORMAT
+
+    The internal state of Rijndael is stored in a number of local 32-bit
+    word varaibles which can be defined either as an array or as individual
+    names variables. Include this section if you want to store these local
+    varaibles in arrays. Otherwise individual local variables will be used.
+*/
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+   32-bit words. The state array can be held in various ways: in an array
+   of words, in a number of individual word variables or in a number of
+   processor registers. The following define maps a variable name x and
+   a column number c to the way the state array variable is to be held.
+   The first define below maps the state into an array x[c] whereas the
+   second form maps the state into a number of individual variables x0,
+   x1, etc.  Another form could map individual state colums to machine
+   register names.
+*/
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+/*  10. VARIABLE BLOCK SIZE SPEED
+
+    This section is only relevant if you wish to use the variable block
+    length feature of the code.  Include this section if you place more
+    emphasis on speed rather than code size.
+*/
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/*  11. FIXED OR DYNAMIC TABLES
+
+    When this section is included the tables used by the code are comipled
+    statically into the binary file.  Otherwise they are computed once when
+    the code is first used.
+*/
+#if 1
+#define FIXED_TABLES
+#endif
+
+/*  12. GLOBAL VARIABLES
+
+    In some circumstances global variables to hold the fixed tables are not
+    possible so the tables have to be placed in a structure that is passed
+    around at run time through the AES API calls. In this case FIXED_TABLES
+    cannot be used. GLOBALS must be defined in order to use the assembler
+    version of this code. If GLOBALS is not defined, then AES_TABLE_PTR must
+    be defined either on the command line or early in aes.h in order to
+    provide space for the table pointer in the AES context.
+*/
+#if 1 || defined(AES_ASM)
+#define GLOBALS
+#elif !defined(AES_TABLE_PTR)
+#error no context space for table pointer (compile with AES_TABLE_PTR defined)
+#elif defined(FIXED_TABLES)
+#undef FIXED_TABLES
+#endif
+
+/*  13. INTERNAL TABLE CONFIGURATION
+
+    This cipher proceeds by repeating in a number of cycles known as 'rounds'
+    which are implemented by a round function which can optionally be speeded
+    up using tables.  The basic tables are each 256 32-bit words, with either
+    one or four tables being required for each round function depending on
+    how much speed is required. The encryption and decryption round functions
+    are different and the last encryption and decrytpion round functions are
+    different again making four different round functions in all.
+
+    This means that:
+      1. Normal encryption and decryption rounds can each use either 0, 1
+         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+      2. The last encryption and decryption rounds can also use either 0, 1
+         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+
+    Include or exclude the appropriate definitions below to set the number
+    of tables used by this implementation.
+*/
+
+#if 1   /* set tables for the normal encryption round */
+#define ENC_ROUND   FOUR_TABLES
+#elif 0
+#define ENC_ROUND   ONE_TABLE
+#else
+#define ENC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last encryption round */
+#define LAST_ENC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND  ONE_TABLE
+#else
+#define LAST_ENC_ROUND  NO_TABLES
+#endif
+
+#if 1   /* set tables for the normal decryption round */
+#define DEC_ROUND   FOUR_TABLES
+#elif 0
+#define DEC_ROUND   ONE_TABLE
+#else
+#define DEC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last decryption round */
+#define LAST_DEC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND  ONE_TABLE
+#else
+#define LAST_DEC_ROUND  NO_TABLES
+#endif
+
+/*  The decryption key schedule can be speeded up with tables in the same
+    way that the round functions can.  Include or exclude the following
+    defines to set this requirement.
+*/
+#if 1
+#define KEY_SCHED   FOUR_TABLES
+#elif 0
+#define KEY_SCHED   ONE_TABLE
+#else
+#define KEY_SCHED   NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH   29
+#else
+#define RC_LENGTH   (5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11))
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef  ENC_UNROLL
+#define ENC_UNROLL  NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef  DEC_UNROLL
+#define DEC_UNROLL  NONE
+#endif
+
+/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
+               higher index positions with wrap around into low positions
+    ups(x,n):  moves bytes by n positions to higher index positions in
+               words but without wrap around
+    bval(x,n): extracts a byte from a word
+
+    NOTE:      The definitions given here are intended only for use with
+               unsigned variables and with shift counts that are compile
+               time constants
+*/
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#define upr(x,n)        (((aes_32t)(x) << (8 * (n))) | ((aes_32t)(x) >> (32 - 8 * (n))))
+#define ups(x,n)        ((aes_32t) (x) << (8 * (n)))
+#define bval(x,n)       ((aes_08t)((x) >> (8 * (n))))
+#define bytes2word(b0, b1, b2, b3)  \
+        (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x,n)        (((aes_32t)(x) >> (8 * (n))) | ((aes_32t)(x) << (32 - 8 * (n))))
+#define ups(x,n)        ((aes_32t) (x) >> (8 * (n))))
+#define bval(x,n)       ((aes_08t)((x) >> (24 - 8 * (n))))
+#define bytes2word(b0, b1, b2, b3)  \
+        (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x)      bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x,v)   { (x)[0] = bval(v,0); (x)[1] = bval(v,1);   \
+                          (x)[2] = bval(v,2); (x)[3] = bval(v,3);   }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x)      (*(aes_32t*)(x))
+#define word_out(x,v)   (*(aes_32t*)(x) = (v))
+
+#else
+
+#if !defined(bswap_32)
+#define brot(x,n)       (((aes_32t)(x) <<  n) | ((aes_32t)(x) >> (32 - n)))
+#define bswap_32(x)     ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
+#endif
+
+#define word_in(x)      bswap_32(*(aes_32t*)(x))
+#define word_out(x,v)   (*(aes_32t*)(x) = bswap_32(v))
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY   0x011b
+#define BPOLY     0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1  0x80808080
+#define m2  0x7f7f7f7f
+#define FFmulX(x)  ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+   give improved performance if a fast 32-bit multiply is not available. Note
+   that a temporary variable u needs to be defined where FFmulX is used.
+
+#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+#define m4  (0x01010101 * BPOLY)
+#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+*/
+
+/* Work out which tables are needed for the different options   */
+
+#ifdef  AES_ASM
+#ifdef  ENC_ROUND
+#undef  ENC_ROUND
+#endif
+#define ENC_ROUND   FOUR_TABLES
+#ifdef  LAST_ENC_ROUND
+#undef  LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND  FOUR_TABLES
+#ifdef  DEC_ROUND
+#undef  DEC_ROUND
+#endif
+#define DEC_ROUND   FOUR_TABLES
+#ifdef  LAST_DEC_ROUND
+#undef  LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND  FOUR_TABLES
+#ifdef  KEY_SCHED
+#undef  KEY_SCHED
+#define KEY_SCHED   FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+/*  If there are no global variables, the AES tables are placed in
+    a structure and a pointer is added to the AES context. If this
+    facility is used, the calling program has to ensure that this
+    pointer is managed appropriately. In particular, the value of
+    the t_dec(in,it) item in the table structure must be set to zero
+    in order to ensure that the tables are initialised. In practice
+    the three code sequences in aeskey.c that control the calls to
+    gen_tabs() and the gen_tabs() routine itself will require some
+    changes for a specific implementation. If global variables are
+    available it will generally be preferable to use them with the
+    precomputed FIXED_TABLES option that uses static global tables.
+
+    The following defines can be used to control the way the tables
+    are defined, initialised and used in embedded environments that
+    require special features for these purposes
+
+    the 't_dec' construction is used to declare fixed table arrays
+    the 't_set' construction is used to set fixed table values
+    the 't_use' construction is used to access fixed table values
+
+    256 byte tables:
+
+        t_xxx(s,box)    => forward S box
+        t_xxx(i,box)    => inverse S box
+
+    256 32-bit word OR 4 x 256 32-bit word tables:
+
+        t_xxx(f,n)      => forward normal round
+        t_xxx(f,l)      => forward last round
+        t_xxx(i,n)      => inverse normal round
+        t_xxx(i,l)      => inverse last round
+        t_xxx(l,s)      => key schedule table
+        t_xxx(i,m)      => key schedule table
+
+    Other variables and tables:
+
+        t_xxx(in,it)    => the table initialsation flag
+        t_xxx(r,c)      => the rcon table
+*/
+
+#define t_dec(m,n) t_##m##n
+#define t_set(m,n) t_##m##n  /* may be redefined once below */
+#define t_use(m,n) t_##m##n  /* may be redefined once below */
+
+#ifdef  FIXED_TABLES
+
+#define prefx    extern const
+#elif defined(GLOBALS)
+#define prefx    extern
+extern aes_08t   t_dec(in,it);
+void gen_tabs(void);
+#else
+#define prefx
+void gen_tabs(aes_ctx cx[1]);
+
+typedef struct {
+#endif
+
+prefx aes_32t  t_dec(r,c)[RC_LENGTH];
+
+#ifdef  SBX_SET
+prefx aes_08t t_dec(s,box)[256];
+#endif
+
+#ifdef  ISB_SET
+prefx aes_08t t_dec(i,box)[256];
+#endif
+
+#ifdef  FT1_SET
+prefx aes_32t t_dec(f,n)[256];
+#endif
+
+#ifdef  FT4_SET
+prefx aes_32t t_dec(f,n)[4][256];
+#endif
+
+#ifdef  FL1_SET
+prefx aes_32t t_dec(f,l)[256];
+#endif
+
+#ifdef  FL4_SET
+prefx aes_32t t_dec(f,l)[4][256];
+#endif
+
+#ifdef  IT1_SET
+prefx aes_32t t_dec(i,n)[256];
+#endif
+
+#ifdef  IT4_SET
+prefx aes_32t t_dec(i,n)[4][256];
+#endif
+
+#ifdef  IL1_SET
+prefx aes_32t t_dec(i,l)[256];
+#endif
+
+#ifdef  IL4_SET
+prefx aes_32t t_dec(i,l)[4][256];
+#endif
+
+#ifdef  LS1_SET
+#ifdef  FL1_SET
+#undef  LS1_SET
+#else
+prefx aes_32t t_dec(l,s)[256];
+#endif
+#endif
+
+#ifdef  LS4_SET
+#ifdef  FL4_SET
+#undef  LS4_SET
+#else
+prefx aes_32t t_dec(l,s)[4][256];
+#endif
+#endif
+
+#ifdef  IM1_SET
+prefx aes_32t t_dec(i,m)[256];
+#endif
+
+#ifdef  IM4_SET
+prefx aes_32t t_dec(i,m)[4][256];
+#endif
+
+prefx aes_08t  t_dec(in,it);
+
+#ifndef GLOBALS
+} s_ty;
+
+extern s_ty s_t;
+
+/* modify the table set macro to cope with a static structure */
+#undef  t_set
+#define t_set(m,n) (s_t.t_##m##n)
+
+/* modify the table use macro to cope with a context pointer  */
+#undef  t_use
+#define t_use(m,n) (((s_ty*)cx->t_ptr)->t_##m##n)
+
+#endif
+
+/* Set the number of columns in nc.  Note that it is important
+   that nc is a constant which is known at compile time if the
+   highest speed version of the code is needed.
+*/
+
+#if defined(BLOCK_SIZE)
+#define nc  (BLOCK_SIZE >> 2)
+#else
+#define nc  (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use tables    */
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+    box[bval(vf(x,0,c),rf(0,c))], \
+    box[bval(vf(x,1,c),rf(1,c))], \
+    box[bval(vf(x,2,c),rf(2,c))], \
+    box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ (     tab[bval(vf(x,0,c),rf(0,c))] \
+  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ (  tab[0][bval(vf(x,0,c),rf(0,c))] \
+  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+  ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c)  (x)
+#define rf1(r,c)    (r)
+#define rf2(r,c)    ((8+r-c)&3)
+
+/* perform forward and inverse column mix operation on four bytes in long word x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */
+
+#define dec_fmvars
+#if defined(FM4_SET)    /* not currently used */
+#define fwd_mcol(x)     four_tables(x,t_use(f,m),vf1,rf1,0)
+#elif defined(FM1_SET)  /* not currently used */
+#define fwd_mcol(x)     one_table(x,upr,t_use(f,m),vf1,rf1,0)
+#else
+#undef  dec_fmvars
+#define dec_fmvars      aes_32t f1, f2;
+#define fwd_mcol(x)     (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x)     four_tables(x,t_use(i,m),vf1,rf1,0)
+#elif defined(IM1_SET)
+#define inv_mcol(x)     one_table(x,upr,t_use(i,m),vf1,rf1,0)
+#else
+#undef  dec_imvars
+#define dec_imvars      aes_32t    f2, f4, f8, f9;
+#define inv_mcol(x) \
+    (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+    f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x,c)     four_tables(x,t_use(f,l),vf1,rf2,c)
+#elif   defined(LS4_SET)
+#define ls_box(x,c)     four_tables(x,t_use(l,s),vf1,rf2,c)
+#elif defined(FL1_SET)
+#define ls_box(x,c)     one_table(x,upr,t_use(f,l),vf1,rf2,c)
+#elif defined(LS1_SET)
+#define ls_box(x,c)     one_table(x,upr,t_use(l,s),vf1,rf2,c)
+#else
+#define ls_box(x,c)     no_table(x,t_use(s,box),vf1,rf2,c)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/aestab.c b/aes_wg/aestab.c
new file mode 100644 (file)
index 0000000..567791b
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the code for generating the fixed tables needed for AES
+*/
+
+#include "aesopt.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+
+/*  finite field arithmetic operations */
+
+#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))
+#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
+#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
+                        ^ (((x>>5) & 4) * WPOLY))
+#define f3(x)   (f2(x) ^ x)
+#define f9(x)   (f8(x) ^ x)
+#define fb(x)   (f8(x) ^ f2(x) ^ x)
+#define fd(x)   (f8(x) ^ f4(x) ^ x)
+#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
+
+#endif
+
+#if defined(FIXED_TABLES)
+
+#define sb_data(w) \
+    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
+    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
+    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
+    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
+    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
+    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
+    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
+    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
+    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
+    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
+    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
+    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
+    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
+    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
+    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
+    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
+    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
+    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
+    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
+    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
+    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
+    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
+    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
+    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
+    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
+    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
+    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
+    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
+    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
+    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
+    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
+    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+
+#define isb_data(w) \
+    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
+    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
+    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
+    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
+    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
+    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
+    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
+    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
+    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
+    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
+    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
+    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
+    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
+    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
+    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
+    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
+    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
+    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
+    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
+    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
+    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
+    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
+    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
+    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
+    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
+    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
+    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
+    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
+    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
+    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
+    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
+    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+
+#define mm_data(w) \
+    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
+    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
+    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
+    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
+    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
+    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
+    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
+    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
+    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
+    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
+    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
+    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
+    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
+    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
+    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
+    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
+    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
+    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
+    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
+    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
+    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
+    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
+    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
+    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
+    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
+    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
+    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
+    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
+    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
+    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
+    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
+    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+
+#define h0(x)   (x)
+
+/*  These defines are used to ensure tables are generated in the
+    right format depending on the internal byte order required
+*/
+
+#define w0(p)   bytes2word(p, 0, 0, 0)
+#define w1(p)   bytes2word(0, p, 0, 0)
+#define w2(p)   bytes2word(0, 0, p, 0)
+#define w3(p)   bytes2word(0, 0, 0, p)
+
+/*  Number of elements required in this table for different
+    block and key lengths is:
+
+    Rcon Table      key length (bytes)
+    Length          16  20  24  28  32
+                ---------------------
+    block     16 |  10   9   8   7   7
+    length    20 |  14  11  10   9   9
+    (bytes)   24 |  19  15  12  11  11
+              28 |  24  19  16  13  13
+              32 |  29  23  19  17  14
+
+    this table can be a table of bytes if the key schedule
+    code is adjusted accordingly
+*/
+
+#define u0(p)   bytes2word(f2(p), p, p, f3(p))
+#define u1(p)   bytes2word(f3(p), f2(p), p, p)
+#define u2(p)   bytes2word(p, f3(p), f2(p), p)
+#define u3(p)   bytes2word(p, p, f3(p), f2(p))
+
+#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))
+#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))
+#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))
+#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))
+
+const aes_32t t_dec(r,c)[RC_LENGTH] =
+{
+    w0(0x01), w0(0x02), w0(0x04), w0(0x08), w0(0x10),
+    w0(0x20), w0(0x40), w0(0x80), w0(0x1b), w0(0x36),
+#if RC_LENGTH > 10
+    w0(0x6c), w0(0xd8), w0(0xab), w0(0x4d),
+#endif
+#if RC_LENGTH > 14
+    w0(0x9a), w0(0x2f), w0(0x5e), w0(0xbc), w0(0x63),
+#endif
+#if RC_LENGTH > 19
+    w0(0xc6), w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
+#endif
+#if RC_LENGTH > 24
+    w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef), w0(0xc5)
+#endif
+};
+
+#ifdef  SBX_SET
+const aes_08t t_dec(s,box)[256] = { sb_data(h0) };
+#endif
+#ifdef  ISB_SET
+const aes_08t t_dec(i,box)[256] = { isb_data(h0) };
+#endif
+
+#ifdef  FT1_SET
+const aes_32t t_dec(f,n)[256] = { sb_data(u0) };
+#endif
+#ifdef  FT4_SET
+const aes_32t t_dec(f,n)[4][256] =
+    { {  sb_data(u0) }, {  sb_data(u1) }, {  sb_data(u2) }, {  sb_data(u3) } };
+#endif
+
+#ifdef  FL1_SET
+const aes_32t t_dec(f,l)[256] = { sb_data(w0) };
+#endif
+#ifdef  FL4_SET
+const aes_32t t_dec(f,l)[4][256] =
+    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
+#endif
+
+#ifdef  IT1_SET
+const aes_32t t_dec(i,n)[256] = { isb_data(v0) };
+#endif
+#ifdef  IT4_SET
+const aes_32t t_dec(i,n)[4][256] =
+    { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
+#endif
+
+#ifdef  IL1_SET
+const aes_32t t_dec(i,l)[256] = { isb_data(w0) };
+#endif
+#ifdef  IL4_SET
+const aes_32t t_dec(i,l)[4][256] =
+    { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
+#endif
+
+#ifdef  LS1_SET
+const aes_32t t_dec(l,s)[256] = { sb_data(w0) };
+#endif
+#ifdef  LS4_SET
+const aes_32t t_dec(l,s)[4][256] =
+    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
+#endif
+
+#ifdef  IM1_SET
+const aes_32t t_dec(i,m)[256] = { mm_data(v0) };
+#endif
+#ifdef  IM4_SET
+const aes_32t t_dec(i,m)[4][256] =
+    { {  mm_data(v0) }, {  mm_data(v1) }, {  mm_data(v2) }, {  mm_data(v3) } };
+#endif
+
+#else   /* dynamic table generation */
+
+#ifdef  GLOBALS
+
+aes_08t t_dec(in,it) = 0;
+
+aes_32t  t_dec(r,c)[RC_LENGTH];
+
+#ifdef  SBX_SET
+aes_08t t_dec(s,box)[256];
+#endif
+#ifdef  ISB_SET
+aes_08t t_dec(i,box)[256];
+#endif
+
+#ifdef  FT1_SET
+aes_32t t_dec(f,n)[256];
+#endif
+#ifdef  FT4_SET
+aes_32t t_dec(f,n)[4][256];
+#endif
+
+#ifdef  FL1_SET
+aes_32t t_dec(f,l)[256];
+#endif
+#ifdef  FL4_SET
+aes_32t t_dec(f,l)[4][256];
+#endif
+
+#ifdef  IT1_SET
+aes_32t t_dec(i,n)[256];
+#endif
+#ifdef  IT4_SET
+aes_32t t_dec(i,n)[4][256];
+#endif
+
+#ifdef  IL1_SET
+aes_32t t_dec(i,l)[256];
+#endif
+#ifdef  IL4_SET
+aes_32t t_dec(i,l)[4][256];
+#endif
+
+#ifdef  LS1_SET
+aes_32t t_dec(l,s)[256];
+#endif
+#ifdef  LS4_SET
+aes_32t t_dec(l,s)[4][256];
+#endif
+
+#ifdef  IM1_SET
+aes_32t t_dec(i,m)[256];
+#endif
+#ifdef  IM4_SET
+aes_32t t_dec(i,m)[4][256];
+#endif
+
+#else
+s_ty s_t;
+#endif
+
+#if !defined(FF_TABLES)
+
+/*  Generate the tables for the dynamic table option
+
+    It will generally be sensible to use tables to compute finite
+    field multiplies and inverses but where memory is scarse this
+    code might sometimes be better. But it only has effect during
+    initialisation so its pretty unimportant in overall terms.
+*/
+
+/*  return 2 ^ (n - 1) where n is the bit number of the highest bit
+    set in x with x in the range 1 < x < 0x00000200.   This form is
+    used so that locals within fi can be bytes rather than words
+*/
+
+static aes_08t hibit(const aes_32t x)
+{   aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
+
+    r |= (r >> 2);
+    r |= (r >> 4);
+    return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static aes_08t fi(const aes_08t x)
+{   aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+    if(x < 2) return x;
+
+    for(;;)
+    {
+        if(!n1) return v1;
+
+        while(n2 >= n1)
+        {
+            n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+        }
+
+        if(!n2) return v2;
+
+        while(n1 >= n2)
+        {
+            n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+        }
+    }
+}
+
+#else
+
+/* define the finite field multiplies required for Rijndael */
+
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+#define fi(x) ((x) ?   pow[255 - log[x]]: 0)
+
+#endif
+
+/* The forward and inverse affine transformations used in the S-box */
+
+#define fwd_affine(x) \
+    (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
+
+#define inv_affine(x) \
+    (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
+
+#ifdef GLOBALS
+void gen_tabs(void)
+#else
+void gen_tabs(aes_ctx cx[1])
+#endif
+{   aes_32t  i, w;
+
+#if defined(FF_TABLES)
+
+    aes_08t  pow[512], log[256];
+
+    /*  log and power tables for GF(2^8) finite field with
+        WPOLY as modular polynomial - the simplest primitive
+        root is 0x03, used here to generate the tables
+    */
+
+    i = 0; w = 1;
+    do
+    {
+        pow[i] = (aes_08t)w;
+        pow[i + 255] = (aes_08t)w;
+        log[w] = (aes_08t)i++;
+        w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+    }
+    while (w != 1);
+
+#endif
+
+#ifndef GLOBALS
+    if(!cx->t_ptr)
+        cx->t_ptr = &s_t;
+#endif
+
+    for(i = 0, w = 1; i < RC_LENGTH; ++i)
+    {
+        t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
+        w = f2(w);
+    }
+
+    for(i = 0; i < 256; ++i)
+    {   aes_08t    b;
+
+        b = fwd_affine(fi((aes_08t)i));
+        w = bytes2word(f2(b), b, b, f3(b));
+
+#ifdef  SBX_SET
+        t_set(s,box)[i] = b;
+#endif
+
+#ifdef  FT1_SET                 /* tables for a normal encryption round */
+        t_set(f,n)[i] = w;
+#endif
+#ifdef  FT4_SET
+        t_set(f,n)[0][i] = w;
+        t_set(f,n)[1][i] = upr(w,1);
+        t_set(f,n)[2][i] = upr(w,2);
+        t_set(f,n)[3][i] = upr(w,3);
+#endif
+        w = bytes2word(b, 0, 0, 0);
+
+#ifdef  FL1_SET                 /* tables for last encryption round (may also   */
+        t_set(f,l)[i] = w;        /* be used in the key schedule)                 */
+#endif
+#ifdef  FL4_SET
+        t_set(f,l)[0][i] = w;
+        t_set(f,l)[1][i] = upr(w,1);
+        t_set(f,l)[2][i] = upr(w,2);
+        t_set(f,l)[3][i] = upr(w,3);
+#endif
+
+#ifdef  LS1_SET                 /* table for key schedule if t_set(f,l) above is    */
+        t_set(l,s)[i] = w;      /* not of the required form                     */
+#endif
+#ifdef  LS4_SET
+        t_set(l,s)[0][i] = w;
+        t_set(l,s)[1][i] = upr(w,1);
+        t_set(l,s)[2][i] = upr(w,2);
+        t_set(l,s)[3][i] = upr(w,3);
+#endif
+
+        b = fi(inv_affine((aes_08t)i));
+        w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+
+#ifdef  IM1_SET                 /* tables for the inverse mix column operation  */
+        t_set(i,m)[b] = w;
+#endif
+#ifdef  IM4_SET
+        t_set(i,m)[0][b] = w;
+        t_set(i,m)[1][b] = upr(w,1);
+        t_set(i,m)[2][b] = upr(w,2);
+        t_set(i,m)[3][b] = upr(w,3);
+#endif
+
+#ifdef  ISB_SET
+        t_set(i,box)[i] = b;
+#endif
+#ifdef  IT1_SET                 /* tables for a normal decryption round */
+        t_set(i,n)[i] = w;
+#endif
+#ifdef  IT4_SET
+        t_set(i,n)[0][i] = w;
+        t_set(i,n)[1][i] = upr(w,1);
+        t_set(i,n)[2][i] = upr(w,2);
+        t_set(i,n)[3][i] = upr(w,3);
+#endif
+        w = bytes2word(b, 0, 0, 0);
+#ifdef  IL1_SET                 /* tables for last decryption round */
+        t_set(i,l)[i] = w;
+#endif
+#ifdef  IL4_SET
+        t_set(i,l)[0][i] = w;
+        t_set(i,l)[1][i] = upr(w,1);
+        t_set(i,l)[2][i] = upr(w,2);
+        t_set(i,l)[3][i] = upr(w,3);
+#endif
+    }
+
+    t_set(in,it) = 1;
+}
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
diff --git a/aes_wg/brg_endian.h b/aes_wg/brg_endian.h
new file mode 100644 (file)
index 0000000..b7f43d0
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
+
+ LICENSE TERMS
+
+ The redistribution and use of this software (with or without changes)
+ is allowed without the payment of fees or royalties provided that:
+
+  1. source code distributions include the above copyright notice, this
+     list of conditions and the following disclaimer;
+
+  2. binary distributions include the above copyright notice, this list
+     of conditions and the following disclaimer in their documentation;
+
+  3. the name of the copyright holder is not used to endorse products
+     built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 20/12/2007
+*/
+
+/**********************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * This "brg_endian.h" file was extracted from a newer AES kit, and
+ * modified (as described below) for use with an older AES kit.
+ **********************************************************************
+ */
+
+#ifndef _BRG_ENDIAN_H
+#define _BRG_ENDIAN_H
+
+#define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+#define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+
+/* Include files where endian defines and byteswap functions may reside */
+/**********************************************************************
+ * 2013-04-12 SMS for Info-ZIP.
+ * SunOS 4.x lacks <sys/isa_defs.h>, so skip it on SPARC.
+ * #if defined( __sun )
+ **********************************************************************
+ */
+#if defined( __sun ) && !defined( __sparc )
+#  include <sys/isa_defs.h>
+#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
+#  include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
+      defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
+#  include <machine/endian.h>
+#elif defined( __linux__ )
+/**********************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * __GNUC__ does _not_ ensure <endian.h>, so we disable the following
+ * terms in the #elif directive above:
+ *    || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
+ * The problem is more general than the exceptions below.
+ **********************************************************************
+ */
+#  if !defined( __MINGW32__ ) && !defined( _AIX )
+#    include <endian.h>
+#    if !defined( __BEOS__ )
+#      include <byteswap.h>
+#    endif
+#  endif
+#endif
+
+/* Now attempt to set the define for platform byte order using any  */
+/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which  */
+/* seem to encompass most endian symbol definitions                 */
+
+#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
+#  if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
+#  if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( _BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( _LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
+#  if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
+#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+/*  if the platform byte order could not be determined, then try to */
+/*  set this define using common machine defines                    */
+#if !defined(PLATFORM_BYTE_ORDER)
+
+#if   defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       || \
+      defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \
+      defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \
+      defined( vax )       || defined( vms )     || defined( VMS )        || \
+      defined( __VMS )     || defined( _M_X64 )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+
+#elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \
+      defined( _CRAY )   || defined( __hppa )    || defined( __hp9000 )   || \
+      defined( ibm370 )  || defined( mc68000 )   || defined( m68k )       || \
+      defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \
+      defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \
+      defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \
+      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#else
+#  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
+#endif
+
+#endif
+
+#endif
diff --git a/aes_wg/fileenc.c b/aes_wg/fileenc.c
new file mode 100644 (file)
index 0000000..ad12f66
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file implements password based file encryption and authentication 
+ using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password 
+ based key derivation.
+
+*/
+
+/*****************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed <memory.h> to <string.h> for portability.
+ *****************************************************************
+ */
+#include <string.h>
+
+#include "fileenc.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* subroutine for data encryption/decryption    */
+/* this could be speeded up a lot by aligning   */
+/* buffers and using 32 bit operations          */
+
+static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1])
+{   unsigned long i = 0, pos = cx->encr_pos;
+
+    while(i < d_len)
+    {
+        if(pos == BLOCK_SIZE)
+        {   unsigned int j = 0;
+            /* increment encryption nonce   */
+            while(j < 8 && !++cx->nonce[j])
+                ++j;
+            /* encrypt the nonce to form next xor buffer    */
+            aes_encrypt_block(cx->nonce, cx->encr_bfr, cx->encr_ctx);
+            pos = 0;
+        }
+
+        data[i++] ^= cx->encr_bfr[pos++];
+    }
+
+    cx->encr_pos = pos;
+}
+
+int fcrypt_init(
+    int mode,                               /* the mode to be used (input)          */
+    const unsigned char pwd[],              /* the user specified password (input)  */
+    unsigned int pwd_len,                   /* the length of the password (input)   */
+    const unsigned char salt[],             /* the salt (input)                     */
+#ifdef PASSWORD_VERIFIER
+    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */
+#endif
+    fcrypt_ctx      cx[1])                  /* the file encryption context (output) */
+{   unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];
+
+    if(pwd_len > MAX_PWD_LENGTH)
+        return PASSWORD_TOO_LONG;
+
+    if(mode < 1 || mode > 3)
+        return BAD_MODE;
+
+    cx->mode = mode;
+    cx->pwd_len = pwd_len;
+
+    /* derive the encryption and authetication keys and the password verifier   */
+    derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,
+                        kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
+
+    /* initialise the encryption nonce and buffer pos   */
+    cx->encr_pos = BLOCK_SIZE;
+    /* if we need a random component in the encryption  */
+    /* nonce, this is where it would have to be set     */
+    memset(cx->nonce, 0, BLOCK_SIZE * sizeof(unsigned char));
+
+    /* initialise for encryption using key 1            */
+    aes_set_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);
+
+    /* initialise for authentication using key 2        */
+    hmac_sha1_begin(cx->auth_ctx);
+    hmac_sha1_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);
+
+#ifdef PASSWORD_VERIFIER
+    memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
+#endif
+
+    return GOOD_RETURN;
+}
+
+/* perform 'in place' encryption and authentication */
+
+void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
+{
+    encr_data(data, data_len, cx);
+    hmac_sha1_data(data, data_len, cx->auth_ctx);
+}
+
+/* perform 'in place' authentication and decryption */
+
+void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
+{
+    hmac_sha1_data(data, data_len, cx->auth_ctx);
+    encr_data(data, data_len, cx);
+}
+
+/* close encryption/decryption and return the MAC value */
+
+int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
+{
+    hmac_sha1_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
+    return MAC_LENGTH(cx->mode);    /* return MAC length in bytes   */
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/fileenc.h b/aes_wg/fileenc.h
new file mode 100644 (file)
index 0000000..b488902
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the header file for fileenc.c, which implements password
+ based file encryption and authentication using AES in CTR mode, HMAC-SHA1 
+ authentication and RFC2898 password based key derivation.
+*/
+
+#ifndef _FENC_H
+#define _FENC_H
+
+#include "aes.h"
+#include "hmac.h"
+#include "pwd2key.h"
+
+#define PASSWORD_VERIFIER
+
+#define MAX_KEY_LENGTH        32
+#define MAX_PWD_LENGTH       128
+#define MAX_SALT_LENGTH       16
+#define KEYING_ITERATIONS   1000
+
+#ifdef  PASSWORD_VERIFIER
+#define PWD_VER_LENGTH         2
+#else
+#define PWD_VER_LENGTH         0
+#endif
+
+#define GOOD_RETURN            0
+#define PASSWORD_TOO_LONG   -100
+#define BAD_MODE            -101
+
+/*
+    Field lengths (in bytes) versus File Encryption Mode (0 < mode < 4)
+
+    Mode Key Salt  MAC Overhead
+       1  16    8   10       18
+       2  24   12   10       22
+       3  32   16   10       26
+
+   The following macros assume that the mode value is correct.
+*/
+
+#define KEY_LENGTH(mode)        (8 * (mode & 3) + 8)
+#define SALT_LENGTH(mode)       (4 * (mode & 3) + 4)
+#define MAC_LENGTH(mode)        (10)
+
+/* the context for file encryption   */
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct
+{   unsigned char   nonce[BLOCK_SIZE];          /* the CTR nonce          */
+    unsigned char   encr_bfr[BLOCK_SIZE];       /* encrypt buffer         */
+    aes_ctx         encr_ctx[1];                /* encryption context     */
+    hmac_ctx        auth_ctx[1];                /* authentication context */
+    unsigned int    encr_pos;                   /* block position (enc)   */
+    unsigned int    pwd_len;                    /* password length        */
+    unsigned int    mode;                       /* File encryption mode   */
+} fcrypt_ctx;
+
+/* initialise file encryption or decryption */
+
+int fcrypt_init(
+    int mode,                               /* the mode to be used (input)          */
+    const unsigned char pwd[],              /* the user specified password (input)  */
+    unsigned int pwd_len,                   /* the length of the password (input)   */
+    const unsigned char salt[],             /* the salt (input)                     */
+#ifdef PASSWORD_VERIFIER
+    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */
+#endif
+    fcrypt_ctx      cx[1]);                 /* the file encryption context (output) */
+
+/* perform 'in place' encryption or decryption and authentication               */
+
+void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);
+void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);
+
+/* close encryption/decryption and return the MAC value */
+/* the return value is the length of the MAC            */
+
+int fcrypt_end(unsigned char mac[],     /* the MAC value (output)   */
+               fcrypt_ctx cx[1]);       /* the context (input)      */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/hmac.c b/aes_wg/hmac.c
new file mode 100644 (file)
index 0000000..8736f86
--- /dev/null
@@ -0,0 +1,151 @@
+/* 2015-03-23 SMS for Info-ZIP.
+ * Changed "long" types to "int" for counters, and to "sha1_32t" for
+ * apparent 32-bit byte groups, where a 64-bit "long" type caused bad
+ * results (on Mac OS X, Intel).
+ */
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of HMAC, the FIPS standard keyed hash function
+*/
+
+#include "hmac.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* initialise the HMAC context to zero */
+void hmac_sha1_begin(hmac_ctx cx[1])
+{
+    memset(cx, 0, sizeof(hmac_ctx));
+}
+
+/* input the HMAC key (can be called multiple times)    */
+int hmac_sha1_key(const unsigned char key[], unsigned int key_len, hmac_ctx cx[1])
+{
+    if(cx->klen == HMAC_IN_DATA)                /* error if further key input   */
+        return HMAC_BAD_MODE;                   /* is attempted in data mode    */
+
+    if(cx->klen + key_len > IN_BLOCK_LENGTH)    /* if the key has to be hashed  */
+    {
+        if(cx->klen <= IN_BLOCK_LENGTH)         /* if the hash has not yet been */
+        {                                       /* started, initialise it and   */
+            sha1_begin(cx->ctx);                /* hash stored key characters   */
+            sha1_hash(cx->key, cx->klen, cx->ctx);
+        }
+
+        sha1_hash(key, key_len, cx->ctx);       /* hash long key data into hash */
+    }
+    else                                        /* otherwise store key data     */
+        memcpy(cx->key + cx->klen, key, key_len);
+
+    cx->klen += key_len;                        /* update the key length count  */
+    return HMAC_OK;
+}
+
+/* input the HMAC data (can be called multiple times) - */
+/* note that this call terminates the key input phase   */
+void hmac_sha1_data(const unsigned char data[], unsigned int data_len, hmac_ctx cx[1])
+{   unsigned int i;
+
+    if(cx->klen != HMAC_IN_DATA)                /* if not yet in data phase */
+    {
+        if(cx->klen > IN_BLOCK_LENGTH)          /* if key is being hashed   */
+        {                                       /* complete the hash and    */
+            sha1_end(cx->key, cx->ctx);         /* store the result as the  */
+            cx->klen = OUT_BLOCK_LENGTH;        /* key and set new length   */
+        }
+
+        /* pad the key if necessary */
+        memset(cx->key + cx->klen, 0, IN_BLOCK_LENGTH - cx->klen);
+
+        /* xor ipad into key value  */
+        for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
+            ((sha1_32t*)cx->key)[i] ^= 0x36363636;
+
+        /* and start hash operation */
+        sha1_begin(cx->ctx);
+        sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
+
+        /* mark as now in data mode */
+        cx->klen = HMAC_IN_DATA;
+    }
+
+    /* hash the data (if any)       */
+    if(data_len)
+        sha1_hash(data, data_len, cx->ctx);
+}
+
+/* compute and output the MAC value */
+void hmac_sha1_end(unsigned char mac[], unsigned int mac_len, hmac_ctx cx[1])
+{   unsigned char dig[OUT_BLOCK_LENGTH];
+    unsigned int i;
+
+    /* if no data has been entered perform a null data phase        */
+    if(cx->klen != HMAC_IN_DATA)
+        hmac_sha1_data((const unsigned char*)0, 0, cx);
+
+    sha1_end(dig, cx->ctx);         /* complete the inner hash      */
+
+    /* set outer key value using opad and removing ipad */
+    for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
+        ((sha1_32t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
+
+    /* perform the outer hash operation */
+    sha1_begin(cx->ctx);
+    sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
+    sha1_hash(dig, OUT_BLOCK_LENGTH, cx->ctx);
+    sha1_end(dig, cx->ctx);
+
+    /* output the hash value            */
+    for(i = 0; i < mac_len; ++i)
+        mac[i] = dig[i];
+}
+
+/* 'do it all in one go' subroutine     */
+void hmac_sha1(const unsigned char key[], unsigned int key_len,
+          const unsigned char data[], unsigned int data_len,
+          unsigned char mac[], unsigned int mac_len)
+{   hmac_ctx    cx[1];
+
+    hmac_sha1_begin(cx);
+    hmac_sha1_key(key, key_len, cx);
+    hmac_sha1_data(data, data_len, cx);
+    hmac_sha1_end(mac, mac_len, cx);
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/hmac.h b/aes_wg/hmac.h
new file mode 100644 (file)
index 0000000..586612b
--- /dev/null
@@ -0,0 +1,86 @@
+/* 2015-03-23 SMS for Info-ZIP.
+ * Changed "long" types to "int" for counters.  See note in hmac.c.
+ */
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of HMAC, the FIPS standard keyed hash function
+*/
+
+#ifndef _HMAC_H
+#define _HMAC_H
+
+/***************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed <memory.h> to <string.h> for portability.
+ ***************************************************************
+ */
+#include <string.h>
+
+#include "sha1.h"
+
+#define IN_BLOCK_LENGTH     SHA1_BLOCK_SIZE
+#define OUT_BLOCK_LENGTH    SHA1_DIGEST_SIZE
+#define HMAC_IN_DATA        0xffffffff
+
+#define HMAC_OK               0
+#define HMAC_BAD_MODE        -1
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct
+{   unsigned char   key[IN_BLOCK_LENGTH];
+    sha1_ctx        ctx[1];
+    unsigned int    klen;
+} hmac_ctx;
+
+void hmac_sha1_begin(hmac_ctx cx[1]);
+
+int  hmac_sha1_key(const unsigned char key[], unsigned int key_len, hmac_ctx cx[1]);
+
+void hmac_sha1_data(const unsigned char data[], unsigned int data_len, hmac_ctx cx[1]);
+
+void hmac_sha1_end(unsigned char mac[], unsigned int mac_len, hmac_ctx cx[1]);
+
+void hmac_sha1(const unsigned char key[], unsigned int key_len,
+          const unsigned char data[], unsigned int data_len,
+          unsigned char mac[], unsigned int mac_len);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/iz_aes_wg.h b/aes_wg/iz_aes_wg.h
new file mode 100644 (file)
index 0000000..2cdf76a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  for terms of use.  If this file is missing, the Info-ZIP license
+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+
+/*
+ * iz_aes_wg.h -- Info-ZIP-specific data associated with WinZip/Gladman
+ * AES encryption.
+ */
+
+#ifndef __iz_aes_wg_h           /* Don't include more than once. */
+# define __iz_aes_wg_h
+
+# ifndef IZ_AES_WG_BETA
+#  define IZ_AES_WG_BETA        /* This is a beta version. */
+# endif
+
+# ifdef IZ_AES_WG_BETA
+#  undef IZ_AES_WG_BETA         /* This is not a beta version. */
+# endif
+
+
+# define IZ_AES_WG_MAJORVER     1
+# define IZ_AES_WG_MINORVER     6
+# ifdef IZ_AES_WG_BETA
+#  define IZ_AES_WG_BETA_VER      "a BETA"     
+#  define IZ_AES_WG_VERSION_DATE  "23 Jan 2017" /* Last real code change. */
+# else
+#  define IZ_AES_WG_BETA_VER      ""
+#  define IZ_AES_WG_VERSION_DATE  "23 Jan 2017" /* Last public release date. */
+#  define IZ_AES_WG_RELEASE
+# endif
+
+#endif /* ndef __iz_aes_wg_h */
diff --git a/aes_wg/main.c b/aes_wg/main.c
new file mode 100644 (file)
index 0000000..e5e5095
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 18th November 2008
+
+ A simple file encryption application based on
+
+    a. RFC2898 for key derivation (using HMAC-SHA1)
+    b. AES in CTR mode for encryption
+    c. HMAC-SHA1 for authentication
+    d. A Random Data Pool based on Peter Gutmann's ideas
+
+The command line is:
+
+    encfile password infile
+
+ If the last file name extension is ".enc", the file is assumed to be an
+ encrypted file and an attempt is made to decrypt it with the given password,
+ writing the output to a file with the same name except for the ".enc" on the
+ end.  Otherwise the file is encrypted with the given password and the output
+ is written to a file with the same name except that ".enc" is added on the
+ end.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <windows.h>
+
+#include "fileenc.h"
+#include "prng.h"
+
+/* error numbers    */
+#define ERROR_USAGE              1
+#define ERROR_PASSWORD_LENGTH    2
+#define ERROR_OUT_OF_MEMORY      3
+#define ERROR_INPUT_FILE         4
+#define ERROR_OUTPUT_FILE        5
+#define ERROR_BAD_PASSWORD       6
+#define ERROR_BAD_AUTHENTICATION 7
+
+/* error messages   */
+char *err_string[] =
+{
+    "\nusage: encfile password infile outfile\n",
+    "\npassword is too short\n",
+    "\nmemory allocation has failed\n",
+    "\ncannot open the input file (%s)\n",
+    "\ncannot open the output file (%s)\n",
+    "\nbad password\n",
+    "\ndamaged file or incorrect password\n"
+};
+
+/* simple entropy collection function that uses the fast timer      */
+/* since we are not using the random pool for generating secret     */
+/* keys we don't need to be too worried about the entropy quality   */
+
+/* Modified in 2008 to add revised entropy generation courtesy of   */
+/* WinZip Inc. This code now performs the following sequence of     */
+/* entropy generation operations on sequential calls:               */ 
+/*                                                                  */
+/*      - the current 8-byte Windows performance counter value      */
+/*      - an 8-byte representation of the current date/time         */
+/*      - an 8-byte value built from the current process ID         */
+/*        and thread ID                                             */
+/*      - all subsequent calls return the then-current 8-byte       */
+/*        performance counter value                                 */
+
+int entropy_fun(unsigned char buf[], unsigned int len)
+{   unsigned __int64    pentium_tsc[1];
+    unsigned int        i;
+    static unsigned int num = 0;
+
+    switch(num)
+    {
+    /* use a value that is unlikely to repeat across system reboots         */
+    case 1: 
+        ++num;
+        GetSystemTimeAsFileTime((FILETIME *)pentium_tsc);
+        break;
+    /* use a value that distinguishes between different instances of this   */
+    /* code that might be running on different processors at the same time  */
+    case 2: 
+        ++num;
+        {   unsigned __int32 processtest = GetCurrentProcessId();
+            unsigned __int32 threadtest  = GetCurrentThreadId();
+
+            pentium_tsc[0] = processtest;
+            pentium_tsc[0] = (pentium_tsc[0] << 32) + threadtest;
+        }
+        break;
+    
+    /* use a rapidly-changing value -- check QueryPerformanceFrequency()    */
+    /* to ensure that QueryPerformanceCounter() will work                   */
+    case 0: 
+        ++num;
+    default:
+        QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
+        break;
+    }
+
+    for(i = 0; i < 8 && i < len; ++i)
+        buf[i] = ((unsigned char*)pentium_tsc)[i];
+    return i;
+}
+
+/* this is the main file encryption/decryption routine code */
+
+int main(int argc, char *argv[])
+{   FILE *inf, *outf;
+    unsigned char buf[1024], tmp_buf1[16], tmp_buf2[16], salt[16], *fname, *cp;
+    fcrypt_ctx  zcx[1];
+    int len, flen, err = 0;
+    unsigned char mode;
+
+    if(argc != 3)   /* the command line is bad  */
+    {
+        err = ERROR_USAGE; goto error_0;
+    }
+
+
+    len = (int)strlen(argv[1]);
+
+    if(len < 8)     /* password is too short    */
+    {
+        err = ERROR_PASSWORD_LENGTH; goto error_0;
+    }
+
+    /* set the key length based on password length assuming that there  */
+    /* are about 4 bits of entropy per password character (the key      */
+    /* length and other mode dependent parameter values are set using   */
+    /* macros defined in fileenc.h)                                     */
+    mode = (len < 32 ? 1 : len < 48 ? 2 : 3);
+
+    /* save input file name to a temporary memory area with extra space */
+    /* for the extension ".enc" to be added                             */
+    fname = (unsigned char*)malloc(strlen(argv[2]) + 5);
+    if(fname == NULL)
+    {
+        err = ERROR_OUT_OF_MEMORY; goto error_0;
+    }
+
+    /* open the input file  */
+    strcpy(fname, argv[2]);
+    if((inf = fopen(fname, "rb")) == NULL)
+    {
+        err = ERROR_INPUT_FILE; goto error_1;
+    }
+
+    /* if the file name extension is ".enc" assume this is an encrypted */
+    /* file                                                             */
+    if((cp = strrchr(fname, '.')) && strcmp(cp, ".enc") == 0)
+    {
+        *cp = 0;
+        mode |= 4;  /* signal decryption */
+    }
+    else                        /* add ".enc" to file name to mark the  */
+        strcat(fname, ".enc");  /* the file as an encrypted one         */
+
+    /* open output file for binary output */
+    if((outf = fopen(fname, "wb")) == NULL)
+    {
+        err = ERROR_OUTPUT_FILE; goto error_2;
+    }
+
+    if(!(mode & 4))         /* encryption operation     */
+    {
+        prng_ctx rng[1];    /* the context for the random number pool   */
+        prng_init(entropy_fun, rng);                /* initialise RNG   */
+        prng_rand(salt, SALT_LENGTH(mode), rng);    /* and the salt     */
+
+        /* write salt value         */
+        fwrite(salt, sizeof(unsigned char), SALT_LENGTH(mode), outf);
+
+        /* initialise encryption and authentication */
+#ifdef PASSWORD_VERIFIER
+        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf1, zcx);
+        /* write password verifier (if used)        */
+        fwrite(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, outf);
+#else
+        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx);
+#endif
+        /* encrypt and authenticate the file        */
+        len = (int)fread(buf, sizeof(unsigned char), 1024, inf);
+        while(len)
+        {
+            fcrypt_encrypt(buf, len, zcx);
+            fwrite(buf, sizeof(unsigned char), len, outf);
+            len = (int)fread(buf, sizeof(unsigned char), len, inf);
+        }
+
+        /* write the MAC    */
+        fcrypt_end(tmp_buf1, zcx);
+        fwrite(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), outf);
+
+        /* and close random pool    */
+        prng_end(rng);
+    }
+    else                    /* decryption operation     */
+    {
+        /* we need to know the file length to avoid reading the MAC */
+        fseek(inf, 0, SEEK_END);
+        flen = ftell(inf);
+        fseek(inf, 0, SEEK_SET);
+        mode &= 3;
+
+        /* recover the password salt     */
+        fread(salt, sizeof(unsigned char), SALT_LENGTH(mode), inf); flen -= SALT_LENGTH(mode);
+#ifdef  PASSWORD_VERIFIER
+        /* initialise encryption and authentication */
+        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf2, zcx);
+        /* recover the password verifier (if used)  */
+        fread(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, inf); flen -= PWD_VER_LENGTH;
+        /* check password verifier  */
+        if(memcmp(tmp_buf1, tmp_buf2, PWD_VER_LENGTH))
+        {
+            err = ERROR_BAD_PASSWORD; fclose(outf); goto error_2;
+        }
+#else
+        /* initialise encryption and authentication */
+        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx);
+#endif
+
+        flen -= MAC_LENGTH(mode);   /* avoid reading the MAC    */
+        /* decrypt the file     */
+        len = (int)fread(buf, sizeof(unsigned char),
+                    (size_t)(flen < 1024 ? flen : 1024), inf);
+        while(len)
+        {   flen -= len;
+            fcrypt_decrypt(buf, len, zcx);
+            fwrite(buf, sizeof(unsigned char), len, outf);
+            len = (int)fread(buf, sizeof(unsigned char),
+                        (size_t)(flen < 1024 ? flen : 1024), inf);
+        }
+
+        /* calculate the MAC value          */
+        fcrypt_end(tmp_buf2, zcx);
+
+        /* now read the stored MAC value    */
+        fread(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), inf);
+
+        /* compare the stored and calculated MAC values */
+        if(memcmp(tmp_buf1, tmp_buf2, MAC_LENGTH(mode)))
+        {   /* authentication failed        */
+
+            err = ERROR_BAD_AUTHENTICATION;
+            fclose(outf);
+            /* delete the (bad) output file */
+            remove(fname);
+            goto error_2;
+        }
+    }
+
+    fclose(outf);
+error_2:
+    fclose(inf);
+error_1:
+    free(fname);
+error_0:
+    if(err)
+        printf(err_string[err - 1], fname);
+    return -err;
+}
diff --git a/aes_wg/orig/aes.h_orig b/aes_wg/orig/aes.h_orig
new file mode 100644 (file)
index 0000000..186ef80
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the definitions required to use AES and Rijndael in C.
+*/
+
+#ifndef _AES_H
+#define _AES_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* If a table pointer is needed in the AES context, include the define  */
+/* #define AES_TABLE_PTR                                                */
+
+/*  This include is used to find 8 and 32 bit unsigned integer types    */
+#include "limits.h"
+
+#if UCHAR_MAX == 0xff                       /* an unsigned 8 bit type   */
+  typedef unsigned char      aes_08t;
+#else
+#error Please define aes_08t as an 8-bit unsigned integer type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff                  /* an unsigned 32 bit type  */
+  typedef   unsigned int     aes_32t;
+#elif ULONG_MAX == 0xffffffff
+  typedef   unsigned long    aes_32t;
+#else
+#error Please define aes_32t as a 32-bit unsigned integer type in aes.h
+#endif
+
+/* This BLOCK_SIZE is in BYTES.  It can have the values 16, 24, 32 or   */
+/* undefined for use with aescrypt.c and aeskey.c, or 16, 20, 24, 28,   */
+/* 32 or undefined for use with aescrypp.c and aeskeypp.c.   When the   */
+/* BLOCK_SIZE is left undefined a version that provides a dynamically   */
+/* variable block size is produced but this is MUCH slower.             */
+
+#define BLOCK_SIZE  16
+
+/* key schedule length (in 32-bit words)                                */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH   128
+#else
+#define KS_LENGTH   (4 * BLOCK_SIZE)
+#endif
+
+typedef unsigned int aes_fret;   /* type for function return value      */
+#define aes_bad      0           /* bad function return value           */
+#define aes_good     1           /* good function return value          */
+#ifndef AES_DLL                  /* implement normal or DLL functions   */
+#define aes_rval     aes_fret
+#else
+#define aes_rval     aes_fret __declspec(dllexport) _stdcall
+#endif
+
+typedef struct                     /* the AES context for encryption    */
+{   aes_32t    k_sch[KS_LENGTH];   /* the encryption key schedule       */
+    aes_32t    n_rnd;              /* the number of cipher rounds       */
+    aes_32t    n_blk;              /* the number of bytes in the state  */
+#if defined(AES_TABLE_PTR)         /* where global variables are not    */
+    void      *t_ptr;              /* available this pointer is used    */
+#endif                             /* to point to the fixed tables      */
+} aes_ctx;
+
+/* The block length (blen) is input in bytes when it is in the range    */
+/* 16 <= blen <= 32 or in bits when in the range 128 <= blen <= 256     */
+/* Only 16 bytes (128 bits) is legal for AES but the files aescrypt.c   */
+/* and aeskey.c provide support for 16, 24 and 32 byte (128, 192 and    */
+/* 256 bit) blocks while aescrypp.c and aeskeypp.c provide support for  */
+/* 16, 20, 24, 28 and 32 byte (128, 160, 192, 224 and 256 bit) blocks.  */
+/* The value aes_good is returned if the requested block size is legal, */
+/* otherwise aes_bad is returned.                                       */
+
+#if !defined(BLOCK_SIZE)
+aes_rval aes_set_block_size(unsigned int blen, aes_ctx cx[1]);
+#endif
+
+/* The key length (klen) is input in bytes when it is in the range      */
+/* 16 <= klen <= 32 or in bits when in the range 128 <= klen <= 256     */
+/* The files aescrypt.c and aeskey.c provide support for 16, 24 and     */
+/* 32 byte (128, 192 and 256 bit) keys while aescrypp.c and aeskeypp.c  */
+/* provide support for 16, 20, 24, 28 and 32 byte (128, 160, 192, 224   */
+/* and 256 bit) keys.  The value aes_good is returned if the requested  */
+/* key size is legal, otherwise aes_bad is returned.                    */
+
+aes_rval aes_set_encrypt_key(const unsigned char in_key[],
+                                        unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_encrypt_block(const unsigned char in_blk[],
+                            unsigned char out_blk[], const aes_ctx cx[1]);
+
+aes_rval aes_set_decrypt_key(const unsigned char in_key[],
+                                        unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_decrypt_block(const unsigned char in_blk[],
+                            unsigned char out_blk[], const aes_ctx cx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/orig/aesopt.h_orig b/aes_wg/orig/aesopt.h_orig
new file mode 100644 (file)
index 0000000..a3e8561
--- /dev/null
@@ -0,0 +1,920 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
+
+    OPERATION
+
+    These source code files implement the AES algorithm Rijndael designed by
+    Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+    block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+    that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+    and 256 bits (16, 20, 24, 28 and 32 bytes).  This file is a common header
+    file for these two implementations and for aesref.c, which is a reference
+    implementation.
+
+    This version is designed for flexibility and speed using operations on
+    32-bit words rather than operations on bytes.  It provides aes_both fixed
+    and  dynamic block and key lengths and can also run with either big or
+    little endian internal byte order (see aes.h).  It inputs block and key
+    lengths in bytes with the legal values being  16, 24 and 32 for aes.c and
+    16, 20, 24, 28 and 32 for aespp.c
+
+    THE CIPHER INTERFACE
+
+    aes_08t         (an unsigned  8-bit type)
+    aes_32t         (an unsigned 32-bit type)
+    aes_fret        (a signed 16 bit type for function return values)
+    aes_good        (value != 0, a good return)
+    aes_bad         (value == 0, an error return)
+    struct aes_ctx  (structure for the cipher encryption context)
+    struct aes_ctx  (structure for the cipher decryption context)
+    aes_rval        the function return type (aes_fret if not DLL)
+
+    C subroutine calls:
+
+      aes_rval aes_set_block_size(unsigned int blen, aes_ctx cx[1]);
+      aes_rval aes_set_encrypt_key(const unsigned char in_key[],
+                                            unsigned int klen, aes_ctx cx[1]);
+      aes_rval aes_encrypt_block(const unsigned char in_blk[],
+                                unsigned char out_blk[], const aes_ctx cx[1]);
+
+      aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+      aes_rval aes_set_decrypt_key(const unsigned char in_key[],
+                                            unsigned int klen, aes_ctx cx[1]);
+      aes_rval aes_decrypt_block(const unsigned char in_blk[],
+                                unsigned char out_blk[], const aes_ctx cx[1]);
+
+    IMPORTANT NOTE: If you are using this C interface and your compiler does
+    not set the memory used for objects to zero before use, you will need to
+    ensure that cx.n_blk is set to zero before using these subroutine calls.
+
+    C++ aes class subroutines:
+
+      class AESclass    for encryption
+      class AESclass    for decryption
+
+      aes_rval len(unsigned int blen = 16);
+      aes_rval key(const unsigned char in_key[], unsigned int klen);
+      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+      aes_rval len(unsigned int blen = 16);
+      aes_rval key(const unsigned char in_key[], unsigned int klen);
+      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+    The block length inputs to set_block and set_key are in numbers of
+    BYTES, not bits.  The calls to subroutines must be made in the above
+    order but multiple calls can be made without repeating earlier calls
+    if their parameters have not changed. If the cipher block length is
+    variable but set_blk has not been called before cipher operations a
+    value of 16 is assumed (that is, the AES block size). In contrast to
+    earlier versions the block and key length parameters are now checked
+    for correctness and the encryption and decryption routines check to
+    ensure that an appropriate key has been set before they are called.
+
+    COMPILATION
+
+    The files used to provide AES (Rijndael) are
+
+    a. aes.h for the definitions needed for use in C.
+    b. aescpp.h for the definitions needed for use in C++.
+    c. aesopt.h for setting compilation options (also includes common
+       code).
+    d. aescrypt.c for encryption and decrytpion, or
+    e. aescrypt.asm for encryption and decryption using assembler code.
+    f. aeskey.c for key scheduling.
+    g. aestab.c for table loading or generation.
+
+    The assembler code uses the NASM assembler. The above files provice
+    block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+    If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+    aeskey.c respectively, the block and key lengths can then be 16, 20,
+    24, 28 or 32 bytes. However this code has not been optimised to the
+    same extent and is hence slower (esepcially for the AES block size
+    of 16 bytes).
+
+    To compile AES (Rijndael) for use in C code use aes.h and exclude
+    the AES_DLL define in aes.h
+
+    To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+    exclude the AES_DLL define in aes.h
+
+    To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+    aes.h, include the AES_DLL define and compile the DLL.  If using
+    the test files to test the DLL, exclude aes.c from the test build
+    project and compile it with the same defines as used for the DLL
+    (ensure that the DLL path is correct)
+
+    CONFIGURATION OPTIONS (here and in aes.h)
+
+    a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+       or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+       extended code) or leave this undefined for dynamically variable
+       block size (this will result in much slower code).
+    b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+    c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+    d. If you want the code to run in a specific internal byte order, then
+       INTERNAL_BYTE_ORDER must be set accordingly.
+    e. set other configuration options decribed below.
+*/
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*  START OF CONFIGURATION OPTIONS
+
+    USE OF DEFINES
+
+    Later in this section there are a number of defines that control the
+    operation of the code.  In each section, the purpose of each define is
+    explained so that the relevant form can be included or excluded by
+    setting either 1's or 0's respectively on the branches of the related
+    #if clauses.
+*/
+
+/*  DO NOT CHANGE THE FOLLOWING EIGHT DEFINES   */
+
+#define NO_TABLES              0
+#define ONE_TABLE              1
+#define FOUR_TABLES            4
+#define NONE                   0
+#define PARTIAL                1
+#define FULL                   2
+#define AES_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+/*  1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
+#include "crypt/aes.h"
+#else
+  #include "aes.h"
+#endif
+
+#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#  include <endian.h>
+#  include <byteswap.h>
+#elif defined(__CRYPTLIB__)
+#  if defined( INC_ALL )
+#    include "crypt.h"
+#  elif defined( INC_CHILD )
+#    include "../crypt.h"
+#  else
+#    include "crypt.h"
+#  endif
+#  if defined(DATA_LITTLEENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  else
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_MSC_VER)
+#  include <stdlib.h>
+#elif !defined(WIN32)
+#  include <stdlib.h>
+#  if !defined (_ENDIAN_H)
+#    include <sys/param.h>
+#  else
+#    include _ENDIAN_H
+#  endif
+#endif
+
+/*  2. BYTE ORDER IN 32-BIT WORDS
+
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the order in which bytes are packed into such words.
+    The following block of code is an attempt to capture the most obvious
+    ways in which various environemnts define byte order. It may well fail,
+    in which case the definitions will need to be set by editing at the
+    points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 241 or 243 of aesopt.h).
+#endif
+
+/*  3. FUNCTIONS REQUIRED
+
+    This implementation provides five main subroutines which provide for
+    setting block length, setting encryption and decryption keys and for
+    encryption and decryption. When the assembler code is not being used
+    the following definition blocks allow the selection of the routines
+    that are to be included in the compilation.
+*/
+#if 1
+#define ENCRYPTION
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+
+#if 0
+#define DECRYPTION
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+/*  4. ASSEMBLER SUPPORT
+
+    This define (which can be on the command line) enables the use of the
+    assembler code routines for encryption and decryption with the C code
+    only providing key scheduling
+*/
+#if 0
+#define AES_ASM
+#endif
+
+/*  5. BYTE ORDER WITHIN 32 BIT WORDS
+
+    The fundamental data processing units in Rijndael are 8-bit bytes. The
+    input, output and key input are all enumerated arrays of bytes in which
+    bytes are numbered starting at zero and increasing to one less than the
+    number of bytes in the array in question. This enumeration is only used
+    for naming bytes and does not imply any adjacency or order relationship
+    from one byte to another. When these inputs and outputs are considered
+    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+    In this implementation bits are numbered from 0 to 7 starting at the
+    numerically least significant end of each byte (bit n represents 2^n).
+
+    However, Rijndael can be implemented more efficiently using 32-bit
+    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+    into word[n]. While in principle these bytes can be assembled into words
+    in any positions, this implementation only supports the two formats in
+    which bytes in adjacent positions within words also have adjacent byte
+    numbers. This order is called big-endian if the lowest numbered bytes
+    in words have the highest numeric significance and little-endian if the
+    opposite applies.
+
+    This code can work in either order irrespective of the order used by the
+    machine on which it runs. Normally the internal byte order will be set
+    to the order of the processor on which the code is to be run but this
+    define can be used to reverse this in special situations
+*/
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif 0
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#else
+#error The internal byte order is not defined
+#endif
+
+/*  6. FAST INPUT/OUTPUT OPERATIONS.
+
+    On some machines it is possible to improve speed by transferring the
+    bytes in the input and output arrays to and from the internal 32-bit
+    variables by addressing these arrays as if they are arrays of 32-bit
+    words.  On some machines this will always be possible but there may
+    be a large performance penalty if the byte arrays are not aligned on
+    the normal word boundaries. On other machines this technique will
+    lead to memory access errors when such 32-bit word accesses are not
+    properly aligned. The option SAFE_IO avoids such problems but will
+    often be slower on those machines that support misaligned access
+    (especially so if care is taken to align the input  and output byte
+    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+    assumed that access to byte arrays as if they are arrays of 32-bit
+    words will not cause problems when such accesses are misaligned.
+*/
+#if 1 && !defined(_MSC_VER)
+#define SAFE_IO
+#endif
+
+/*  7. LOOP UNROLLING
+
+    The code for encryption and decrytpion cycles through a number of rounds
+    that can be implemented either in a loop or by expanding the code into a
+    long sequence of instructions, the latter producing a larger program but
+    one that will often be much faster. The latter is called loop unrolling.
+    There are also potential speed advantages in expanding two iterations in
+    a loop with half the number of iterations, which is called partial loop
+    unrolling.  The following options allow partial or full loop unrolling
+    to be set independently for encryption and decryption
+*/
+#if 1
+#define ENC_UNROLL  FULL
+#elif 0
+#define ENC_UNROLL  PARTIAL
+#else
+#define ENC_UNROLL  NONE
+#endif
+
+#if 1
+#define DEC_UNROLL  FULL
+#elif 0
+#define DEC_UNROLL  PARTIAL
+#else
+#define DEC_UNROLL  NONE
+#endif
+
+/*  8. FAST FINITE FIELD OPERATIONS
+
+    If this section is included, tables are used to provide faster finite
+    field arithmetic (this has no effect if FIXED_TABLES is defined).
+*/
+#if 1
+#define FF_TABLES
+#endif
+
+/*  9. INTERNAL STATE VARIABLE FORMAT
+
+    The internal state of Rijndael is stored in a number of local 32-bit
+    word varaibles which can be defined either as an array or as individual
+    names variables. Include this section if you want to store these local
+    varaibles in arrays. Otherwise individual local variables will be used.
+*/
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+   32-bit words. The state array can be held in various ways: in an array
+   of words, in a number of individual word variables or in a number of
+   processor registers. The following define maps a variable name x and
+   a column number c to the way the state array variable is to be held.
+   The first define below maps the state into an array x[c] whereas the
+   second form maps the state into a number of individual variables x0,
+   x1, etc.  Another form could map individual state colums to machine
+   register names.
+*/
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+/*  10. VARIABLE BLOCK SIZE SPEED
+
+    This section is only relevant if you wish to use the variable block
+    length feature of the code.  Include this section if you place more
+    emphasis on speed rather than code size.
+*/
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/*  11. FIXED OR DYNAMIC TABLES
+
+    When this section is included the tables used by the code are comipled
+    statically into the binary file.  Otherwise they are computed once when
+    the code is first used.
+*/
+#if 1
+#define FIXED_TABLES
+#endif
+
+/*  12. GLOBAL VARIABLES
+
+    In some circumstances global variables to hold the fixed tables are not
+    possible so the tables have to be placed in a structure that is passed
+    around at run time through the AES API calls. In this case FIXED_TABLES
+    cannot be used. GLOBALS must be defined in order to use the assembler
+    version of this code. If GLOBALS is not defined, then AES_TABLE_PTR must
+    be defined either on the command line or early in aes.h in order to
+    provide space for the table pointer in the AES context.
+*/
+#if 1 || defined(AES_ASM)
+#define GLOBALS
+#elif !defined(AES_TABLE_PTR)
+#error no context space for table pointer (compile with AES_TABLE_PTR defined)
+#elif defined(FIXED_TABLES)
+#undef FIXED_TABLES
+#endif
+
+/*  13. INTERNAL TABLE CONFIGURATION
+
+    This cipher proceeds by repeating in a number of cycles known as 'rounds'
+    which are implemented by a round function which can optionally be speeded
+    up using tables.  The basic tables are each 256 32-bit words, with either
+    one or four tables being required for each round function depending on
+    how much speed is required. The encryption and decryption round functions
+    are different and the last encryption and decrytpion round functions are
+    different again making four different round functions in all.
+
+    This means that:
+      1. Normal encryption and decryption rounds can each use either 0, 1
+         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+      2. The last encryption and decryption rounds can also use either 0, 1
+         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+
+    Include or exclude the appropriate definitions below to set the number
+    of tables used by this implementation.
+*/
+
+#if 1   /* set tables for the normal encryption round */
+#define ENC_ROUND   FOUR_TABLES
+#elif 0
+#define ENC_ROUND   ONE_TABLE
+#else
+#define ENC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last encryption round */
+#define LAST_ENC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND  ONE_TABLE
+#else
+#define LAST_ENC_ROUND  NO_TABLES
+#endif
+
+#if 1   /* set tables for the normal decryption round */
+#define DEC_ROUND   FOUR_TABLES
+#elif 0
+#define DEC_ROUND   ONE_TABLE
+#else
+#define DEC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last decryption round */
+#define LAST_DEC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND  ONE_TABLE
+#else
+#define LAST_DEC_ROUND  NO_TABLES
+#endif
+
+/*  The decryption key schedule can be speeded up with tables in the same
+    way that the round functions can.  Include or exclude the following
+    defines to set this requirement.
+*/
+#if 1
+#define KEY_SCHED   FOUR_TABLES
+#elif 0
+#define KEY_SCHED   ONE_TABLE
+#else
+#define KEY_SCHED   NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH   29
+#else
+#define RC_LENGTH   (5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11))
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef  ENC_UNROLL
+#define ENC_UNROLL  NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef  DEC_UNROLL
+#define DEC_UNROLL  NONE
+#endif
+
+/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
+               higher index positions with wrap around into low positions
+    ups(x,n):  moves bytes by n positions to higher index positions in
+               words but without wrap around
+    bval(x,n): extracts a byte from a word
+
+    NOTE:      The definitions given here are intended only for use with
+               unsigned variables and with shift counts that are compile
+               time constants
+*/
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#define upr(x,n)        (((aes_32t)(x) << (8 * (n))) | ((aes_32t)(x) >> (32 - 8 * (n))))
+#define ups(x,n)        ((aes_32t) (x) << (8 * (n)))
+#define bval(x,n)       ((aes_08t)((x) >> (8 * (n))))
+#define bytes2word(b0, b1, b2, b3)  \
+        (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x,n)        (((aes_32t)(x) >> (8 * (n))) | ((aes_32t)(x) << (32 - 8 * (n))))
+#define ups(x,n)        ((aes_32t) (x) >> (8 * (n))))
+#define bval(x,n)       ((aes_08t)((x) >> (24 - 8 * (n))))
+#define bytes2word(b0, b1, b2, b3)  \
+        (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x)      bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x,v)   { (x)[0] = bval(v,0); (x)[1] = bval(v,1);   \
+                          (x)[2] = bval(v,2); (x)[3] = bval(v,3);   }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x)      (*(aes_32t*)(x))
+#define word_out(x,v)   (*(aes_32t*)(x) = (v))
+
+#else
+
+#if !defined(bswap_32)
+#define brot(x,n)       (((aes_32t)(x) <<  n) | ((aes_32t)(x) >> (32 - n)))
+#define bswap_32(x)     ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
+#endif
+
+#define word_in(x)      bswap_32(*(aes_32t*)(x))
+#define word_out(x,v)   (*(aes_32t*)(x) = bswap_32(v))
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY   0x011b
+#define BPOLY     0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1  0x80808080
+#define m2  0x7f7f7f7f
+#define FFmulX(x)  ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+   give improved performance if a fast 32-bit multiply is not available. Note
+   that a temporary variable u needs to be defined where FFmulX is used.
+
+#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+#define m4  (0x01010101 * BPOLY)
+#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+*/
+
+/* Work out which tables are needed for the different options   */
+
+#ifdef  AES_ASM
+#ifdef  ENC_ROUND
+#undef  ENC_ROUND
+#endif
+#define ENC_ROUND   FOUR_TABLES
+#ifdef  LAST_ENC_ROUND
+#undef  LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND  FOUR_TABLES
+#ifdef  DEC_ROUND
+#undef  DEC_ROUND
+#endif
+#define DEC_ROUND   FOUR_TABLES
+#ifdef  LAST_DEC_ROUND
+#undef  LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND  FOUR_TABLES
+#ifdef  KEY_SCHED
+#undef  KEY_SCHED
+#define KEY_SCHED   FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+/*  If there are no global variables, the AES tables are placed in
+    a structure and a pointer is added to the AES context. If this
+    facility is used, the calling program has to ensure that this
+    pointer is managed appropriately. In particular, the value of
+    the t_dec(in,it) item in the table structure must be set to zero
+    in order to ensure that the tables are initialised. In practice
+    the three code sequences in aeskey.c that control the calls to
+    gen_tabs() and the gen_tabs() routine itself will require some
+    changes for a specific implementation. If global variables are
+    available it will generally be preferable to use them with the
+    precomputed FIXED_TABLES option that uses static global tables.
+
+    The following defines can be used to control the way the tables
+    are defined, initialised and used in embedded environments that
+    require special features for these purposes
+
+    the 't_dec' construction is used to declare fixed table arrays
+    the 't_set' construction is used to set fixed table values
+    the 't_use' construction is used to access fixed table values
+
+    256 byte tables:
+
+        t_xxx(s,box)    => forward S box
+        t_xxx(i,box)    => inverse S box
+
+    256 32-bit word OR 4 x 256 32-bit word tables:
+
+        t_xxx(f,n)      => forward normal round
+        t_xxx(f,l)      => forward last round
+        t_xxx(i,n)      => inverse normal round
+        t_xxx(i,l)      => inverse last round
+        t_xxx(l,s)      => key schedule table
+        t_xxx(i,m)      => key schedule table
+
+    Other variables and tables:
+
+        t_xxx(in,it)    => the table initialsation flag
+        t_xxx(r,c)      => the rcon table
+*/
+
+#define t_dec(m,n) t_##m##n
+#define t_set(m,n) t_##m##n  /* may be redefined once below */
+#define t_use(m,n) t_##m##n  /* may be redefined once below */
+
+#ifdef  FIXED_TABLES
+
+#define prefx    extern const
+#elif defined(GLOBALS)
+#define prefx    extern
+extern aes_08t   t_dec(in,it);
+void gen_tabs(void);
+#else
+#define prefx
+void gen_tabs(aes_ctx cx[1]);
+
+typedef struct {
+#endif
+
+prefx aes_32t  t_dec(r,c)[RC_LENGTH];
+
+#ifdef  SBX_SET
+prefx aes_08t t_dec(s,box)[256];
+#endif
+
+#ifdef  ISB_SET
+prefx aes_08t t_dec(i,box)[256];
+#endif
+
+#ifdef  FT1_SET
+prefx aes_32t t_dec(f,n)[256];
+#endif
+
+#ifdef  FT4_SET
+prefx aes_32t t_dec(f,n)[4][256];
+#endif
+
+#ifdef  FL1_SET
+prefx aes_32t t_dec(f,l)[256];
+#endif
+
+#ifdef  FL4_SET
+prefx aes_32t t_dec(f,l)[4][256];
+#endif
+
+#ifdef  IT1_SET
+prefx aes_32t t_dec(i,n)[256];
+#endif
+
+#ifdef  IT4_SET
+prefx aes_32t t_dec(i,n)[4][256];
+#endif
+
+#ifdef  IL1_SET
+prefx aes_32t t_dec(i,l)[256];
+#endif
+
+#ifdef  IL4_SET
+prefx aes_32t t_dec(i,l)[4][256];
+#endif
+
+#ifdef  LS1_SET
+#ifdef  FL1_SET
+#undef  LS1_SET
+#else
+prefx aes_32t t_dec(l,s)[256];
+#endif
+#endif
+
+#ifdef  LS4_SET
+#ifdef  FL4_SET
+#undef  LS4_SET
+#else
+prefx aes_32t t_dec(l,s)[4][256];
+#endif
+#endif
+
+#ifdef  IM1_SET
+prefx aes_32t t_dec(i,m)[256];
+#endif
+
+#ifdef  IM4_SET
+prefx aes_32t t_dec(i,m)[4][256];
+#endif
+
+prefx aes_08t  t_dec(in,it);
+
+#ifndef GLOBALS
+} s_ty;
+
+extern s_ty s_t;
+
+/* modify the table set macro to cope with a static structure */
+#undef  t_set
+#define t_set(m,n) (s_t.t_##m##n)
+
+/* modify the table use macro to cope with a context pointer  */
+#undef  t_use
+#define t_use(m,n) (((s_ty*)cx->t_ptr)->t_##m##n)
+
+#endif
+
+/* Set the number of columns in nc.  Note that it is important
+   that nc is a constant which is known at compile time if the
+   highest speed version of the code is needed.
+*/
+
+#if defined(BLOCK_SIZE)
+#define nc  (BLOCK_SIZE >> 2)
+#else
+#define nc  (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use tables    */
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+    box[bval(vf(x,0,c),rf(0,c))], \
+    box[bval(vf(x,1,c),rf(1,c))], \
+    box[bval(vf(x,2,c),rf(2,c))], \
+    box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ (     tab[bval(vf(x,0,c),rf(0,c))] \
+  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ (  tab[0][bval(vf(x,0,c),rf(0,c))] \
+  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+  ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c)  (x)
+#define rf1(r,c)    (r)
+#define rf2(r,c)    ((8+r-c)&3)
+
+/* perform forward and inverse column mix operation on four bytes in long word x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */
+
+#define dec_fmvars
+#if defined(FM4_SET)    /* not currently used */
+#define fwd_mcol(x)     four_tables(x,t_use(f,m),vf1,rf1,0)
+#elif defined(FM1_SET)  /* not currently used */
+#define fwd_mcol(x)     one_table(x,upr,t_use(f,m),vf1,rf1,0)
+#else
+#undef  dec_fmvars
+#define dec_fmvars      aes_32t f1, f2;
+#define fwd_mcol(x)     (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x)     four_tables(x,t_use(i,m),vf1,rf1,0)
+#elif defined(IM1_SET)
+#define inv_mcol(x)     one_table(x,upr,t_use(i,m),vf1,rf1,0)
+#else
+#undef  dec_imvars
+#define dec_imvars      aes_32t    f2, f4, f8, f9;
+#define inv_mcol(x) \
+    (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+    f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x,c)     four_tables(x,t_use(f,l),vf1,rf2,c)
+#elif   defined(LS4_SET)
+#define ls_box(x,c)     four_tables(x,t_use(l,s),vf1,rf2,c)
+#elif defined(FL1_SET)
+#define ls_box(x,c)     one_table(x,upr,t_use(f,l),vf1,rf2,c)
+#elif defined(LS1_SET)
+#define ls_box(x,c)     one_table(x,upr,t_use(l,s),vf1,rf2,c)
+#else
+#define ls_box(x,c)     no_table(x,t_use(s,box),vf1,rf2,c)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/orig/brg_endian.h_orig b/aes_wg/orig/brg_endian.h_orig
new file mode 100644 (file)
index 0000000..e3cf0d1
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
+
+ LICENSE TERMS
+
+ The redistribution and use of this software (with or without changes)
+ is allowed without the payment of fees or royalties provided that:
+
+  1. source code distributions include the above copyright notice, this
+     list of conditions and the following disclaimer;
+
+  2. binary distributions include the above copyright notice, this list
+     of conditions and the following disclaimer in their documentation;
+
+  3. the name of the copyright holder is not used to endorse products
+     built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 20/12/2007
+*/
+
+#ifndef _BRG_ENDIAN_H
+#define _BRG_ENDIAN_H
+
+#define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+#define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+
+/* Include files where endian defines and byteswap functions may reside */
+#if defined( __sun )
+#  include <sys/isa_defs.h>
+#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
+#  include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
+      defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
+#  include <machine/endian.h>
+#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
+#  if !defined( __MINGW32__ ) && !defined( _AIX )
+#    include <endian.h>
+#    if !defined( __BEOS__ )
+#      include <byteswap.h>
+#    endif
+#  endif
+#endif
+
+/* Now attempt to set the define for platform byte order using any  */
+/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which  */
+/* seem to encompass most endian symbol definitions                 */
+
+#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
+#  if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
+#  if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( _BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( _LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
+#  if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
+#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+/*  if the platform byte order could not be determined, then try to */
+/*  set this define using common machine defines                    */
+#if !defined(PLATFORM_BYTE_ORDER)
+
+#if   defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       || \
+      defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \
+      defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \
+      defined( vax )       || defined( vms )     || defined( VMS )        || \
+      defined( __VMS )     || defined( _M_X64 )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+
+#elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \
+      defined( _CRAY )   || defined( __hppa )    || defined( __hp9000 )   || \
+      defined( ibm370 )  || defined( mc68000 )   || defined( m68k )       || \
+      defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \
+      defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \
+      defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \
+      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#else
+#  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
+#endif
+
+#endif
+
+#endif
diff --git a/aes_wg/orig/fileenc.c_orig b/aes_wg/orig/fileenc.c_orig
new file mode 100644 (file)
index 0000000..cff7d67
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file implements password based file encryption and authentication 
+ using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password 
+ based key derivation.
+
+*/
+
+#include <memory.h>
+
+#include "fileenc.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* subroutine for data encryption/decryption    */
+/* this could be speeded up a lot by aligning   */
+/* buffers and using 32 bit operations          */
+
+static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1])
+{   unsigned long i = 0, pos = cx->encr_pos;
+
+    while(i < d_len)
+    {
+        if(pos == BLOCK_SIZE)
+        {   unsigned int j = 0;
+            /* increment encryption nonce   */
+            while(j < 8 && !++cx->nonce[j])
+                ++j;
+            /* encrypt the nonce to form next xor buffer    */
+            aes_encrypt_block(cx->nonce, cx->encr_bfr, cx->encr_ctx);
+            pos = 0;
+        }
+
+        data[i++] ^= cx->encr_bfr[pos++];
+    }
+
+    cx->encr_pos = pos;
+}
+
+int fcrypt_init(
+    int mode,                               /* the mode to be used (input)          */
+    const unsigned char pwd[],              /* the user specified password (input)  */
+    unsigned int pwd_len,                   /* the length of the password (input)   */
+    const unsigned char salt[],             /* the salt (input)                     */
+#ifdef PASSWORD_VERIFIER
+    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */
+#endif
+    fcrypt_ctx      cx[1])                  /* the file encryption context (output) */
+{   unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];
+
+    if(pwd_len > MAX_PWD_LENGTH)
+        return PASSWORD_TOO_LONG;
+
+    if(mode < 1 || mode > 3)
+        return BAD_MODE;
+
+    cx->mode = mode;
+    cx->pwd_len = pwd_len;
+
+    /* derive the encryption and authetication keys and the password verifier   */
+    derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,
+                        kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
+
+    /* initialise the encryption nonce and buffer pos   */
+    cx->encr_pos = BLOCK_SIZE;
+    /* if we need a random component in the encryption  */
+    /* nonce, this is where it would have to be set     */
+    memset(cx->nonce, 0, BLOCK_SIZE * sizeof(unsigned char));
+
+    /* initialise for encryption using key 1            */
+    aes_set_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);
+
+    /* initialise for authentication using key 2        */
+    hmac_sha1_begin(cx->auth_ctx);
+    hmac_sha1_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);
+
+#ifdef PASSWORD_VERIFIER
+    memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
+#endif
+
+    return GOOD_RETURN;
+}
+
+/* perform 'in place' encryption and authentication */
+
+void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
+{
+    encr_data(data, data_len, cx);
+    hmac_sha1_data(data, data_len, cx->auth_ctx);
+}
+
+/* perform 'in place' authentication and decryption */
+
+void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
+{
+    hmac_sha1_data(data, data_len, cx->auth_ctx);
+    encr_data(data, data_len, cx);
+}
+
+/* close encryption/decryption and return the MAC value */
+
+int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
+{
+    hmac_sha1_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
+    return MAC_LENGTH(cx->mode);    /* return MAC length in bytes   */
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/orig/hmac.c_orig b/aes_wg/orig/hmac.c_orig
new file mode 100644 (file)
index 0000000..3632a99
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of HMAC, the FIPS standard keyed hash function
+*/
+
+#include "hmac.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* initialise the HMAC context to zero */
+void hmac_sha1_begin(hmac_ctx cx[1])
+{
+    memset(cx, 0, sizeof(hmac_ctx));
+}
+
+/* input the HMAC key (can be called multiple times)    */
+int hmac_sha1_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])
+{
+    if(cx->klen == HMAC_IN_DATA)                /* error if further key input   */
+        return HMAC_BAD_MODE;                   /* is attempted in data mode    */
+
+    if(cx->klen + key_len > IN_BLOCK_LENGTH)    /* if the key has to be hashed  */
+    {
+        if(cx->klen <= IN_BLOCK_LENGTH)         /* if the hash has not yet been */
+        {                                       /* started, initialise it and   */
+            sha1_begin(cx->ctx);                /* hash stored key characters   */
+            sha1_hash(cx->key, cx->klen, cx->ctx);
+        }
+
+        sha1_hash(key, key_len, cx->ctx);       /* hash long key data into hash */
+    }
+    else                                        /* otherwise store key data     */
+        memcpy(cx->key + cx->klen, key, key_len);
+
+    cx->klen += key_len;                        /* update the key length count  */
+    return HMAC_OK;
+}
+
+/* input the HMAC data (can be called multiple times) - */
+/* note that this call terminates the key input phase   */
+void hmac_sha1_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1])
+{   unsigned int i;
+
+    if(cx->klen != HMAC_IN_DATA)                /* if not yet in data phase */
+    {
+        if(cx->klen > IN_BLOCK_LENGTH)          /* if key is being hashed   */
+        {                                       /* complete the hash and    */
+            sha1_end(cx->key, cx->ctx);         /* store the result as the  */
+            cx->klen = OUT_BLOCK_LENGTH;        /* key and set new length   */
+        }
+
+        /* pad the key if necessary */
+        memset(cx->key + cx->klen, 0, IN_BLOCK_LENGTH - cx->klen);
+
+        /* xor ipad into key value  */
+        for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
+            ((unsigned long*)cx->key)[i] ^= 0x36363636;
+
+        /* and start hash operation */
+        sha1_begin(cx->ctx);
+        sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
+
+        /* mark as now in data mode */
+        cx->klen = HMAC_IN_DATA;
+    }
+
+    /* hash the data (if any)       */
+    if(data_len)
+        sha1_hash(data, data_len, cx->ctx);
+}
+
+/* compute and output the MAC value */
+void hmac_sha1_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
+{   unsigned char dig[OUT_BLOCK_LENGTH];
+    unsigned int i;
+
+    /* if no data has been entered perform a null data phase        */
+    if(cx->klen != HMAC_IN_DATA)
+        hmac_sha1_data((const unsigned char*)0, 0, cx);
+
+    sha1_end(dig, cx->ctx);         /* complete the inner hash      */
+
+    /* set outer key value using opad and removing ipad */
+    for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
+        ((unsigned long*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
+
+    /* perform the outer hash operation */
+    sha1_begin(cx->ctx);
+    sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
+    sha1_hash(dig, OUT_BLOCK_LENGTH, cx->ctx);
+    sha1_end(dig, cx->ctx);
+
+    /* output the hash value            */
+    for(i = 0; i < mac_len; ++i)
+        mac[i] = dig[i];
+}
+
+/* 'do it all in one go' subroutine     */
+void hmac_sha1(const unsigned char key[], unsigned int key_len,
+          const unsigned char data[], unsigned int data_len,
+          unsigned char mac[], unsigned int mac_len)
+{   hmac_ctx    cx[1];
+
+    hmac_sha1_begin(cx);
+    hmac_sha1_key(key, key_len, cx);
+    hmac_sha1_data(data, data_len, cx);
+    hmac_sha1_end(mac, mac_len, cx);
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/orig/hmac.h_orig b/aes_wg/orig/hmac.h_orig
new file mode 100644 (file)
index 0000000..bbeac00
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of HMAC, the FIPS standard keyed hash function
+*/
+
+#ifndef _HMAC_H
+#define _HMAC_H
+
+#include <memory.h>
+
+#include "sha1.h"
+
+#define IN_BLOCK_LENGTH     SHA1_BLOCK_SIZE
+#define OUT_BLOCK_LENGTH    SHA1_DIGEST_SIZE
+#define HMAC_IN_DATA        0xffffffff
+
+#define HMAC_OK               0
+#define HMAC_BAD_MODE        -1
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct
+{   unsigned char   key[IN_BLOCK_LENGTH];
+    sha1_ctx        ctx[1];
+    unsigned int    klen;
+} hmac_ctx;
+
+void hmac_sha1_begin(hmac_ctx cx[1]);
+
+int  hmac_sha1_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]);
+
+void hmac_sha1_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]);
+
+void hmac_sha1_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]);
+
+void hmac_sha1(const unsigned char key[], unsigned int key_len,
+          const unsigned char data[], unsigned int data_len,
+          unsigned char mac[], unsigned int mac_len);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/orig/prng.c_orig b/aes_wg/orig/prng.c_orig
new file mode 100644 (file)
index 0000000..14fc09d
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file implements a random data pool based on the use of an external
+ entropy function.  It is based on the ideas advocated by Peter Gutmann in
+ his work on pseudo random sequence generators.  It is not a 'paranoid'
+ random sequence generator and no attempt is made to protect the pool
+ from prying eyes either by memory locking or by techniques to obscure
+ its location in memory.
+*/
+
+#include <memory.h>
+#include "prng.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* mix a random data pool using the SHA1 compression function (as   */
+/* suggested by Peter Gutmann in his paper on random pools)         */
+
+static void prng_mix(unsigned char buf[])
+{   unsigned int    i, len;
+    sha1_ctx        ctx[1];
+
+    /*lint -e{663}  unusual array to pointer conversion */
+    for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE)
+    {
+        /* copy digest size pool block into SHA1 hash block */
+        memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE)
+                            - SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE);
+
+        /* copy data from pool into the SHA1 data buffer    */
+        len = PRNG_POOL_SIZE - i;
+        memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len));
+
+        if(len < SHA1_BLOCK_SIZE)
+            memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len);
+
+        /* compress using the SHA1 compression function     */
+        sha1_compile(ctx);
+
+        /* put digest size block back into the random pool  */
+        memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE);
+    }
+}
+
+/* refresh the output buffer and update the random pool by adding   */
+/* entropy and remixing                                             */
+
+static void update_pool(prng_ctx ctx[1])
+{   unsigned int    i = 0;
+
+    /* transfer random pool data to the output buffer   */
+    memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE);
+
+    /* enter entropy data into the pool */
+    while(i < PRNG_POOL_SIZE)
+        i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i);
+
+    /* invert and xor the original pool data into the pool  */
+    for(i = 0; i < PRNG_POOL_SIZE; ++i)
+        ctx->rbuf[i] ^= ~ctx->obuf[i];
+
+    /* mix the pool and the output buffer   */
+    prng_mix(ctx->rbuf);
+    prng_mix(ctx->obuf);
+}
+
+void prng_init(prng_entropy_fn fun, prng_ctx ctx[1])
+{   int i;
+
+    /* clear the buffers and the counter in the context     */
+    memset(ctx, 0, sizeof(prng_ctx));
+
+    /* set the pointer to the entropy collection function   */
+    ctx->entropy = fun;
+
+    /* initialise the random data pool                      */
+    update_pool(ctx);
+
+    /* mix the pool a minimum number of times               */
+    for(i = 0; i < PRNG_MIN_MIX; ++i)
+        prng_mix(ctx->rbuf);
+
+    /* update the pool to prime the pool output buffer      */
+    update_pool(ctx);
+}
+
+/* provide random bytes from the random data pool   */
+
+void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1])
+{   unsigned char   *rp = data;
+    unsigned int    len, pos = ctx->pos;
+
+    while(data_len)
+    {
+        /* transfer 'data_len' bytes (or the number of bytes remaining  */
+        /* the pool output buffer if less) into the output              */
+        len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos);
+        memcpy(rp, ctx->obuf + pos, len);
+        rp += len;          /* update ouput buffer position pointer     */
+        pos += len;         /* update pool output buffer pointer        */
+        data_len -= len;    /* update the remaining data count          */
+
+        /* refresh the random pool if necessary */
+        if(pos == PRNG_POOL_SIZE)
+        {
+            update_pool(ctx); pos = 0;
+        }
+    }
+
+    ctx->pos = pos;
+}
+
+void prng_end(prng_ctx ctx[1])
+{
+    /* ensure the data in the context is destroyed  */
+    memset(ctx, 0, sizeof(prng_ctx));
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
diff --git a/aes_wg/orig/pwd2key.c_orig b/aes_wg/orig/pwd2key.c_orig
new file mode 100644 (file)
index 0000000..7763f6a
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of RFC2898, which specifies key derivation from
+ a password and a salt value.
+*/
+
+#include <memory.h>
+#include "hmac.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+void derive_key(const unsigned char pwd[],  /* the PASSWORD     */
+               unsigned int pwd_len,        /* and its length   */
+               const unsigned char salt[],  /* the SALT and its */
+               unsigned int salt_len,       /* length           */
+               unsigned int iter,   /* the number of iterations */
+               unsigned char key[], /* space for the output key */
+               unsigned int key_len)/* and its required length  */
+{
+    unsigned int    i, j, k, n_blk;
+    unsigned char uu[OUT_BLOCK_LENGTH], ux[OUT_BLOCK_LENGTH];
+    hmac_ctx c1[1], c2[1], c3[1];
+
+    /* set HMAC context (c1) for password               */
+    hmac_sha1_begin(c1);
+    hmac_sha1_key(pwd, pwd_len, c1);
+
+    /* set HMAC context (c2) for password and salt      */
+    memcpy(c2, c1, sizeof(hmac_ctx));
+    hmac_sha1_data(salt, salt_len, c2);
+
+    /* find the number of SHA blocks in the key         */
+    n_blk = 1 + (key_len - 1) / OUT_BLOCK_LENGTH;
+
+    for(i = 0; i < n_blk; ++i) /* for each block in key */
+    {
+        /* ux[] holds the running xor value             */
+        memset(ux, 0, OUT_BLOCK_LENGTH);
+
+        /* set HMAC context (c3) for password and salt  */
+        memcpy(c3, c2, sizeof(hmac_ctx));
+
+        /* enter additional data for 1st block into uu  */
+        uu[0] = (unsigned char)((i + 1) >> 24);
+        uu[1] = (unsigned char)((i + 1) >> 16);
+        uu[2] = (unsigned char)((i + 1) >> 8);
+        uu[3] = (unsigned char)(i + 1);
+
+        /* this is the key mixing iteration         */
+        for(j = 0, k = 4; j < iter; ++j)
+        {
+            /* add previous round data to HMAC      */
+            hmac_sha1_data(uu, k, c3);
+
+            /* obtain HMAC for uu[]                 */
+            hmac_sha1_end(uu, OUT_BLOCK_LENGTH, c3);
+
+            /* xor into the running xor block       */
+            for(k = 0; k < OUT_BLOCK_LENGTH; ++k)
+                ux[k] ^= uu[k];
+
+            /* set HMAC context (c3) for password   */
+            memcpy(c3, c1, sizeof(hmac_ctx));
+        }
+
+        /* compile key blocks into the key output   */
+        j = 0; k = i * OUT_BLOCK_LENGTH;
+        while(j < OUT_BLOCK_LENGTH && k < key_len)
+            key[k++] = ux[j++];
+    }
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+struct
+{   unsigned int    pwd_len;
+    unsigned int    salt_len;
+    unsigned int    it_count;
+    unsigned char   *pwd;
+    unsigned char   salt[32];
+    unsigned char   key[32];
+} tests[] =
+{
+    {   8, 4, 5, (unsigned char*)"password",
+        {   0x12, 0x34, 0x56, 0x78 },
+        {   0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
+            0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 } /* ... */
+    },
+    {   8, 8, 5, (unsigned char*)"password",
+        {   0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 },
+        {   0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
+            0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 } /* ... */
+    }
+};
+
+int main()
+{   unsigned int    i, j, key_len = 256;
+    unsigned char   key[256];
+
+    printf("\nTest of RFC2898 Password Based Key Derivation");
+    for(i = 0; i < 2; ++i)
+    {
+        derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
+                    tests[i].salt_len, tests[i].it_count, key, key_len);
+
+        printf("\ntest %i: ", i + 1);
+        printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good");
+        for(j = 0; j < key_len && j < 64; j += 4)
+        {
+            if(j % 16 == 0)
+                printf("\n");
+            printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]);
+        }
+        printf(j < key_len ? " ... \n" : "\n");
+    }
+    printf("\n");
+    return 0;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/orig/sha1.c_orig b/aes_wg/orig/sha1.c_orig
new file mode 100644 (file)
index 0000000..68aeeb9
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is a byte oriented version of SHA1 that operates on arrays of bytes
+ stored in memory.
+*/
+
+#include <string.h>     /* for memcpy() etc.        */
+#include <stdlib.h>     /* for _lrotl with VC++     */
+
+#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#include <byteswap.h>
+#include <endian.h>
+#endif
+
+#include "sha1.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the order in which bytes are packed into such words.
+    The following block of code is an attempt to capture the most obvious
+    ways in which various environemnts specify their endian definitions.
+    It may well fail, in which case the definitions will need to be set by
+    editing at the points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#define SHA_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define SHA_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 87 or 89 of sha1.c).
+#endif
+
+#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
+
+#if (PLATFORM_BYTE_ORDER == SHA_BIG_ENDIAN)
+#define swap_b32(x) (x)
+#elif defined(bswap_32)
+#define swap_b32(x) bswap_32(x)
+#else
+#define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00))
+#endif
+
+#define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
+
+/* reverse byte order in 32-bit words       */
+
+#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
+#define parity(x,y,z)   ((x) ^ (y) ^ (z))
+#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* A normal version as set out in the FIPS  */
+
+#define rnd(f,k)    \
+    t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \
+    e = d; d = c; c = rotl32(b, 30); b = t
+
+void sha1_compile(sha1_ctx ctx[1])
+{   sha1_32t    w[80], i, a, b, c, d, e, t;
+
+    /* note that words are compiled from the buffer into 32-bit */
+    /* words in big-endian order so an order reversal is needed */
+    /* here on little endian machines                           */
+    for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
+        w[i] = swap_b32(ctx->wbuf[i]);
+
+    for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i)
+        w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
+
+    a = ctx->hash[0];
+    b = ctx->hash[1];
+    c = ctx->hash[2];
+    d = ctx->hash[3];
+    e = ctx->hash[4];
+
+    for(i = 0; i < 20; ++i)
+    {
+        rnd(ch, 0x5a827999);
+    }
+
+    for(i = 20; i < 40; ++i)
+    {
+        rnd(parity, 0x6ed9eba1);
+    }
+
+    for(i = 40; i < 60; ++i)
+    {
+        rnd(maj, 0x8f1bbcdc);
+    }
+
+    for(i = 60; i < 80; ++i)
+    {
+        rnd(parity, 0xca62c1d6);
+    }
+
+    ctx->hash[0] += a;
+    ctx->hash[1] += b;
+    ctx->hash[2] += c;
+    ctx->hash[3] += d;
+    ctx->hash[4] += e;
+}
+
+void sha1_begin(sha1_ctx ctx[1])
+{
+    ctx->count[0] = ctx->count[1] = 0;
+    ctx->hash[0] = 0x67452301;
+    ctx->hash[1] = 0xefcdab89;
+    ctx->hash[2] = 0x98badcfe;
+    ctx->hash[3] = 0x10325476;
+    ctx->hash[4] = 0xc3d2e1f0;
+}
+
+/* SHA1 hash data in an array of bytes into hash buffer and */
+/* call the hash_compile function as required.              */
+
+void sha1_hash(const unsigned char data[], unsigned int len, sha1_ctx ctx[1])
+{   sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK),
+             space = SHA1_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks if possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
+        sha1_compile(ctx);
+    }
+
+    /*lint -e{803} conceivable data overrun */
+    /* there are two cases: the above while loop entered or not */
+    /* entered. If not entered, 'space = SHA1_BLOCK_SIZE - pos' */
+    /* and 'len < space' so that 'len + pos < SHA1_BLOCK_SIZE'. */
+    /* If entered, 'pos = 0', 'space = SHA1_BLOCK_SIZE' and     */
+    /* 'len < space' so that 'pos + len < SHA1_BLOCK_SIZE'. In  */
+    /* both cases, therefore, the memory copy is in the buffer  */
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA1 final padding and digest calculation  */
+
+#if (PLATFORM_BYTE_ORDER == SHA_LITTLE_ENDIAN)
+static sha1_32t  mask[4] =
+    {   0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
+static sha1_32t  bits[4] =
+    {   0x00000080, 0x00008000, 0x00800000, 0x80000000 };
+#else
+static sha1_32t  mask[4] =
+    {   0x00000000, 0xff000000, 0xffff0000, 0xffffff00 };
+static sha1_32t  bits[4] =
+    {   0x80000000, 0x00800000, 0x00008000, 0x00000080 };
+#endif
+
+void sha1_end(unsigned char hval[], sha1_ctx ctx[1])
+{   sha1_32t    i = (sha1_32t)(ctx->count[0] & SHA1_MASK);
+
+    /* mask out the rest of any partial 32-bit word and then set    */
+    /* the next byte to 0x80. On big-endian machines any bytes in   */
+    /* the buffer will be at the top end of 32 bit words, on little */
+    /* endian machines they will be at the bottom. Hence the AND    */
+    /* and OR masks above are reversed for little endian systems    */
+    /* Note that we can always add the first padding byte at this   */
+    /* point because the buffer always has at least one empty slot  */
+    ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & mask[i & 3]) | bits[i & 3];
+
+    /* we need 9 or more empty positions, one for the padding byte  */
+    /* (above) and eight for the length count.  If there is not     */
+    /* enough space pad and empty the buffer                        */
+    if(i > SHA1_BLOCK_SIZE - 9)
+    {
+        if(i < 60) ctx->wbuf[15] = 0;
+        sha1_compile(ctx);
+        i = 0;
+    }
+    else    /* compute a word index for the empty buffer positions  */
+        i = (i >> 2) + 1;
+
+    while(i < 14) /* and zero pad all but last two positions        */
+        ctx->wbuf[i++] = 0;
+
+    /* assemble the eight byte counter in in big-endian format      */
+    ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29));
+    ctx->wbuf[15] = swap_b32(ctx->count[0] << 3);
+
+    sha1_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* misaligned for 32-bit words                                  */
+    /*lint -e{504} unusual shift operation (unusually formed right argument) */
+    for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
+}
+
+void sha1(unsigned char hval[], const unsigned char data[], unsigned int len)
+{   sha1_ctx    cx[1];
+
+    sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/prng.c b/aes_wg/prng.c
new file mode 100644 (file)
index 0000000..8d18ffd
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file implements a random data pool based on the use of an external
+ entropy function.  It is based on the ideas advocated by Peter Gutmann in
+ his work on pseudo random sequence generators.  It is not a 'paranoid'
+ random sequence generator and no attempt is made to protect the pool
+ from prying eyes either by memory locking or by techniques to obscure
+ its location in memory.
+*/
+
+/********************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed <memory.h> to <string.h> for portability.
+ ********************************************************
+ */
+#include <string.h>
+#include "prng.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* mix a random data pool using the SHA1 compression function (as   */
+/* suggested by Peter Gutmann in his paper on random pools)         */
+
+static void prng_mix(unsigned char buf[])
+{   unsigned int    i, len;
+    sha1_ctx        ctx[1];
+
+    /*lint -e{663}  unusual array to pointer conversion */
+    for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE)
+    {
+        /* copy digest size pool block into SHA1 hash block */
+        memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE)
+                            - SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE);
+
+        /* copy data from pool into the SHA1 data buffer    */
+        len = PRNG_POOL_SIZE - i;
+        memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len));
+
+        if(len < SHA1_BLOCK_SIZE)
+            memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len);
+
+        /* compress using the SHA1 compression function     */
+        sha1_compile(ctx);
+
+        /* put digest size block back into the random pool  */
+        memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE);
+    }
+}
+
+/* refresh the output buffer and update the random pool by adding   */
+/* entropy and remixing                                             */
+
+static void update_pool(prng_ctx ctx[1])
+{   unsigned int    i = 0;
+
+    /* transfer random pool data to the output buffer   */
+    memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE);
+
+    /* enter entropy data into the pool */
+    while(i < PRNG_POOL_SIZE)
+        i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i);
+
+    /* invert and xor the original pool data into the pool  */
+    for(i = 0; i < PRNG_POOL_SIZE; ++i)
+        ctx->rbuf[i] ^= ~ctx->obuf[i];
+
+    /* mix the pool and the output buffer   */
+    prng_mix(ctx->rbuf);
+    prng_mix(ctx->obuf);
+}
+
+void prng_init(prng_entropy_fn fun, prng_ctx ctx[1])
+{   int i;
+
+    /* clear the buffers and the counter in the context     */
+    memset(ctx, 0, sizeof(prng_ctx));
+
+    /* set the pointer to the entropy collection function   */
+    ctx->entropy = fun;
+
+    /* initialise the random data pool                      */
+    update_pool(ctx);
+
+    /* mix the pool a minimum number of times               */
+    for(i = 0; i < PRNG_MIN_MIX; ++i)
+        prng_mix(ctx->rbuf);
+
+    /* update the pool to prime the pool output buffer      */
+    update_pool(ctx);
+}
+
+/* provide random bytes from the random data pool   */
+
+void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1])
+{   unsigned char   *rp = data;
+    unsigned int    len, pos = ctx->pos;
+
+    while(data_len)
+    {
+        /* transfer 'data_len' bytes (or the number of bytes remaining  */
+        /* the pool output buffer if less) into the output              */
+        len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos);
+        memcpy(rp, ctx->obuf + pos, len);
+        rp += len;          /* update ouput buffer position pointer     */
+        pos += len;         /* update pool output buffer pointer        */
+        data_len -= len;    /* update the remaining data count          */
+
+        /* refresh the random pool if necessary */
+        if(pos == PRNG_POOL_SIZE)
+        {
+            update_pool(ctx); pos = 0;
+        }
+    }
+
+    ctx->pos = pos;
+}
+
+void prng_end(prng_ctx ctx[1])
+{
+    /* ensure the data in the context is destroyed  */
+    memset(ctx, 0, sizeof(prng_ctx));
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
diff --git a/aes_wg/prng.h b/aes_wg/prng.h
new file mode 100644 (file)
index 0000000..9a77426
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is the header file for an implementation of a random data pool based on
+ the use of an external entropy function (inspired by Peter Gutmann's work).
+*/
+
+#ifndef _PRNG_H
+#define _PRNG_H
+
+#include "sha1.h"
+
+#define PRNG_POOL_LEN    256    /* minimum random pool size             */
+#define PRNG_MIN_MIX      20    /* min initial pool mixing iterations   */
+
+/* ensure that pool length is a multiple of the SHA1 digest size        */
+
+#define PRNG_POOL_SIZE  (SHA1_DIGEST_SIZE * (1 + (PRNG_POOL_LEN - 1) / SHA1_DIGEST_SIZE))
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* A function for providing entropy is a parameter in the prng_init()   */
+/* call.  This function has the following form and returns a maximum    */
+/* of 'len' bytes of pseudo random data in the buffer 'buf'.  It can    */
+/* return less than 'len' bytes but will be repeatedly called for more  */
+/* data in this case.                                                   */
+
+typedef int (*prng_entropy_fn)(unsigned char buf[], unsigned int len);
+
+typedef struct
+{   unsigned char   rbuf[PRNG_POOL_SIZE];   /* the random pool          */
+    unsigned char   obuf[PRNG_POOL_SIZE];   /* pool output buffer       */
+    unsigned int    pos;                    /* output buffer position   */
+    prng_entropy_fn entropy;                /* entropy function pointer */
+} prng_ctx;
+
+/* initialise the random stream generator   */
+void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]);
+
+/* obtain random bytes from the generator   */
+void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]);
+
+/* close the random stream generator        */
+void prng_end(prng_ctx ctx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/pwd2key.c b/aes_wg/pwd2key.c
new file mode 100644 (file)
index 0000000..e764b45
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of RFC2898, which specifies key derivation from
+ a password and a salt value.
+*/
+
+/*************************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed <memory.h> to <string.h> for portability.
+ * The appropriate #include directive in "hmac.h" obviates any here.
+ *************************************************************************
+ */
+#include "hmac.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+void derive_key(const unsigned char pwd[],  /* the PASSWORD     */
+               unsigned int pwd_len,        /* and its length   */
+               const unsigned char salt[],  /* the SALT and its */
+               unsigned int salt_len,       /* length           */
+               unsigned int iter,   /* the number of iterations */
+               unsigned char key[], /* space for the output key */
+               unsigned int key_len)/* and its required length  */
+{
+    unsigned int    i, j, k, n_blk;
+    unsigned char uu[OUT_BLOCK_LENGTH], ux[OUT_BLOCK_LENGTH];
+    hmac_ctx c1[1], c2[1], c3[1];
+
+    /* set HMAC context (c1) for password               */
+    hmac_sha1_begin(c1);
+    hmac_sha1_key(pwd, pwd_len, c1);
+
+    /* set HMAC context (c2) for password and salt      */
+    memcpy(c2, c1, sizeof(hmac_ctx));
+    hmac_sha1_data(salt, salt_len, c2);
+
+    /* find the number of SHA blocks in the key         */
+    n_blk = 1 + (key_len - 1) / OUT_BLOCK_LENGTH;
+
+    for(i = 0; i < n_blk; ++i) /* for each block in key */
+    {
+        /* ux[] holds the running xor value             */
+        memset(ux, 0, OUT_BLOCK_LENGTH);
+
+        /* set HMAC context (c3) for password and salt  */
+        memcpy(c3, c2, sizeof(hmac_ctx));
+
+        /* enter additional data for 1st block into uu  */
+        uu[0] = (unsigned char)((i + 1) >> 24);
+        uu[1] = (unsigned char)((i + 1) >> 16);
+        uu[2] = (unsigned char)((i + 1) >> 8);
+        uu[3] = (unsigned char)(i + 1);
+
+        /* this is the key mixing iteration         */
+        for(j = 0, k = 4; j < iter; ++j)
+        {
+            /* add previous round data to HMAC      */
+            hmac_sha1_data(uu, k, c3);
+
+            /* obtain HMAC for uu[]                 */
+            hmac_sha1_end(uu, OUT_BLOCK_LENGTH, c3);
+
+            /* xor into the running xor block       */
+            for(k = 0; k < OUT_BLOCK_LENGTH; ++k)
+                ux[k] ^= uu[k];
+
+            /* set HMAC context (c3) for password   */
+            memcpy(c3, c1, sizeof(hmac_ctx));
+        }
+
+        /* compile key blocks into the key output   */
+        j = 0; k = i * OUT_BLOCK_LENGTH;
+        while(j < OUT_BLOCK_LENGTH && k < key_len)
+            key[k++] = ux[j++];
+    }
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+struct
+{   unsigned int    pwd_len;
+    unsigned int    salt_len;
+    unsigned int    it_count;
+    unsigned char   *pwd;
+    unsigned char   salt[32];
+    unsigned char   key[32];
+} tests[] =
+{
+    {   8, 4, 5, (unsigned char*)"password",
+        {   0x12, 0x34, 0x56, 0x78 },
+        {   0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
+            0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 } /* ... */
+    },
+    {   8, 8, 5, (unsigned char*)"password",
+        {   0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 },
+        {   0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
+            0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 } /* ... */
+    }
+};
+
+int main()
+{   unsigned int    i, j, key_len = 256;
+    unsigned char   key[256];
+
+    printf("\nTest of RFC2898 Password Based Key Derivation");
+    for(i = 0; i < 2; ++i)
+    {
+        derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
+                    tests[i].salt_len, tests[i].it_count, key, key_len);
+
+        printf("\ntest %i: ", i + 1);
+        printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good");
+        for(j = 0; j < key_len && j < 64; j += 4)
+        {
+            if(j % 16 == 0)
+                printf("\n");
+            printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]);
+        }
+        printf(j < key_len ? " ... \n" : "\n");
+    }
+    printf("\n");
+    return 0;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/pwd2key.h b/aes_wg/pwd2key.h
new file mode 100644 (file)
index 0000000..d8bc401
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is an implementation of RFC2898, which specifies key derivation from
+ a password and a salt value.
+*/
+
+#ifndef PWD2KEY_H
+#define PWD2KEY_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+void derive_key(
+        const unsigned char pwd[],   /* the PASSWORD, and   */
+        unsigned int pwd_len,        /*    its length       */
+        const unsigned char salt[],  /* the SALT and its    */
+        unsigned int salt_len,       /*    length           */
+        unsigned int iter,      /* the number of iterations */
+        unsigned char key[],    /* space for the output key */
+        unsigned int key_len);  /* and its required length  */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/sha1.c b/aes_wg/sha1.c
new file mode 100644 (file)
index 0000000..d824128
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This is a byte oriented version of SHA1 that operates on arrays of bytes
+ stored in memory.
+*/
+
+#include <string.h>     /* for memcpy() etc.        */
+#include <stdlib.h>     /* for _lrotl with VC++     */
+
+/**************************************************************************
+ * 2011-06-16 SMS for Info-ZIP.
+ * Changed to use (a modified) "brg_endian.h" for endian determination
+ * instead of the code below.
+ **************************************************************************
+ */
+#include "brg_endian.h"
+
+#if 0
+
+#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#include <byteswap.h>
+#include <endian.h>
+#endif
+
+#endif /* 0 */
+
+#include "sha1.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the order in which bytes are packed into such words.
+    The following block of code is an attempt to capture the most obvious
+    ways in which various environemnts specify their endian definitions.
+    It may well fail, in which case the definitions will need to be set by
+    editing at the points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#define SHA_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define SHA_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 87 or 89 of sha1.c).
+#endif
+
+#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
+
+#if (PLATFORM_BYTE_ORDER == SHA_BIG_ENDIAN)
+#define swap_b32(x) (x)
+#elif defined(bswap_32)
+#define swap_b32(x) bswap_32(x)
+#else
+#define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00))
+#endif
+
+#define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
+
+/* reverse byte order in 32-bit words       */
+
+#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
+#define parity(x,y,z)   ((x) ^ (y) ^ (z))
+#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* A normal version as set out in the FIPS  */
+
+#define rnd(f,k)    \
+    t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \
+    e = d; d = c; c = rotl32(b, 30); b = t
+
+void sha1_compile(sha1_ctx ctx[1])
+{   sha1_32t    w[80], i, a, b, c, d, e, t;
+
+    /* note that words are compiled from the buffer into 32-bit */
+    /* words in big-endian order so an order reversal is needed */
+    /* here on little endian machines                           */
+    for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
+        w[i] = swap_b32(ctx->wbuf[i]);
+
+    for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i)
+        w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
+
+    a = ctx->hash[0];
+    b = ctx->hash[1];
+    c = ctx->hash[2];
+    d = ctx->hash[3];
+    e = ctx->hash[4];
+
+    for(i = 0; i < 20; ++i)
+    {
+        rnd(ch, 0x5a827999);
+    }
+
+    for(i = 20; i < 40; ++i)
+    {
+        rnd(parity, 0x6ed9eba1);
+    }
+
+    for(i = 40; i < 60; ++i)
+    {
+        rnd(maj, 0x8f1bbcdc);
+    }
+
+    for(i = 60; i < 80; ++i)
+    {
+        rnd(parity, 0xca62c1d6);
+    }
+
+    ctx->hash[0] += a;
+    ctx->hash[1] += b;
+    ctx->hash[2] += c;
+    ctx->hash[3] += d;
+    ctx->hash[4] += e;
+}
+
+void sha1_begin(sha1_ctx ctx[1])
+{
+    ctx->count[0] = ctx->count[1] = 0;
+    ctx->hash[0] = 0x67452301;
+    ctx->hash[1] = 0xefcdab89;
+    ctx->hash[2] = 0x98badcfe;
+    ctx->hash[3] = 0x10325476;
+    ctx->hash[4] = 0xc3d2e1f0;
+}
+
+/* SHA1 hash data in an array of bytes into hash buffer and */
+/* call the hash_compile function as required.              */
+
+void sha1_hash(const unsigned char data[], unsigned int len, sha1_ctx ctx[1])
+{   sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK),
+             space = SHA1_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks if possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
+        sha1_compile(ctx);
+    }
+
+    /*lint -e{803} conceivable data overrun */
+    /* there are two cases: the above while loop entered or not */
+    /* entered. If not entered, 'space = SHA1_BLOCK_SIZE - pos' */
+    /* and 'len < space' so that 'len + pos < SHA1_BLOCK_SIZE'. */
+    /* If entered, 'pos = 0', 'space = SHA1_BLOCK_SIZE' and     */
+    /* 'len < space' so that 'pos + len < SHA1_BLOCK_SIZE'. In  */
+    /* both cases, therefore, the memory copy is in the buffer  */
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA1 final padding and digest calculation  */
+
+#if (PLATFORM_BYTE_ORDER == SHA_LITTLE_ENDIAN)
+static sha1_32t  mask[4] =
+    {   0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
+static sha1_32t  bits[4] =
+    {   0x00000080, 0x00008000, 0x00800000, 0x80000000 };
+#else
+static sha1_32t  mask[4] =
+    {   0x00000000, 0xff000000, 0xffff0000, 0xffffff00 };
+static sha1_32t  bits[4] =
+    {   0x80000000, 0x00800000, 0x00008000, 0x00000080 };
+#endif
+
+void sha1_end(unsigned char hval[], sha1_ctx ctx[1])
+{   sha1_32t    i = (sha1_32t)(ctx->count[0] & SHA1_MASK);
+
+    /* mask out the rest of any partial 32-bit word and then set    */
+    /* the next byte to 0x80. On big-endian machines any bytes in   */
+    /* the buffer will be at the top end of 32 bit words, on little */
+    /* endian machines they will be at the bottom. Hence the AND    */
+    /* and OR masks above are reversed for little endian systems    */
+    /* Note that we can always add the first padding byte at this   */
+    /* point because the buffer always has at least one empty slot  */
+    ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & mask[i & 3]) | bits[i & 3];
+
+    /* we need 9 or more empty positions, one for the padding byte  */
+    /* (above) and eight for the length count.  If there is not     */
+    /* enough space pad and empty the buffer                        */
+    if(i > SHA1_BLOCK_SIZE - 9)
+    {
+        if(i < 60) ctx->wbuf[15] = 0;
+        sha1_compile(ctx);
+        i = 0;
+    }
+    else    /* compute a word index for the empty buffer positions  */
+        i = (i >> 2) + 1;
+
+    while(i < 14) /* and zero pad all but last two positions        */
+        ctx->wbuf[i++] = 0;
+
+    /* assemble the eight byte counter in in big-endian format      */
+    ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29));
+    ctx->wbuf[15] = swap_b32(ctx->count[0] << 3);
+
+    sha1_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* misaligned for 32-bit words                                  */
+    /*lint -e{504} unusual shift operation (unusually formed right argument) */
+    for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
+}
+
+void sha1(unsigned char hval[], const unsigned char data[], unsigned int len)
+{   sha1_ctx    cx[1];
+
+    sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
+}
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/aes_wg/sha1.h b/aes_wg/sha1.h
new file mode 100644 (file)
index 0000000..3061235
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 24/01/2003
+
+ This file contains the definitions needed for SHA1
+*/
+
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#include <limits.h>
+
+#define SHA1_BLOCK_SIZE  64
+#define SHA1_DIGEST_SIZE 20
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* define an unsigned 32-bit type */
+
+#if UINT_MAX == 0xffffffff
+  typedef   unsigned int     sha1_32t;
+#elif ULONG_MAX == 0xffffffff
+  typedef   unsigned long    sha1_32t;
+#else
+#error Please define sha1_32t as an unsigned 32 bit type in sha2.h
+#endif
+
+/* type to hold the SHA256 context  */
+
+typedef struct
+{   sha1_32t count[2];
+    sha1_32t hash[5];
+    sha1_32t wbuf[16];
+} sha1_ctx;
+
+void sha1_compile(sha1_ctx ctx[1]);
+
+void sha1_begin(sha1_ctx ctx[1]);
+void sha1_hash(const unsigned char data[], unsigned int len, sha1_ctx ctx[1]);
+void sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
+void sha1(unsigned char hval[], const unsigned char data[], unsigned int len);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/aes_wg/zip-comment.txt b/aes_wg/zip-comment.txt
new file mode 100644 (file)
index 0000000..576dd4b
--- /dev/null
@@ -0,0 +1,10 @@
+
+IZ_AES_WG -- Info-ZIP AES (WinZip/Gladman) encryption source kit,
+Version 1.6  2017-01-23.
+For use with Info-ZIP UnZip and Zip (and related utilities).
+
+See enclosed files LICENSE, README_AES_WG.txt, and USexport_AES_WG.msg
+for terms and conditions, and notification pursuant to Section 740.13(e)
+of the amended Export Administration Regulations of the Bureau of
+Industry and Security of the U.S. Department of Commerce.
index 5cecab8..f9fb273 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4cc2a25..94ccc66 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index d8da77e..00bff2d 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 11c7a53..69c0b93 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in unzip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index ab591b2..6920003 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 6075c21..e7006a1 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 53d6cd1..6c26c76 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 27944ec..b0e33f9 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/api.c b/api.c
index a38e868..3ad524d 100644 (file)
--- a/api.c
+++ b/api.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -429,7 +429,7 @@ char *UzpFeatures()
     strcat( featurelist, "no_zipinfo;");
 # endif
 
-    feats = malloc( strlen( featurelist) + 1);
+    feats = izu_malloc( strlen( featurelist) + 1);
     if (feats != NULL)
     {
         strcpy( feats, featurelist);
@@ -879,8 +879,10 @@ int UZ_EXP UzpGrep( OFT( char *)archive,
     UzpCB *UsrFuncts;
 #  endif /* def NO_PROTO */
 {
-    int retcode = FALSE, compare;
-    ulg i, j, patternLen, buflen;
+    int retcode = FALSE;
+    int compare;
+    ulg i, j, buflen;
+    size_t patternLen;
     char * sz, *p;
     UzpOpts flgopts;
     UzpBuffer retstr;
index f527c4e..825e093 100644 (file)
--- a/apihelp.c
+++ b/apihelp.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 17b9844..96e5aeb 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 29fca9c..d9a4850 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2004 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 909ebc4..6abc2f8 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2004 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 290c612..ef00a1a 100644 (file)
@@ -1,8 +1,8 @@
 // -*- C++ -*-
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 5eea4a9..5b4f5c1 100644 (file)
--- a/consts.h
+++ b/consts.h
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
@@ -24,20 +24,23 @@ ZCONST unsigned near mask_bits[17] = {
 };
 
 #ifndef SFX
-   ZCONST char Far EndSigMsg[] =
-   "\nnote:  didn't find end-of-central-dir signature at end of central dir.\n";
+ZCONST char Far DigSigMsg[] =
+ "\nnote: central-dir digital signature found (and ignored).  Bytes: %ld\n";
+ZCONST char Far EndSigMsg[] =
+ "\nnote:  didn't find end-of-central-dir signature at end of central dir.\n";
 #endif
 
+ZCONST char Far ActionMsg[] =
+  "%8sing: %-22s  %s%s";
 ZCONST char Far CentSigMsg[] =
   "error:  expected central file header signature not found (file #%lu).\n";
-ZCONST char Far SeekMsg[] =
-  "error [%s]:  attempt to seek before beginning of zipfile (%d)\n%s";
-ZCONST char Far FilenameNotMatched[] = "caution: filename not matched:  %s\n";
+ZCONST char Far ErrorUnexpectedEOF[] =
+ "error:  Unexpected end-of-file (loc=%d) reading %s.\n";
 ZCONST char Far ExclFilenameNotMatched[] =
   "caution: excluded filename not matched:  %s\n";
-
-ZCONST char Far ActionMsg[] =
-  "%8sing: %-22s  %s%s";
+ZCONST char Far FilenameNotMatched[] = "caution: filename not matched:  %s\n";
+ZCONST char Far SeekMsg[] =
+  "error [%s]:  attempt to seek before beginning of zipfile (%d)\n%s";
 
 #if (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE))
 ZCONST char Far ActionMsgw[] =
diff --git a/crc32.c b/crc32.c
index 02f504d..ac460b7 100644 (file)
--- a/crc32.c
+++ b/crc32.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2005-Feb-10 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/crc32.h b/crc32.h
index 83af240..e68a673 100644 (file)
--- a/crc32.h
+++ b/crc32.h
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/crypt.c b/crypt.c
index 05dc8a8..43734df 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-2 or later
   (the contents of which are also included in zip.h) for terms of use.
@@ -626,7 +626,7 @@ int zipcloak(z, passwd)
         res = fcrypt_init(
          (encryption_method- (AES_MIN_ENCRYPTION- 1)),  /* AES mode. */
          (unsigned char*) passwd,                       /* Password. */
-         strlen( passwd),                               /* Password length. */
+         (unsigned int) strlen( passwd),                /* Password length. */
          zsalt,                                         /* Salt. */
          zpwd_verifier,                                 /* Password vfy buf. */
          &zctx);                                        /* AES context. */
@@ -824,7 +824,7 @@ int zipbare(z, passwd)
         /* Initialize the AES decryption machine for the password check. */
         fcrypt_init( aes_mode,                  /* AES mode. */
                      (unsigned char*) passwd,   /* Password. */
-                     strlen( passwd),           /* Password length. */
+                     (unsigned int) strlen( passwd),    /* Password length. */
                      h,                         /* Salt. */
                      hh,                        /* PASSWORD_VERIFIER. */
                      &zctx);                    /* AES context. */
@@ -1252,7 +1252,7 @@ local int testkey(__G__ hd_len, h, key)
     {
         fcrypt_init( GLOBAL( pInfo->cmpr_mode_aes),     /* AES mode. */
                      (unsigned char*) key,      /* Password. */
-                     strlen( key),              /* Password length. */
+                     (unsigned int) strlen( key),       /* Password length. */
                      h,                         /* Salt. */
                      hh,                        /* PASSWORD_VERIFIER. */
                      GLOBAL( zcx));             /* AES context. */
index 9282803..278dc28 100644 (file)
@@ -6,3 +6,5 @@ unzip.txt       UnZip manual page, formatted output
 unzipsfx.txt    UnZipSFX manual page, formatted output
 zipgrep.txt     ZipGrep manual page, formatted output
 zipinfo.txt     ZipInfo manual page, formatted output
+UNZIP.HTX       UnZip VMS Help output (Unix-style command-line)
+UNZIP_CLI.HTX   UnZip VMS Help output (VMS-style command-line)
diff --git a/docs/UNZIP.HTX b/docs/UNZIP.HTX
new file mode 100644 (file)
index 0000000..ba88afc
--- /dev/null
@@ -0,0 +1,2425 @@
+
+UNZIP
+
+
+    UnZip lists, tests, or extracts files from a ZIP archive (an archive
+    format  commonly  used  on  many  different  systems).   The default
+    behavior (with no options) is to extract into the current  directory
+    (and  subdirectories  below  it)  all  files  from the specified ZIP
+    archive.  A companion program, Zip, creates ZIP archives.
+
+    Info-ZIP UnZip and Zip were intended to be compatible with  archives
+    created  by  PKWARE's  PKZIP  and  PKUNZIP  programs (originally for
+    MS-DOS), but in many cases the program options or default  behaviors
+    differ.  Nowadays, many other programs are available which work with
+    ZIP archives.
+
+    This help file describes  the  Unix-style  command-line  edition  of
+    UnZip.   A  VMS  CLI edition is also available, with a separate help
+    file.
+
+    Format
+
+      unzip [ unzip_options ] [ file[.zip] ] [ member ... ]
+      unzip -Z [ zipinfo_options ] [ file[.zip] ] [ member ... ]
+
+    Note:  Beginning with UnZip version 6.1, the old command-line parser
+    has  been replaced by one like the one used in Zip.  One significant
+    change is that option negation now uses a TRAILING hyphen ("-"), so,
+    for  example,  -B-  negates  the  -B  option.   This change was made
+    because a double hyphen ("--") now introduces a long option.
+
+    To display the basic built-in help, use the command:
+      unzip -h
+
+    To display the extended built-in help, use the command:
+      unzip -hh
+
+    The  built-in  help  may  be  more  current  than  this  help  file,
+    especially between full product releases.
+
+    To list all available options for a particular  UnZip  program,  use
+    the command:
+      unzip --show-options
+
+    This report will not include any options which are available only on
+    other  system  types, or options which must be enabled at build-time
+    but were not enabled in the particular UnZip program being used.
+
+
+UNZIP
+
+  Command_Parameters
+
+
+    file[.zip]
+
+      File path/name of a ZIP archive.  A wildcard name  may  be  used  to
+      specify  multiple  ZIP  archives to be processed in one command.  On
+      VMS systems, any of the  standard  wildcards  for  a  directory/file
+      specification  may be used:  "...", "*", or "%" (or, since VMS V7.2,
+      "?").  The default archive file specification is ".ZIP".
+
+      Note that a ".zip" or ".ZIP" file type on an  archive  is  merely  a
+      convention,  not  a requirement.  For example, a self-extracting ZIP
+      archive named "fred" or "fred.exe" could be processed as if it  were
+      an  ordinary  archive;  just  specify  the actual file name with its
+      actual name ending (if any), whatever that may be.
+
+    member ...
+
+      An optional list of archive members to be  processed,  separated  by
+      spaces.   If  no  member list is specified, then all archive members
+      are processed.  Unix-like ("globbing") wildcard patterns may be used
+      to match multiple members:
+
+          *      Matches a sequence of 0 or more characters.
+          ?      Matches exactly 1 character.
+          [...]  Matches any single character found inside the brackets.
+                 Ranges are specified by a beginning character, a hyphen, and
+                 an ending character.  If an exclamation point ("!") or a
+                 caret ("^") follows the left bracket, then the range of
+                 characters within the brackets is complemented.  That is,
+                 anything except the characters inside the brackets is
+                 considered a match.  To specify a literal left bracket, use
+                 the three-character sequence "[[]".
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+      Options in this group specify  the  primary  mode  of  operation  of
+      UnZip.  Only one of these primary mode options may be specified.
+
+      Note that uppercase options (like -T) must be  specified  in  quotes
+      (unless SET PROCESS/PARSE_STYLE=EXTENDED is set).  For example:
+
+        unzip "-VX" -a zipfile
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -c
+
+      -c
+      --to-stdout
+
+        Primary Mode.  Extract  files  to  stdout/screen.   This  option  is
+        similar  to  the  -p  option  except  that  the name of each file is
+        displayed as it is extracted, and the -a option  is  allowed,  which
+        can provide automatic ASCII-EBCDIC conversion, where appropriate.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -f
+
+      -f
+      --freshen
+
+        Primary Mode.  Freshen existing files.  That is, extract only  those
+        files  that  already  exist on disk and that are newer than the disk
+        copies.  By default UnZip queries before  overwriting,  but  the  -o
+        option may be used to suppress the queries.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -h
+
+      -h
+      --help
+
+        Primary Mode.  Display brief (roughly 24 lines) usage  instructions.
+        See also -hh.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -hh
+
+      -hh
+      --long-help
+
+        Primary  Mode.   Display  extended   help   (more   complete   usage
+        instructions).  See also -h.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -l
+
+      -l
+      --list
+
+        Primary Mode.  List archive members.  By default, a brief format  is
+        used, which includes the following items:  member name, uncompressed
+        file size ("Length"), and modification date-time of the  member.   A
+        summary is included at the end of the report, showing total size and
+        count for all the members in the report.  Specifying a  member  list
+        limits the report to those members.
+
+        Adding -v (--verbose)  to  an  "unzip  -l"  command  line  adds  the
+        following  items to the report:  compression method, compressed size
+        ("Size"), compression ratio, and 32-bit CRC.
+
+        In contrast to some other  programs,  UnZip  does  not  include  the
+        12-byte  encryption  header  in  the  compressed  size  values for a
+        Traditionally encrypted  member.   Therefore,  compressed  size  and
+        compression ratio figures are independent of the member's encryption
+        status and show the correct compression performance.  (The  complete
+        size  of the encrypted compressed data stream for archive members is
+        reported by the more verbose ZipInfo reports.  See ZipInfo.
+
+        If UnZip was built with OS2_EAS enabled, then  the  -l  report  also
+        includes the sizes of stored OS/2 extended attributes (EAs) and OS/2
+        access control lists (ACLs).  In addition, the archive  comment  and
+        individual member comments (if any) are displayed.
+
+        If a file was archived from a single-case file system (for  example,
+        the  old  MS-DOS  FAT  file system) and the -L option was given, the
+        filename is converted to lowercase and  is  shown  prefixed  with  a
+        caret (^).
+
+        Note:  If only -v (--verbose) is specified  with  an  archive  name,
+        then UnZip acts as if "-l -v" were specified, and a detailed listing
+        is generated.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    --license
+
+
+        Primary Mode.  Display the Info-ZIP license.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -p
+
+      -p
+      --pipe-to-stdout
+
+        Primary Mode.  Extract files to stdout (pipe).  Only the actual file
+        data  for  the  members  are sent to stdout (no file names, or other
+        information, as would be displayed with -c, and the files are always
+        extracted   in   binary   format,   just  as  they  are  stored  (no
+        conversions).
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -T
+
+      -T
+      --timestamp-new
+
+        Primary Mode.  Set the timestamp on the archive(s) to  that  of  the
+        newest  file  in  each  one.   This corresponds to Zip's -go option,
+        except that it can be used on wildcard archives (for example, "unzip
+        -T *.zip"), and is much faster.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -t
+
+      -t
+      --test
+
+        Primary Mode.   Test  archive  members.   Testing  means  that  each
+        archive  member is extracted in memory (expanding and decrypting, as
+        needed), but not written to  a  file.   The  resulting  CRC  (cyclic
+        redundancy  check,  an  enhanced  checksum) of the extracted data is
+        then compared with the original file's  stored  CRC  value,  and  an
+        error message is emitted if a CRC mismatch is detected.
+
+        Adding -v to -t adds some diagnostic information to the  report  for
+        archive members with LZMA or PPMd compression.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -u
+
+      -u
+      --update
+
+        Primary mode.  Update existing files and create new ones if  needed.
+        This  mode  performs  the  same  function  as the Freshen (-f) mode,
+        extracting (with query) files that are newer  than  those  with  the
+        same  name  on  disk,  but  it also extracts those files that do not
+        already exist on disk.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -v
+
+      -v
+      --verbose
+
+        Primary mode (when alone) or option.  When used as  a  primary  mode
+        (alone),  and  no  archive  is  specified,  an  "unzip  -v"  command
+        generates a report showing the program version, build  options,  and
+        relevant envrironment variables.
+
+        When used with some other primary mode option, -v  can  make  output
+        more verbose (detailed).
+
+        If no other primary mode is specified, and an archive is  specified,
+        then UnZip acts as if "-l -v" were specified, and a detailed listing
+        is generated.  See -l.
+
+
+UNZIP
+
+  Options_Primary_Mode
+
+    -z
+
+      -z
+      --zipfile-comment
+
+        Primary mode.  Display only the archive comment.
+
+
+UNZIP
+
+  Options_Ordinary
+
+      Options in this group modify the operation of UnZip.
+
+      Note that uppercase options (like -V) must be  specified  in  quotes
+      (unless SET PROC/PARSE=EXTEND is set).  For example:
+
+          unzip "-VX" -a zipfile
+
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -2
+
+      -2
+      --force-ods2
+
+        [VMS] Convert extracted file names to ODS2-compatible names, even on
+        an  ODS5 file system.  By default, if the destination file system is
+        ODS5, case is preserved,  and  extended  file  name  characters  are
+        caret-escaped  as  needed,  while  if the destination file system is
+        ODS2, invalid characters are replaced by underscores.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -A
+
+      -A
+      --api-help
+
+        [OS/2, Unix DLL] Print  extended  help  for  the  DLL's  application
+        programming interface (API).
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -a
+
+      -a
+      --ascii
+
+        Convert text files.  Ordinarily, all files are extracted exactly  as
+        they  are  stored,  byte-for-byte.   With -a, line endings in a text
+        file are adjusted to the local standard as the  file  is  extracted.
+        When appropriate, ASCII<-->EBCDIC conversion is also done.
+
+        Zip (or a similar archiving program) identifies files as "binary" or
+        "text"  when  they  are  archived.   (A  short-format ZipInfo report
+        denotes a binary file with a "b", and a text file with a "t".) Zip's
+        identification  of  text  files  may not be perfect, so UnZip prints
+        "[binary]" or "[text]" as a visual check for each file  it  extracts
+        with  -a.   The  -aa  option  forces  all files to be extracted (and
+        converted) as text, regardless of the supposed file type.
+
+        [VMS] On VMS, for archives with VMS attribute information (made with
+        "zip  -V"),  files  are  always  created  with their original record
+        formats.  For archives without VMS attribute information  (not  made
+        with "zip -V"), all files are normally created with Stream_LF record
+        format.   With  -a,   text   files   are   normally   created   with
+        variable-length  record  format,  but adding -S gives them Stream_LF
+        record format.  With -aa, all files are treated as text files.   See
+        also -b and -S.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -B
+
+      -B
+      --backup
+
+        [when built with UNIXBACKUP enabled] Save  a  backup  copy  of  each
+        overwritten  file.  The backup file gets the name of the target file
+        with a tilde and optionally  a  unique  sequence  number  (up  to  5
+        digits)  appended.  The sequence number is appended whenever another
+        file with the original name plus tilde already  exists.   When  used
+        together  with the "overwrite all" option, -o, numbered backup files
+        are never created.  In this case, all backup files are named as  the
+        original  file with an appended tilde, and existing backup files are
+        deleted without notice.  This feature works similarly to the default
+        behavior of emacs(1) in many locations.
+
+        Example:  the old copy of "foo" is renamed to "foo~".
+
+        Warning:  Users should be aware that the -B option does not  prevent
+        loss  of  existing  data under all circumstances.  For example, when
+        UnZip is run in overwrite-all  mode,  an  existing  "foo~"  file  is
+        deleted  before UnZip attempts to rename "foo" to "foo~".  When this
+        rename  attempt  fails  (because  of  a  file   lock,   insufficient
+        privileges,  or  any  other  reason),  the extraction of "foo~" gets
+        cancelled, but the old backup  file  is  already  lost.   A  similar
+        scenario  takes  place  when  the sequence number range for numbered
+        backup files gets exhausted (99999, or 65535  for  16-bit  systems).
+        In  this  case,  the backup file with the maximum sequence number is
+        deleted and replaced by the new backup version without notice.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -b
+
+      -b
+      --binary
+
+        [Tandem, VMS] Selects the file record format  used  when  extracting
+        binary files.  -b may conflict or interact with -a in different ways
+        on different system types.  -b is  ignored  on  systems  other  than
+        Tandem and VMS.
+
+        Zip (or a similar archiving program) identifies files as "binary" or
+        "text"  when  they  are  archived.   (A  short-format ZipInfo report
+        denotes a binary file with a "b", and a text file with a "t".)
+
+        [Tandem] Force the creation files with filecode type 180 ('C')  when
+        extracting  archive  members  marked  as  "text".  (On Tandem, -a is
+        enabled by default, see above).
+
+        [VMS] On VMS, for archives with VMS attribute information (made with
+        "zip  -V"),  files  are  always  created  with their original record
+        formats.  For archives without VMS attribute information  (not  made
+        with  "zip  -V"),  files  are normally created with Stream_LF record
+        format.  With  -b,  binary  files  are  created  with  fixed-length,
+        512-byte  record  format.   With  -bb,  all  files  are created with
+        fixed-length, 512-byte record format.  When extracting  to  standard
+        output  (-c  or -p option in effect), the default conversion of text
+        record delimiters is disabled for binary files (with -b), or for all
+        files (with -bb).
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -C
+
+      -c
+      --ignore-case    ([CMS, MVS] --CMS-MVS-lower)
+
+        Use case-insensitive name matching for names in the member list  and
+        the  -x  excluded-member  list  on  the  command  line.  By default,
+        case-sensitive matching is done.  For example, specifying "makefile"
+        on  the  command line will match only "makefile" in the archive, not
+        "Makefile" or "MAKEFILE".  On many systems, the local file system is
+        case-insensitive,  so  case-insensitive  name matching would be more
+        natural.  With -C, "makefile" would match "makefile", "Makefile", or
+        "MAKEFILE".
+
+        -C does not affect the search for the ZIP archive file(s),  nor  the
+        matching  of  archive  members  to  existing files on the extraction
+        path.  So, on a case-sensitive file system, UnZip will never try  to
+        overwrite a file "FOO" when extracting a member named "foo"!
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -c
+
+      -c
+      --to-stdout
+
+        Primary Mode.  Extract files to  stdout/screen.   For  details,  see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -D
+
+      -D
+      --dir-timestamps
+
+        Control timestamps on extracted files and directories.  By  default,
+        UnZip   restores   timestamps  for  extracted  files,  but  not  for
+        directories it creates.  Specifying -D tells UnZip  not  to  restore
+        any  timestamps.   Specifying  -D- tells UnZip to restore timestamps
+        for directories as well as other items.  -D- works only  on  systems
+        that  support  setting timestamps for directories (currently ATheOS,
+        BeOS, MacOS, OS/2, Unix, VMS, Win32).  On other systems, -D- has  no
+        effect.
+
+        [Non-VMS]  Timestamp  restoration  behavior  changed  between  UnZip
+        versions  6.00  and  6.1.   The following table shows the effects of
+        various -D options for both versions.
+
+               UnZip version      |
+              6.00    |    6.1    | Restore timestamps on:
+           -----------+-----------+------------------------
+               -DD    |    -D     | Nothing.
+               -D     | (default) | Files, not directories.
+            (default) |    -D-    | Files and directories.
+
+        [VMS] The old behavior on VMS was the same as the  new  behavior  on
+        all  systems.   (The  old  negated --D option is now -D-, because of
+        changes to the command-line parser.)
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -d
+
+      -d dest_dir
+      --extract-dir dest_dir
+
+        Specifies a destination directory for extracted files.  By  default,
+        files  are  extracted  (and  subdirectories  created) in the current
+        directory.   With  "-d  dest_dir",  extraction  is  done  into   the
+        specified directory, instead.  See also -da.
+
+        The option and directory may be concatenated without any white space
+        between  them,  but  this  may  cause  normal  shell  behavior to be
+        suppressed.  For example, "-d ~" (tilde) is expanded by Unix  shells
+        into  the name of the user's home directory, but "-d~" is treated as
+        a literal "~" subdirectory of the current directory.
+
+        [VMS] On VMS, only a VMS-style device:[directory]  specification  is
+        permitted.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -d
+
+      -da[=reuse]
+      --auto-extract-dir[=reuse]
+
+        Specifies a destination  directory  for  extracted  files  which  is
+        derived  from  the  base name of the archive.  By default, files are
+        extracted  (and  subdirectories  created)  in  the  current  default
+        directory.   With  -da,  UnZip  automatically derives a subdirectory
+        name from the archive name, creates that subdirectory, and  extracts
+        files into that subdirectory.
+
+        For example,  with  -da,  extraction  of  "fred.zip"  is  done  into
+        subdirectory  "[.fred]"  instead of into the current directory.  (On
+        non-VMS, systems, subdirectory "fred".)
+
+        For greater safety, by default, UnZip will refuse to extract into an
+        automatic extraction directory which already exists.  Specifying the
+        optional keyword "reuse" will allow  an  existing  directory  to  be
+        used.
+
+        If -da is specified as a default option in an environment  variable,
+        it  can be overridden by either a negated -da- option or an explicit
+        "-d dest_dir" option.  See also -d.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -f
+
+      -f
+      --freshen
+
+        Primary  Mode.   Freshen   existing   files.    For   details,   see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -h
+
+      -h
+      --help
+
+        Primary Mode.  Display brief (roughly 24 lines) usage  instructions.
+        For details, see Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -hh
+
+      -hh
+      --long-help
+
+        Primary Mode.  Display complete usage  instructions.   For  details,
+        see Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -i
+
+      -i
+      --no-mac-ef-names
+
+        [MacOS (pre-OS-X)] Ignore filenames stored in  MacOS  extra  fields.
+        Instead,  the most compatible filename stored in the generic part of
+        the member's header is used.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -J
+
+      -J
+      --junk-attrs
+
+        [BeOS] Junk file attributes.  The file's BeOS  file  attributes  are
+        not restored, only the file's data.
+
+        [MacOS] Ignore MacOS extra fields.  All Macintosh-specific  info  is
+        skipped.  AppleDouble files are restored as separate files.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -j
+
+      -j[=depth]
+      --junk-dirs[=depth]
+
+        Junk  directories  on  extracted  files.   With  -j,  all  directory
+        information  is  stripped  from an archive member name, so all files
+        are extracted into the destination directory.  (See also -d.)
+
+        If a depth ("=depth",  where  "depth"  is  a  positive  integer)  is
+        specified,  then  that  number  of directory levels will be stripped
+        from an archive member name.  For example, an  archive  member  like
+        "a/b/c/d/ee.txt"  would normally be extracted as "[.a.b.c.d]ee.txt".
+        With -j, it would be extracted as "ee.txt".  With  -j=2,  the  first
+        two  directory levels would be stripped, so it would be extracted as
+        "[.c.d]ee.txt".
+
+
+UNZIP
+
+  Options_Ordinary
+
+    --jar
+
+
+        Treat archive(s) as  Java  JAR.   Over-simplification  in  Java  JAR
+        archives  can cause UnZip to transform UTF-8 file names according to
+        inappropriate (MS-DOS) rules, yielding corrupt  names  on  extracted
+        files   (typically   those  with  ASCII  codes  128-255).   Archives
+        containing  a  Java  "CAFE"   extra   field   should   be   detected
+        automatically,  and  handled  correctly,  but  not  all JAR archives
+        include that extra field.  Specifying --jar tells  UnZip  to  expect
+        UTF-8  file  names,  regardless  of  whether  the archive contains a
+        "CAFE" extra field.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -K
+
+      -K
+      --keep-s-attrs
+
+        [AtheOS, BeOS, Unix] Retain  SUID/SGID/Tacky  permission  bits.   By
+        default, these permission bits are cleared, for security reasons.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -k
+
+      --keep-permissions
+
+        [AtheOS, BeOS,  Unix,  VMS]  Control  how  archived  permissions  or
+        protections are restored on extracted files and directories.
+
+        By default, archived permissions are restored with some limitations.
+        On  AtheOS,  BeOS,  and Unix, the current umask value is applied (to
+        the normal  user/group/other  permissions).   On  VMS,  the  current
+        default protection is applied to the UIC-based (SOGW) protections.
+
+        With -k, the archived permissions are restored without regard to the
+        Unix  umask  or  VMS  default  protection.   (This  was  the default
+        behavior in UnZip versions before 6.1.)
+
+        With -k-, the archived permissions are ignored,  so  only  the  Unix
+        umask  or VMS default protection is effective.  (On VMS, directories
+        are always created without any Delete access.)
+
+        On AtheOS, BeOS, and Unix, the SUID/SGID/Tacky permission  bits  are
+        controlled  by  the  -K/--keep-s-attrs  option,  regardless  of  the
+        -k/--keep-permissions setting.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -ka
+
+      --keep-acl [VMS] Restore ACLs on extracted files and directories.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -L
+
+      -L
+      --lowercase-names
+
+        Convert to lowercase any filename originating on  an  uppercase-only
+        operating system or file system.  (This was UnZip's default behavior
+        in versions before 5.11.  The current default behavior is  the  same
+        as  the old behavior with the -U option.  -U is now used for another
+        purpose.)
+
+        Depending on the archiver,  files  archived  from  single-case  file
+        systems  (old  MS-DOS  FAT,  VMS  ODS2,  and so on) may be stored as
+        all-uppercase  names;  this  can  be  ugly  or   inconvenient   when
+        extracting  to  a case-preserving file system such as OS/2 HPFS or a
+        case-sensitive one such as on Unix.   By  default  UnZip  lists  and
+        extracts   such  filenames  exactly  as  they're  stored  (excepting
+        truncation, conversion of unsupported characters, an so  on).   With
+        -L, the names of all files from certain systems will be converted to
+        lowercase.  With -LL, all file names will be down-cased,  regardless
+        of the originating file system.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -l
+
+      -l
+      --list
+
+        Primary   Mode.    List   archive   members.    For   details,   see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -M
+
+      -M ([CMS,MVS] Or:  " -m )
+      --more
+
+        Pipe all output through  an  internal  pager  similar  to  the  Unix
+        more(1)  command.  At the end of a screenful of output, UnZip pauses
+        with a "--More--" prompt;  the  next  screenful  may  be  viewed  by
+        pressing  the  Enter  (Return)  key  or the space bar.  UnZip can be
+        terminated by pressing  the  "q"  key  and,  on  some  systems,  the
+        Enter/Return    key.     Unlike    Unix   more(1),   there   is   no
+        forward-searching or editing capability.  Also, UnZip doesn't notice
+        if  long lines wrap at the edge of the screen, effectively resulting
+        in the printing of two or more lines and the  likelihood  that  some
+        text  will scroll off the top of the screen before being viewed.  If
+        the actual number of lines on the screen can not be  determined,  24
+        lines will be assumed.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -mc
+
+      -mc
+      --member-counts
+
+        Control inclusion of separate member counts for directories,  files,
+        and  links,  after  the totals summary at the end of the report.  By
+        default, they are included.  Use  "-mc-"  or  "--member-counts-"  to
+        suppress them.  See also -t.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -N
+
+      -N
+      --comment-to-note
+
+        [Amiga] Extract member comments as Amiga filenotes.  Member comments
+        are  created with the -c option of Zip, or with the -N option of the
+        Amiga port of Zip, which stores filenotes as comments.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -n
+
+      -n
+      --never-overwrite
+
+        When extracting, never overwrite existing files.  If a file  already
+        exists,  skip  the extraction of that file without asking.  See also
+        -o (--overwrite).
+
+        By default, UnZip queries the user before extracting any  file  that
+        already  exists.   The user may choose to overwrite only the current
+        file, overwrite all files, skip extraction of the current file, skip
+        extraction of all existing files, or rename the current file (choose
+        a new name for the extracted file).
+
+        [VMS] On VMS, the usual query choices are to create a new version of
+        an existing file, to skip extraction, or to rename the current file.
+        In the case where an archive member name includes a version  number,
+        and  -V  ("retain  VMS  file version numbers") is in effect, then an
+        additional query choice is offered:  to overwrite the existing file.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -O
+
+      -O
+      --oem-char-set char_set
+
+        [Unix] Select OEM character set char_set.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -o
+
+      -o
+      --overwrite
+
+        Always overwrite  existing  files  without  prompting.   This  is  a
+        dangerous  option,  so use it with care.  (It is often used with -f,
+        however, and is the only way to overwrite directory EAs on OS/2.)
+
+        By default, UnZip queries the user before extracting any  file  that
+        already exists.
+
+        [Non-VMS] On non-VMS systems, the user may choose to overwrite  only
+        the  current  file,  overwrite  all  files,  skip  extraction of the
+        current file, skip extraction of all existing files, or  rename  the
+        current file (choose a new name for the extracted file).
+
+        [VMS] On VMS, the usual query choices are to create a new version of
+        an existing file, to skip extraction, or to rename the current file.
+        In the case where an archive member name includes a version  number,
+        and  -V  ("retain  VMS  file version numbers") is in effect, then an
+        additional query choice is offered:  to overwrite the existing file.
+        In  this  case, -o selects the "new version" choice, and -oo (or "-o
+        -o") selects the "overwrite" choice.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -P
+
+      -P password
+      --password password
+
+        Use "password" to decrypt encrypted archive members (if any).   THIS
+        IS INSECURE!  Many multi-user operating systems provide ways for any
+        user to see the current command line of any  other  user.   Even  on
+        stand-alone systems, there is always the threat of over-the-shoulder
+        peeking.  Storing the plaintext password as part of a  command  line
+        in  an  automated script can be even less secure, Whenever possible,
+        use the non-echoing, interactive prompt to enter  passwords.   Where
+        security is truly important, use a strong encryption method, such as
+        AES,  instead  of  the  relatively  weak  encryption   provided   by
+        Traditional ZIP encryption.  Or, use an external encryption program,
+        such as GnuPG, before archiving  the  file.   (Note  that  Zip  will
+        probably  not  be able to do significant compression on a file which
+        has already been encrypted.)
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -p
+
+      -p
+      --pipe-to-stdout
+
+        Primary Mode.  Extract files to stdout  (pipe).   For  details,  see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -q
+
+      -q
+      --quiet
+
+        Perform operations quietly.  (-qq:  even more quietly).  By default,
+        UnZip  prints the names of the files it's extracting or testing, the
+        extraction methods, any member  or  archive  comments  that  may  be
+        stored  in  the  archive,  and possibly a summary when finished with
+        each archive.  The -q[q] options suppress the printing  of  some  or
+        all of these messages.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -r
+
+      -r
+      --remove-exts
+
+        [Tandem] Remove file extensions.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -S
+
+      -S
+      --streamlf
+
+        [VMS] Use Stream_LF record format  when  converting  extracted  text
+        files  (-a,  -aa), instead of the text-file default, variable-length
+        record format.
+
+        [VMS] On VMS, for archives with VMS attribute information (made with
+        "zip  -V"),  files  are  always  created  with their original record
+        formats.  For archives without VMS attribute information  (not  made
+        with "zip -V"), all files are normally created with Stream_LF record
+        format.   With  -a,   text   files   are   normally   created   with
+        variable-length  record  format,  but adding -S gives them Stream_LF
+        record format.  With -aa, all files are treated as text files.   See
+        also -a and -b.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -s
+
+      -s
+      --space-to-uscore
+
+        [OS/2, NT, MS-DOS]  Convert  spaces  in  filenames  to  underscores.
+        Because all these operating systems allow spaces in filenames, UnZip
+        normally extracts filenames with spaces  intact  (for  example,  "EA
+        DATA.   SF").  Working with such file names can be awkward, however,
+        so -s can be used to replace spaces with underscores.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -sc
+
+      -sc
+      --show-command
+
+        Show processed command line (options, arguments), and then exit.
+
+        Strictly speaking this is a primary-mode option, but  it's  intended
+        for use in program development, not in normal use.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -si
+
+      -si
+      --show-pid
+
+        [Non-VMS]  Show  the  UnZip  program's  process  ID   (pid)   before
+        performing  any  other work.  This value can then be used in a "kill
+        -USR1 pid" command to trigger a user-triggered progress report.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -so
+
+      -so
+      --show-options
+
+        Display all valid program options, then exit.
+
+        Strictly speaking this is a primary-mode option, but  it's  intended
+        for use in program development, not in normal use.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -T
+
+      -T
+      --timestamp-new
+
+        Primary Mode.  Set the timestamp on the archive(s) to  that  of  the
+        newest file in each one.  For details, see Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -t
+
+      -t
+      --test
+
+        Primary   Mode.    Test   archive   members.    For   details,   see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -U
+
+      -U
+      --unicode
+
+        [UNICODE_SUPPORT] Control UTF-8 handling.  When  UNICODE_SUPPORT  is
+        available,  -U  forces UnZip to escape all non-ASCII characters from
+        UTF-8  coded  filenames  as  "#Uxxxx'  (for  UCS-2  characters,   or
+        "#Lxxxxxx" for Unicode codepoints needing 3 octets).  This option is
+        mainly provided for debugging purpose  when  the  fairly  new  UTF-8
+        support is suspected to mangle up extracted filenames.
+
+        -UU disables  the  recognition  of  UTF-8  encoded  filenames.   The
+        handling of filename codings within UnZip falls back to the behavior
+        of previous versions.
+
+        [old, obsolete  usage]  Leave  filenames  uppercase  if  created  on
+        MS-DOS, VMS, and so on.  See -L.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -u
+
+      -u
+      --update
+
+        Primary mode.  Update existing files and create new ones if  needed.
+        For details, see Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -V
+
+      -V
+      --keep-versions
+
+        [Non-CMS-MVS] Retain VMS file version numbers.   VMS  files  can  be
+        stored  with  a  version number, in the format "file.type;##", where
+        "##" is a decimal number.  By default the ";##" version numbers  are
+        stripped,  but  this  option  allows  them to be retained.  (On file
+        systems that limit filenames  to  particularly  short  lengths,  the
+        version  numbers  may  be  truncated  or stripped regardless of this
+        option.)
+
+        [Non-VMS] Note that before UnZip version 6.1, on a non-VMS system, a
+        file  with a name like "fred;123" would, by default, be extracted as
+        "fred", even if the file did not originate on a VMS system (so  that
+        ";123"  was  probably  not  really a VMS version number).  Beginning
+        with UnZip version 6.1, the default behavior is to strip VMS version
+        numbers  only  from  files  which were archived on a VMS system.  To
+        restore the old behavior, and  always  strip  apparent  VMS  version
+        numbers, explicitly negate the option:  "-V-".
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -v
+
+      -v
+      --verbose
+
+        When used with some primary mode option, -v  can  make  output  more
+        verbose.  See also Primary Mode options, and -l in particular.
+
+        Note:  If only -v (--verbose) is specified  with  an  archive  name,
+        then UnZip acts as if "-l -v" were specified, and a detailed listing
+        is generated.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -W
+
+      -W
+      --wild-no-span
+
+        [WILD_STOP_AT_DIR] (Valid when the program  was  built  with  the  C
+        macro WILD_STOP_AT_DIR defined.) By default, the wildcard characters
+        "?" (single-character wildcard) and "*"  (multi-character  wildcard)
+        match  any  character  in  a  member  path/name.   "-W" modifies the
+        pattern-matching behavior for  archive  members  so  that  both  "?"
+        (single-character  wildcard)  and  "*" (multi-character wildcard) do
+        not match the directory separator character "/".  (The two-character
+        sequence  "**"  acts as a multi-character wildcard that includes the
+        directory separator in its matched characters.)  For  example,  with
+        "-W":
+
+            "*.c"   matches "foo.c" but not "mydir/foo.c"
+            "**.c"  matches both "foo.c" and "mydir/foo.c"
+            "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c"
+            "??*/*" matches "ab/foo" and "abc/foo"
+                    but not "a/foo" or "a/b/foo"
+
+        This modified behavior is equivalent to the pattern  matching  style
+        used  by  the  shells  of  some of UnZip's supported target OSs (one
+        example is Acorn RISC OS).  This option  may  not  be  available  on
+        systems   where  the  Zip  archive's  internal  directory  separator
+        character "/" is allowed as regular character  in  native  operating
+        system filenames.
+
+        [non-VMS] Currently, UnZip uses the same pattern matching rules  for
+        both  wildcard  archive  file name specifications and archive member
+        selection patterns on most system types.  For systems  allowing  "/"
+        as  regular  filename  character,  the  -W  option would not work as
+        expected on a wildcard file name specification.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -X
+
+      -X
+      --restore-info
+
+        [VMS, Unix, OS/2, NT, Tandem] Restore  owner/protection  info  (UICs
+        and ACL entries on VMS, or user and group info (UID/GID) on Unix, or
+        access control lists (ACLs) on certain network-enabled  versions  of
+        OS/2  (Warp  Server  with  IBM LAN Server/Requester 3.0 to 5.0; Warp
+        Connect with IBM Peer 1.0), or security ACLs on Windows NT.) In most
+        cases  this will require special system privileges, and doubling the
+        option (-XX) on NT instructs UnZip to use privileges for extraction;
+        but  on  Unix, for example, a user who belongs to several groups can
+        restore files owned by any of those groups, so long as the user  IDs
+        match the user's own.  Note that ordinary file attributes are always
+        restored.  This option applies only  to  optional,  extra  ownership
+        info  available  on  some  operating  systems.  (NT's access control
+        lists do not appear to be especially compatible with OS/2's,  so  no
+        attempt  is made at cross-platform portability of access privileges.
+        It is not clear under which conditions this  would  ever  be  useful
+        anyway.)
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -x
+
+      -x member ...
+      --exclude member ...
+
+        An optional list of archive members to be excluded from  processing.
+        Because  wildcard characters normally match "/" directory separators
+        (for exceptions see the option -W),  this  option  may  be  used  to
+        exclude  any  files that are in subdirectories.  For example, "unzip
+        foo *.[ch] -x */*" would extract all C source files  (*.c,  *.h)  in
+        the  main directory, but none in any subdirectories.  Without the -x
+        option, all C source files in all  directories  within  the  archive
+        would be extracted.
+
+        When the program sees -x (--exclude) on a  command  line,  it  stops
+        scanning for options, and treats every succeeding item as an archive
+        member name.  To avoid confusion between member  names  and  command
+        options, it's simplest to specify -x (--exclude) and its member list
+        as the last items on a command  line.   Alternatively,  the  special
+        name  "@"  can  be  used to terminate the member list (and cause the
+        program to resume scanning for options).  That is, the following two
+        commands are equivalent:
+
+              unzip fred.zip -b -x file1 file2 file3
+              unzip fred.zip -x file1 file2 file3 @ -b
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -Y
+
+      -Y
+      --dot-version
+
+        [VMS] Treat archive member name endings of ".nnn" (where "nnn" is  a
+        decimal  number) as if they were VMS version numbers (";nnn").  (The
+        default is to treat them as file types.) For example:
+
+             "a.b.3" -> "a.b;3"
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -Z
+
+      -Z
+      --zipinfo-mode
+
+        ZipInfo mode.  If the first option on the command line is  -Z,  then
+        the  program  runs  in  ZipInfo  mode,  which  is  used  to  display
+        information about an archive and its members.  Remaining options are
+        interpreted as ZipInfo options.  See ZipInfo_mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -z
+
+      -z
+      --zipfile-comment
+
+        Primary mode.  Display only the archive comment.  For  details,  see
+        Options_Primary_Mode.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -$
+
+      -$
+      --volume-labels
+
+        [MS-DOS, OS/2, NT] Restore the volume label if the extraction medium
+        is  removable  (for example, a diskette).  Doubling the option (-$$)
+        allows fixed media (hard disks) to be labeled as well.  By  default,
+        volume labels are ignored.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -/
+
+      -/
+      --extensions
+
+        [Acorn] Overrides the  extension  list  supplied  by  the  Unzip$Ext
+        environment  variable.   During extraction, filename extensions that
+        match one of the items in this extension list are swapped  in  front
+        of the base name of the extracted file.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -:
+
+      -:
+      --do-double-dots
+
+        [all but Acorn, VM/CMS, MVS, Tandem] Allows UnZip to extract archive
+        members into locations outside of the current extraction destination
+        directory (and its subdirectories).
+
+        For security reasons, UnZip normally removes "parent directory" path
+        components  ("../")  from  the path names of archive members as they
+        are extracted.  This safety feature (new for version 5.50)  prevents
+        UnZip  from  accidentally  writing  files to directories outside the
+        current destination directory tree.  The -:  option sets UnZip  back
+        to its previous, more liberal behavior, allowing exact extraction of
+        archives that use "../" path components to create multiple directory
+        trees at or above the level of the destination directory.
+
+        This option does not enable writing explicitly to the root directory
+        ("/").   To  achieve  this,  it  is  necessary to set the extraction
+        target folder to "/" (by using an option  like  "-d  /").   However,
+        when the -:  option is specified, it is still possible implicitly to
+        write to the root directory if member paths specifying enough  "../"
+        path components.
+
+        Use this option with extreme caution.
+
+
+UNZIP
+
+  Options_Ordinary
+
+    -^
+
+      -^
+      --control-in-name
+
+        [Unix] Allow control characters  in  file  names  of  extracted  ZIP
+        archive  members.   On  Unix,  a  file  name may contain any (8-bit)
+        character code  with  the  two  exceptions  of  "/"  (the  directory
+        delimiter)  and  NUL  (0x00,  the  C  string-termination character),
+        unless the specific file system has  more  restrictive  conventions.
+        Generally,  this allows embedding ASCII control characters or escape
+        sequences in file names.  However, this feature allows  the  use  of
+        malicious  file  names  which can cause various kinds of bad trouble
+        when displayed on a user's terminal/emulator.   (Even  a  file  name
+        with   unprintable  but  otherwise  harmless  characters  can  cause
+        problems for users.)
+
+        For these reasons, by default, UnZip applies a filter  that  removes
+        potentially  dangerous  control  characters  from the extracted file
+        names.  The -^ option overrides this filter in the  rare  case  that
+        embedded   filename   dangerous   control   characters   are  to  be
+        intentionally restored.
+
+
+UNZIP
+
+  Environment_Options
+
+      UnZip's default behavior may be  modified  by  placing  command-line
+      options  in  an  environment  variable.   This  can be done with any
+      option, but it is probably most useful options like -a (auto-convert
+      text files), -L (downcase file names from systems with all uppercase
+      file names), -C (use case-insensitive name matching), -q (quiet), -o
+      (always overwrite), or -n (never overwrite).
+
+      For UnZip, the  environment  variable  name  on  VMS  is  UNZIP_OPTS
+      (non-VMS:   UNZIP).   The name on VMS is different to avoid conflict
+      with a foreign-command DCL symbol, UNZIP.   For  compatibility  with
+      Zip,  if UNZIP_OPTS is not defined, then UnZip will use UNZIPOPT the
+      same way.
+
+      For ZipInfo ("unzip -Z"), the environment variable name  on  VMS  is
+      ZIPINFO_OPTS  (non-VMS:   ZIPINFO).   For compatibility with Zip, if
+      ZIPINFO_OPTS is not defined, then ZipInfo will  use  ZIPINFOOPT  the
+      same way.
+
+      For example,  to  make  UnZip  act  as  quietly  as  possible,  only
+      reporting errors, one could use commands like the following:
+
+      Unix Bourne (or similar) shell:
+        UNZIP='-q -q'; export UNZIP
+
+      Unix C shell:
+        setenv UNZIP '-q -q'
+
+      OS/2 or MS-DOS:
+        set UNZIP="-q -q"
+
+      VMS (with quotation to preserve lower case in DCL):
+        define UNZIP_OPTS "-q -q"       ! Logical name, or
+        UNZIP_OPTS = "-q -q"            ! DCL symbol.  (Either works.)
+
+      Environment options are treated the same as any  other  command-line
+      options,  except  that they are effectively the first options on the
+      command line.  To override an environment option,  one  may  use  an
+      explicit  option to cancel or override it.  For example, to override
+      one of the "quiet" flags in the example above, use a command like:
+
+        unzip -q- [other options] archive.zip
+
+      The leading hyphen is the normal option character, and the  trailing
+      one negates the option, canceling one level of quietness.  To cancel
+      multiple "quiet" flags, use multiple -q- options:
+
+        unzip -t -q- -q- archive
+        unzip -q- -q- -t archive
+
+      Note that multiple one-character options like "-q" and "-q"  can  be
+      combined  into  a  single  "-qq", but it's generally clearer to keep
+      each  instance  of  each  option   separate.    Similarly,   negated
+      one-character  options  can  be  combined, as with "-q-q-", but "-q-
+      -q-" is generally clearer.
+
+      The examples show short (one-character)  options,  but  long  ("--")
+      options are also allowed.
+
+
+UNZIP
+
+  Encryption_Decryption
+
+      Zip and UnZip have  long  supported  a  relatively  weak  encryption
+      method,  which  we call Traditional ZIP encryption.  The source code
+      for Traditional encryption is  included  in  the  source  kits,  and
+      support   for   Traditional   encryption   is  enabled  by  default.
+      (Build-time C macro:  CRYPT_TRAD.)
+
+      Beginning with UnZip version 6.1 and Zip version 3.1, these programs
+      also offer a stronger, Advanced Encryption Standard (AES) encryption
+      method, which we call AES WinZip/Gladman (AES_WG) encryption.   (The
+      encryption  code  was  supplied  by  Brian  Gladman, and the archive
+      format is intended to be compatible with that  used  by  the  WinZip
+      program.   WinZip  is a registered trademark of WinZip International
+      LLC.) The source code for AES_WG  encryption  is  distributed  in  a
+      separate  kit  (for  export control reasons), and support for AES_WG
+      encryption must be enabled explicitly at build time.  (Build-time  C
+      macro:   CRYPT_AES_WG.)  See  the INSTALL file in the source kit for
+      details on how to  enable  AES_WG  encryption  (or  how  to  disable
+      Traditional encryption).
+
+      For details on the WinZip AES scheme, see:
+          http://www.winzip.com/aes_info.htm
+
+      For information on the separate AES_WG source kit, see:
+          ftp://ftp.info-zip.org/pub/infozip/crypt/
+          ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
+
+      Normally,  encryption   passwords   are   supplied   by   the   user
+      interactively  when requested by the program.  See the -P option for
+      a (less secure) method of specifying a password on the command line.
+
+      With Traditional encryption, when decrypting,  a  password  will  be
+      checked  against  header data, and used if it appears to be correct.
+      The correct password will always check out against the header  data,
+      but  there  is  a 1-in-256 chance that an incorrect password will as
+      well.  (This is a security feature of the PKWARE archive format;  it
+      helps  prevent brute-force attacks that might otherwise gain a large
+      speed advantage by testing only the header.) In  the  case  that  an
+      incorrect  password  is  given but it passes the header test anyway,
+      either an incorrect CRC will be generated for the extracted data  or
+      else  UnZip  will fail during the extraction because the "decrypted"
+      bytes do not constitute a valid compressed data stream.
+
+      If the first password fails the header check  on  some  file,  UnZip
+      will  prompt  for  another  password,  and so on until all files are
+      extracted.  If a password is not known,  entering  a  null  password
+      (that is, just a carriage return or "Enter") is taken as a signal to
+      skip  all  further  prompting.   Only  unencrypted  files   in   the
+      archive(s) will thereafter be extracted.  (The situation is actually
+      a little more complicated.  Some old versions of  Zip  and  ZipCloak
+      allowed  null  passwords, so UnZip checks each encrypted file to see
+      if the null password works.  This may result  in  "false  positives"
+      and extraction errors, as noted above.)
+
+      Archives encrypted  with  8-bit-character  passwords  (for  example,
+      passwords  with  accented  European  characters) may not be portable
+      across systems or to other archivers.  This problem stems  from  the
+      use  of  multiple  encoding  methods  for such characters, including
+      Latin-1 (ISO 8859-1) and OEM code page 850.  DOS  PKZIP  2.04g  uses
+      the OEM code page; Windows PKZIP 2.50 uses Latin-1 (and is therefore
+      incompatible with DOS PKZIP; Info-ZIP uses the OEM code page on DOS,
+      OS/2 and Win3.x ports but ISO coding (Latin-1 etc.) everywhere else;
+      and Nico Mak's WinZip 6.x does not allow  8-bit-character  passwords
+      at  all.  UnZip 5.3 (or newer) attempts to use the default character
+      set first (e.g., Latin-1), followed by the alternate one (e.g.,  OEM
+      code  page)  to test passwords.  On EBCDIC systems, if both of these
+      fail, EBCDIC encoding will be tested as a last resort.   (EBCDIC  is
+      not  tested  on  non-EBCDIC  systems,  because  there  are  no known
+      archivers  that  encrypt  using  EBCDIC  encoding.)  ISO   character
+      encodings other than Latin-1 are not supported.  The new addition of
+      (partial) Unicode (UTF-8) support in UnZip  6.0  has  not  yet  been
+      adapted  to  the  encryption password handling in UnZip.  On systems
+      that use UTF-8 as native  character  encoding,  UnZip  simply  tries
+      decryption  with  the  native  UTF-8  encoded password; the built-in
+      attempts to check the password in translated encoding have  not  yet
+      been adapted for UTF-8 support and will consequently fail.
+
+
+UNZIP
+
+  Examples
+
+      To use UnZip to extract all members of the archive letters.zip  into
+      the  current  directory  and  subdirectories  below it, creating any
+      subdirectories as necessary:
+
+        unzip letters
+
+      To extract all members of letters.zip  into  the  current  directory
+      only:
+
+        unzip -j letters
+
+      To test letters.zip, printing  only  a  summary  message  indicating
+      whether the archive is OK or not:
+
+        unzip -t -q letters
+
+      To test all ".zip" archives in the current directory, printing  only
+      the summaries:
+
+        unzip -t -q *.zip
+
+      (On a Unix system, the wildcard archive name would typically need to
+      be  quoted  to  keep  a a Unix shell from expanding ("globbing") it.
+      This is not necessary on VMS.)
+
+      The following command extracts to standard  output  all  members  of
+      letters.zip  whose names end in ".tex", auto-converting to the local
+      end-of-line convention, in Stream_LF record format, and  piping  the
+      output into TYPE /PAGE:
+
+        pipe unzip -c -a -S letters *.tex | type /page sys$input
+
+      To extract from source.zip all Fortran and C source files (*.f, *.c,
+      *.h) and Makefile into the SYS$SCRATCH directory:
+
+        unzip source.zip *.[fch] Makefile -d sys$scratch
+
+      To extract all FORTRAN and C source files, regardless of  case  (for
+      example,  both  *.c and *.C, and any makefile, Makefile, MAKEFILE or
+      similar):
+
+        unzip -C source.zip *.[fch] makefile -d sys$scratch
+
+      The following command extracts only  newer  versions  of  the  files
+      already  in  the  current  directory,  without querying.  (Note:  Be
+      careful of extracting in one timezone an archive created in another.
+      ZIP  archives created by Zip versions before 2.1 contain no timezone
+      information, and a "newer" file from an  eastern  timezone  may,  in
+      fact, be older):
+
+        unzip -f -o sources
+
+      To extract newer versions  of  the  files  already  in  the  current
+      directory  and to create any files not already there (same caveat as
+      previous example):
+
+        unzip -u -o sources
+
+      To display a configuration report showing the program  version,  the
+      OS  and  compiler  used  to  build  it,  a list of optional features
+      enabled  at  build  time,  and  the  values  of  all  the   relevant
+      environment variables:
+
+        unzip -v
+
+      In the last five examples, assume that UNZIP_OPTS is set to -q.   To
+      do a (singly) quiet listing:
+
+        unzip -l file.zip
+
+      To do a doubly quiet listing:
+
+        unzip -l -q file.zip
+
+      (Note that the ".zip" is generally not necessary.) To do a  standard
+      listing:
+
+        unzip -l -q- file.zip
+
+      or:
+
+        unzip -lq- file.zip
+
+      or:
+
+        unzip -q-l file.zip
+
+
+
+UNZIP
+
+  Exit_Status
+
+      UnZip's exit status approximates the exit codes defined  by  PKWARE.
+      On VMS, UnZip's UNIX-style exit values are translated into VMS-style
+      status  codes  with  facility  code  1954  =  %x7A2,  and  with  the
+      inhibit-message (%x10000000) and facility-specific (%x00008000) bits
+      set:
+
+         %x17A28001                        normal exit
+         %x17A28000 + 16*UnZip_error_code  warnings
+         %x17A28002 + 16*UnZip_error_code  normal errors
+         %x17A28004 + 16*UnZip_error_code  fatal errors
+
+      Note that multiplying the UNIX-style UnZip error code by  16  places
+      it  conveniently  in  the hexadecimal representation of the VMS exit
+      code, "__" in %x17A28__s, where  "s"  is  the  severity  code.   For
+      example,  a  missing  archive  might cause UnZip error code 9, which
+      would be transformed into the VMS exit status %X17A28092.
+
+      The UnZip VMS exit codes include severity values  which  approximate
+      those defined by PKWARE, as shown in the following table:
+
+          VMS        UnZip
+        severity   err code   Error description
+       ----------+----------+----------------------------------------------
+        Success       0       Normal.  No errors or warnings detected.
+        Warning       1       One or more warnings were encountered, but
+                              processing completed successfully.  This
+                              includes archives where one or more (but not
+                              all) files were skipped because of an
+                              unsupported compression or encryption method,
+                              or a bad encryption password.
+        Error         2       Error in the archive format.  Processing may
+                              or may not have completed  successfully.
+        Fatal         3       Severe error in the archive format.
+                              Processing probably failed immediately.
+        Fatal         4       Memory allocation failed in program
+                              initialization.
+        Fatal         5       Memory  allocation or terminal I/O failed in
+                              password processing.
+        Fatal         6       Memory allocation failed while decompressing
+                              to disk.
+        Fatal         7       Memory allocation failed while decompressing
+                              in memory.
+        Fatal         8       Memory allocation failed.  (Currently not
+                              used.)
+        Error         9       Specified archive files were not found.
+        Error        10       Invalid command-line options or parameters.
+        Error        11       No matching files were found.
+        Fatal        50       Disk (file system) filled during extraction.
+        Fatal        51       Unexpected end-of-file while reading the
+                              archive.
+        Error        80       User interrupt (Ctrl/C).
+        Error        81       No files were processed, because of
+                              unsupported compression or encryption
+                              methods.
+        Error        82       No files were processed, because of bad
+                              encryption password(s).
+        Fatal        83       Large-file archive could not be processed by
+                              this small-file program.
+
+
+UNZIP
+
+  Bugs
+
+      Multi-part archives are not yet  supported,  except  in  conjunction
+      with  Zip.   (All  parts must be concatenated together in order, and
+      then "zip -F" (for Zip 2.x) or "zip  -FF"  (for  Zip  3.x)  must  be
+      performed  on  the concatenated archive in order to "fix" it.  Also,
+      zip 3.0 and later can combine multi-part  (split)  archives  into  a
+      combined   single-file   archive   using   "zip   -s-  inarchive  -O
+      outarchive".  See the zip manual page for  more  information.)  This
+      may be corrected in the next major release.
+
+      Archives read from standard input are not yet supported, except with
+      UnZip  (and  then  only  the  first  member  of  the  archive can be
+      extracted).
+
+      Archives encrypted with 8-bit-character passwords (such as passwords
+      with  accented  European  characters)  may  not  be  portable across
+      systems and/or other archivers.  See also Encryption_Decryption.
+
+      UnZip's -M ("--more") option tries to take  into  account  automatic
+      wrapping  of  long  lines.  However, the code may fail to detect the
+      correct wrapping locations.   First,  TAB  characters  (and  similar
+      control  sequences)  are not taken into account, they are handled as
+      ordinary printable characters.   Second,  depending  on  the  actual
+      system  type,  UnZip  may  not  detect  the  true  terminal/emulator
+      geometry,  but  instead  may  rely  on   "commonly   used"   default
+      dimensions.    The  correct  handling  of  tabs  would  require  the
+      implementation of a query for the actual tab  setup  on  the  output
+      terminal/emulator.
+
+      [Unix] Unix special files such as FIFO buffers (named pipes),  block
+      devices  and  character  devices  are  not restored even if they are
+      somehow represented  in  the  archive,  nor  are  hard-linked  files
+      relinked.   Basically,  the  only  file  types restored by UnZip are
+      regular files, directories, and symbolic (soft) links.
+
+      [OS/2] Extended attributes for existing directories are only updated
+      if  the -o ("--overwrite") option is given.  This is a limitation of
+      the operating system; because directories only have a creation  time
+      associated  with  them,  UnZip  has  no way to determine whether the
+      stored attributes are  newer  or  older  than  those  on  disk.   In
+      practice  this  may  mean  a  two-pass  approach is required:  first
+      unpack the archive normally  (with  or  without  freshening/updating
+      existing  files),  then  overwrite  just  the directory entries (for
+      example, "unzip -o foo */").
+
+      Note that uppercase options (-C, -D, -L, -M, -P, -S, -T, -V, -X, -Y,
+      and -Z) must be specified in quotes (unless SET PROC/PARSE=EXTEND is
+      set).  For example:
+
+        unzip "-VX" -a zipfile
+
+      When extracting to SYS$OUTPUT (-c or -p  options)  redirected  to  a
+      file,  you  may want to override the default text file conversion by
+      specifying the -b option.  A single "-b" option switches to  "binary
+      piping"  mode  for  Zip  entries marked as non-text, only.  To force
+      "binary piping" mode even for Zip file entries marked as  text,  the
+      "-bb" option should be used.  (Please note that a later "-a" cancels
+      any -b option, see below.)
+
+      The output conversion options -b and -a may be combined  to  perform
+      binary  conversions  on  binary  files  and  text conversion on text
+      files.  But note:  For compatibility with  implementation  on  other
+      systems,  -b  cancels  any -a option; to get the intended result, -a
+      must be specified AFTER -b.  And, in combination, "text" recognition
+      takes  precedence; this means that -bba (-bb -a) has the same effect
+      as -ba (-b -a), and -aa overrides binary conversion for ALL files.
+
+      The conversion option -S is only effective when used  together  with
+      -a  or  -aa.   When specified, "text" files are written in Stream_LF
+      record format instead of the VMS default of  Variable-Length  record
+      format.   (When  no  conversion  options  are specified, all non-VMS
+      entries are always written as Stream_LF files.)
+
+      Please note that using the "-P<password>" option is higly  insecure,
+      the  plaintext password may be seen by others.  For this reason (and
+      because  of  lack  of  space),  the  "-P<password>"  option  is  not
+      advertised on UnZip's online help screen.
+
+
+UNZIP
+
+  URL
+
+      The Info-ZIP main Web page is:
+          http://www.info-zip.org/
+
+      FTP access is available, too:
+          ftp://ftp.info-zip.org/pub/infozip/
+
+
+UNZIP
+
+  ZipInfo_mode
+
+      If the first option on the UnZip command  line  is  "-Z",  then  the
+      program  runs in ZipInfo mode.  Remaining options are interpreted as
+      ZipInfo options.
+
+      ZipInfo reports detailed information about a  ZIP  archive  and  its
+      members.   This  information  may  include  file access permissions,
+      compression method, encryption method, version and operating  system
+      (or  file  system)  of the archive-creating program, and so on.  The
+      default behavior (with no options) is to show  a  single-line  entry
+      for  each  member  in  the  archive,  with  a  header  and a trailer
+      providing summary information for the entire archive.  The format is
+      a   cross  between  Unix  "ls  -l"  and  "unzip  -lv"  output.   See
+      Detailed_Description.  ZipInfo is the same program  as  UnZip.   (On
+      Unix,  "zipinfo"  may  be  a  link to "unzip".  On VMS, "zipinfo" is
+      normally a DCL symbol defined as "''unzip'  -Z".)  However,  ZipInfo
+      support may have been disabled when UnZip was built.
+
+      Format
+
+          zipinfo [ zipinfo_options ] [ file[.zip] ] [ member ...  ]
+          unzip -Z [ zipinfo_options ] [ file[.zip] ] [ member ...  ]
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Command_Parameters
+
+
+      file[.zip]
+
+        File path/name of a ZIP archive.  A wildcard name  may  be  used  to
+        specify  multiple  ZIP  archives to be processed in one command.  On
+        VMS systems, any of the  standard  wildcards  for  a  directory/file
+        specification  may be used:  "...", "*", or "%" (or, since VMS V7.2,
+        "?").  The default archive file specification is "[]*.ZIP".
+
+        Note that a ".zip" or ".ZIP" file type on an  archive  is  merely  a
+        convention,  not  a requirement.  For example, a self-extracting ZIP
+        archive named "fred" or "fred.exe" could be processed as if it  were
+        an  ordinary  archive;  just  specify  the actual file name with its
+        actual name ending (if any), whatever that may be.
+
+      member ...
+
+        An optional list of archive members to be  processed,  separated  by
+        spaces.   Unix-like  ("globbing")  wildcard  patterns may be used to
+        match multiple members:
+
+            *      Matches a sequence of 0 or more characters.
+            ?      Matches exactly 1 character.
+            [...]  Matches any single character found inside the brackets.
+                   Ranges are specified by a beginning character, a hyphen, and
+                   an ending character.  If an exclamation point ("!") or a
+                   caret ("^") follows the left bracket, then the range of
+                   characters within the brackets is complemented.  That is,
+                   anything except the characters inside the brackets is
+                   considered a match.  To specify a literal left bracket, use
+                   the three-character sequence "[[]".
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+        Options in this group (-1, -2, -l, -m, -s, -v) specify  the  primary
+        report  format of ZipInfo.  Only one of these primary format options
+        may be specified.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -1
+
+        -1
+        --names-only
+
+          Primary Format.  Show member names only, one per line.  This  option
+          excludes  all  others,  and  the  report  does  not include headers,
+          trailers, or archive comments.  This format may be useful with  Unix
+          shell (or other) scripts.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -2
+
+        -2
+        --names-mostly
+
+          Primary Format.  Show member names  only,  one  per  line  (as  with
+          "-1"),  but  allow headers (-h), trailers (-t), and archive comments
+          (-z), if requested explicitly.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -l
+
+        -l
+        --long-list
+
+          Primary Format.  Show member info in long Unix "ls -l" format.  Like
+          the -m format, except that the compressed size (in bytes) is printed
+          instead of the compression ratio.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -m
+
+        -m
+        --medium-list
+
+          Primary Format.  Show member info  in  medium-length  Unix  "ls  -l"
+          format.   Like  the  -s  format, except that the compression factor,
+          expressed as a percentage, is also included.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -s
+
+        -s
+        --short-list
+
+          Primary Format.  Show member info in  short  Unix  "ls  -l"  format.
+          This is the default behavior, unless -h or -t is specified.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Primary_Format
+
+      -v
+
+        -v
+        --verbose
+
+          Primary Format.  The verbose report is  very  detailed,  and  mostly
+          self-explanatory,  but  it does assume some familiarity with the ZIP
+          archive format.  It also  includes  the  archive  comment,  if  any.
+          Extra   fields  in  the  central  directory  are  broken  dowm  into
+          subfields, with  brief  descriptions  of  recognized  subfields  (or
+          abbreviated dumps of unrecognized subfields).
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+        Options in this group modify  the  operation  or  report  format  of
+        ZipInfo.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -C
+
+        -C
+        --ignore-case    ([CMS, MVS] --CMS-MVS-lower)
+
+          Use case-insensitive name matching for names in the member list  and
+          the  -x  excluded-member  list  on  the  command  line.  By default,
+          case-sensitive matching is done.  For example, specifying "makefile"
+          on  the  command line will match only "makefile" in the archive, not
+          "Makefile" or "MAKEFILE".  On many systems, the local file system is
+          case-insensitive,  so  case-insensitive  name matching would be more
+          natural.  With -C, "makefile" would match "makefile", "Makefile", or
+          "MAKEFILE".
+
+          /CASE_MATCH does not affect the search for the ZIP archive file(s).
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -h
+
+        -h
+        --header
+
+          Include a header in  the  report,  showing  the  archive  name,  the
+          archive size (in bytes), and the number of members in the archive.
+
+          For the Unix-format reports (options -l,  -m,  -s),  the  header  is
+          included  by default, if no archive members are specified.  If -h is
+          specified alone, that is, without one of  the  Unix-format  options,
+          and  without  a  member list, then only the header lines will be put
+          out.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -M
+
+        -M ([CMS,MVS] Or:  -m)
+        --more
+
+          Pipe all output through  an  internal  pager  similar  to  the  Unix
+          more(1)  command.   At  the  end  of  a screenful of output, Zipinfo
+          pauses with a "--More--" prompt; the next screenful may be viewed by
+          pressing  the  Enter  (Return) key or the space bar.  ZipInfo can be
+          terminated by pressing  the  "q"  key,  or,  on  some  systems,  the
+          Enter/Return    key.     Unlike    Unix   more(1),   there   is   no
+          forward-searching or  editing  capability.   Also,  ZipInfo  doesn't
+          notice  if  long  lines  wrap at the edge of the screen, effectively
+          resulting in the printing of two or more lines  and  the  likelihood
+          that  some  text  will scroll off the top of the screen before being
+          viewed.  If the actual number of lines on  the  screen  can  not  be
+          determined, 24 lines will be assumed.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -T
+
+        -T
+        --decimal-time
+
+          Show   the   file   date-times   in   a    sortable,    all-numeric,
+          "YYYYMMDD.hhmmss"   format.    The   default   date   format  is  an
+          alpha-numeric "YY-Mmm-DD hh:mm".  For example ("-s", "-s -T"):
+
+          -rw-a--     3.1 fat   211916 tx defX 10-Jun-18 00:27 zip31c/zip.c
+          -rw-a--     3.1 fat   211916 tx defX 20100618.002703 zip31c/zip.c
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -t
+
+        -t
+        --totals
+
+          Include a totals summary at the  end  of  the  report,  showing  the
+          number  of  members  in  the  report,  the sum of their uncompressed
+          sizes, the sum of their compressed sizes, and the compression factor
+          as a percentage.
+
+          For the Unix-format reports (options -l, -m, -s), the totals summary
+          is  included by default, if no archive members are specified.  If -t
+          is specified alone, that is, without one of the Unix-format options,
+          and  without  a  member  list,  then only the totals summary trailer
+          lines will be put out.
+
+          The total "bytes compressed" reported includes only the actual data,
+          not  the  ZIP  archive  meta-data,  so  the size of the archive will
+          always be greater than this value.
+
+          See also -mc.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -U
+
+        -U
+        --unicode
+
+          [UNICODE_SUPPORT] Control UTF-8 handling.  When  UNICODE_SUPPORT  is
+          available, -U forces ZipInfo to escape all non-ASCII characters from
+          UTF-8  coded  filenames  as  "#Uxxxx"  (for  UCS-2  characters,   or
+          "#Lxxxxxx" for Unicode codepoints needing 3 octets).  This option is
+          mainly provided for debugging purpose  when  the  fairly  new  UTF-8
+          support is suspected of damaging extracted filenames.
+
+          -UU disables  the  recognition  of  UTF-8  encoded  filenames.   The
+          handling  of  filename  codings  within  ZipInfo  falls  back to the
+          behavior of pre-Unicode versions.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -W
+
+        -W
+        --wild-no-span
+
+          [WILD_STOP_AT_DIR] (Valid when the program  was  built  with  the  C
+          macro WILD_STOP_AT_DIR defined.) By default, the wildcard characters
+          "?" (single-character wildcard) and "*"  (multi-character  wildcard)
+          match  any  character  in  a  member  path/name.   "-W" modifies the
+          pattern-matching behavior for  archive  members  so  that  both  "?"
+          (single-character  wildcard)  and  "*" (multi-character wildcard) do
+          not match the directory separator character "/".  (The two-character
+          sequence  "**"  acts as a multi-character wildcard that includes the
+          directory separator in its matched characters.)  For  example,  with
+          "-W":
+
+              "*.c"   matches "foo.c" but not "mydir/foo.c"
+              "**.c"  matches both "foo.c" and "mydir/foo.c"
+              "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c"
+              "??*/*" matches "ab/foo" and "abc/foo"
+                      but not "a/foo" or "a/b/foo"
+
+          This modified behavior is equivalent to the pattern  matching  style
+          used  by  the  shells  of  some of UnZip's supported target OSs (one
+          example is Acorn RISC OS).  This option  may  not  be  available  on
+          systems   where  the  Zip  archive's  internal  directory  separator
+          character "/" is allowed as regular character  in  native  operating
+          system  filenames.  (Currently, UnZip uses the same pattern matching
+          rules for both wildcard archive file name specifications and archive
+          member  selection  patterns  on  most  system  types.   For  systems
+          allowing "/" as regular filename character, the -W option would  not
+          work as expected on a wildcard file name specification.)
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -x
+
+        -x member ...
+        --exclude member ...
+
+          An optional list of archive members to be excluded from  processing.
+          Because  wildcard characters normally match "/" directory separators
+          (for exceptions see the option -W),  this  option  may  be  used  to
+          exclude  any  files that are in subdirectories.  For example, "unzip
+          foo *.[ch] -x */*" would extract all C source files  (*.c,  *.h)  in
+          the  main directory, but none in any subdirectories.  Without the -x
+          option, all C source files in all  directories  within  the  archive
+          would be extracted.
+
+          When the program sees -x (--exclude) on a  command  line,  it  stops
+          scanning for options, and treats every succeeding item as an archive
+          member name.  To avoid confusion between member  names  and  command
+          options, it's simplest to specify -x (--exclude) and its member list
+          as the last items on a command  line.   Alternatively,  the  special
+          name  "@"  can  be  used to terminate the member list (and cause the
+          program to resume scanning for options).  That is, the following two
+          commands are equivalent:
+
+            zipinfo fred.zip -2 -t -x file1 file2 file3
+            zipinfo fred.zip -x file1 file2 file3 @ -2 -t
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Options_Ordinary
+
+      -z
+
+        -z
+        --zipfile-comment
+
+          Include the archive comments (if any) in the report.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Detailed_Description
+
+        ZipInfo has three basic report formats, providing different  degrees
+        of  detail  in  the  information about the members of an archive:  a
+        simple list of names (-1, -2), a Unix ls-style listing (-l, -m, -s),
+        and a very detailed analysis (-v).  Some of the information, such as
+        file sizes, is easy to interpret.  Some of the information  involves
+        fairly  obscure  details  of  ZIP  archive  structure.   ZIP archive
+        structure is documented in the PKWARE Inc.  APPNOTE.TXT:
+        http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+        The table below shows some typical -l report entries:
+
+        Perm/Prot  Zver Ofs UncSize At CmpSize Cmth  ModDate  Mtime Name
+        ----------+----+---+-------+--+-------+----+---------------+----------
+        -rw-a--     3.1 fat  211916 tx   53467 defX 10-Jun-18 00:27 zip3/zip.c
+        -rwxr-x---  3.1 unx     709 Tx     311 aesw 11-Aug-21 22:20 endian.c
+        RWED,RE,    3.1 vms    6656 bx    2295 defN 07-Aug-15 14:12 it/T.EXE;8
+
+        Field 1 (Perm/Prot) shows the file permission/protection attributes,
+        formatted  according to the original operating system or file system
+        where the archive was created.
+
+        Field 2 (Zver) shows the (approximate) version of  the  Zip  program
+        which created the archive.
+
+        Field 3 (Ofs) shows the original operating system where the  archive
+        was created, or the file system on which the member file was stored.
+
+        Field 4 (UncSize) shows the original, uncompressed file size.
+
+        Field 5 (At) shows some archive member attributes,  as  detailed  in
+        the  tables below.  The first character indicates whether a file was
+        binary or text, and whether it was encrypted.  The second  character
+        indicates the presence of a data descriptor and/or an extra field in
+        the member data.
+
+                      |   File Type     Extra Field |
+          First char  | binary  text      yes   no  |  Second char
+        --------------+-------+-----    ------+-----+--------------------
+        Encrypted  no |   b      t         x     -  | no  Data Descriptor
+                  yes |   B      T         X     l  | yes
+
+        A Data Descriptor holds CRC and size data at an alternate  place  in
+        the  archive (after processed member data instead of before), and is
+        normally used when the archiving program can't seek  in  the  output
+        archive  data/file.  An Extra Field can hold a wide variety of data,
+        including 64-bit file sizes, many  kinds  of  OS-specific  attribute
+        data, UTC times, and so on.
+
+        Field 6 (CmpSize) shows the compressed file  size.   With  -m,  this
+        field  shows the compression fraction as a percentage.  With -s (the
+        default), this field is omitted.  This compressed size value (unlike
+        the one in an "unzip -l" report) includes all the overhead resulting
+        from Traditional encryption.
+
+        Field 7 (Cmth) shows the compression method used.  Note that  AES_WG
+        encryption  is treated as a compression method here.  Not all of the
+        methods  shown  in  the  table  below  are  supported.   (Some   are
+        obsolete.)
+
+         Num Abbr  Name, description
+        ----+----+------------------------------------------------------------
+          0  stor  Store (no compression)
+          1  shrk  Shrink
+          2  re:1  Reduce (factor 1)
+          3  re:2  Reduce (factor 2)
+          4  re:3  Reduce (factor 3)
+          5  re:4  Reduce (factor 4)
+          6  i#:#  Implode (dictonary_size:Shannon-Fano_trees)
+          7  tokn  Tokenize
+          8  def#  Deflate (N: normal, X: maximum, F: fast, S: super-fast)
+          9  d64#  Deflate64 (N: normal, X: maximum, F: fast, S: super-fast)
+         10  dcli  PKWARE Data Compression Library Imploding - IBM TERSE (old)
+         12  bzp2  bzip2
+         14  lzma  LZMA
+         18  ters  IBM TERSE (new)
+         19  lz77  IBM LZ77 z Architecture (PFS)
+         96  jpeg  JPEG
+         97  wavp  WavPack
+         98  ppmd  PPMd version I, Rev 1
+         99  aesw  AES_WG encryption
+
+        Fields 8 and 9 (ModDate, Mtime) show the file modification date-time
+        (MS-DOS format, local time).
+
+        Field 10 (Name) shows the file path/name.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Environment_Options
+
+        ZipInfo's default behavior may be modified by  placing  command-line
+        options  in  an  environment  variable.   This  can be done with any
+        option, but it is probably most useful options like -T (decimal time
+        format) or one of the non-default Unix format options:  -l, -m.
+
+        For ZipInfo ("unzip -Z"), the environment variable name  on  VMS  is
+        ZIPINFO_OPTS  (non-VMS:   ZIPINFO).   For compatibility with Zip, if
+        ZIPINFO_OPTS is not defined, then ZipInfo will  use  ZIPINFOOPT  the
+        same way.
+
+        For example, to make the default format the long Unix format instead
+        of the short Unix format, one could use commands like the following:
+
+        Unix Bourne (or similar) shell:
+          ZIPINFO='-l'; export UNZIP
+
+        Unix C shell:
+          setenv ZIPINFO '-l'
+
+        OS/2 or MS-DOS:
+          set ZIPINFO="-l"
+
+        VMS (with quotation to preserve lower case in DCL):
+          define ZIPINFO_OPTS "-l"        ! Logical name, or
+          ZIPINFO_OPTS = "-l"             ! DCL symbol.  (Either works.)
+
+        Environment options are treated the same as any  other  command-line
+        options,  except  that they are effectively the first options on the
+        command line.  To override an environment option,  one  may  use  an
+        explicit  option  to cancel or override it.  For example, to disable
+        the totals trailer line by default, one could use commands like  the
+        following:
+
+        Unix Bourne (or similar) shell:
+          ZIPINFO='-t-'; export ZIPINFO
+
+        Unix C shell:
+          setenv ZIPINFO '-t-'
+
+        VMS (with quotation to preserve lower case in DCL):
+          define ZIPINFO_OPTS "-t-"       ! Logical name, or
+          ZIPINFO_OPTS = "-t-"            ! DCL symbol.  (Either works.)
+
+        The examples show short (one-character)  options,  but  long  ("--")
+        options are also allowed.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Examples
+
+        To get a basic, short-format listing of the complete contents  of  a
+        ZIP  archive zip31c.zip, with both header and totals lines, use only
+        the archive name as an argument to zipinfo:
+
+          zipinfo zip31c.zip
+          zipinfo zip31c
+
+        To produce a basic, long-format  listing  (not  verbose),  including
+        header and totals lines, use -l:
+
+          zipinfo -l zip31c.zip
+
+        To list the complete contents of  the  archive  without  header  and
+        totals  lines,  either  negate the -h and -t options or else specify
+        the contents explicitly:
+
+          zipinfo -h- -t- zip31c.zip
+          zipinfo zip31c.zip *
+
+        (On a Unix system, the wildcard member name would typically need  to
+        be  quoted  to  keep  a a Unix shell from expanding ("globbing") it.
+        This is not necessary on VMS.)
+
+        To list information on a single archive member,  in  medium  format,
+        specify the member name explicitly:
+
+          zipinfo -m unzip60.zip */unshrink.c
+
+        When any member name is specified, the  header  and  totals  trailer
+        are,  by  default,  not  included  in  the  report,  but  explicitly
+        specifying -h and/or -t will restore them.  For example:
+
+          zipinfo -m -t unzip610b.zip *.[ch] */Make*
+
+        On a Unix system, one could use the -T option along with an external
+        sorting  program (and another filter like "head" or "tail") to get a
+        listing of the least or most recently modified files in the archive:
+
+          zipinfo -l -T -h- -t- zip31c.zip | sort -k 8 | head -12
+          zipinfo -l -T -h- -t- zip31c.zip | sort -r -k 8 | head -12
+
+        The "sort" option "-k 8" tells it to sort on field 8, which  is  the
+        date-time field in a long- or medium-format (-l, -m) ZipInfo report.
+        (Use "-k 7" for the short (-s) format.) The -r option  reverses  the
+        default smallest-to-largest sort order.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Bugs
+
+        As with UnZip, ZipInfo's -M ("--more") option is  overly  simplistic
+        in  its  handling  of  screen  output.   As noted above, it fails to
+        detect the wrapping of long lines and may thereby cause lines at the
+        top  of  the  screen  to be scrolled off before being read.  ZipInfo
+        should  detect  and  treat  each  occurrence  of  line-wrap  as  one
+        additional  line  printed.   This requires knowledge of the screen's
+        width as well as its height.  In addition, ZipInfo should detect the
+        true screen geometry on all systems.
+
+        The interactions among  the  various  listing  format,  header,  and
+        trailer  options  (-h, -l, -m, -s, -t) are unnecessarily complex and
+        should be simplified, despite the potential  disruption  to  current
+        users.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    URL
+
+        The Info-ZIP main Web page is:
+            http://www.info-zip.org/
+
+        FTP access is available, too:
+            ftp://ftp.info-zip.org/pub/infozip/
+
diff --git a/docs/UNZIP_CLI.HTX b/docs/UNZIP_CLI.HTX
new file mode 100644 (file)
index 0000000..303cd34
--- /dev/null
@@ -0,0 +1,1818 @@
+
+UNZIP
+
+     UnZip lists, tests, or  extracts  files  from  a  ZIP  archive  (an
+     archive  format  commonly  used  on  many  different systems).  The
+     default behavior (with no options) is to extract into  the  current
+     directory   (and  subdirectories  below  it)  all  files  from  the
+     specified ZIP archive.   A  companion  program,  Zip,  creates  ZIP
+     archives.
+
+     Info-ZIP UnZip and Zip were intended to be compatible with archives
+     created  by  PKWARE's  PKZIP  and  PKUNZIP programs (originally for
+     MS-DOS), but in many cases the program options or default behaviors
+     differ.   Nowadays,  many  other  programs are available which work
+     with ZIP archives.
+
+     This  help  file  describes  the  VMS  CLI  edition  of  UnZip.   A
+     Unix-style  command-line edition is also available, with a separate
+     help file.
+
+     The VMS CLI edition of UnZip adds a command-line translator to  the
+     normal   UnZip  program.   This  translator  transforms  a  set  of
+     VMS-style qualifiers and  parameters  into  an  equivalent  set  of
+     Unix-style   options   and   parameters,   and  then  passes  those
+     transformed arguments to UnZip's standard  Unix-style  command-line
+     processor.   The  documentation  often shows the related Unix-style
+     options in parentheses after a VMS-style qualifier.   For  example:
+     /HELP (-h, -hh).
+
+     Format:
+
+       UNZIP [/unzip_qualifiers] [file[.zip]] [member [,...]]
+
+       UNZIP /ZIPINFO [/zipinfo_qualifiers] [file[.zip]] [member [,...]]
+
+       ZIPINFO [/zipinfo_qualifiers] [file[.zip]] [member [,...]]
+
+     To display the basic built-in help, use the command:
+
+       UNZIP /HELP
+
+     To display the extended built-in help, use the command:
+
+       UNZIP /HELP=EXTENDED
+
+     The built-in  help  may  be  more  current  than  this  help  file,
+     especially between full product releases.
+
+     The VMS CLI edition of the program can also provide  built-in  help
+     on  the Unix-style command-line edition; just use the "-h" or "-hh"
+     options.
+
+
+UNZIP
+
+  Command_Parameters
+
+     file[.zip]
+
+          File path/name of a ZIP archive.  A wildcard name may be used to
+          specify  multiple  ZIP  archives to be processed in one command.
+          On  VMS  systems,  any  of  the   standard   wildcards   for   a
+          directory/file  specification  may  be used:  "...", "*", or "%"
+          (or,  since  VMS  V7.2,  "?").    The   default   archive   file
+          specification is ".ZIP".
+
+          Note that a ".zip" or ".ZIP" file type on an archive is merely a
+          convention,  not  a requirement.  For example, a self-extracting
+          ZIP archive named "fred" or "fred.exe" could be processed as  if
+          it  were  an ordinary archive; just specify the actual file name
+          with its actual name ending (if any), whatever that may be.
+
+     member [,...]
+
+          An optional list of archive members to be  processed,  separated
+          by  commas.   If  no  member list is specified, then all archive
+          members are processed.  Unix-like ("globbing") wildcard patterns
+          may be used to match multiple members:
+
+              *       Matches a sequence of 0 or more characters.
+              ?       Matches exactly 1 character.
+              [...]   Matches any single character found inside the brackets.
+                      Ranges are specified by a beginning character, a hyphen,
+                      and an ending character.  If an exclamation point ("!")
+                      or a caret ("^") follows the left bracket, then the
+                      range of characters within the brackets is complemented.
+                      That is, anything except the characters inside the
+                      brackets is considered a match.  To specify a literal
+                      left bracket, use the three-character sequence "[[]".
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+       Qualifiers in this group specify the primary mode of  operation  of
+       UnZip.  Only one of these primary mode qualifiers may be specified.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /COMMENT (-z)
+
+         Primary mode.  Display only the archive comment.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /FRESHEN (-f)
+
+         Primary Mode.  Freshen existing files.  That is, extract only those
+         files  that  already exist on disk and that are newer than the disk
+         copies.  By default  UnZip  queries  before  overwriting,  but  the
+         /EXISTING (-o) option may be used to suppress the queries.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /HELP (-h, -hh)
+
+         /HELP [=NORMAL]
+         /HELP=EXTENDED
+
+         Primary Mode.  Display brief (roughly 24 lines) usage  instructions
+         (NORMAL,  the  default),  or  EXTENDED  help  (more  complete usage
+         instructions).
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /LICENSE (--license)
+
+         Primary Mode.  Display the Info-ZIP license.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /LIST (-l)
+
+         Primary Mode.  List archive members.  By default, a brief format is
+         used,   which   includes   the   following   items:   member  name,
+         uncompressed file size ("Length"), and  modification  date-time  of
+         the  member.   A  summary  is  included  at  the end of the report,
+         showing total size and count for all the  members  in  the  report.
+         Specifying a member list limits the report to those members.
+
+         Adding /VERBOSE to an "UNZIP /LIST" command line adds the following
+         items to the report:  compression method, compressed size ("Size"),
+         compression ratio, and 32-bit CRC.
+
+         In contrast to some other programs,  UnZip  does  not  include  the
+         12-byte  encryption  header  in  the  compressed  size values for a
+         Traditionally encrypted member.   Therefore,  compressed  size  and
+         compression   ratio   figures   are  independent  of  the  member's
+         encryption status and show  the  correct  compression  performance.
+         (The  complete  size  of  the  encrypted compressed data stream for
+         archive members is reported by the more  verbose  ZipInfo  reports.
+         See ZipInfo.
+
+         If UnZip was built with OS2_EAS enabled, then the /LIST report also
+         includes  the  sizes  of  stored OS/2 extended attributes (EAs) and
+         OS/2 access control lists (ACLs).  In addition, the archive comment
+         and individual member comments (if any) are displayed.
+
+         If a file was archived from a single-case file system (for example,
+         the  old MS-DOS FAT file system) and the /NAMES=DOWNCASE option was
+         given, the filename is converted to lowercase and is shown prefixed
+         with a caret (^).
+
+         Note:  If only /VERBOSE is specified with  an  archive  name,  then
+         UnZip  acts  as  if "/LIST /VERBOSE" were specified, and a detailed
+         listing is generated.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /PIPE (-p)
+
+         Primary Mode.  Extract files to stdout  (pipe).   Only  the  actual
+         file  data  for  the  members are sent to stdout (no file names, or
+         other information, as would be displayed with /SCREEN (-c), and the
+         files  are  always  extracted  in  binary  format, just as they are
+         stored (no conversions).  See also /SCREEN.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /SCREEN (-c)
+
+         Primary Mode.  Extract files  to  stdout/screen.   This  option  is
+         similar  to the /PIPE (-p) option except that the name of each file
+         is displayed as it is extracted,  and  the  /TEXT  (-a)  option  is
+         allowed, which can provide automatic ASCII-EBCDIC conversion, where
+         appropriate.  See also /PIPE.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /TEST (-t)
+
+         Primary Mode.  Test  archive  members.   Testing  means  that  each
+         archive member is extracted in memory (expanding and decrypting, as
+         needed), but not written to a  file.   The  resulting  CRC  (cyclic
+         redundancy  check,  an  enhanced checksum) of the extracted data is
+         then compared with the original file's stored  CRC  value,  and  an
+         error message is emitted if a CRC mismatch is detected.
+
+         Adding /VERBOSE (-v) to /TEST adds some diagnostic  information  to
+         the report for archive members with LZMA or PPMd compression.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /TIMESTAMP (-T)
+
+         Primary Mode.  Set the timestamp on the archive(s) to that  of  the
+         newest file in each one.  This corresponds to Zip's /APPEND /LATEST
+         (-go) option, except that it can be used on wildcard archives  (for
+         example, "unzip -T *.zip"), and is much faster.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /UPDATE (-u)
+
+         Primary mode.  Update existing files and create new ones if needed.
+         This  mode performs the same function as the Freshen (/FRESHEN, -f)
+         mode, extracting (with query) files that are newer than those  with
+         the same name on disk, but it also extracts those files that do not
+         already exist on disk.
+
+
+UNZIP
+
+  Qualifiers_Primary_mode
+
+    /VERBOSE (-v)
+
+
+         Primary mode (when alone) or option.  When used as a  primary  mode
+         (alone),  and  no archive is specified, an "UNZIP /VERBOSE" command
+         generates a report showing the program version, build options,  and
+         relevant envrironment variables.
+
+         When used with some other primary mode option,  /VERBOSE  can  make
+         output more verbose (detailed).
+
+         If no other primary mode is specified, and an archive is specified,
+         then  UnZip  acts  as  if  "/LIST  /VERBOSE"  were specified, and a
+         detailed  listing  is  generated.    See   Qualifiers_Primary_mode,
+         particularly /LIST.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+       Qualifiers in this group modify the operation of UnZip.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /AUTO_DIRECTORY (-da)
+
+         /NOAUTO_DIRECTORY (default)
+         /AUTO_DIRECTORY[=REUSE]
+
+         Specifies a destination directory  for  extracted  files  which  is
+         derived  from  the base name of the archive.  By default, files are
+         extracted (and  subdirectories  created)  in  the  current  default
+         directory.   With  /AUTO_DIRECTORY,  UnZip  automatically derives a
+         subdirectory name from the archive name, creates that subdirectory,
+         and extracts files into that subdirectory.
+
+         For example, with /AUTO_DIRECTORY, extraction of "fred.zip" is done
+         into  subdirectory "[.fred]" instead of into the current directory.
+         (On non-VMS systems, subdirectory "fred".)
+
+         Using  this  option  can  help  to  avoid  cluttering  the  current
+         directory with files extracted from an archive whose structure does
+         not include a top-level directory.
+
+         If -da is specified as a default option in an environment variable,
+         it  can be overridden by either a /NOAUTO_DIRECTORY qualifier or an
+         explicit /DIRECTORY=dest_dir qualifier.  See also /DIRECTORY.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /BINARY (-b, -bb)
+
+         /BINARY[=keyword]
+         /NOBINARY   (Default.)
+
+         Selects the file record format used when extracting binary files.
+
+         The optional keywords are:
+
+             ALL      Extract all files with fixed-length, 512-byte record
+                      format.  (-bb)
+             AUTO     Extract binary files with fixed-length, 512-byte
+                      record format.  (Default value keyword: "/BINARY" is
+                      equivalent to "/BINARY=AUTO".)  (-b)
+             NONE     Same as /NOBINARY.  Extract binary files with
+                      Stream_LF record format.  (Default condition.)
+
+         Zip (or a similar archiving program) identifies files  as  "binary"
+         or  "text"  when they are archived.  (A short-format ZipInfo report
+         denotes a binary file with a "b", and a text file with a "t".)
+
+         [VMS] On VMS, for archives with  VMS  attribute  information  (made
+         with  "zip  -V",  "ZIP  /VMS"), files are always created with their
+         original  record  formats.   For  archives  without  VMS  attribute
+         information  (not  made  with  "zip  -V",  "ZIP  /VMS"),  files are
+         normally   created   with   Stream_LF    record    format.     With
+         /BINARY[=AUTO],   binary   files  are  created  with  fixed-length,
+         512-byte record format.  With /BINARY=ALL, all  files  are  created
+         with  fixed-length,  512-byte  record  format.   When extracting to
+         standard  output  (/PIPE  or  /SCREEN  in  effect),   the   default
+         conversion  of  text record delimiters is disabled for binary files
+         (with /BINARY[=AUTO]), or for all files (with /BINARY=ALL).
+
+         /BINARY may conflict or interact  with  /TEXT.   A  combination  of
+         /BINARY[=AUTO] and /TEXT[=AUTO] is allowed.  (See /TEXT.)
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /BRIEF
+
+         Deprecated.  Ignored.  A no-op place-holder, originally intended as
+         an     opposite     of     /FULL     (also     deprecated).     See
+         Qualifiers_Primary_mode, particularly /LIST and /VERBOSE.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /CASE_INSENSITIVE (-C)
+
+         /CASE_INSENSITIVE
+         /NOCASE_INSENSITIVE (default)
+
+         Deprecated.  Use /MATCH=CASE.
+
+         With /CASE_INSENSITIVE, match member names case-blindly.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /DIRECTORY (-d)
+
+         /DIRECTORY=dest_dir
+
+         Specifies a destination directory for extracted files.  By default,
+         files  are  extracted  (and  subdirectories created) in the current
+         default directory.  With "/DIRECTORY=dest_dir", extraction is  done
+         into the specified directory, instead.
+
+         [VMS] On VMS, only a VMS-style device:[directory] specification  is
+         permitted.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /DOT_VERSION (-Y)
+
+         [VMS] Treat archive member name endings of ".nnn" (where "nnn" is a
+         decimal number) as if they were VMS version numbers (";nnn").  (The
+         default is to treat them as file types.) For example:
+
+             "a.b.3" -> "a.b;3"
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /EXCLUDE (-x)
+
+         /EXCLUDE=(member [,...])
+
+         An optional list of archive members to be excluded from processing.
+         Because wildcard characters normally match "/" directory separators
+         (for exceptions see /MATCH=[NO]WILD_MATCH_SLASH (-W)), this  option
+         may  be  used to exclude any files that are in subdirectories.  For
+         example,
+             UNZIP foo *.[ch] /EXCLUDE = */*
+         would extract all C source files (*.c, *.h) in the main  directory,
+         but none in any subdirectories.  Without the /EXCLUDE option, all C
+         source files  in  all  directories  within  the  archive  would  be
+         extracted.
+
+         Note that archive members are specified using the Unix-style  names
+         which are used in ZIP archives, not VMS-style names.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /EXISTING (-n, -o)
+
+         /EXISTING[=keyword]
+
+         Specifies the action when extracting  files,  and  a  file  already
+         exists.
+
+         The optional keywords are:
+
+             NEW_VERSION  Create a new version of an existing file.  (-o)
+             OVERWRITE    Overwrite an existing file.  (-oo)
+             NOEXTRACT    Do not extract.  Leave an existing file intact.  (-n)
+
+         By default, UnZip queries the user before extracting any file  that
+         already exists.
+
+         [Non-VMS] On non-VMS systems, the user may choose to overwrite only
+         the  current  file,  overwrite  all  files,  skip extraction of the
+         current file, skip extraction of all existing files, or rename  the
+         current file (choose a new name for the extracted file).
+
+         [VMS] On VMS, the usual query choices are to create a  new  version
+         of  an  existing file, to skip extraction, or to rename the current
+         file.  In the case where an archive member name includes a  version
+         number,  and /VERSION (-V, "retain VMS file version numbers") is in
+         effect, then an additional query choice is offered:   to  overwrite
+         the existing file.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /FULL (-v)
+
+         /FULL
+         /FULL=DIAGNOSTICS
+
+         Deprecated.    Adds   detail    to    a    /LIST    report.     See
+         Qualifiers_Primary_mode,   particularly  /LIST  and  /VERBOSE,  and
+         Qualifiers_Ordinary, particularly /VERBOSE.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /JAR (--jar)
+
+         Treat archive(s) as Java  JAR.   Over-simplification  in  Java  JAR
+         archives can cause UnZip to transform UTF-8 file names according to
+         inappropriate (MS-DOS) rules, yielding corrupt names  on  extracted
+         files   (typically  those  with  ASCII  codes  128-255).   Archives
+         containing  a  Java  "CAFE"  extra   field   should   be   detected
+         automatically,  and  handled  correctly,  but  not all JAR archives
+         include that extra field.  Specifying /JAR tells  UnZip  to  expect
+         UTF-8  file  names,  regardless  of  whether the archive contains a
+         "CAFE" extra field.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /JUNK_DIRS (-j)
+
+         /NOJUNK_DIRS   (Default.)
+         /JUNK_DIRS[=depth]
+
+         Junk  directories  on  extracted  files.   With   /JUNK_DIRS,   all
+         directory  information  is stripped from an archive member name, so
+         all files are extracted into the destination directory.  (See  also
+         /DIRECTORY.)
+
+         If a depth ("=depth", where  "depth"  is  a  positive  integer)  is
+         specified,  then  that  number of directory levels will be stripped
+         from an archive member name.  For example, an archive  member  like
+         "a/b/c/d/ee.txt" would normally be extracted as "[.a.b.c.d]ee.txt".
+         With  /JUNK_DIRS,  it  would  be  extracted  as   "ee.txt".    With
+         /JUNK_DIRS=2,  the first two directory levels would be stripped, so
+         it would be extracted as "[.c.d]ee.txt".
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /LOWERCASE (-L)
+
+         /[NO]LOWERCASE
+
+         Deprecated.  Use /NAMES=[NO]DOWNCASE.
+
+         /LOWERCASE:  Convert to lowercase any filename  originating  on  an
+         uppercase-only operating system or file system.
+
+         /NOLOWERCASE:  Do not convert to lowercase any filename originating
+         on an uppercase-only operating system or file system.
+
+         See also /UPPERCASE, which is also deprecated.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /MATCH (-C, -W)
+
+         /MATCH=(keyword, ...)
+
+         Specifies name-matching behavior for names in the member  list  and
+         the /EXCLUDE excluded-member list on the command line.
+
+         The optional keywords and values are:
+
+             CASE=BLIND          Name matching is case-insensitive.  (-C)
+             CASE=SENSITIVE      Name matching is case-sensitive.  (Default.)
+
+         By  default,  case-sensitive  matching  is  done.    For   example,
+         specifying   "makefile"   on  the  command  line  will  match  only
+         "makefile" in the archive, not "Makefile" or "MAKEFILE".   On  many
+         systems,   the   local   file   system   is   case-insensitive,  so
+         case-insensitive  name  matching  would  be  more  natural.    With
+         /MATCH=CASE=BLIND,  "makefile"  would match "makefile", "Makefile",
+         or "MAKEFILE".
+
+         /MATCH does not affect the search for the ZIP archive file(s),  nor
+         the matching of archive members to existing files on the extraction
+         path.  So, on a case-sensitive file system, UnZip will never try to
+         overwrite a file "FOO" when extracting a member named "foo"!
+
+         [WILD_STOP_AT_DIR] If the C macro WILD_STOP_AT_DIR  is  defined  at
+         build time, then an additional keyword is allowed:
+
+             NOWILD_MATCH_SLASH  Wildcards stop at directory slash.  (-W)
+             WILD_MATCH_SLASH    Wildcards match directory slash.  (Default.)
+
+         By default, the wildcard characters "?" (single-character wildcard)
+         and  "*" (multi-character wildcard) match any character in a member
+         path/name.     /MATCH=NOWILD_MATCH_SLASH    (-W)    modifies    the
+         pattern-matching  behavior  for  archive  members  so that both "?"
+         (single-character wildcard) and "*" (multi-character  wildcard)  do
+         not   match   the   directory   separator   character   "/".   (The
+         two-character sequence "**" acts as a multi-character wildcard that
+         includes  the  directory  separator in its matched characters.) For
+         example, with /MATCH=NOWILD_MATCH_SLASH:
+
+             "*.c"   matches "foo.c" but not "mydir/foo.c"
+             "**.c"  matches both "foo.c" and "mydir/foo.c"
+             "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c"
+             "??*/*" matches "ab/foo" and "abc/foo"
+                     but not "a/foo" or "a/b/foo"
+
+         This modified behavior is equivalent to the pattern matching  style
+         used  by  the  shells of some of \fIUnZip\fP's supported target OSs
+         (one example is Acorn RISC OS).  This option may not  be  available
+         on  systems  where  the  Zip archive's internal directory separator
+         character "/" is allowed as regular character in  native  operating
+         system filenames.
+
+         [non-VMS] (Currently, UnZip uses the same  pattern  matching  rules
+         for  both  wildcard  archive  file  name specifications and archive
+         member selection  patterns  on  most  system  types.   For  systems
+         allowing "/" as regular filename character, the -W option would not
+         work as expected on a wildcard file name specification.)
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /NAMES (-0 -2, -L, -s)
+
+         /NAMES
+         /NAMES=(keyword, ...)
+
+         Selects name transformations during extraction.  The keywords are:
+
+             [NO]CHAR_SET  CHAR_SET: Use CP850 character-set mapping on names
+                           of archive members which originated on a FAT or
+                           NTFS file system.  (Default condition.)
+                           NOCHAR_SET: Do not map these archive member names.
+             DOWNCASE      Convert filenames from all-uppercase operating
+                           systems to lowercase.  (-L)
+             DOWNCASE=ALL  Convert all filenames to lowercase.  (-LL)
+             ODS2          Restrict names to ODS2 conventions, regardless
+                           of the destination file system.  (Invalid
+                           character -> "_".)  (-2)
+             [NO]SPACES    SPACES: Permit space characters in (ODS5) names.
+                           (Default condition.)
+                           NOSPACES: Change spaces to underscores.  (-s)
+
+         The default is to use ODS5-compatible file names (including spaces)
+         when  the destination file system is ODS5, and to convert the names
+         to ODS2-compatible names when the destination file system is ODS2.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /OVERWRITE (-n, -o)
+
+         /[NO]OVERWRITE
+
+         Deprecated.  Use /EXISTING.
+
+         /OVERWRITE is equivalent to /EXISTING=NEW_VERSION.
+         /NOOVERWRITE is equivalent to /EXISTING=NOEXTRACT.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /PAGE (-M)
+
+         Pipe all output through an  internal  pager  similar  to  the  Unix
+         more(1) command.  At the end of a screenful of output, UnZip pauses
+         with a "--More--" prompt; the  next  screenful  may  be  viewed  by
+         pressing  the  Enter  (Return)  key or the space bar.  UnZip can be
+         terminated by pressing the  "Q"  key  and,  on  some  systems,  the
+         Enter/Return    key.     Unlike   Unix   more(1),   there   is   no
+         forward-searching  or  editing  capability.   Also,  UnZip  doesn't
+         notice  if  long  lines wrap at the edge of the screen, effectively
+         resulting in the printing of two or more lines and  the  likelihood
+         that  some  text will scroll off the top of the screen before being
+         viewed.  If the actual number of lines on the  screen  can  not  be
+         determined, 24 lines will be assumed.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /PASSWORD (-P)
+
+         /PASSWORD=password
+
+         Use "password" to decrypt encrypted archive members (if any).  THIS
+         IS  INSECURE!   Many  multi-user operating systems provide ways for
+         any user to see the current command line of any other  user.   Even
+         on   stand-alone   systems,   there   is   always   the  threat  of
+         over-the-shoulder peeking.  Storing the plaintext password as  part
+         of  a  command line in an automated script can be even less secure,
+         Whenever possible, use the non-echoing, interactive prompt to enter
+         passwords.   Where  security  is  truly  important,  use  a  strong
+         encryption method, such as AES,  instead  of  the  relatively  weak
+         encryption  provided  by  Traditional  ZIP  encryption.  Or, use an
+         external encryption program, such as GnuPG,  before  archiving  the
+         file.   (Note  that Zip will probably not be able to do significant
+         compression on a file which has already been encrypted.)
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /QUIET (-q, -qq)
+
+         /QUIET[=SUPER]
+
+         Perform operations quietly.  (/QUIET=SUPER:  even more quietly).
+
+         By default, UnZip prints the names of the files it's extracting  or
+         testing,  the  extraction  methods,  any member or archive comments
+         that may be stored in the archive,  and  possibly  a  summary  when
+         finished  with  each  archive.  The /QUIET[=SUPER] options suppress
+         the printing of some or all of these messages.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /RESTORE (-D, -k, -ka, -X)
+
+         /RESTORE[=(keyword, ...)]
+
+         Selects restoration  options  for  some  meta-data.   The  optional
+         keywords are:
+
+             ACL           Restore file ACL settings.  (-ka)
+             OWNER         Restore file owner/UIC settings.  (-X)
+             PROTECTION = LIMITED   Restore file UIC-based (SOGW) protection
+                                    settings, respecting the current default
+                                    protection.  (Default.)
+             PROTECTION = ORIGINAL  Restore file UIC-based (SOGW) protection
+                                    settings, ignoring the current default
+                                    protection.  (-k)
+             NOPROTECTION  Do not restore file UIC-based (SOGW) protection settings.
+                           The current default protection is used.  (-k-)
+             NODATE        Do not restore any timestamps.
+             DATE=ALL      Restore timestamps for all extracted entries,
+                           files and directories.
+             DATE=FILES    Restore timestamps for extracted files.  (Default.)
+
+         By  default,  on  VMS,  UnZip  restores  the   original   date-time
+         attributes  for  files,  but not for directories.  This agrees with
+         the behavior of VMS BACKUP (and UnZip versions  before  5.52  where
+         the capability to restore directory timestamps was added).
+
+         For compatibility  with  UnZip  versions  before  6.0  (5.53),  the
+         following deprecated short forms are still accepted:
+
+             Deprecated form:      Modern form:
+             /RESTORE              /RESTORE=PROTECTION
+             /NORESTORE            /RESTORE=NOPROTECTION
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /TEXT (-a, -aa, -S)
+
+
+         /TEXT[=(keyword, ...)]
+         /NOTEXT   (Default.)
+
+         The optional keywords are:
+
+             ALL      Extract all files with variable-length record format.
+                      Adjust line endings to local standard, and convert
+                      EBCDIC to  ASCII, as needed.  (-aa)
+             AUTO     Extract text files with variable-length record format.
+                      Adjust line endings to local standard, and convert
+                      EBCDIC to ASCII, as needed.  (Default value keyword:
+                      "/TEXT" is equivalent to "/TEXT=AUTO".)  (-a)
+             NONE     Same as /NOTEXT.  Extract text files with Stream_LF
+                      record format without conversions.  (Default
+                      condition.)
+             STMLF    Use Stream_LF record format for text files (instead of
+                      variable-length record format) when ALL or AUTO is in
+                      effect.  Adjust line endings to local standard, and
+                      convert EBCDIC to ASCII, as needed.  (-S)
+
+         Selects the file record format, character encoding, and line-ending
+         type used when extracting text files.
+
+         Zip (or a similar archiving program) identifies files  as  "binary"
+         or  "text"  when they are archived.  (A short-format ZipInfo report
+         denotes a binary file with a "b", and a  text  file  with  a  "t".)
+         Zip's  identification  of  text  files may not be perfect, so UnZip
+         prints "[binary]" or "[text]" as a visual check for  each  file  it
+         extracts  with  /TEXT.   /TEXT=ALL forces all files to be extracted
+         (and converted) as text, regardless of the supposed file type.
+
+         [VMS] On VMS, for archives with  VMS  attribute  information  (made
+         with  "zip  -V",  "ZIP  /VMS"), files are always created with their
+         original  record  formats.   For  archives  without  VMS  attribute
+         information  (not  made  with  "zip -V", "ZIP /VMS"), all files are
+         normally created with Stream_LF record format.  With  /TEXT[=AUTO],
+         text files are normally created with variable-length record format,
+         but adding STMLF gives them Stream_LF record format.  Additionally,
+         line  endings  (CR,  LF,  CR+LF,  ..)  are  adjusted  to  the local
+         standard, and EBCDIC is converted to ASCII.   With  /TEXT=ALL,  all
+         files are treated as text files, and processed as described above.
+
+         See also /BINARY.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /TRAVERSE_DIRS (-:)
+
+         /[NO]TRAVERSE_DIRS   (Default: /NOTRAVERSE_DIRS.)
+
+         Allows UnZip to extract archive members into locations  outside  of
+         the    current    extraction   destination   directory   (and   its
+         subdirectories).
+
+         For security reasons, UnZip  normally  removes  "parent  directory"
+         path  components  ("../") from the path names of archive members as
+         they are extracted.  This safety feature  (new  for  version  5.50)
+         prevents  UnZip  from  accidentally  writing  files  to directories
+         outside the current  destination  directory  tree.   /TRAVERSE_DIRS
+         sets  UnZip  back  to its previous, more liberal behavior, allowing
+         exact extraction of archives that  use  "../"  path  components  to
+         create  multiple  directory  trees  at  or  above  the level of the
+         destination directory.
+
+         Use this option with extreme caution.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /UPPERCASE (-L)
+
+         /[NO]UPPERCASE
+
+         Deprecated.  Use /NAMES=[NO]DOWNCASE.
+
+         /UPPERCASE:  Do not convert to lowercase any  filename  originating
+         on an uppercase-only operating system or file system.
+
+         /NOUPPERCASE:  Convert to lowercase any filename originating on  an
+         uppercase-only operating system or file system.
+
+         See also /LOWERCASE, which is also deprecated.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /VERBOSE (-v)
+
+         /VERBOSE[=(keyword, ...)]
+
+         The optional keywords are:
+
+             NORMAL   Make a report more detailed/verbose.  (Default value
+                      keyword: "/VERBOSE" is equivalent to
+                      "/VERBOSE=NORMAL".)  (-v)
+             MORE     Enable special developer I/O diagnostics.  See below.
+                      (-vv)
+             COMMAND  Enable special developer CLI diagnostics.  See below.
+
+         MORE and NORMAL may  not  be  specified  together.   (MORE  implies
+         NORMAL.)
+
+         When used with some primary mode options, /VERBOSE can make  output
+         more    detailed/verbose.     See   also   Qualifiers_Primary_mode,
+         particularly /LIST.
+
+         If no other primary mode is specified, and an archive is specified,
+         then  UnZip  acts  as  if  "/LIST  /VERBOSE"  were specified, and a
+         detailed  listing  is  generated.    See   Qualifiers_Primary_mode,
+         particularly /LIST and /VERBOSE.
+
+         /VERBOSE=MORE ("-vv")  enables  some  VMS-specific  I/O  diagnostic
+         messages,  and  is  intended for use in program development, not in
+         normal use.
+
+         /VERBOSE=COMMAND causes UnZip to  show  the  translated  Unix-style
+         command-line  argument vector before processing it, and is intended
+         for   use   in   program   development,   not   in   normal    use.
+         /VERBOSE=COMMAND has no Unix-style equivalent.
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /VERSION (-V)
+
+         [Non-CMS-MVS] Retain VMS file version numbers.  VMS  files  can  be
+         stored  with  a version number, in the format "file.type;##", where
+         "##" is a decimal number.  By default the ";##" version numbers are
+         stripped,  but  this  option  allows them to be retained.  (On file
+         systems that limit filenames to  particularly  short  lengths,  the
+         version  numbers  may  be  truncated or stripped regardless of this
+         option.)
+
+         [Non-VMS] Note that before UnZip version 6.1, on a non-VMS  system,
+         a  file with a name like "fred;123" would, by default, be extracted
+         as "fred", even if the file did not originate on a VMS  system  (so
+         that  ";123"  was  probably  not  really  a  VMS  version  number).
+         Beginning with UnZip version 6.1, the default behavior is to  strip
+         VMS  version  numbers  only from files which were archived on a VMS
+         system.  To restore the old behavior, and always strip apparent VMS
+         version numbers, explicitly negate the option:  "-V-".
+
+
+UNZIP
+
+  Qualifiers_Ordinary
+
+    /ZIPINFO (-Z)
+
+         ZipInfo mode.  With /ZIPINFO, the program  runs  in  ZipInfo  mode,
+         which  is  used  to  display  information  about an archive and its
+         members.  Remaining options are interpreted as ZipInfo options.  If
+         used,  /ZIPINFO  must  be  the first qualifier on the command line.
+         See ZipInfo_mode.
+
+
+UNZIP
+
+  Environment_Options
+
+       UnZip's default behavior may  be  modified  by  placing  Unix-style
+       command-line  options  in  an  environment  variable.  (The VMS CLI
+       translator acts only  on  the  command  line  itself,  not  on  the
+       environment variables.) This can be done with any option, but it is
+       probably most useful options  like  -a  (/TEXT,  auto-convert  text
+       files),  -L  (/NAMES,  downcase  file  names  from systems with all
+       uppercase file names), -C (/MATCH=CASE=BLIND, use  case-insensitive
+       name   matching),   -q   (/QUIET,  quiet),  -o  (/EXISTING,  always
+       overwrite), or -n (/EXISTING, never overwrite).
+
+       For UnZip, the environment  variable  name  on  VMS  is  UNZIP_OPTS
+       (non-VMS:   UNZIP).  The name on VMS is different to avoid conflict
+       with a foreign-command DCL symbol, UNZIP.  For  compatibility  with
+       Zip, if UNZIP_OPTS is not defined, then UnZip will use UNZIPOPT the
+       same way.
+
+       For ZipInfo ("UNZIP /ZIPINFO"), the environment  variable  name  on
+       VMS  is  ZIPINFO_OPTS  (non-VMS:  ZIPINFO).  For compatibility with
+       Zip,  if  ZIPINFO_OPTS  is  not  defined,  then  ZipInfo  will  use
+       ZIPINFOOPT the same way.
+       For example, to  make  UnZip  act  as  quietly  as  possible,  only
+       reporting  errors,  one could use commands like the following (with
+       quotation to preserve lower case in DCL):
+
+           define UNZIP_OPTS "-q -q"       ! Logical name, or
+           UNZIP_OPTS = "-q -q"            ! DCL symbol.  (Either works.)
+
+       Environment options are treated the same as  any  other  Unix-style
+       command-line  options,  except  that they are effectively the first
+       options on the command line.  Generally,  the  VMS  CLI  translator
+       will  override  an  environment option if an explicit corresponding
+       VMS-style qualifier is specified.
+
+       The examples show short (one-character) options,  but  long  ("--")
+       options are also allowed.
+
+
+UNZIP
+
+  Encryption_Decryption
+
+       Zip and UnZip have long  supported  a  relatively  weak  encryption
+       method,  which we call Traditional ZIP encryption.  The source code
+       for Traditional encryption is included  in  the  source  kits,  and
+       support   for   Traditional   encryption  is  enabled  by  default.
+       (Build-time C macro:  CRYPT_TRAD.)
+
+       Beginning with  UnZip  version  6.1  and  Zip  version  3.1,  these
+       programs  also offer a stronger, Advanced Encryption Standard (AES)
+       encryption  method,  which  we  call  AES  WinZip/Gladman  (AES_WG)
+       encryption.   (The  encryption  code was supplied by Brian Gladman,
+       and the archive format is intended to be compatible with that  used
+       by  the WinZip program.  WinZip is a registered trademark of WinZip
+       International LLC.)  The  source  code  for  AES_WG  encryption  is
+       distributed  in  a  separate  kit (for export control reasons), and
+       support for AES_WG encryption must be enabled explicitly  at  build
+       time.  (Build-time C macro:  CRYPT_AES_WG.) See the INSTALL file in
+       the source kit for details on how to enable AES_WG  encryption  (or
+       how to disable Traditional encryption).
+
+       For details on the WinZip AES scheme, see:
+           http://www.winzip.com/aes_info.htm
+
+       For information on the separate AES_WG source kit, see:
+           ftp://ftp.info-zip.org/pub/infozip/crypt/
+           ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
+
+       Normally,  encryption  passwords   are   supplied   by   the   user
+       interactively  when  requested by the program.  See /PASSWORD for a
+       (less secure) method of specifying a password on the command line.
+
+       With Traditional encryption, when decrypting, a  password  will  be
+       checked  against header data, and used if it appears to be correct.
+       The correct password will always check out against the header data,
+       but  there  is a 1-in-256 chance that an incorrect password will as
+       well.  (This is a security feature of the PKWARE archive format; it
+       helps prevent brute-force attacks that might otherwise gain a large
+       speed advantage by testing only the header.) In the  case  that  an
+       incorrect  password  is given but it passes the header test anyway,
+       either an incorrect CRC will be generated for the extracted data or
+       else  UnZip will fail during the extraction because the "decrypted"
+       bytes do not constitute a valid compressed data stream.
+
+       If the first password fails the header check on  some  file,  UnZip
+       will  prompt  for  another  password, and so on until all files are
+       extracted.  If a password is not known, entering  a  null  password
+       (that  is,  just a carriage return or "Enter") is taken as a signal
+       to skip all further  prompting.   Only  unencrypted  files  in  the
+       archive(s)   will  thereafter  be  extracted.   (The  situation  is
+       actually a little more complicated.  Some old versions of  Zip  and
+       ZipCloak  allowed  null  passwords,  so UnZip checks each encrypted
+       file to see if the null password works.  This may result in  "false
+       positives" and extraction errors, as noted above.)
+
+       Archives encrypted with  8-bit-character  passwords  (for  example,
+       passwords  with  accented  European characters) may not be portable
+       across systems or to other archivers.  This problem stems from  the
+       use  of  multiple  encoding  methods for such characters, including
+       Latin-1 (ISO 8859-1) and OEM code page 850.  DOS PKZIP  2.04g  uses
+       the  OEM  code  page;  Windows  PKZIP  2.50  uses  Latin-1  (and is
+       therefore incompatible with DOS PKZIP; Info-ZIP uses the  OEM  code
+       page  on  DOS,  OS/2 and Win3.x ports but ISO coding (Latin-1 etc.)
+       everywhere  else;  and  Nico  Mak's  WinZip  6.x  does  not   allow
+       8-bit-character passwords at all.  UnZip 5.3 (or newer) attempts to
+       use the default character set first (e.g.,  Latin-1),  followed  by
+       the  alternate  one  (e.g.,  OEM  code page) to test passwords.  On
+       EBCDIC systems, if both of these  fail,  EBCDIC  encoding  will  be
+       tested  as  a  last  resort.   (EBCDIC  is not tested on non-EBCDIC
+       systems, because there are no known archivers  that  encrypt  using
+       EBCDIC  encoding.)  ISO  character encodings other than Latin-1 are
+       not supported.  The  new  addition  of  (partial)  Unicode  (UTF-8)
+       support  in  UnZip  6.0  has not yet been adapted to the encryption
+       password handling in UnZip.  On systems that use  UTF-8  as  native
+       character  encoding,  UnZip simply tries decryption with the native
+       UTF-8 encoded password; the built-in attempts to check the password
+       in  translated encoding have not yet been adapted for UTF-8 support
+       and will consequently fail.
+
+
+UNZIP
+
+  Examples
+
+       To use UnZip to extract all members of the archive letters.zip into
+       the  current  directory  and  subdirectories below it, creating any
+       subdirectories as necessary:
+
+           unzip letters
+
+       To extract all members of letters.zip into  the  current  directory
+       only:
+
+           unzip /junk_dirs letters
+
+       To test letters.zip, printing only  a  summary  message  indicating
+       whether the archive is OK or not:
+
+           unzip /test /quiet letters
+
+       To test all ".zip" archives in the current directory, printing only
+       the summaries:
+
+           unzip /test /quiet *.zip
+
+       (On a Unix system, the wildcard member name would typically need to
+       be  quoted  to  keep a a Unix shell from expanding ("globbing") it.
+       This is not necessary on VMS.  However, a name with a  slash  ("/")
+       character,  such as "*/zip*.*", must be quoted.  Otherwise, DCL may
+       interpret the slash as introducing a qualifier, causing  unexpected
+       behavior or an "%CLI-W-IVQUAL, unrecognized qualifier" error.)
+
+       The following command extracts to standard output  all  members  of
+       letters.zip whose names end in ".tex", auto-converting to the local
+       end-of-line convention, in Stream_LF record format, and piping  the
+       output into TYPE /PAGE:
+
+           pipe unzip /screen /text=(auto, stmlf) letters *.tex | \
+            type /page sys$input
+
+       To extract from source.zip all Fortran and  C  source  files  (*.f,
+       *.c, *.h) and Makefile into the SYS$SCRATCH directory:
+
+           unzip source.zip *.[fch] Makefile /directory = sys$scratch
+
+       To extract all FORTRAN and C source files, regardless of case  (for
+       example,  both *.c and *.C, and any makefile, Makefile, MAKEFILE or
+       similar):
+
+           unzip -C source.zip *.[fch] makefile /directory = sys$scratch
+
+       The following command extracts only newer  versions  of  the  files
+       already  in  the  current  directory, without querying.  (Note:  Be
+       careful of  extracting  in  one  timezone  an  archive  created  in
+       another.   ZIP  archives created by Zip versions before 2.1 contain
+       no timezone  information,  and  a  "newer"  file  from  an  eastern
+       timezone may, in fact, be older):
+
+           unzip /freshen /existing=new_version sources
+
+       To extract newer versions of  the  files  already  in  the  current
+       directory and to create any files not already there (same caveat as
+       previous example):
+
+           unzip /update /existing=new_version sources
+
+       To display a configuration report showing the program version,  the
+       OS  and  compiler  used  to  build  it, a list of optional features
+       enabled  at  build  time,  and  the  values  of  all  the  relevant
+       environment variables:
+
+           unzip /verbose
+
+
+UNZIP
+
+  Exit_Status
+
+       UnZip's exit status approximates the exit codes defined by  PKWARE.
+       On   VMS,  UnZip's  UNIX-style  exit  values  are  translated  into
+       VMS-style status codes with facility code 1954 =  %x7A2,  and  with
+       the inhibit-message (%x10000000) and facility-specific (%x00008000)
+       bits set:
+
+           %x17A28001                        normal exit
+           %x17A28000 + 16*UnZip_error_code  warnings
+           %x17A28002 + 16*UnZip_error_code  normal errors
+           %x17A28004 + 16*UnZip_error_code  fatal errors
+
+       Note that multiplying the UNIX-style UnZip error code by 16  places
+       it  conveniently  in the hexadecimal representation of the VMS exit
+       code, "__" in %x17A28__s, where "s"  is  the  severity  code.   For
+       example,  a  missing  archive might cause UnZip error code 9, which
+       would be transformed into the VMS exit status %X17A28092.
+
+       The UnZip VMS exit codes include severity values which  approximate
+       those defined by PKWARE, as shown in the following table:
+
+          VMS        UnZip
+        severity   err code   Error description
+       ----------+----------+----------------------------------------------
+        Success       0       Normal.  No errors or warnings detected.
+        Warning       1       One or more warnings were encountered, but
+                              processing completed successfully.  This
+                              includes archives where one or more (but not
+                              all) files were skipped because of an
+                              unsupported compression or encryption method,
+                              or a bad encryption password.
+        Error         2       Error in the archive format.  Processing may
+                              or may not have completed  successfully.
+        Fatal         3       Severe error in the archive format.
+                              Processing probably failed immediately.
+        Fatal         4       Memory allocation failed in program
+                              initialization.
+        Fatal         5       Memory  allocation or terminal I/O failed in
+                              password processing.
+        Fatal         6       Memory allocation failed while decompressing
+                              to disk.
+        Fatal         7       Memory allocation failed while decompressing
+                              in memory.
+        Fatal         8       Memory allocation failed.  (Currently not
+                              used.)
+        Error         9       Specified archive files were not found.
+        Error        10       Invalid command-line options or parameters.
+        Error        11       No matching files were found.
+        Fatal        50       Disk (file system) filled during extraction.
+        Fatal        51       Unexpected end-of-file while reading the
+                              archive.
+        Error        80       User interrupt (Ctrl/C).
+        Error        81       No files were processed, because of
+                              unsupported compression or encryption
+                              methods.
+        Error        82       No files were processed, because of bad
+                              encryption password(s).
+        Fatal        83       Large-file archive could not be processed by
+                              this small-file program.
+
+
+UNZIP
+
+  Bugs
+
+       Multi-part archives are not yet supported,  except  in  conjunction
+       with  Zip.   (All parts must be concatenated together in order, and
+       then "zip -F" (for Zip 2.x) or "zip -FF"  (for  Zip  3.x)  must  be
+       performed  on the concatenated archive in order to "fix" it.  Also,
+       zip 3.0 and later can combine multi-part (split)  archives  into  a
+       combined   single-file   archive   using   "zip  -s-  inarchive  -O
+       outarchive".  See the zip manual page for more  information.)  This
+       may be corrected in the next major release.
+
+       Archives read from standard input are  not  yet  supported,  except
+       with  UnZip  (and  then only the first member of the archive can be
+       extracted).
+
+       Archives  encrypted  with  8-bit-character   passwords   (such   as
+       passwords  with  accented  European characters) may not be portable
+       across    systems    and/or    other    archivers.     See     also
+       Encryption_Decryption.
+
+       UnZip's -M ("--more") option tries to take into  account  automatic
+       wrapping  of  long lines.  However, the code may fail to detect the
+       correct wrapping locations.  First,  TAB  characters  (and  similar
+       control  sequences) are not taken into account, they are handled as
+       ordinary printable characters.  Second,  depending  on  the  actual
+       system  type,  UnZip  may  not  detect  the  true terminal/emulator
+       geometry,  but  instead  may  rely  on  "commonly   used"   default
+       dimensions.   The  correct  handling  of  tabs  would  require  the
+       implementation of a query for the actual tab setup  on  the  output
+       terminal/emulator.
+
+       [Unix] Unix special files such as FIFO buffers (named pipes), block
+       devices  and  character  devices  are not restored even if they are
+       somehow represented in  the  archive,  nor  are  hard-linked  files
+       relinked.   Basically,  the  only  file types restored by UnZip are
+       regular files, directories, and symbolic (soft) links.
+
+       [OS/2]  Extended  attributes  for  existing  directories  are  only
+       updated  if  the  -o  ("--overwrite")  option  is given.  This is a
+       limitation of the operating system; because directories only have a
+       creation  time  associated with them, UnZip has no way to determine
+       whether the stored attributes are newer  or  older  than  those  on
+       disk.   In  practice this may mean a two-pass approach is required:
+       first   unpack   the   archive   normally    (with    or    without
+       freshening/updating   existing  files),  then  overwrite  just  the
+       directory entries (for example, "unzip -o foo */").
+
+
+UNZIP
+
+  URL
+
+       The Info-ZIP main Web page is:
+           http://www.info-zip.org/
+
+       FTP access is available, too:
+           ftp://ftp.info-zip.org/pub/infozip/
+
+
+UNZIP
+
+  ZipInfo_mode
+
+       When /ZIPINFO is specified,  the  program  runs  in  ZipInfo  mode.
+       Remaining  options  are  interpreted  as ZipInfo options.  If used,
+       /ZIPINFO must be the first qualifier on the command line.
+
+       ZipInfo reports detailed information about a ZIP  archive  and  its
+       members.   This  information  may  include file access permissions,
+       compression method, encryption method, version and operating system
+       (or  file  system) of the archive-creating program, and so on.  The
+       default behavior (with no options) is to show a  single-line  entry
+       for  each  member  in  the  archive,  with  a  header and a trailer
+       providing summary information for the entire archive.   The  format
+       is  a cross between Unix "ls -l" and "UNZIP /LIST /VERBOSE" output.
+       See Detailed_Description.  ZipInfo is the same  program  as  UnZip.
+       (On Unix, "zipinfo" may be a link to "unzip".  On VMS, "ZIPINFO" is
+       normally a DCL symbol defined  as  "''UNZIP'  /ZIPINFO".)  However,
+       ZipInfo support may have been disabled when UnZip was built.
+
+       Format:
+
+         ZIPINFO [/zipinfo_options] [file[.zip]] [member [,...]]
+
+         UNZIP /ZIPINFO [/zipinfo_options] [file[.zip]] [member [,...]]
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Command_Parameters
+
+       file[.zip]
+
+            File path/name of a ZIP archive.  A wildcard name may be used to
+            specify  multiple  ZIP  archives to be processed in one command.
+            On  VMS  systems,  any  of  the   standard   wildcards   for   a
+            directory/file  specification  may  be used:  "...", "*", or "%"
+            (or,  since  VMS  V7.2,  "?").    The   default   archive   file
+            specification is ".ZIP".
+
+            Note that a ".zip" or ".ZIP" file type on an archive is merely a
+            convention,  not  a requirement.  For example, a self-extracting
+            ZIP archive named "fred" or "fred.exe" could be processed as  if
+            it  were  an ordinary archive; just specify the actual file name
+            with its actual name ending (if any), whatever that may be.
+
+       member [,...]
+
+            An optional list of archive members to be  processed,  separated
+            by  commas.   If  no  member list is specified, then all archive
+            members are processed.  Unix-like ("globbing") wildcard patterns
+            may be used to match multiple members:
+
+                *       Matches a sequence of 0 or more characters.
+                ?       Matches exactly 1 character.
+                [...]   Matches any single character found inside the
+                        brackets.  Ranges are specified by a beginning
+                        character, a hyphen, and an ending character.  If an
+                        exclamation point ("!") or a caret ("^") follows the
+                        left bracket, then the range of characters within
+                        the brackets is complemented.  That is, anything
+                        except the characters inside the brackets is
+                        considered a match.  To specify a literal left
+                        bracket, use the three-character sequence "[[]".
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+         Qualifiers in this group  specify  the  primary  report  format  of
+         ZipInfo.   Only  one  of  these  primary  format  qualifiers may be
+         specified.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+      /LONG (-l)
+
+           Primary Format.  Show member info in  long  Unix  "ls  -l"  format.
+           Like the /MEDIUM format, except that the compressed size (in bytes)
+           is printed instead of the compression ratio.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+      /ONE_LINE (-2)
+
+           Primary Format.  Show member  names  only,  one  per  line.   Other
+           report elements are allowed, if requested explicitly using /HEADER,
+           /TOTALS, and/or /COMMENT.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+      /MEDIUM (-m)
+
+           Primary Format.  Show member info in  medium-length  Unix  "ls  -l"
+           format.   Like  the  /SHORT  format,  except  that  the compression
+           factor, expressed as a percentage, is also included.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+      /SHORT (-s)
+
+           Primary Format.  Show member info in short  Unix  "ls  -l"  format.
+           This  is  the  default  behavior,  unless  /HEADER  or  /TOTALS  is
+           specified.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Primary_Format
+
+      /VERBOSE (-v)
+
+           Primary Format.  The ZipInfo /VERBOSE report is very detailed,  and
+           mostly  self-explanatory,  but it does assume some familiarity with
+           the ZIP archive format.  It also includes the archive  comment,  if
+           any.   Extra  fields  in the central directory are broken down into
+           subfields, with brief interpretations of recognized  subfields  (or
+           abbreviated dumps of unrecognized subfields).
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Ordinary
+
+         Qualifiers in this group modify the operation or report  format  of
+         ZipInfo.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Ordinary
+
+      /COMMENT (-z)
+
+           Include the archive comments (if any) in the report.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Ordinary
+
+      /DECIMAL_TIME (-T)
+
+           Show   the   file   date-times   in   a   sortable,    all-numeric,
+           "YYYYMMDD.hhmmss"   format.    The   default   date  format  is  an
+           alpha-numeric "YY-Mmm-DD hh:mm".  For  example  ("/SHORT",  "/SHORT
+           /DECIMAL_TIME"):
+
+           -rw-a--     3.1 fat   211916 tx defX 10-Jun-18 00:27 zip31c/zip.c
+           -rw-a--     3.1 fat   211916 tx defX 20100618.002703 zip31c/zip.c
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Ordinary
+
+      /EXCLUDE (-x)
+
+           /EXCLUDE=(member [,...])
+           An optional list of archive members to be excluded from processing.
+           Because wildcard characters normally match "/" directory separators
+           (for exceptions see /WILD_SPAN (-W)), this option may  be  used  to
+           exclude any files that are in subdirectories.  For example,
+               UNZIP foo *.[ch] /EXCLUDE = */*
+           would extract all C source files (*.c, *.h) in the main  directory,
+           but none in any subdirectories.  Without the /EXCLUDE option, all C
+           source files  in  all  directories  within  the  archive  would  be
+           extracted.
+
+           Note that archive members are specified using the Unix-style  names
+           which are used in ZIP archives, not VMS-style names.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Qualifiers_Ordinary
+
+      /HEADER (-h)
+
+           Include a header in the  report,  showing  the  archive  name,  the
+           archive size (in bytes), and the number of members in the archive.
+
+           For the Unix-format reports (options /LONG, /MEDIUM,  /SHORT),  the
+           header is included by default, if no archive members are specified.
+           If /HEADER  is  specified  alone,  that  is,  without  one  of  the
+           Unix-format  options,  and  without  a  member  list, then only the
+           header lines will be put out.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    /MATCH (-C, -W)
+
+         /MATCH=(keyword, ...)
+
+         Specifies name-matching behavior for names in the member  list  and
+         the /EXCLUDE excluded-member list on the command line.
+
+         The optional keywords and values are:
+
+             CASE=BLIND          Name matching is case-insensitive.  (-C)
+             CASE=SENSITIVE      Name matching is case-sensitive.  (Default.)
+
+         By  default,  case-sensitive  matching  is  done.    For   example,
+         specifying   "makefile"   on  the  command  line  will  match  only
+         "makefile" in the archive, not "Makefile" or "MAKEFILE".   On  many
+         systems,   the   local   file   system   is   case-insensitive,  so
+         case-insensitive  name  matching  would  be  more  natural.    With
+         /MATCH=CASE=BLIND,  "makefile"  would match "makefile", "Makefile",
+         or "MAKEFILE".
+
+         /MATCH does not affect the search for the ZIP archive file(s),  nor
+         the matching of archive members to existing files on the extraction
+         path.  So, on a case-sensitive file system, UnZip will never try to
+         overwrite a file "FOO" when extracting a member named "foo"!
+
+         [WILD_STOP_AT_DIR] If the C macro WILD_STOP_AT_DIR  is  defined  at
+         build time, then an additional keyword is allowed:
+
+             NOWILD_MATCH_SLASH  Wildcards stop at directory slash.  (-W)
+             WILD_MATCH_SLASH    Wildcards match directory slash.  (Default.)
+
+         By default, the wildcard characters "?" (single-character wildcard)
+         and  "*" (multi-character wildcard) match any character in a member
+         path/name.     /MATCH=NOWILD_MATCH_SLASH    (-W)    modifies    the
+         pattern-matching  behavior  for  archive  members  so that both "?"
+         (single-character wildcard) and "*" (multi-character  wildcard)  do
+         not   match   the   directory   separator   character   "/".   (The
+         two-character sequence "**" acts as a multi-character wildcard that
+         includes  the  directory  separator in its matched characters.) For
+         example, with /MATCH=NOWILD_MATCH_SLASH:
+             "*.c"   matches "foo.c" but not "mydir/foo.c"
+             "**.c"  matches both "foo.c" and "mydir/foo.c"
+             "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c"
+             "??*/*" matches "ab/foo" and "abc/foo"
+                     but not "a/foo" or "a/b/foo"
+
+         This modified behavior is equivalent to the pattern matching  style
+         used  by  the  shells of some of \fIUnZip\fP's supported target OSs
+         (one example is Acorn RISC OS).  This option may not  be  available
+         on  systems  where  the  Zip archive's internal directory separator
+         character "/" is allowed as regular character in  native  operating
+         system filenames.
+
+         [non-VMS] (Currently, UnZip uses the same  pattern  matching  rules
+         for  both  wildcard  archive  file  name specifications and archive
+         member selection  patterns  on  most  system  types.   For  systems
+         allowing "/" as regular filename character, the -W option would not
+         work as expected on a wildcard file name specification.)
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    /MATCH (-C, -W)
+
+      /MEMBER_COUNTS (default) (-mc)
+
+           /NOMEMBER_COUNTS
+           Control inclusion of separate member counts for directories, files,
+           and  (if symlinks are supported) links, after the totals summary at
+           the end of  the  report.   By  default,  they  are  included.   Use
+           /NOMEMBER_COUNTS" to suppress them.  See also /TOTALS.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    /MATCH (-C, -W)
+
+      /PAGE (-M)
+
+           Pipe all output through an  internal  pager  similar  to  the  Unix
+           more(1) command.  At the end of a screenful of output, UnZip pauses
+           with a "--More--" prompt; the  next  screenful  may  be  viewed  by
+           pressing  the  Enter  (Return)  key or the space bar.  UnZip can be
+           terminated by pressing the  "Q"  key  and,  on  some  systems,  the
+           Enter/Return    key.     Unlike   Unix   more(1),   there   is   no
+           forward-searching  or  editing  capability.   Also,  UnZip  doesn't
+           notice  if  long  lines wrap at the edge of the screen, effectively
+           resulting in the printing of two or more lines and  the  likelihood
+           that  some  text will scroll off the top of the screen before being
+           viewed.  If the actual number of lines on the  screen  can  not  be
+           determined, 24 lines will be assumed.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    /MATCH (-C, -W)
+
+      /TOTALS (-t)
+
+           Include a totals summary at the end  of  the  report,  showing  the
+           number  of  members  in  the  report, the sum of their uncompressed
+           sizes, the sum of  their  compressed  sizes,  and  the  compression
+           factor as a percentage.
+
+           For the Unix-format reports (/LONG, /MEDIUM,  /SHORT),  the  totals
+           summary   is  included  by  default,  if  no  archive  members  are
+           specified.  If /TOTALS is specified alone, that is, without one  of
+           the  Unix-format  options, and without a member list, then only the
+           totals summary trailer lines will be put out.
+
+           The total "bytes compressed"  reported  includes  only  the  actual
+           data,  not  the  ZIP  archive meta-data, so the size of the archive
+           will always be greater than this value.
+
+           See also /MEMBER_COUNTS.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Detailed_Description
+
+         ZipInfo has three basic report formats, providing different degrees
+         of  detail  in  the information about the members of an archive:  a
+         simple list of names (/ONE_LINE (-1, -2)), a Unix ls-style  listing
+         (/LONG  (-l),  /MEDIUM  (-m),  /SHORT  (-s)),  and  a very detailed
+         analysis (/VERBOSE (-v)).  Some of the information,  such  as  file
+         sizes,  is  easy  to  interpret.   Some of the information involves
+         fairly obscure details  of  ZIP  archive  structure.   ZIP  archive
+         structure is documented in the PKWARE Inc.  APPNOTE.TXT:
+             http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+         The table below shows some typical /LONG report entries:
+
+         Perm/Prot  Zver Ofs UncSize At CmpSize Cmth  ModDate  Mtime Name
+         ----------+----+---+-------+--+-------+----+---------------+----------
+         -rw-a--     3.1 fat  211916 tx   53467 defX 10-Jun-18 00:27 zip3/zip.c
+         -rwxr-x---  3.1 unx     709 Tx     311 aesw 11-Aug-21 22:20 endian.c
+         RWED,RE,    3.1 vms    6656 bx    2295 defN 07-Aug-15 14:12 it/T.EXE;8
+
+         Field  1   (Perm/Prot)   shows   the   file   permission/protection
+         attributes, formatted according to the original operating system or
+         file system where the archive was created.
+
+         Field 2 (Zver) shows the (approximate) version of the  Zip  program
+         which created the archive.
+
+         Field 3 (Ofs) shows the original operating system where the archive
+         was  created,  or  the  file  system  on  which the member file was
+         stored.
+
+         Field 4 (UncSize) shows the original, uncompressed file size.
+
+         Field 5 (At) shows some archive member attributes, as  detailed  in
+         the tables below.  The first character indicates whether a file was
+         binary or text, and whether it was encrypted.  The second character
+         indicates  the  presence of a data descriptor and/or an extra field
+         in the member data.
+
+                       |   File Type     Extra Field |
+           First char  | binary  text      yes   no  |  Second char
+         --------------+-------+-----    ------+-----+--------------------
+         Encrypted  no |   b      t         x     -  | no  Data Descriptor
+                   yes |   B      T         X     l  | yes
+
+         A Data Descriptor holds CRC and size data at an alternate place  in
+         the archive (after processed member data instead of before), and is
+         normally used when the archiving program can't seek in  the  output
+         archive data/file.  An Extra Field can hold a wide variety of data,
+         including 64-bit file sizes, many kinds  of  OS-specific  attribute
+         data, UTC times, and so on.
+
+         Field 6 (CmpSize) shows the compressed file  size.   With  /MEDIUM,
+         this  field  shows  the compression fraction as a percentage.  With
+         /SHORT (the default), this field is omitted.  This compressed  size
+         value  (unlike the one in an "UNZIP /LIST" report) includes all the
+         overhead resulting from Traditional encryption.
+
+         Field 7 (Cmth) shows the compression method used.  Note that AES_WG
+         encryption is treated as a compression method here.  Not all of the
+         methods  shown  in  the  table  below  are  supported.   (Some  are
+         obsolete.)
+
+          Num Abbr  Name, description
+         ----+----+------------------------------------------------------------
+           0  stor  Store (no compression)
+           1  shrk  Shrink
+           2  re:1  Reduce (factor 1)
+           3  re:2  Reduce (factor 2)
+           4  re:3  Reduce (factor 3)
+           5  re:4  Reduce (factor 4)
+           6  i#:#  Implode (dictonary_size:Shannon-Fano_trees)
+           7  tokn  Tokenize
+           8  def#  Deflate (N: normal, X: maximum, F: fast, S: super-fast)
+           9  d64#  Deflate64 (N: normal, X: maximum, F: fast, S: super-fast)
+          10  dcli  PKWARE Data Compression Library Imploding - IBM TERSE (old)
+          12  bzp2  bzip2
+          14  lzma  LZMA
+          18  ters  IBM TERSE (new)
+          19  lz77  IBM LZ77 z Architecture (PFS)
+          96  jpeg  JPEG
+          97  wavp  WavPack
+          98  ppmd  PPMd version I, Rev 1
+          99  aesw  AES_WG encryption
+
+         Fields  8  and  9  (ModDate,  Mtime)  show  the  file  modification
+         date-time (MS-DOS format, local time).
+
+         Field 10 (Name) shows the file path/name.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Environment_Options
+
+         ZipInfo's default behavior may be modified  by  placing  Unix-style
+         command-line  options  in  an  environment  variable.  (The VMS CLI
+         translator acts only  on  the  command  line  itself,  not  on  the
+         environment variables.) This can be done with any option, but it is
+         probably most useful options like -T (/DECIMAL_TIME,  decimal  time
+         format) or one of the non-default Unix format options:  -l (/LONG),
+         -m (/MEDIUM).
+
+         For ZipInfo ("UNZIP /ZIPINFO", ZIPINFO), the  environment  variable
+         name on VMS is ZIPINFO_OPTS (non-VMS:  ZIPINFO).  For compatibility
+         with Zip, if ZIPINFO (ZIPINFO_OPTS on VMS)  is  not  defined,  then
+         ZipInfo will use ZIPINFOOPT the same way.
+
+         For example, to make  the  default  format  the  long  Unix  format
+         instead  of  the short Unix format, one could use commands like the
+         following (with quotation to preserve lower case in DCL):
+
+             define ZIPINFO_OPTS "-l"        ! Logical name, or
+             ZIPINFO_OPTS = "-l"             ! DCL symbol.  (Either works.)
+
+         Environment options are treated the same as  any  other  Unix-style
+         command-line  options,  except  that they are effectively the first
+         options on the command line.  Generally,  the  VMS  CLI  translator
+         will  override  an  environment option if an explicit corresponding
+         VMS-style qualifier is specified.
+
+         The examples show short (one-character) options,  but  long  ("--")
+         options are also allowed.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Examples
+
+         To get a basic, short-format listing of the complete contents of  a
+         ZIP archive zip31c.zip, with both header and totals lines, use only
+         the archive name as an argument to zipinfo:
+
+             zipinfo zip31c.zip
+             zipinfo zip31c
+
+         To produce a basic, long-format listing  (not  verbose),  including
+         header and totals lines, use /LONG:
+
+             zipinfo /long zip31c.zip
+
+         To list the complete contents of the  archive  without  header  and
+         totals  lines,  either negate the /HEADER and /TOTALS qualifiers or
+         else specify the contents explicitly:
+
+             zipinfo /noheader /nototals zip31c.zip
+             zipinfo zip31c.zip *
+
+         (On a Unix system, the wildcard member name would typically need to
+         be  quoted  to  keep a a Unix shell from expanding ("globbing") it.
+         This is not necessary on VMS.  However, a name with a  slash  ("/")
+         character,  such as "*/zip*.*", must be quoted.  Otherwise, DCL may
+         interpret the slash as introducing a qualifier, causing  unexpected
+         behavior or an "%CLI-W-IVQUAL, unrecognized qualifier" error.)
+
+         To list information on a single archive member, in  medium  format,
+         specify the member name explicitly:
+
+             zipinfo /medium unzip60.zip */unshrink.c
+
+         On a VMS system, one could use /DECIMAL_TIME along with an external
+         sorting  program  to  get  a  listing  of  files  in the archive in
+         date-time order:
+
+             pipe zipinfo /decimal_time /long /noheader /nototals zip31c.zip | -
+              sort sys$input sys$output /key = (position:47, size:15, descend)
+
+         For a /LONG (-l) format report, the date-time field should begin at
+         position  47; for /MEDIUM (-m), 42; for /SHORT (-s), 38.  HELP SORT
+         [/KEY] should lead to an explanation of the various  SORT  options.
+         (Unlike  Unix,  VMS  does  not  include  a  useful "head" or "tail"
+         program.)
+
+         On a Unix system, one  could  use  the  -T  option  along  with  an
+         external sorting program (and another filter like "head" or "tail")
+         to get a listing of the least or most recently  modified  files  in
+         the archive:
+
+             zipinfo -l -T -h- -t- zip31c.zip | sort -k 8 | head -12
+             zipinfo -l -T -h- -t- zip31c.zip | sort -r -k 8 | head -12
+
+         The "sort" option "-k 8" tells it to sort on field 8, which is  the
+         date-time  field  in  a  long-  or  medium-format  (-l, -m) ZipInfo
+         report.  (Use "-k 7" for the short  (-s)  format.)  The  -r  option
+         reverses the default smallest-to-largest sort order.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    Bugs
+
+         As with UnZip, ZipInfo's /PAGE (-M) option is overly simplistic  in
+         its  handling of screen output.  As noted above, it fails to detect
+         the wrapping of long lines and may thereby cause lines at  the  top
+         of the screen to be scrolled off before being read.  ZipInfo should
+         detect and treat each occurrence of  line-wrap  as  one  additional
+         line  printed.   This  requires  knowledge of the screen's width as
+         well as its height.  In addition, ZipInfo should  detect  the  true
+         screen geometry on all systems.
+
+         The interactions among the  various  listing  format,  header,  and
+         trailer  options  (/HEADER,  /LONG,  /MEDIUM,  /SHORT, /TOTALS) are
+         unnecessarily  complex  and  should  be  simplified,  despite   the
+         potential disruption to current users.
+
+
+UNZIP
+
+  ZipInfo_mode
+
+    URL
+
+         The Info-ZIP main Web page is:
+             http://www.info-zip.org/
+
+         FTP access is available, too:
+             ftp://ftp.info-zip.org/pub/infozip/
+
index 73aad80..3cf9c8e 100644 (file)
@@ -76,10 +76,10 @@ ARGUMENTS
 
               If  no  wildcard  matches  are  found, then the specification is
               assumed to be a literal filename.  If that also fails, then  the
-              suffix  ".zip"  and/or  ".ZIP"  is  appended, and that is tried.
-              (For this reason, if a non-existent file is specified, then  the
-              resulting error message may mention these other names with their
-              ".zip" or ".ZIP" suffixes.)
+              suffix  ".zip" and/or ".ZIP" is appended, and the resulting name
+              is tried.  (For this reason, if a non-existent  file  is  speci-
+              fied,  then  the resulting error message may mention these other
+              names with their ".zip" or ".ZIP" suffixes.)
 
               Note that a ".zip" or ".ZIP" name ending on an archive is merely
               a convention, not a requirement.  For example, a self-extracting
@@ -149,17 +149,17 @@ OPTIONS (Primary Mode)
        --freshen
               Primary Mode.  Freshen existing files.  That  is,  extract  only
               those  files  that already exist on disk and that are newer than
-              the disk copies.  By default UnZip queries  before  overwriting,
-              but  the  -o  option  may be used to suppress the queries.  Note
-              that on many operating systems, the  TZ  (timezone)  environment
-              variable  must  be  set  correctly in order for -f/--freshen and
-              -u/--update to work properly.  (On Unix the variable is  usually
-              set  automatically.)   The  reasons for this are somewhat subtle
-              but have to do with  the  differences  between  DOS-format  file
-              times (always local time) and Unix-format times (always UTC) and
-              the necessity to  compare  the  two.   A  typical  TZ  value  is
-              "PST8PDT"  (US  Pacific  time with automatic adjustment for Day-
-              light Saving Time).
+              the disk copies.  By default,  UnZip  queries  the  user  before
+              overwriting,  but  the  -o  option  may  be used to suppress the
+              queries.  Note that on many operating systems, the TZ (timezone)
+              environment   variable  must  be  set  correctly  in  order  for
+              -f/--freshen and -u/--update to work  properly.   (On  Unix  the
+              variable  is  usually  set automatically.)  The reasons for this
+              are somewhat subtle but have to do with the differences  between
+              DOS-format  file times (always local time) and Unix-format times
+              (always UTC) and the necessity to compare the two.  A typical TZ
+              value  is  "PST8PDT"  (US Pacific time with automatic adjustment
+              for Daylight Saving Time).
 
        -h
        --help
@@ -200,8 +200,8 @@ OPTIONS (Primary Mode)
 
               If a file was archived from a single-case file system (for exam-
               ple, the old MS-DOS FAT file  system)  and  the  -L  option  was
-              given,  the filename is converted to lowercase and is shown pre-
-              fixed with a caret (^).
+              given,  then the filename is converted to lowercase and is shown
+              prefixed with a caret (^).
 
               Note: If only -v (--verbose) is specified with an archive  name,
               then  UnZip  acts  as  if "-l -v" were specified, and a detailed
@@ -216,14 +216,14 @@ OPTIONS (Primary Mode)
               file  data for the members are sent to stdout (no file names, or
               other information, as would be displayed with -c), and the files
               are  always  extracted in binary format, just as they are stored
-              (no line-ending or ASCII-EBCDIC conversions).
+              (with no line-ending or ASCII-EBCDIC conversions).
 
        -T
        --timestamp-new
               Primary Mode.  Set the timestamp on the archive(s)  to  that  of
               the  newest  file  in  each  one.  This corresponds to Zip's -go
               option, except that it can be used  on  wildcard  archives  (for
-              example, "unzip -T '*.zip'") and is much faster.
+              example, "unzip -T '*.zip'") and may be faster.
 
        -t
        --test
@@ -304,8 +304,8 @@ OPTIONS (Ordinary)
 
        -A
        --api-help
-              [OS/2,  Unix  DLL] Print extended help for the DLL's application
-              programming interface (API).
+              [DLL,  object library] Print extended help for the DLL or object
+              library application programming interface (API).
 
        -a
        --ascii
@@ -336,7 +336,7 @@ OPTIONS (Ordinary)
 
        -B
        --backup
-              [when  built with UNIXBACKUP enabled] Save a backup copy of each
+              [When  built with UNIXBACKUP enabled] Save a backup copy of each
               overwritten file.  The backup file gets the name of  the  target
               file with a tilde and optionally a unique sequence number (up to
               5 digits) appended.  The sequence number  is  appended  whenever
@@ -1108,72 +1108,74 @@ ENCRYPTION/DECRYPTION
        Zip  and UnZip have long supported a relatively weak encryption method,
        which we call Traditional ZIP encryption.  The source code  for  Tradi-
        tional  encryption is included in the source kits, and support for Tra-
-       ditional encryption is  enabled  by  default.   (Build-time  C  macros:
-       IZ_CRYPT_TRAD, NO_CRYPT.)
-
-       Beginning  with  UnZip  version 6.1 and Zip version 3.1, these programs
-       also offer a stronger, Advanced Encryption  Standard  (AES)  encryption
-       method,  which  we  call  AES WinZip/Gladman (AES_WG) encryption.  (The
-       encryption code was supplied by Brian Gladman, and the  archive  format
-       is  intended  to  be  compatible  with that used by the WinZip program.
-       WinZip is a registered trademark of  WinZip  International  LLC.)   The
-       source code for AES_WG encryption is distributed in a separate kit (for
-       export control reasons), and support  for  AES_WG  encryption  must  be
-       enabled    explicitly    at   build   time.    (Build-time   C   macro:
-       IZ_CRYPT_AES_WG.)  See the INSTALL file in the source kit  for  details
-       on  how  to  enable  AES_WG  encryption  (or how to disable Traditional
-       encryption).
-
-       For details on the WinZip AES scheme, see:
+       ditional encryption is enabled by default.
+
+       The Info-ZIP programs UnZip (version 6.1 and later)  and  Zip  (version
+       3.1 and later)include optional support for Advanced Encryption Standard
+       (AES) encryption, a relatively strong encryption method.
+
+       The Info-ZIP AES implementation is based on the WinZip AES
+              specification, and uses AES encryption code  supplied  by  Brian
+              Gladman.  We refer to it as IZ_AES_WG (Info-ZIP AES WinZip/Glad-
+              man) or simply AES_WG.  (WinZip is  a  registered  trademark  of
+              WinZip  International  LLC.)  The source code for AES_WG encryp-
+              tion is included in the normal UnZip source kit, and support for
+              it will be enabled by default.
+
+       The WinZip AES scheme is described in:
               http://www.winzip.com/aes_info.htm
 
-       For information on the separate AES_WG source kit, see:
-              ftp://ftp.info-zip.org/pub/infozip/crypt/
+       For information on the IZ_AES_WG source code, see:
+              aes_wg/README_AES_WG.txt
+              or:
               ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
 
-       Normally, encryption passwords are supplied by the  user  interactively
-       when  requested  by the program.  See the -P option for a (less secure)
+       See the INSTALL file in the source kit for details on how to disable
+              AES_WG encryption (or how to disable Traditional encryption).
+
+       Normally,  encryption  passwords are supplied by the user interactively
+       when requested by the program.  See the -P option for a  (less  secure)
        method of specifying a password on the command line.
 
-       With Traditional  encryption,  when  decrypting,  a  password  will  be
+       With  Traditional  encryption,  when  decrypting,  a  password  will be
        checked against header data, and used if it appears to be correct.  The
-       correct password will always check out against  the  header  data,  but
-       there  is  a  1-in-256  chance that an incorrect password will as well.
+       correct  password  will  always  check out against the header data, but
+       there is a 1-in-256 chance that an incorrect  password  will  as  well.
        (This is a security feature of the PKWARE archive format; it helps pre-
        vent brute-force attacks that might otherwise gain a large speed advan-
-       tage by testing only the header.)  In the case that an incorrect  pass-
+       tage  by testing only the header.)  In the case that an incorrect pass-
        word is given but it passes the header test anyway, either an incorrect
-       CRC will be generated for the extracted data or else  UnZip  will  fail
+       CRC  will  be  generated for the extracted data or else UnZip will fail
        during the extraction because the "decrypted" bytes do not constitute a
        valid compressed data stream.
 
-       If the first password fails the header check on some file,  UnZip  will
-       prompt  for  another password, and so on until all files are extracted.
-       If a password is not known, entering a null password (that is,  just  a
-       carriage  return  or  "Enter") is taken as a signal to skip all further
+       If  the  first password fails the header check on some file, UnZip will
+       prompt for another password, and so on until all files  are  extracted.
+       If  a  password is not known, entering a null password (that is, just a
+       carriage return or "Enter") is taken as a signal to  skip  all  further
        prompting.  Only unencrypted files in the archive(s) will thereafter be
        extracted.  (The situation is actually a little more complicated.  Some
-       old versions of Zip and  ZipCloak  allowed  null  passwords,  so  UnZip
+       old  versions  of  Zip  and  ZipCloak  allowed null passwords, so UnZip
        checks each encrypted file to see if the null password works.  This may
        result in "false positives" and extraction errors, as noted above.)
 
-       Archives encrypted with 8-bit-character passwords (for  example,  pass-
-       words  with  accented  European  characters) may not be portable across
+       Archives  encrypted  with 8-bit-character passwords (for example, pass-
+       words with accented European characters) may  not  be  portable  across
        systems or to other archivers.  This problem stems from the use of mul-
-       tiple  encoding  methods  for  such  characters, including Latin-1 (ISO
+       tiple encoding methods for  such  characters,  including  Latin-1  (ISO
        8859-1) and OEM code page 850.  DOS PKZIP 2.04g uses the OEM code page;
        Windows PKZIP 2.50 uses Latin-1 (and is therefore incompatible with DOS
-       PKZIP); Info-ZIP uses the OEM code page on DOS, OS/2 and  Win3.x  ports
-       but  ISO  coding  (Latin-1 etc.) everywhere else; and Nico Mak's WinZip
-       6.x does not allow 8-bit-character passwords at  all.   UnZip  5.3  (or
+       PKZIP);  Info-ZIP  uses the OEM code page on DOS, OS/2 and Win3.x ports
+       but ISO coding (Latin-1 etc.) everywhere else; and  Nico  Mak's  WinZip
+       6.x  does  not  allow  8-bit-character passwords at all.  UnZip 5.3 (or
        newer) attempts to use the default character set first (e.g., Latin-1),
-       followed by the alternate one (e.g., OEM code page) to test  passwords.
-       On  EBCDIC  systems,  if  both  of  these fail, EBCDIC encoding will be
-       tested as a last resort.  (EBCDIC is not tested on non-EBCDIC  systems,
-       because  there  are no known archivers that encrypt using EBCDIC encod-
-       ing.)  ISO character encodings other than Latin-1  are  not  supported.
-       The  new addition of (partial) Unicode (UTF-8) support in UnZip 6.0 has
-       not yet been adapted to the encryption password handling in UnZip.   On
+       followed  by the alternate one (e.g., OEM code page) to test passwords.
+       On EBCDIC systems, if both of  these  fail,  EBCDIC  encoding  will  be
+       tested  as a last resort.  (EBCDIC is not tested on non-EBCDIC systems,
+       because there are no known archivers that encrypt using  EBCDIC  encod-
+       ing.)   ISO  character  encodings other than Latin-1 are not supported.
+       The new addition of (partial) Unicode (UTF-8) support in UnZip 6.0  has
+       not  yet been adapted to the encryption password handling in UnZip.  On
        systems that use UTF-8 as native character encoding, UnZip simply tries
        decryption  with  the  native  UTF-8  encoded  password;  the  built-in
        attempts to check the password in translated encoding have not yet been
@@ -1200,11 +1202,11 @@ EXAMPLES
 
            unzip -t -q "*.zip"
 
-       Here, the wildcard archive name was quoted to keep a  Unix  shell  from
+       Here,  the  wildcard  archive name was quoted to keep a Unix shell from
        expanding ("globbing") it.  (This would not be necessary on VMS.)
 
-       The  following  command extracts to standard output all members of let-
-       ters.zip whose names end in .tex, auto-converting to the local  end-of-
+       The following command extracts to standard output all members  of  let-
+       ters.zip  whose names end in .tex, auto-converting to the local end-of-
        line convention, and piping the output into more(1) (again, quoting the
        wildcard member name pattern):
 
@@ -1215,27 +1217,27 @@ EXAMPLES
 
            unzip -p articles paper1.dvi | dvips
 
-       To  extract  from  source.zip all Fortran and C source files (*.f, *.c,
-       *.h) and Makefile into the /tmp directory  (again,  quoting  the  wild-
+       To extract from source.zip all Fortran and C source  files  (*.f,  *.c,
+       *.h)  and  Makefile  into  the /tmp directory (again, quoting the wild-
        card):
 
            unzip source.zip "*.[fch]" Makefile -d /tmp
 
-       To  extract  all  FORTRAN  and  C source files, regardless of case (for
+       To extract all FORTRAN and C source  files,  regardless  of  case  (for
        example, both *.c and *.C, and any makefile, Makefile, MAKEFILE or sim-
        ilar):
 
            unzip -C source.zip "*.[fch]" makefile -d /tmp
 
        To extract any such files but convert any uppercase MS-DOS or VMS names
-       to lowercase and convert the line-endings of all of the  files  to  the
-       local  standard  (without  respect  to  any  files that might be marked
+       to  lowercase  and  convert the line-endings of all of the files to the
+       local standard (without respect to  any  files  that  might  be  marked
        "binary"):
 
            unzip -aa -C -L source.zip "*.[fch]" makefile -d /tmp
 
        The following command extracts only newer versions of the files already
-       in  the  current  directory,  without  querying.   (Note: Be careful of
+       in the current directory,  without  querying.   (Note:  Be  careful  of
        extracting in one timezone an archive created in another.  ZIP archives
        created by Zip versions before 2.1 contain no timezone information, and
        a "newer" file from an eastern timezone may, in fact, be older):
@@ -1243,18 +1245,18 @@ EXAMPLES
            unzip -f -o sources
 
        To extract newer versions of the files already in the current directory
-       and  to  create  any  files  not already there (same caveat as previous
+       and to create any files not already  there  (same  caveat  as  previous
        example):
 
            unzip -u -o sources
 
-       To display a configuration report showing the program version,  the  OS
-       and  compiler  used to build it, a list of optional features enabled at
+       To  display  a configuration report showing the program version, the OS
+       and compiler used to build it, a list of optional features  enabled  at
        build time, and the values of all the relevant environment variables:
 
            unzip -v
 
-       In the last five examples, assume that UNZIP or UNZIP_OPTS  is  set  to
+       In  the  last  five examples, assume that UNZIP or UNZIP_OPTS is set to
        -q.  To do a (singly) quiet listing:
 
            unzip -l file.zip
@@ -1263,7 +1265,7 @@ EXAMPLES
 
            unzip -l -q file.zip
 
-       (Note  that  the  ".zip" is generally not necessary.)  To do a standard
+       (Note that the ".zip" is generally not necessary.)  To  do  a  standard
        listing:
 
            unzip -l -q- file.zip
@@ -1278,21 +1280,21 @@ EXIT STATUS
 
               0      Normal.  No errors or warnings detected.
 
-              1      One  or  more  warnings  were encountered, but processing
+              1      One or more warnings  were  encountered,  but  processing
                      completed successfully.  This includes archives where one
-                     or  more  (but  not all) files were skipped because of an
-                     unsupported compression or encryption method,  or  a  bad
+                     or more (but not all) files were skipped  because  of  an
+                     unsupported  compression  or  encryption method, or a bad
                      encryption password.
 
-              2      Error  in  the archive format.  Processing may or may not
+              2      Error in the archive format.  Processing may or  may  not
                      have completed successfully.
 
-              3      Severe error in the archive format.  Processing  probably
+              3      Severe  error in the archive format.  Processing probably
                      failed immediately.
 
               4      Memory allocation failed in program initialization.
 
-              5      Memory  allocation  or  terminal I/O failed in encryption
+              5      Memory allocation or terminal I/O  failed  in  encryption
                      password processing.
 
               6      Memory allocation failed while decompressing to disk.
@@ -1313,63 +1315,63 @@ EXIT STATUS
 
               80     User interrupt (Ctrl/C or similar).
 
-              81     No files were processed, because of unsupported  compres-
+              81     No  files were processed, because of unsupported compres-
                      sion or encryption methods.
 
-              82     No  files were processed, because of bad encryption pass-
+              82     No files were processed, because of bad encryption  pass-
                      word(s).
 
-              83     Large-file archive could not be processed by this  small-
+              83     Large-file  archive could not be processed by this small-
                      file program.
 
-              84     Failed   to   create   automatic   extraction  directory.
+              84     Failed  to   create   automatic   extraction   directory.
                      (Already exists?)
 
-       [VMS] On VMS, the standard Unix exit status values are translated  into
-       valid  VMS  status codes.  For details, see the file [.vms]NOTES.TXT in
+       [VMS]  On VMS, the standard Unix exit status values are translated into
+       valid VMS status codes.  For details, see the file  [.vms]NOTES.TXT  in
        the source kit.
 
 BUGS
-       Multi-part archives are not yet supported, except in  conjunction  with
-       Zip.   (All  parts  must  be  concatenated  together in order, and then
-       "zip -F" (for Zip 2.x) or "zip -FF" (for Zip 3.x) must be performed  on
-       the  concatenated  archive in order to "fix" it.  Also, zip version 3.0
-       and later can combine multi-part (split) archives into a combined  sin-
-       gle-file  archive using "zip -s- inarchive -O outarchive".  See the zip
-       manual page for more information.)  This may be corrected in  the  next
+       Multi-part  archives  are not yet supported, except in conjunction with
+       Zip.  (All parts must be  concatenated  together  in  order,  and  then
+       "zip -F"  (for Zip 2.x) or "zip -FF" (for Zip 3.x) must be performed on
+       the concatenated archive in order to "fix" it.  Also, zip  version  3.0
+       and  later can combine multi-part (split) archives into a combined sin-
+       gle-file archive using "zip -s- inarchive -O outarchive".  See the  zip
+       manual  page  for more information.)  This may be corrected in the next
        major release.
 
-       Archives  read  from  standard input are not yet supported, except with
+       Archives read from standard input are not yet  supported,  except  with
        fUnZip  (and  then  only  the  first  member  of  the  archive  can  be
        extracted).
 
-       Archives  encrypted  with  8-bit-character passwords (such as passwords
-       with accented European characters) may not be portable  across  systems
+       Archives encrypted with 8-bit-character passwords  (such  as  passwords
+       with  accented  European characters) may not be portable across systems
        and/or other archivers.  See also ENCRYPTION/DECRYPTION.
 
        UnZip's -M ("--more") option tries to take into account automatic wrap-
-       ping of long lines.  However, the code may fail to detect  the  correct
-       wrapping   locations.   First,  TAB  characters  (and  similar  control
-       sequences) are not taken into account, they  are  handled  as  ordinary
-       printable  characters.   Second,  depending  on the actual system type,
-       UnZip may not detect the true terminal/emulator geometry,  but  instead
-       may  rely  on "commonly used" default dimensions.  The correct handling
-       of tabs would require the implementation of a query for the actual  tab
+       ping  of  long lines.  However, the code may fail to detect the correct
+       wrapping  locations.   First,  TAB  characters  (and  similar   control
+       sequences)  are  not  taken  into account, they are handled as ordinary
+       printable characters.  Second, depending on  the  actual  system  type,
+       UnZip  may  not detect the true terminal/emulator geometry, but instead
+       may rely on "commonly used" default dimensions.  The  correct  handling
+       of  tabs would require the implementation of a query for the actual tab
        setup on the output terminal/emulator.
 
-       [Unix]  Unix  special  files  such as FIFO buffers (named pipes), block
+       [Unix] Unix special files such as FIFO  buffers  (named  pipes),  block
        devices and character devices are not restored even if they are somehow
-       represented  in the archive, nor are hard-linked files relinked.  Basi-
-       cally, the only file types restored by UnZip are regular files,  direc-
+       represented in the archive, nor are hard-linked files relinked.   Basi-
+       cally,  the only file types restored by UnZip are regular files, direc-
        tories, and symbolic (soft) links.
 
        [OS/2] Extended attributes for existing directories are only updated if
-       the -o ("overwrite all") option is given.  This is a limitation of  the
+       the  -o ("overwrite all") option is given.  This is a limitation of the
        operating system; because directories only have a creation time associ-
-       ated with them, UnZip has  no  way  to  determine  whether  the  stored
+       ated  with  them,  UnZip  has  no  way  to determine whether the stored
        attributes are newer or older than those on disk.  In practice this may
-       mean a two-pass approach is required:  first unpack  the  archive  nor-
-       mally  (with or without freshening/updating existing files), then over-
+       mean  a  two-pass  approach is required:  first unpack the archive nor-
+       mally (with or without freshening/updating existing files), then  over-
        write just the directory entries (for example, "unzip -o foo */").
 
 SEE ALSO
@@ -1384,31 +1386,31 @@ URL
                   ftp://ftp.info-zip.org/pub/infozip/
 
 AUTHORS
-       The primary Info-ZIP authors (current semi-active members of  the  Zip-
+       The  primary  Info-ZIP authors (current semi-active members of the Zip-
        Bugs workgroup) are:  Ed Gordon (Zip, general maintenance, shared code,
-       Zip64, Win32, Unix,  Unicode);  Christian  Spieler  (UnZip  maintenance
-       coordination,  VMS,  MS-DOS,  Win32, shared code, general Zip and UnZip
-       integration and optimization); Onno van der Linden  (Zip);  Mike  White
-       (Win32,  Windows  GUI,  Windows  DLLs);  Kai  Uwe Rommel (OS/2, Win32);
-       Steven M. Schweda (VMS, Unix, support of new  features);  Paul  Kienitz
-       (Amiga,  Win32,  Unicode);  Chris Herborth (BeOS, QNX, Atari); Jonathan
-       Hudson (SMS/QDOS); Sergio Monesi (Acorn RISC OS); Harald Denker (Atari,
-       MVS);  John  Bush  (Solaris, Amiga); Hunter Goatley (VMS, Info-ZIP Site
-       maintenance); Steve Salisbury (Win32); Steve Miller (Windows  CE  GUI),
-       Johnny Lee (MS-DOS, Win32, Zip64); and Dave Smith (Tandem NSK).
-
-       The  following  people  are  former members of the Info-ZIP development
-       group, and provided major contributions to key  parts  of  the  current
-       code:  Greg  "Cave Newt" Roelofs (UnZip, unshrink decompression); Jean-
-       loup Gailly (deflate compression); Mark Adler  (inflate  decompression,
+       Zip64,  Win32,  Unix,  Unicode); Christian Spieler (VMS, MS-DOS, Win32,
+       shared code, general Zip and UnZip integration and optimization);  Onno
+       van  der  Linden  (Zip); Mike White (Win32, Windows GUI, Windows DLLs);
+       Kai Uwe Rommel (OS/2, Win32); Steven  M.  Schweda  (UnZip  maintenance,
+       VMS,  Unix,  support of new features); Paul Kienitz (Amiga, Win32, Uni-
+       code); Chris Herborth (BeOS, QNX, Atari); Jonathan  Hudson  (SMS/QDOS);
+       Sergio  Monesi  (Acorn  RISC OS); Harald Denker (Atari, MVS); John Bush
+       (Solaris, Amiga); Hunter Goatley (VMS,  Info-ZIP  server  maintenance);
+       Steve Salisbury (Win32); Steve Miller (Windows CE GUI), Johnny Lee (MS-
+       DOS, Win32, Zip64); and Dave Smith (Tandem NSK).
+
+       The following people are former members  of  the  Info-ZIP  development
+       group,  and  provided  major  contributions to key parts of the current
+       code: Greg "Cave Newt" Roelofs (UnZip, unshrink  decompression);  Jean-
+       loup  Gailly  (deflate compression); Mark Adler (inflate decompression,
        fUnZip).
 
-       The  author  of the original unzip code upon which Info-ZIP's was based
-       is Samuel H. Smith; Carl Mascott did the first Unix port; and David  P.
-       Kirschbaum  organized  and  led  Info-ZIP  in its early days with Keith
-       Petersen hosting the original mailing list at WSMR-SimTel20.  The  full
-       list  of  contributors  to UnZip has grown quite large; please refer to
+       The author of the original unzip code upon which Info-ZIP's  was  based
+       is  Samuel H. Smith; Carl Mascott did the first Unix port; and David P.
+       Kirschbaum organized and led Info-ZIP in  its  early  days  with  Keith
+       Petersen  hosting the original mailing list at WSMR-SimTel20.  The full
+       list of contributors to UnZip has grown quite large;  please  refer  to
        the proginfo/CONTRIBS file in the UnZip source distribution for a rela-
        tively complete version.
 
-Info-ZIP                      17 Apr 2015 (v6.1)                     UNZIP(1L)
+Info-ZIP                       2016-09-29 (v6.1)                     UNZIP(1L)
index 504f9bc..3c64fe1 100644 (file)
--- a/ebcdic.h
+++ b/ebcdic.h
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 0a4e3cb..194ac8b 100644 (file)
--- a/envargs.c
+++ b/envargs.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index d7d8fce..09e07ed 100644 (file)
--- a/explode.c
+++ b/explode.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2007-Mar-04 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4a5e8cd..71b595c 100644 (file)
--- a/extract.c
+++ b/extract.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -182,10 +182,10 @@ static ZCONST char Far ComprMsgNum[] =
 static ZCONST char Far FilNamMsg[] =
   "%s:  bad filename length (%s)\n";
 #ifndef SFX
-   static ZCONST char Far WarnNoMemCFName[] =
    "%s:  warning, no memory for comparison with local header\n";
-   static ZCONST char Far LvsCFNamMsg[] =
    "%s:  mismatching \"local\" filename (%s),\n\
+static ZCONST char Far WarnNoMemCFName[] =
+ "%s:  warning, no memory for comparison with local header\n";
+static ZCONST char Far LvsCFNamMsg[] =
+ "%s:  mismatching \"local\" filename (%s),\n\
          continuing with \"central\" filename version\n";
 #endif /* ndef SFX */
 #if !defined(SFX) && defined(UNICODE_SUPPORT)
@@ -293,8 +293,6 @@ static ZCONST char Far AplDblNameTooLong[] =
      "error:  invalid response [%s]\n";
 #endif /* ndef WINDLL */
 
-static ZCONST char Far ErrorUnexpectedEOF[] =
-  "error:  Unexpected end-of-file reading %s.\n";
 static ZCONST char Far ErrorInArchive[] =
   "At least one %serror %swas detected in %s.\n";
 static ZCONST char Far ZeroFilesTested[] =
@@ -2223,7 +2221,7 @@ static int extract_test_trailer(__G__ n_fil, n_bad_pwd, n_skip, err_in_arch)
 
 void action_msg( __G__ action, flag)
   __GDEF
-  char *action;
+  ZCONST char *action;
   int flag;                             /* 0: Name only; 1: Name + [type]. */
 {
   char *str1;
@@ -3341,28 +3339,11 @@ startover:
      * SFX, because we assume that our Zip doesn't do it.
      */
 #ifndef SFX
-    if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/'))
+    error = backslash_slash( __G);
+    if (error != PK_OK)
     {
-      char *p = G.filename;
-
-      if (*p)
-      {
-        do
-        {
-          if (*p == '\\')
-          {
-            if (!G.reported_backslash)
-            {
-              Info(slide, 0x21, ((char *)slide,
-               LoadFarString(BackslashPathSep), G.zipfn));
-              G.reported_backslash = TRUE;
-              if (*perr_in_arch == PK_OK)
-                *perr_in_arch = PK_WARN;
-            }
-            *p = '/';
-          }
-        } while (*PREINCSTR(p));
-      }
+      if (*perr_in_arch == PK_OK)
+        *perr_in_arch = error;
     }
 #endif /* ndef SFX */
 
@@ -3577,28 +3558,11 @@ startover:
      * SFX, because we assume that our Zip doesn't do it.
      */
 #ifndef SFX
-    if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/'))
+    error = backslash_slash( __G);
+    if (error != PK_OK)
     {
-      char *p = G.filename;
-
-      if (*p)
-      {
-        do
-        {
-          if (*p == '\\')
-          {
-            if (!G.reported_backslash)
-            {
-              Info(slide, 0x21, ((char *)slide,
-               LoadFarString(BackslashPathSep), G.zipfn));
-              G.reported_backslash = TRUE;
-              if (*perr_in_arch == PK_OK)
-                *perr_in_arch = PK_WARN;
-            }
-            *p = '/';
-          }
-        } while (*PREINCSTR(p));
-      }
+      if (*perr_in_arch == PK_OK)
+        *perr_in_arch = error;
     }
 #endif /* ndef SFX */
 
@@ -5430,6 +5394,7 @@ int extract_or_test_files(__G)    /* return PK-type error code */
     zuvl_t sgmnt_nr;
     zipfd_t zipfd;
 #ifndef SFX
+    long enddigsig_len;
     int no_endsig_found;
 #endif
     int do_this_file;
@@ -5511,6 +5476,7 @@ int extract_or_test_files(__G)    /* return PK-type error code */
 
     members_processed = 0;
 #ifndef SFX
+    enddigsig_len = -1;
     no_endsig_found = FALSE;
 #endif
     reached_end = FALSE;
@@ -5537,11 +5503,32 @@ int extract_or_test_files(__G)    /* return PK-type error code */
 
             if (readbuf(__G__ G.sig, 4) == 0) {
                 Info(slide, 0x221, ((char *)slide,
-                 LoadFarString( ErrorUnexpectedEOF), G.zipfn));
+                 LoadFarString( ErrorUnexpectedEOF), 1, G.zipfn));
                 error_in_archive = PK_EOF;
                 reached_end = TRUE;     /* ...so no more left to do */
                 break;
             }
+
+            if (memcmp( G.sig, central_digsig_sig, 4) == 0)
+            { /* Central directory digital signature.  Record its
+               * existence (unless SFX).  Read (and, for now, ignore)
+               * the data.
+               */
+#ifdef SFX
+# define ENDDIGSIGLENPTR NULL
+#else
+# define ENDDIGSIGLENPTR &enddigsig_len
+#endif /* def SFX [else] */
+
+              error = process_cdir_digsig( __G__ ENDDIGSIGLENPTR);
+              if (error != PK_OK)
+              {
+                error_in_archive = error;
+                reached_end = TRUE;    /* Actual EOF or no mem. */
+                break;
+              }
+            } /* process_cdir_digsig() should have read the next sig. */
+
             if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a new entry? */
                 /* no new central directory entry
                  * -> is the number of processed entries compatible with the
@@ -5554,13 +5541,11 @@ int extract_or_test_files(__G)    /* return PK-type error code */
                     /* yes, so look if we ARE back at the end_central record
                      */
                     no_endsig_found =
-                      ( (memcmp(G.sig,
-                                (G.ecrec.have_ecr64 ?
-                                 end_central64_sig : end_central_sig),
-                                4) != 0)
-                       && (!G.ecrec.is_zip64_archive)
-                       && (memcmp(G.sig, end_central_sig, 4) != 0)
-                      );
+                     ((memcmp( G.sig,
+                     (G.ecrec.have_ecr64 ?
+                     end_central64_sig : end_central_sig), 4) != 0) &&
+                     (!G.ecrec.is_zip64_archive) &&
+                     (memcmp( G.sig, end_central_sig, 4) != 0));
 #endif /* ndef SFX */
                 } else {
                     /* no; we have found an error in the central directory
@@ -5762,7 +5747,7 @@ int extract_or_test_files(__G)    /* return PK-type error code */
         else
         {
             Info(slide, 0x221, ((char *)slide,
-             LoadFarString( ErrorUnexpectedEOF), G.zipfn));
+             LoadFarString( ErrorUnexpectedEOF), 11, G.zipfn));
             error_in_archive = PK_EOF;
             reached_end = TRUE;     /* ...so no more left to do */
             break;
@@ -5835,6 +5820,16 @@ int extract_or_test_files(__G)    /* return PK-type error code */
         if (!error_in_archive)       /* don't overwrite stronger error */
             error_in_archive = PK_WARN;
     }
+
+    if (enddigsig_len >= 0)
+    {
+      Info( slide, 0x401, ((char *)slide, LoadFarString( DigSigMsg),
+       enddigsig_len));
+# if 0   /* Enable to make this a warning. */
+      if (error_in_archive < PK_WARN)           /* Keep more severe error. */
+        error_in_archive = PK_WARN;
+# endif /* 0 */
+    }
 #endif /* ndef SFX */
 
     error_in_archive = extract_test_trailer( __G__ filnum,
index bab6c3f..a001dd4 100644 (file)
--- a/fileio.c
+++ b/fileio.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -890,7 +890,7 @@ void defer_leftover_input(__G)
 
 unsigned readbuf(__G__ buf, size)   /* return number of bytes read into buf */
     __GDEF
-    char *buf;
+    uch *buf;
     register unsigned size;
 {
     register unsigned count;
@@ -903,7 +903,7 @@ unsigned readbuf(__G__ buf, size)   /* return number of bytes read into buf */
         {
             if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
             {
-              /* read() got no data.  If the srchive is segmented, then
+              /* read() got no data.  If the archive is segmented, then
                * try again with the next segment file.
                */
               /*if(fd_is_valid(G.zipfd_sgmnt)) {*/
@@ -961,7 +961,7 @@ int readbyte(__G)   /* refill inbuf and return a byte if available, else EOF */
     {
         if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
         {
-            /* read() got no data.  If the srchive is segmented, then
+            /* read() got no data.  If the archive is segmented, then
              * try again with the next segment file.
              */
             /* if(fd_is_valid(G.zipfd_sgmnt)) { */
@@ -1154,10 +1154,10 @@ int seek_zipf(__G__ abs_offset)
     }
     /* Get the new segment size, and calculate the new offset. */
 #ifdef USE_STRM_INPUT
-    zfseeko(G.zipfd, 0, SEEK_END);
+    zfseeko(G.zipfd, (zoff_t)0, SEEK_END);
     request += zftello(G.zipfd);
 #else /* def USE_STRM_INPUT */
-    request += zlseek(G.zipfd, 0, SEEK_END);
+    request += zlseek(G.zipfd, (zoff_t)0, SEEK_END);
 #endif /* USE_STRM_INPUT */
 
     /* now it should be always -1
@@ -2378,7 +2378,7 @@ void UZ_EXP UzpMorePause(pG, prompt, flag)
 
 
 
-#ifndef WINDLL
+#if !defined( WINDLL) && !defined( DLL)
 
 /**************************/
 /* Function UzpPassword() */
@@ -2437,12 +2437,8 @@ int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, efn)
 
 } /* end function UzpPassword() */
 
-#endif /* ndef WINDLL */
-
-
 
 
-#if !defined( WINDLL) && !defined( DLL)
 
 /**********************/
 /* Function handler() */
@@ -2990,7 +2986,7 @@ int do_string(__G__ length, option)   /* return PK-type error code */
         comment_bytes_left = length;
         if (length >= 10)
         {
-            block_len = readbuf(__G__ (char *)G.outbuf, 10);
+            block_len = readbuf(__G__ G.outbuf, 10);
             if (block_len == 0)
                 return PK_EOF;
             comment_bytes_left -= block_len;
@@ -3048,7 +3044,7 @@ int do_string(__G__ length, option)   /* return PK-type error code */
             register uch *p = G.outbuf;
             register uch *q = G.outbuf;
 
-            if ((block_len = readbuf(__G__ (char *)G.outbuf,
+            if ((block_len = readbuf(__G__ G.outbuf,
                    IZ_MIN((unsigned)OUTBUFSIZ, comment_bytes_left))) == 0)
                 return PK_EOF;
             comment_bytes_left -= block_len;
@@ -3202,7 +3198,7 @@ int do_string(__G__ length, option)   /* return PK-type error code */
         } else
             /* no excess size */
             block_len = 0;
-        if (readbuf(__G__ G.filename, length) == 0)
+        if (readbuf(__G__ (uch *)G.filename, length) == 0)
             return PK_EOF;
         G.filename[length] = '\0';      /* terminate w/zero:  ASCIIZ */
 #endif /* def UNICODE_SUPPORT [else] */
@@ -3303,7 +3299,7 @@ int do_string(__G__ length, option)   /* return PK-type error code */
              */
             unsigned int len_rb;
 
-            if ((len_rb = readbuf(__G__ (char *)G.extra_field, length)) == 0)
+            if ((len_rb = readbuf(__G__ G.extra_field, length)) == 0)
                 return PK_EOF;
             if (len_rb < length)
             {
@@ -3530,7 +3526,7 @@ char *name_only( path)
     }
 # endif /* def WIN32 */
 
-    dot = strchr( name, '.');
+    dot = strrchr( name, '.');
     if (dot == NULL)
     {
         len = strlen( name);    /* No dot found. */
index 6bb910f..343d71a 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index f3169fc..31a48d2 100644 (file)
--- a/gbloffs.c
+++ b/gbloffs.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 128ebc2..9bc0f98 100644 (file)
--- a/globals.c
+++ b/globals.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2003-May-08 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
 #include "unzip.h"
 
 #ifndef FUNZIP
-/* initialization of sigs is completed at runtime so unzip(sfx) executable
- * won't look like a zipfile
+/* Initialization of sigs is completed ("PK" inserted) at runtime so
+ * that a program executable won't look like a zip archive.
  */
-char central_hdr_sig[4]   = {0, 0, 0x01, 0x02};
-char local_hdr_sig[4]     = {0, 0, 0x03, 0x04};
-char end_central_sig[4]   = {0, 0, 0x05, 0x06};
-char end_central64_sig[4] = {0, 0, 0x06, 0x06};
-char end_centloc64_sig[4] = {0, 0, 0x06, 0x07};
-/* extern char extd_local_sig[4] = {0, 0, 0x07, 0x08};  NOT USED YET */
+uch central_digsig_sig[ 4]      = { 0, 0, 0x05, 0x05 };
+uch central_hdr_sig[ 4]         = { 0, 0, 0x01, 0x02 };
+uch end_central_sig[ 4]         = { 0, 0, 0x05, 0x06 };
+uch end_central64_sig[ 4]       = { 0, 0, 0x06, 0x06 };
+uch end_centloc64_sig[ 4]       = { 0, 0, 0x06, 0x07 };
+/* uch extd_local_sig[ 4]          = { 0, 0, 0x07, 0x08 }; */ /* NOT USED YET */
+uch local_hdr_sig[ 4]           = { 0, 0, 0x03, 0x04 };
 #endif /* ndef FUNZIP */
 
 
-#ifndef REENTRANT
-   Uz_Globs G;
-#else /* REENTRANT */
-
-#  ifndef USETHREADID
-     Uz_Globs *GG;
-#  else /* USETHREADID */
+# ifdef REENTRANT
+#  ifdef USETHREADID
 #    define THREADID_ENTRIES  0x40
 
      int lastScan;
@@ -149,8 +145,12 @@ Uz_Globs *getGlobalPointer()
     return threadPtrTable[scan];
 }
 
-#  endif /* ?USETHREADID */
-#endif /* ?REENTRANT */
+#  else /* def USETHREADID */
+     Uz_Globs *GG;
+#  endif /* def USETHREADID [else] */
+# else /* def REENTRANT */
+   Uz_Globs G;
+#endif /* def REENTRANT [else] */
 
 
 
@@ -167,20 +167,27 @@ Uz_Globs *globalsCtor()
 
     memzero(&G, sizeof(Uz_Globs));
 
+    /* Program version string for unzip.c:UzpVersionStr(). */
+    *G.prog_vers_str = '\0';
+
+    /* Command-line option processing. */
+    G.permute_opts_args = 1;    /* !0: Return "-" options first. */
+    G.dashdash_ends_opts = 1;   /* !0: "--" ends options. */
+
 #ifndef FUNZIP
-#ifdef CMS_MVS
+# ifdef CMS_MVS
     uO.aflag=1;
     uO.C_flag=1;
-#endif
-#ifdef TANDEM
+# endif
+# ifdef TANDEM
     uO.aflag=1;     /* default to '-a' auto create Text Files as type 101 */
-#endif
-#if (!defined(NO_TIMESTAMPS))
+# endif
+# if (!defined(NO_TIMESTAMPS))
     uO.D_flag = 1;  /* Default to '-D', no restoration of dir timestamps. */
-#endif
-#ifdef VMS
+# endif
+# ifdef VMS
     G.echo_orig = -1;   /* Original terminal echo state (-1: unknown). */
-#endif
+# endif
 
     uO.lflag=(-1);
     G.wildzipfn = "";
@@ -189,23 +196,31 @@ Uz_Globs *globalsCtor()
 
     G.message = UzpMessagePrnt;
     G.input = UzpInput;           /* not used by anyone at the moment... */
-#if defined(WINDLL) || defined(MACOS) || defined( DLL)
+# if defined(WINDLL) || defined(MACOS) || defined( DLL)
     G.mpause = NULL;              /* has scrollbars:  no need for pausing */
-#else
+# else
     G.mpause = UzpMorePause;
-#endif
+# endif
+# if !defined( DLL)
     G.decr_passwd = UzpPassword;
+# endif /* !defined( DLL) */
     G.zipfn_sgmnt = NULL;               /* Archive segment name */
     G.zipfn_sgmnt_size = 0;             /* Archive segment size */
     G.zipfd_sgmnt = ZIPFD_INVALID;      /* Archive segment file descr/pntr */
-#endif /* !FUNZIP */
+
+# ifdef ENABLE_USER_PROGRESS
+    /* User-progress messages. */
+    G.u_p_not_first = 0;                /* First time flag. */
+    G.u_p_nodename[ 0] = '\0';          /* "host::tty". */
+# endif /* def ENABLE_USER_PROGRESS */
+#endif /* ndef FUNZIP */
 
     G.query_fp = stdin;         /* Change to terminal if streaming archive. */
 
 #if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
-#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
+# if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
     G.echofd = -1;
-#endif /* !(MACOS || ATARI || VMS) */
+# endif /* !(MACOS || ATARI || VMS) */
 #endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
 
 #ifdef SYSTEM_SPECIFIC_CTOR
@@ -213,11 +228,11 @@ Uz_Globs *globalsCtor()
 #endif
 
 #ifdef REENTRANT
-#ifdef USETHREADID
+# ifdef USETHREADID
     registerGlobalPointer(__G);
-#else
+# else
     GG = &G;
-#endif /* ?USETHREADID */
+# endif /* ?USETHREADID */
 #endif /* REENTRANT */
 
     return &G;
index 3c38b3c..7130d06 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -195,9 +195,16 @@ typedef struct Globals {
     zvoid *callerglobs; /* pointer to structure of pass-through global vars */
 # endif
 
+    /* Program version string for unzip.c:UzpVersionStr(). */
+    char prog_vers_str[ 32];
+
     /* command options of general use */
     UzpOpts UzO;        /* command options of general use */
 
+    /* Option processing. */
+    int permute_opts_args;      /* !0: Return "-" options first. */
+    int dashdash_ends_opts;     /* !0: "--" ends options. */
+
 # ifndef FUNZIP
     /* command options specific to the high level command line interface */
 #  ifdef MORE
@@ -273,7 +280,7 @@ typedef struct Globals {
 
     char **pfnames;
     char **pxnames;
-    char sig[4];
+    uch sig[4];
     char answerbuf[10];
     min_info info[DIR_BLKSIZ];
     min_info *pInfo;
@@ -499,6 +506,8 @@ typedef struct Globals {
 
 #  ifdef ENABLE_USER_PROGRESS
     ZCONST char *action_msg_str;        /* Mthd str used with ActionMsg[]. */
+    int u_p_not_first;                          /* First time flag. */
+    char u_p_nodename[ U_P_NODENAME_LEN+ 1];    /* "host::tty". */
 #  endif /* def ENABLE_USER_PROGRESS */
 
 # endif /* ndef FUNZIP */
@@ -518,16 +527,17 @@ typedef struct Globals {
 
 Uz_Globs *globalsCtor   OF((void));
 
-/* pseudo constant sigs; they are initialized at runtime so unzip executable
- * won't look like a zipfile
+/* Pseudo-constant sigs.  They are partially initialized at runtime, so
+ * that a program executable won't look like a zip archive.  See
+ * globals.c and process.c:process_zipfiles().
  */
-extern char local_hdr_sig[4];
-extern char central_hdr_sig[4];
-extern char end_central_sig[4];
-extern char end_central32_sig[4];
-extern char end_central64_sig[4];
-extern char end_centloc64_sig[4];
-/* extern char extd_local_sig[4];  NOT USED YET */
+extern uch central_digsig_sig[ 4];
+extern uch central_hdr_sig[ 4];
+extern uch end_centloc64_sig[ 4];
+extern uch end_central_sig[ 4];
+extern uch end_central64_sig[ 4];
+/* extern uch extd_local_sig[ 4]; */   /* NOT USED YET */
+extern uch local_hdr_sig[ 4];
 
 # ifdef REENTRANT
 #  define G                   (*(Uz_Globs *)pG)
index 9ce78d8..60792fd 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index de1f24c..48503be 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in unzip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9ce48af..c6f0ece 100644 (file)
--- a/inflate.h
+++ b/inflate.h
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 13c7f60..0e4e130 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
 #include <string.h>
 
 
+/* Ask the MS VS linker to search for the unzip and bzip2 libraries. */
+#ifdef WIN32
+# pragma comment( lib, "unzip32")
+# pragma comment( lib, "libbz2")
+#endif
+
+
 #ifdef MY_PW
 # define UZP_PW MyUzpPassword
 /*
diff --git a/list.c b/list.c
index 5e501c5..7d536f9 100644 (file)
--- a/list.c
+++ b/list.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -93,7 +93,10 @@ static ZCONST char Far ShortFileTrailer[] =
 int list_files(__G)     /* return PK-type error code */
     __GDEF
 {
-    int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
+    int do_this_file = FALSE;
+    int cfactor;
+    int error;
+    int error_in_archive = PK_COOL;
 #ifndef WINDLL
     char sgn, cfactorstr[12];
     int longhdr=(uO.vflag>1);
@@ -113,6 +116,7 @@ int list_files(__G)     /* return PK-type error code */
     ulg ea_size, tot_easize=0L, tot_eafiles=0L;
     ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
 #endif
+    long enddigsig_len;
     min_info info;
     char methbuf[8];
     static ZCONST char dtype[]="NXFS";  /* see zi_short() */
@@ -158,10 +162,24 @@ int list_files(__G)     /* return PK-type error code */
     }
 #endif /* ndef WINDLL */
 
-    for (j = 1L;;j++) {
+    enddigsig_len = -1;
 
+    for (j = 1L; ; j++)
+    {
         if (readbuf(__G__ G.sig, 4) == 0)
             return PK_EOF;
+
+        if (memcmp(G.sig, central_digsig_sig, 4) == 0)
+        { /* Central directory digital signature.  Record its
+           * existence.  Read (and, for now, ignore) the data.
+           */
+          error = process_cdir_digsig( __G__ &enddigsig_len);
+          if (error != PK_OK)
+          {
+            return error;       /* Return the error code. */
+          }
+        } /* process_cdir_digsig() should have read the next sig. */
+
         if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
             /* no new central directory entry
              * -> is the number of processed entries compatible with the
@@ -339,7 +357,7 @@ int list_files(__G)     /* return PK-type error code */
                 methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
             } else if (methnum >= NUM_METHODS) {
                 /* 2013-02-26 SMS.
-                 * http://sourceforge.net/p/infozip/bugs/27/
+                 * http://sourceforge.net/p/infozip/bugs/27/  CVE-2014-9913.
                  * Unexpectedly large compression methods overflow
                  * &methbuf[].  Use the old, three-digit decimal format
                  * for values which fit.  Otherwise, sacrifice the
@@ -515,27 +533,34 @@ int list_files(__G)     /* return PK-type error code */
     }
 
     /* Skip the following checks in case of a premature listing break. */
-    if (error_in_archive <= PK_WARN) {
-
+    if (error_in_archive <= PK_WARN)
+    {
 /*---------------------------------------------------------------------------
     Double check that we're back at the end-of-central-directory record.
   ---------------------------------------------------------------------------*/
-
-        if ( (memcmp(G.sig,
-                     (G.ecrec.have_ecr64 ?
-                      end_central64_sig : end_central_sig),
-                     4) != 0)
-            && (!G.ecrec.is_zip64_archive)
-            && (memcmp(G.sig, end_central_sig, 4) != 0)
-           ) {          /* just to make sure again */
+        if ((memcmp( G.sig,
+         (G.ecrec.have_ecr64 ? end_central64_sig : end_central_sig), 4)
+         != 0) &&
+         (!G.ecrec.is_zip64_archive) &&
+         (memcmp( G.sig, end_central_sig, 4) != 0))
+        {
             Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
-            error_in_archive = PK_WARN;   /* didn't find sig */
+            error_in_archive = PK_WARN; /* Didn't find EOCD sig. */
+        }
+
+        if (enddigsig_len >= 0)
+        {
+          Info( slide, 0x401, ((char *)slide, LoadFarString( DigSigMsg),
+           enddigsig_len));
+# if 0   /* Enable to make this a warning. */
+          if (error_in_archive < PK_WARN)       /* Keep more severe error. */
+            error_in_archive = PK_WARN;
+# endif /* 0 */
         }
 
         /* Set specific return code when no files have been found. */
         if (members == 0L && error_in_archive <= PK_WARN)
             error_in_archive = PK_FIND;
-
     }
 
     return error_in_archive;
@@ -573,11 +598,14 @@ int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
     time_t *last_modtime;
     ulg *nmember;
 {
-    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+    int do_this_file = FALSE;
+    int error;
+    int error_in_archive = PK_COOL;
     ulg j;
 # ifdef USE_EF_UT_TIME
     iztimes z_utime;
 # endif
+    long enddigsig_len;
     min_info info;
 
 
@@ -592,10 +620,24 @@ int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
     *nmember = 0L;
     G.pInfo = &info;
 
-    for (j = 1L;; j++) {
+    enddigsig_len = -1;
 
+    for (j = 1L; ; j++)
+    {
         if (readbuf(__G__ G.sig, 4) == 0)
             return PK_EOF;
+
+        if (memcmp(G.sig, central_digsig_sig, 4) == 0)
+        { /* Central directory digital signature.  Record its
+           * existence.  Read (and, for now, ignore) the data.
+           */
+          error = process_cdir_digsig( __G__ &enddigsig_len);
+          if (error != PK_OK)
+          {
+            return error;       /* Return the error code. */
+          }
+        } /* process_cdir_digsig() should have read the next sig. */
+
         if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
             if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
                 (unsigned)G.ecrec.total_entries_central_dir) {
@@ -689,11 +731,26 @@ int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
 /*---------------------------------------------------------------------------
     Double check that we're back at the end-of-central-directory record.
   ---------------------------------------------------------------------------*/
-
-    if (memcmp(G.sig, end_central_sig, 4)) {    /* just to make sure again */
+    if ((memcmp( G.sig,
+     (G.ecrec.have_ecr64 ? end_central64_sig : end_central_sig), 4) != 0) &&
+     (!G.ecrec.is_zip64_archive) &&
+     (memcmp( G.sig, end_central_sig, 4) != 0))
+    {
         Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
         error_in_archive = PK_WARN;
     }
+
+    if (enddigsig_len >= 0)
+    {
+      Info( slide, 0x401, ((char *)slide, LoadFarString( DigSigMsg),
+       enddigsig_len));
+# if 0   /* Enable to make this a warning. */
+      if (error_in_archive < PK_WARN)       /* Keep more severe
+error. */
+        error_in_archive = PK_WARN;
+# endif /* 0 */
+    }
+
     if (*nmember == 0L && error_in_archive <= PK_WARN)
         error_in_archive = PK_FIND;
 
index 8c52be7..88607d4 100644 (file)
@@ -29,9 +29,9 @@ If you are new to MacZip please read first the file
 
 License:
 --------
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index dc4a9e0..3db680a 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index e2bc6fd..23642cf 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 1317815..4264916 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index d3d4446..8919414 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 5656b63..a7dbc3d 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3b22327..26b5627 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 36b5bef..a6445a6 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index a9df5d8..cd3982d 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 201dbf9..82301dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index dbe55ee..e78a00d 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 429889a..fc7c38a 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index f453bb5..ee6abd5 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 2c47157..bfc7327 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2003 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 85c0f2b..5cc5896 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9e92dce..89537c6 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index af9ad5e..a734625 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index cb76aa4..cb86110 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 90eb20e..1ef548f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2006 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4db33c6..e0c4032 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 1a39ed3..20dd485 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 906e412..6890dfd 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 95e7359..33b2d9e 100644 (file)
@@ -1,4 +1,4 @@
-.\"  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+.\"  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 .\"
 .\"  See the accompanying file LICENSE, version 2009-Jan-02 or later
 .\"  (the contents of which are also included in unzip.h) for terms of use.
@@ -8,7 +8,7 @@
 .\" unzip.1 by Greg Roelofs, Fulvio Marino, Jim van Zandt and others.
 .\"
 .\" =========================================================================
-.TH UNZIP 1L "17 Apr 2015 (v6.1)" "Info-ZIP"
+.TH UNZIP 1L "2016-09-29 (v6.1)" "Info-ZIP"
 .\" =========================================================================
 .\"
 .\" Define .EX/.EE (for multiline user-command examples; normal Courier font).
@@ -115,9 +115,9 @@ the three-character sequence "[[]".
 .IP
 If no wildcard matches are found, then the specification is assumed to
 be a literal filename.  If that also fails, then the
-suffix "\fC\.zip\fR" and/or "\fC\.ZIP\fR" is appended, and that is
-tried.  (For this reason, if a non-existent file is specified, then the
-resulting error message may mention these other names with
+suffix "\fC\.zip\fR" and/or "\fC\.ZIP\fR" is appended, and the resulting
+name is tried.  (For this reason, if a non-existent file is specified,
+then the resulting error message may mention these other names with
 their "\fC\.zip\fR" or "\fC\.ZIP\fR" suffixes.)
 .IP
 Note that a "\fC\.zip\fR" or "\fC\.ZIP\fR" name ending on an archive is
@@ -196,10 +196,10 @@ provide automatic ASCII-EBCDIC conversion, where appropriate.
 .br
 Primary Mode.  Freshen existing files.  That is, extract only those
 files that already exist on disk and that are newer than the disk
-copies.  By default \fIUnZip\fP queries before overwriting, but the
-\fB\-o\fP option may be used to suppress the queries.  Note that on
-many operating systems, the TZ (timezone) environment variable must be
-set correctly in order for \fB\-f\fP/\fB\-\-freshen\fP and
+copies.  By default, \fIUnZip\fP queries the user before overwriting,
+but the \fB\-o\fP option may be used to suppress the queries.  Note that
+on many operating systems, the TZ (timezone) environment variable must
+be set correctly in order for \fB\-f\fP/\fB\-\-freshen\fP and
 \fB\-u\fP/\fB\-\-update\fP to work properly.  (On Unix the variable is
 usually set automatically.)  The reasons for this are somewhat subtle
 but have to do with the differences between DOS-format file times
@@ -257,7 +257,7 @@ OS/2 access control lists (ACLs).  In addition, the archive comment and
 individual member comments (if any) are displayed.
 .IP
 If a file was archived from a single-case file system (for example, the
-old MS-DOS FAT file system) and the \fB\-L\fP option was given, the
+old MS-DOS FAT file system) and the \fB\-L\fP option was given, then the
 filename is converted to lowercase and is shown prefixed with a caret
 (^).
 .IP
@@ -280,7 +280,7 @@ Primary Mode.  Display the Info-ZIP license.
 Primary Mode.  Extract files to stdout (pipe).  Only the actual file
 data for the members are sent to stdout (no file names, or other
 information, as would be displayed with \fB\-c\fP), and the files are
-always extracted in binary format, just as they are stored (no
+always extracted in binary format, just as they are stored (with no
 line-ending or ASCII-EBCDIC conversions).
 .PP
 .PD 0
@@ -292,7 +292,7 @@ line-ending or ASCII-EBCDIC conversions).
 Primary Mode.  Set the timestamp on the archive(s) to that of the newest
 file in each one.  This corresponds to \fIZip\fP's \fB\-go\fP option,
 except that it can be used on wildcard archives (for example,
-"\fCunzip\ \-T\ '*.zip'\fR") and is much faster.
+"\fCunzip\ \-T\ '*.zip'\fR") and may be faster.
 .PP
 .PD 0
 .B \-t
@@ -406,8 +406,8 @@ characters are replaced by underscores.
 .PD
 .B \-\-api\-help
 .br
-[OS/2, Unix DLL] Print extended help for the DLL's application
-programming interface (API).
+[DLL, object library] Print extended help for the DLL or object library
+application programming interface (API).
 .PP
 .PD 0
 .B \-a
@@ -444,7 +444,7 @@ text files.  See also \fB\-b\fP and \fB\-S\fP.
 .PD
 .B \-\-backup
 .br
-[when built with UNIXBACKUP enabled] Save a backup copy of each
+[When built with UNIXBACKUP enabled] Save a backup copy of each
 overwritten file.  The backup file gets the name of the target file with
 a tilde and optionally a unique sequence number (up to 5 digits)
 appended.  The sequence number is appended whenever another file with
@@ -1441,29 +1441,31 @@ variable is ignored on these systems.
 \fIZip\fP and \fIUnZip\fP have long supported a relatively weak
 encryption method, which we call Traditional ZIP encryption.  The source
 code for Traditional encryption is included in the source kits, and
-support for Traditional encryption is enabled by default.  (Build-time C
-macros: IZ_CRYPT_TRAD, NO_CRYPT.)
-.PP
-Beginning with \fIUnZip\fP version 6.1 and \fIZip\fP version 3.1,
-these programs also offer a stronger, Advanced Encryption Standard (AES)
-encryption method, which we call AES WinZip/Gladman (AES_WG)
-encryption.  (The encryption code was supplied by Brian Gladman, and the
-archive format is intended to be compatible with that used by the
-\fIWinZip\fP program.  \fIWinZip\fP is a registered trademark of WinZip
-International LLC.)  The source code for AES_WG encryption is
-distributed in a separate kit (for export control reasons), and support
-for AES_WG encryption must be enabled explicitly at build
-time.  (Build-time C macro: IZ_CRYPT_AES_WG.)  See the INSTALL file in
-the source kit for details on how to enable AES_WG encryption (or how to
-disable Traditional encryption).
-.TP
-For details on the WinZip AES scheme, see:
+support for Traditional encryption is enabled by default.
+.PP
+The Info-ZIP programs \fIUnZip\fP (version 6.1 and later) and \fIZip\fP
+(version 3.1 and later)include optional support for Advanced Encryption
+Standard (AES) encryption, a relatively strong encryption method.
+.TP
+The Info-ZIP AES implementation is based on the \fIWinZip\fP AES
+specification, and uses AES encryption code supplied by Brian Gladman.
+We refer to it as IZ_AES_WG (Info-ZIP AES WinZip/Gladman) or simply
+AES_WG.  (\fIWinZip\fP is a registered trademark of WinZip International
+LLC.)  The source code for AES_WG encryption is included in the normal
+UnZip source kit, and support for it will be enabled by default.
+.TP
+The WinZip AES scheme is described in:
 http://www.winzip.com/aes_info.htm
 .TP
-For information on the separate AES_WG source kit, see:
-ftp://ftp.info-zip.org/pub/infozip/crypt/
+For information on the IZ_AES_WG source code, see:
+aes_wg/README_AES_WG.txt
+.br
+or:
 .br
 ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
+.TP
+See the INSTALL file in the source kit for details on how to disable
+AES_WG encryption (or how to disable Traditional encryption).
 .PP
 Normally, encryption passwords are supplied by the user interactively
 when requested by the program.  See the \fB\-P\fP option for a (less
@@ -1769,15 +1771,15 @@ FTP access is available, too:
 .SH AUTHORS
 The primary Info-ZIP authors (current semi-active members of the
 Zip-Bugs workgroup) are:  Ed Gordon (Zip, general maintenance, shared
-code, Zip64, Win32, Unix, Unicode); Christian Spieler (\fIUnZip\fP
-maintenance coordination, VMS, MS-DOS, Win32, shared code, general Zip
-and \fIUnZip\fP integration and optimization); Onno van der Linden
-(Zip); Mike White (Win32, Windows GUI, Windows DLLs); Kai Uwe Rommel
-(OS/2, Win32); Steven M. Schweda (VMS, Unix, support of new features);
-Paul Kienitz (Amiga, Win32, Unicode); Chris Herborth (BeOS, QNX, Atari);
+code, Zip64, Win32, Unix, Unicode); Christian Spieler (VMS, MS-DOS,
+Win32, shared code, general Zip and \fIUnZip\fP integration and
+optimization); Onno van der Linden (Zip); Mike White (Win32, Windows
+GUI, Windows DLLs); Kai Uwe Rommel (OS/2, Win32); Steven M. Schweda
+(\fIUnZip\fP maintenance, VMS, Unix, support of new features); Paul
+Kienitz (Amiga, Win32, Unicode); Chris Herborth (BeOS, QNX, Atari);
 Jonathan Hudson (SMS/QDOS); Sergio Monesi (Acorn RISC OS); Harald Denker
 (Atari, MVS); John Bush (Solaris, Amiga); Hunter Goatley (VMS, Info-ZIP
-Site maintenance); Steve Salisbury (Win32); Steve Miller (Windows CE
+server maintenance); Steve Salisbury (Win32); Steve Miller (Windows CE
 GUI), Johnny Lee (MS-DOS, Win32, Zip64); and Dave Smith (Tandem NSK).
 .PP
 The following people are former members of the Info-ZIP development
diff --git a/match.c b/match.c
index 6d6fd42..fb8732a 100644 (file)
--- a/match.c
+++ b/match.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -376,36 +376,65 @@ static int namecmp(s1, s2)
 
 
 
+/* iswild() was originally only used for stat()-bug workaround in
+ *          VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs.
+ *          It's now used in process_zipfiles() as well.
+ *
+ * 2017-03-14 SMS.  Added code to deal with caret escapes on VMS.
+ * Archive name containing "^%" or "^*" was erroneously treated as wild.
+ * Similarly, on VMS, "^", not "\", is an escape character.
+ * Also, as of VMS V7.2 (non-VAX), "?" is wild (equivalent to "%").
+ * The classy method on VMS would be to use $PARSE, and check
+ * nam[l].naml$v_wildcard, but this scheme should be adequate (and
+ * better than it was).
+ */
 
-int iswild(p)        /* originally only used for stat()-bug workaround in */
-    ZCONST char *p;  /*  VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
-{                    /*  now used in process_zipfiles() as well */
-    for (; *p; INCSTR(p))
-        if (*p == '\\' && *(p+1))
+#ifdef VMS
+# define ESC_CHR '^'
+#else
+# define ESC_CHR '\\'
+#endif
+
+int iswild(p)
+    ZCONST char *p;
+{
+    for (; *p; INCSTR( p))
+    {
+        if ((*p == ESC_CHR) && *(p+ 1))
+        {
             ++p;
+        }
 #ifdef THEOS
         else if (*p == '?' || *p == '*' || *p=='#'|| *p == '@')
-#else /* !THEOS */
-#ifdef VMS
-        else if (*p == '%' || *p == '*')
-#else /* !VMS */
-#ifdef AMIGA
+#else /* def THEOS */
+# ifdef VMS
+        else if ((*p == '%') ||
+#  if !defined(__VAX) && defined( __VMS_VER) && (__VMS_VER >= 70200000)
+         (*p == '?') ||
+#  endif
+         (*p == '*'))
+# else /* def VMS */
+#  ifdef AMIGA
         else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
-#else /* !AMIGA */
+#  else /* def AMIGA */
         else if (*p == '?' || *p == '*' || *p == '[')
-#endif /* ?AMIGA */
-#endif /* ?VMS */
-#endif /* ?THEOS */
+#  endif /* def AMIGA [else] */
+# endif /* def VMS [else] */
+#endif /* def THEOS [else] */
+        {
 #ifdef QDOS
             return (int)p;
 #else
             return TRUE;
 #endif
-
+        }
+    }
     return FALSE;
 
 } /* end function iswild() */
 
+
+
 #if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
 int iswildw(pw)          /* originally only used for stat()-bug workaround in */
     ZCONST wchar_t *pw;  /*  VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
diff --git a/mod/win32/w32cfg.h b/mod/win32/w32cfg.h
deleted file mode 100644 (file)
index b450c2a..0000000
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
-
-  See the accompanying file LICENSE, version 2009-Jan-02 or later
-  (the contents of which are also included in unzip.h) for terms of use.
-  If, for some reason, all these files are missing, the Info-ZIP license
-  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*---------------------------------------------------------------------------
-    Win32 specific configuration section:
-  ---------------------------------------------------------------------------*/
-
-#ifndef __w32cfg_h
-#define __w32cfg_h
-
-#ifdef __CYGWIN__
-/* We treat the file system underneath the Cygwin Unix emulator environment
- * as "native VFAT/NTFS" and use the WIN32 API for its special attributes...
- */
-#  ifdef UNIX
-#    undef UNIX
-#  endif
-#endif
-
-#if (defined(_MSC_VER) && !defined(MSC))
-#  define MSC
-#endif
-
-/* enable multibyte character set support by default */
-#if (!defined(_MBCS) && !defined(NO_MBCS))
-#  define _MBCS
-#endif
-#if (defined(_MBCS) && defined(NO_MBCS))
-#  undef _MBCS
-#endif
-#if (defined(__CYGWIN__) && defined(_MBCS))
-#  undef _MBCS                  /* Cygwin RTL lacks support for __mb_cur_max */
-#endif
-#if (defined(__DJGPP__) && !defined(__EMX__) && defined(_MBCS))
-#  undef _MBCS                  /* __mb_cur_max missing for RSXNTdj 1.6 beta */
-#endif
-
-#include <sys/types.h>          /* off_t, time_t, dev_t, ... */
-#include <sys/stat.h>
-#include <io.h>                 /* read(), open(), etc. */
-#include <time.h>
-#if ((defined(__RSXNT__) || defined(__EMX__)) && !defined(tzset))
-#  define tzset _tzset
-#endif
-#if (defined(__LCC__) && !defined(tzset))
-#  define tzset _tzset
-#endif
-#ifdef __MINGW32__
-   extern void _tzset(void);    /* this is missing in <time.h> */
-#  ifndef tzset
-#    define tzset _tzset
-#  endif
-#endif
-#ifdef W32_USE_IZ_TIMEZONE
-#  ifdef __BORLANDC__
-#    define tzname tzname
-#    define IZTZ_DEFINESTDGLOBALS
-#  endif
-#  ifdef __WATCOMC__
-#    define IZTZ_DEFINESTDGLOBALS
-#  endif
-#  ifndef tzset
-#    define tzset _tzset
-#  endif
-#  ifndef timezone
-#    define timezone _timezone
-#  endif
-#  ifndef daylight
-#    define daylight _daylight
-#  endif
-#  ifndef tzname
-#    define tzname _tzname
-#  endif
-#  if (!defined(NEED__ISINDST) && !defined(__BORLANDC__))
-#    define NEED__ISINDST
-#  endif
-#  ifdef IZTZ_GETLOCALETZINFO
-#    undef IZTZ_GETLOCALETZINFO
-#  endif
-#  define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone
-#endif /* W32_USE_IZ_TIMEZONE */
-#include <memory.h>
-#if (!defined(__RSXNT__) && !defined(__CYGWIN__))
-#  include <direct.h>           /* mkdir() */
-#endif
-#include <fcntl.h>
-#ifdef __CYGWIN__
-#  include <unistd.h>
-   extern int setmode(int, int);        /* this is missing in <fcntl.h> */
-#endif
-#if (defined(MSC) || defined(__WATCOMC__) || defined(__MINGW32__))
-#  include <sys/utime.h>
-#  define HAVE_LOCALE_H 1       /* 2012-12-18 SMS. */
-#else
-#  include <utime.h>
-#endif
-#define GOT_UTIMBUF
-
-#ifdef _MBCS
-#  if (!defined(__EMX__) && !defined(__DJGPP__) && !defined(__CYGWIN__))
-#  if (!defined(__MINGW32__) || defined(__MSVCRT__))
-#    include <stdlib.h>
-#    include <mbstring.h>
-     /* for MSC (and compatible compilers), use routines supplied by RTL */
-#    define CLEN(ptr) _mbclen((const uch *)(ptr))
-#    define PREINCSTR(ptr) (ptr = (char *)_mbsinc((const uch *)(ptr)))
-#    define MBSCHR(str, c) (char *)_mbschr((const uch *)(str), (c))
-#    define MBSRCHR(str, c) (char *)_mbsrchr((const uch *)(str), (c))
-#  endif
-#  endif
-#  if (defined(__MINGW32__) && !defined(MB_CUR_MAX))
-#    ifdef __MSVCRT__
-       extern int *__p___mb_cur_max(void);
-#      define MB_CUR_MAX (*__p___mb_cur_max())
-#    else
-       extern int *_imp____mb_cur_max_dll;
-#      define MB_CUR_MAX (*_imp____mb_cur_max_dll)
-#    endif
-#  endif
-#  if (defined(__LCC__) && !defined(MB_CUR_MAX))
-     extern int *_imp____mb_cur_max;
-#    define MB_CUR_MAX (*_imp____mb_cur_max)
-#  endif
-#  if (defined(__DJGPP__) && !defined(__EMX__) && !defined(MB_CUR_MAX))
-     extern int *_imp____mb_cur_max;
-#    define MB_CUR_MAX (*_imp____mb_cur_max)
-#  endif
-#endif
-
-/* for UnZip, the "basic" part of the win32 api is sufficient */
-#ifndef WIN32_LEAN_AND_MEAN
-#  define WIN32_LEAN_AND_MEAN
-#endif
-
-#if defined(__FILEIO_C)
-#  ifndef __CYGWIN__
-#    include <conio.h>
-#  endif
-#  include <windows.h>
-#  ifdef __RSXNT__
-#    include "../win32/rsxntwin.h"
-#  endif
-#  ifndef TIME_ZONE_ID_INVALID
-#    define TIME_ZONE_ID_INVALID  (DWORD)0xFFFFFFFFL
-#  endif
-#endif
-#if (defined(__ENVARGS_C) || defined(__EXTRACT_C) || defined(__UNZIP_C) || \
-     defined(ZCRYPT_INTERNAL))
-#  include <windows.h>
-#  ifdef __RSXNT__
-#    include "../win32/rsxntwin.h"
-#  endif
-#  ifndef TIME_ZONE_ID_INVALID
-#    define TIME_ZONE_ID_INVALID  (DWORD)0xFFFFFFFFL
-#  endif
-#endif
-
-#ifndef Cdecl
-#  define Cdecl __cdecl
-#endif
-
-/* the following definitions are considered as "obsolete" by Microsoft and
- * might be missing in some versions of <windows.h>
- */
-#ifndef AnsiToOem
-#  define AnsiToOem CharToOemA
-#endif
-#ifndef OemToAnsi
-#  define OemToAnsi OemToCharA
-#endif
-
-#define DIR_END       '\\'      /* OS uses '\\' as directory separator */
-#define DIR_END2      '/'       /* also check for '/' (RTL may convert) */
-#ifdef DATE_FORMAT
-#  undef DATE_FORMAT
-#endif
-#define DATE_FORMAT   dateformat()
-#ifdef DATE_SEPCHAR
-#  undef DATE_SEPCHAR
-#endif
-#define DATE_SEPCHAR  dateseparator()
-#define lenEOL        2
-#define PutNativeEOL  {*q++ = native(CR); *q++ = native(LF);}
-
-#if (defined(__RSXNT__) && !defined(HAVE_MKTIME))
-#  define HAVE_MKTIME           /* use mktime() in time conversion routines */
-#endif
-#if (defined(MSC) && !defined(HAVE_MKTIME))
-#  define HAVE_MKTIME           /* use mktime() in time conversion routines */
-#endif
-#if (defined(__CYGWIN__) && defined(HAVE_MKTIME))
-#  undef HAVE_MKTIME            /* Cygnus' mktime() implementation is buggy */
-#endif
-#if (defined(W32_USE_IZ_TIMEZONE) && !defined(HAVE_MKTIME))
-#  define HAVE_MKTIME           /* use mktime() in time conversion routines */
-#endif
-#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
-#  define USE_EF_UT_TIME
-#endif
-#if (!defined(NO_DIR_ATTRIB) && !defined(SET_DIR_ATTRIB))
-#  define SET_DIR_ATTRIB
-#endif
-#if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
-#  define TIMESTAMP
-#endif
-#if (!defined(NO_NTSD_EAS) && !defined(NTSD_EAS))
-#  define NTSD_EAS      /* enable NTSD support unless explicitly suppressed */
-#endif
-#if (defined(NTSD_EAS) && !defined(RESTORE_ACL))
-#  define RESTORE_ACL   /* "restore ACLs" only needed when NTSD_EAS active */
-#endif
-#ifdef NO_UNICODE_SUPPORT
-# ifdef UNICODE_SUPPORT
-#  undef UNICODE_SUPPORT
-# endif
-#endif
-#if (!defined(NO_UNICODE_SUPPORT) && !defined(UNICODE_SUPPORT))
-#  define UNICODE_SUPPORT      /* enable UTF-8 filename support by default */
-#endif
-#ifdef UNICODE_SUPPORT
-# ifndef WIN32_WIDE
-#  define WIN32_WIDE
-# endif
-#endif
-#if (defined(UNICODE_SUPPORT) && !defined(UNICODE_WCHAR))
-#  define UNICODE_WCHAR        /* wchar_t is UTF-16 encoded on WIN32 */
-#endif
-#ifdef UTF8_MAYBE_NATIVE
-#  undef UTF8_MAYBE_NATIVE      /* UTF-8 cannot be system charset on WIN32 */
-#endif
-
-/* Windows-only, wide-character, fopen() modes.  See also unzpriv.h. */
-#if defined( UNICODE_SUPPORT) && defined( WIN32_WIDE)
-# define FOPR_W  L"rb"
-# define FOPM_W  L"r+b"
-# define FOPW_W  L"wb"
-# define FOPWT_W L"wt"
-# define FOPWR_W L"w+b"
-#endif
-
-/* The following compiler systems provide or use a runtime library with a
- * locale-aware isprint() implementation.  For these systems, the "enhanced"
- * unprintable charcode detection in fnfilter() gets enabled.
- */
-#if (!defined(HAVE_WORKING_ISPRINT) && !defined(NO_WORKING_ISPRINT))
-#  if defined(MSC) || defined(__BORLANDC__)
-#    define HAVE_WORKING_ISPRINT
-#  endif
-#  if defined(__MINGW32__) && defined(__MSVCRT__)
-#    define HAVE_WORKING_ISPRINT
-#  endif
-#endif
-
-/* WIN32 runs solely on little-endian processors; enable support
- * for the 32-bit optimized CRC-32 C code by default.
- */
-#ifdef IZ_CRC_BE_OPTIMIZ
-#  undef IZ_CRC_BE_OPTIMIZ
-#endif
-#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ)
-#  define IZ_CRC_LE_OPTIMIZ
-#endif
-
-/* handlers for OEM <--> ANSI string conversions */
-#ifdef __RSXNT__
-   /* RSXNT uses OEM coded strings in functions supplied by C RTL */
-#  ifdef CRTL_CP_IS_ISO
-#    undef CRTL_CP_IS_ISO
-#  endif
-#  ifndef CRTL_CP_IS_OEM
-#    define CRTL_CP_IS_OEM
-#  endif
-#else
-   /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */
-#  ifndef CRTL_CP_IS_ISO
-#    define CRTL_CP_IS_ISO
-#  endif
-#  ifdef CRTL_CP_IS_OEM
-#    undef CRTL_CP_IS_OEM
-#  endif
-#endif
-
-#ifdef CRTL_CP_IS_ISO
-   /* C RTL's file system support assumes ANSI coded strings */
-#  define ISO_TO_INTERN(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
-#  define OEM_TO_INTERN(src, dst)  OemToAnsi(src, dst)
-#  define INTERN_TO_ISO(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
-#  define INTERN_TO_OEM(src, dst)  AnsiToOem(src, dst)
-#endif /* CRTL_CP_IS_ISO */
-#ifdef CRTL_CP_IS_OEM
-   /* C RTL's file system support assumes OEM coded strings */
-#  define ISO_TO_INTERN(src, dst)  AnsiToOem(src, dst)
-#  define OEM_TO_INTERN(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
-#  define INTERN_TO_ISO(src, dst)  OemToAnsi(src, dst)
-#  define INTERN_TO_OEM(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
-#endif /* CRTL_CP_IS_OEM */
-#define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1)
-#define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1)
-#ifndef WINDLL
-   /* Despite best intentions, for the command-line version UzpPassword()
-    * could return either character set, depending on whether running under
-    * Win95 (DOS-session) or WinNT (native WinNT command interpreter)! */
-#  define STR_TO_CP2(dst, src)  (AnsiToOem(src, dst), dst)
-#  define STR_TO_CP3(dst, src)  (OemToAnsi(src, dst), dst)
-#else
-   /* The WINDLL front end is known to supply ISO/ANSI-coded passwords! */
-#  define STR_TO_CP2(dst, src)  (AnsiToOem(src, dst), dst)
-#endif
-/* dummy defines to disable these functions, they are not needed */
-#define STR_TO_OEM
-#define STR_TO_ISO
-
-#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-# if defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS)
-    wchar_t *utf8_to_wchar_string_dyn OF((const char *));
-# endif /* defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) */
-# ifdef DYNAMIC_WIDE_NAME
-#  define utf8_to_wchar_string utf8_to_wchar_string_dyn
-# else /* def DYNAMIC_WIDE_NAME */
-#  define utf8_to_wchar_string utf8_to_wchar_string_stat
-    void utf8_to_wchar_string_stat OF((wchar_t *, const char *));
-# endif /* def DYNAMIC_WIDE_NAME [else] */
-    wchar_t *local_to_wchar_string OF((char *));
-    int has_win32_wide();
-#endif /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-
-/* 2013-07-08 SMS.
- * Some anti-virus programs may temporarily lock a newly created
- * file, causing transient failures of CreateFile[AW]() when
- * setting date-time (win32/win32.c:close_outfile()).
- * We try up to IZ_CREATEFILE_TRY_COUNT times, at intervals of
- * IZ_CREATEFILE_TRY_TIME_MS (millisecond).  To disable the
- * retries, define IZ_CREATEFILE_TRY_COUNT as zero. (win32/w32cfg.h).
- * http://sourceforge.net/p/infozip/bugs/44/
- * http://support.microsoft.com/kb/316609
- */
-#ifndef IZ_CREATEFILE_TRY_COUNT
-# define IZ_CREATEFILE_TRY_COUNT 8
-#endif
-#ifndef IZ_CREATEFILE_TRY_TIME_MS
-# define IZ_CREATEFILE_TRY_TIME_MS 125
-#endif
-#if defined( IZ_CREATEFILE_TRY_COUNT) && (IZ_CREATEFILE_TRY_COUNT > 1)
-# define RETRY_CREATEFILE 1
-#endif
-
-/* Static variables that we have to add to Uz_Globs: */
-#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-#define SYSTEM_SPECIFIC_GLOBALS \
-    int created_dir;\
-    int renamed_fullpath;\
-    size_t fnlen;\
-    unsigned nLabelDrive;\
-    char lastRootPath[4];\
-    wchar_t lastRootPathw[4];\
-    int lastVolOldFAT, lastVolLocTim;\
-    char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\
-    wchar_t *rootpathw, *buildpathHPFSw, *buildpathFATw, *endHPFSw, *endFATw;\
-    ZCONST char *wildname;\
-    ZCONST wchar_t *wildnamew;\
-    char *dirname, matchname[FILNAMSIZ];\
-    wchar_t *dirnamew, matchnamew[FILNAMSIZ];\
-    size_t dirnamelen;\
-    size_t rootlen;\
-    int have_dirname, notfirstcall;\
-    zvoid *wild_dir;
-#else /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-#define SYSTEM_SPECIFIC_GLOBALS \
-    int created_dir, renamed_fullpath, fnlen;\
-    unsigned nLabelDrive;\
-    char lastRootPath[4];\
-    int lastVolOldFAT, lastVolLocTim;\
-    char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\
-    ZCONST char *wildname;\
-    char *dirname, matchname[FILNAMSIZ];\
-    int rootlen, have_dirname, dirnamelen, notfirstcall;\
-    zvoid *wild_dir;
-#endif /* ?(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-
-/* created_dir, renamed_fullpath, fnlen, and nLabelDrive are used by   */
-/*    both mapname() and checkdir().                                   */
-/* lastRootPath, lastVolOldFAT and lastVolLocTim are used by           */
-/*    IsVolumeOldFAT() and NTQueryVolInfo().                           */
-/* rootlen, rootpath, buildpathHPFS, buildpathFAT, endHPFS, and endFAT */
-/*    are used by checkdir().                                          */
-/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
-/*    and notfirstcall are used by do_wild().                          */
-
-/* This replacement for C-RTL-supplied getch() (or similar) functionality
- * avoids leaving unabsorbed LFs in the keyboard buffer under Windows95,
- * and supports the <ALT>+[0]<digit><digit><digit> feature.
- */
-int getch_win32  OF((void));
-
-/* Up to now, all versions of Microsoft C runtime libraries lack the support
- * for customized (non-US) switching rules between daylight saving time and
- * standard time in the TZ environment variable string.
- * But non-US timezone rules are correctly supported when timezone information
- * is read from the OS system settings in the Win32 registry.
- * The following work-around deletes any TZ environment setting from
- * the process environment.  This results in a fallback of the RTL time
- * handling code to the (correctly interpretable) OS system settings, read
- * from the registry.
- */
-#ifdef USE_EF_UT_TIME
-# if (defined(__WATCOMC__) || defined(__CYGWIN__) || \
-      defined(W32_USE_IZ_TIMEZONE))
-#   define iz_w32_prepareTZenv()
-# else
-#   define iz_w32_prepareTZenv()        putenv("TZ=")
-# endif
-#endif
-
-/* This patch of stat() is useful for at least two compilers.  It is   */
-/* difficult to take a stat() of a root directory under Windows95, so  */
-/* zstat_win32() detects that case and fills in suitable values.       */
-#ifndef __RSXNT__
-#  ifndef W32_STATROOT_FIX
-#    define W32_STATROOT_FIX
-#  endif
-#endif /* !__RSXNT__ */
-
-#define W32_STAT_BANDAID
-#if defined(REENTRANT)
-#  define __W32STAT_GLOBALS__       Uz_Globs *pG,
-#  define __W32STAT_G__             pG,
-#else
-#  define __W32STAT_GLOBALS__
-#  define __W32STAT_G__
-#endif
-#ifdef SSTAT
-#  undef SSTAT
-#endif
-#ifdef WILD_STAT_BUG
-#  define SSTAT(path, pbuf) (iswild(path) || zstat_win32(__W32STAT_G__ path, pbuf))
-#else
-#  define SSTAT(path, pbuf) zstat_win32(__W32STAT_G__ path, pbuf)
-#endif
-
-#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-# ifdef WILD_STAT_BUG
-#  define SSTATW(pathw, pbuf) (iswildw(pathw) || zstat_win32w(__W32STAT_G__ pathw, pbuf))
-# else
-#  define SSTATW(pathw, pbuf) zstat_win32w(__W32STAT_G__ pathw, pbuf)
-# endif
-#endif /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-
-
-#ifdef SYMLINKS
-# define lstat SSTAT
-# define lstatw SSTATW
-# ifndef S_ISLNK
-#  ifndef S_IFLNK
-#   define S_IFLNK  0120000
-#  endif
-# define S_ISLNK(m) (((m)& S_IFMT) == S_IFLNK)
-# endif /* ndef S_ISLNK */
-
-int symlink( const char *target, const char *name, int is_dir);
-# ifdef UNICODE_SUPPORT
-int symlinkw( const char *target, const wchar_t *name, int is_dir);
-# endif /* def UNICODE_SUPPORT */
-#endif /* def SYMLINKS */
-
-
-#ifdef __WATCOMC__
-#  ifdef __386__
-#    ifndef WATCOMC_386
-#      define WATCOMC_386
-#    endif
-#    define __32BIT__
-#    undef far
-#    define far
-#    undef near
-#    define near
-#    undef Cdecl
-#    define Cdecl
-
-/* gaah -- Watcom's docs claim that _get_osfhandle exists, but it doesn't.  */
-#    define _get_osfhandle _os_handle
-
-/* Get asm routines to link properly without using "__cdecl": */
-#    ifndef USE_ZLIB
-#      pragma aux crc32         "_*" parm caller [] value [eax] modify [eax]
-#      pragma aux get_crc_table "_*" parm caller [] value [eax] \
-                                      modify [eax ecx edx]
-#    endif /* !USE_ZLIB */
-#  endif /* __386__ */
-#endif /* __WATCOMC__ */
-
-#define SCREENWIDTH 80
-#define SCREENSIZE(scrrows, scrcols)  screensize(scrrows, scrcols)
-int screensize(int *tt_rows, int *tt_cols);
-
-/* on the DOS or NT console screen, line-wraps are always enabled */
-#define SCREENLWRAP 1
-#define TABSIZE 8
-
-
-/* 64-bit-Integers & Large File Support
- * (pasted here from Zip 3b, osdep.h - Myles Bennett 7-jun-2004)
- * (updated from Zip 3.0d - Ed Gordon 6-oct-2004)
- *
- *  If this is set it is assumed that the port
- *  supports 64-bit file calls.  The types are
- *  defined here.  Any local implementations are
- *  in w32i64.c and the prototypes for the calls are
- *  in unzip.h.  Note that a port must support
- *  these calls fully or should not set
- *  LARGE_FILE_SUPPORT.
- */
-
-/* Automatically set ZIP64_SUPPORT if supported */
-
-#ifndef NO_ZIP64_SUPPORT
-# ifndef ZIP64_SUPPORT
-#   if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
-#     define ZIP64_SUPPORT
-#   elif defined(__LCC__)
-      /* LCC links against crtdll.dll -> no support of 64-bit offsets :( */
-#   elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
-#     define ZIP64_SUPPORT
-#   elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520))
-      /* Borland C RTL lacks any support to get/set 64-bit file pointer :( */
-#   endif
-# endif
-#endif
-
-#ifdef ZIP64_SUPPORT
-  /* base type for file offsets and file sizes */
-# if (defined(__GNUC__) || defined(ULONG_LONG_MAX))
-    typedef long long    zoff_t;
-# else
-    /* all other compilers use this as intrinsic 64-bit type */
-    typedef __int64      zoff_t;
-# endif
-# define ZOFF_T_DEFINED
-
-  /* user-defined types and format strings for 64-bit numbers and
-   * file pointer functions  (these depend on the rtl library and library
-   * headers used; they are NOT compiler-specific)
-   */
-# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__LCC__)
-    /* MS C and VC, MinGW32, lcc32 */
-    /* these systems use the Microsoft C RTL */
-
-    /* 64-bit stat struct */
-    typedef struct _stati64 z_stat;
-#   define Z_STAT_DEFINED
-
-#   ifdef __LCC__
-      /* The LCC headers lack these declarations of MSC rtl functions in
-         sys/stat.h. */
-      struct _stati64 {
-        unsigned int st_dev;
-        unsigned short st_ino;
-        unsigned short st_mode;
-        short st_nlink;
-        short st_uid;
-        short st_gid;
-        unsigned int st_rdev;
-        __int64 st_size;
-        time_t st_atime;
-        time_t st_mtime;
-        time_t st_ctime;
-      };
-      int _stati64(const char *, struct _stati64 *);
-      int _fstati64(int, struct _stati64 *);
-       __int64 _lseeki64(int, __int64, int);
-#   endif /* __LCC__ */
-
-    /* printf format size prefix for zoff_t values */
-#   define FZOFFT_FMT "I64"
-#   define FZOFFT_HEX_WID_VALUE "16"
-
-#   define SHORTHDRSTATS "%9I64u  %02u%c%02u%c%02u %02u:%02u  %c"
-#   define SHORTFILETRAILER " --------                   -------\n%9I64u                   %9lu file%s\n"
-
-# elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520))
-    /* Borland C 5.2 or newer */
-
-    /* 64-bit stat struct */
-    typedef struct stati64 z_stat;
-#   define Z_STAT_DEFINED
-
-    /* Borland C does not provide a 64-bit-capable _lseeki64(), so we
-       need to use the stdio.h stream functions instead. */
-#   ifndef USE_STRM_INPUT
-#     define USE_STRM_INPUT
-#   endif
-
-    /* printf format size prefix for zoff_t values */
-#   define FZOFFT_FMT "L"
-#   define FZOFFT_HEX_WID_VALUE "16"
-
-#   define SHORTHDRSTATS "%9Lu  %02u%c%02u%c%02u %02u:%02u  %c"
-#   define SHORTFILETRAILER " --------                   -------\n%9Lu                   %9lu file%s\n"
-
-# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
-    /* WATCOM C */
-
-    /* 64-bit stat struct */
-    typedef struct _stati64 z_stat;
-#   define Z_STAT_DEFINED
-
-    /* printf format size prefix for zoff_t values */
-#   define FZOFFT_FMT "ll"
-#   define FZOFFT_HEX_WID_VALUE "16"
-
-#   define SHORTHDRSTATS "%9llu  %02u%c%02u%c%02u %02u:%02u  %c"
-#   define SHORTFILETRAILER " --------                   -------\n%9llu                   %9lu file%s\n"
-
-# elif (defined(__IBMC__) && (__IBMC__ >= 350))
-    /* IBM C */
-
-    /* 64-bit stat struct */
-
-    /* printf format size prefix for zoff_t values */
-#   define FZOFFT_FMT "I64"
-#   define FZOFFT_HEX_WID_VALUE "16"
-
-#   define SHORTHDRSTATS "%9I64u  %02u%c%02u%c%02u %02u:%02u  %c"
-#   define SHORTFILETRAILER " --------                   -------\n%9I64u                   %9lu file%s\n"
-
-# endif
-
-#endif
-
-/* If port has LARGE_FILE_SUPPORT then define here
-   to make automatic unless overridden */
-
-#ifndef LARGE_FILE_SUPPORT
-# ifndef NO_LARGE_FILE_SUPPORT
-#   if defined(_MSC_VER) || defined(__MINGW32__)
-#     define LARGE_FILE_SUPPORT
-#   elif defined(__LCC__)
-      /* LCC links against crtdll.dll -> no support of 64-bit offsets :( */
-#   elif defined(__CYGWIN__)
-#     define LARGE_FILE_SUPPORT
-#   elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
-#     define LARGE_FILE_SUPPORT
-#   elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520))
-      /* Borland C RTL lacks any support to get/set 64-bit file pointer :( */
-#   endif
-# endif
-#endif
-
-
-#ifndef LARGE_FILE_SUPPORT
-  /* No Large File Support */
-
-  /* base type for file offsets and file sizes */
-  typedef long zoff_t;
-# define ZOFF_T_DEFINED
-
-  /* stat struct */
-  typedef struct stat z_stat;
-# define Z_STAT_DEFINED
-
-#  define FZOFFT_FMT "l"
-#  define FZOFFT_HEX_WID_VALUE "8"
-
-
-#  define SHORTHDRSTATS "%9lu  %02u%c%02u%c%02u %02u:%02u  %c"
-#  define SHORTFILETRAILER " --------                   -------\n%9lu                   %9lu file%s\n"
-
-#endif /* LARGE_FILE_SUPPORT */
-
-#endif /* !__w32cfg_h */
diff --git a/mod/win32/win32.c b/mod/win32/win32.c
deleted file mode 100644 (file)
index 4a7d1bc..0000000
+++ /dev/null
@@ -1,5050 +0,0 @@
-/*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
-
-  See the accompanying file LICENSE, version 2009-Jan-02 or later
-  (the contents of which are also included in unzip.h) for terms of use.
-  If, for some reason, all these files are missing, the Info-ZIP license
-  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*---------------------------------------------------------------------------
-
-  win32.c
-
-  32-bit Windows-specific (NT/9x) routines for use with Info-ZIP's UnZip 5.3
-  and later.
-
-  Contains:  GetLoadPath()
-             Opendir()
-             Readdir()
-             Closedir()
-             SetSD()              set security descriptor on file
-             FindSDExtraField()   extract SD e.f. block from extra field
-             IsWinNT()            indicate type of WIN32 platform
-             test_NTSD()          test integrity of NT security data
-             utime2NtfsFileTime()
-             utime2VFatFileTime()
-             FStampIsLocTime()
-             NtfsFileTime2utime()
-             VFatFileTime2utime()
-             getNTfiletime()
-             SetFileSize()
-             close_outfile()
-             defer_dir_attribs()
-             set_direc_attribs()
-             stamp_file()
-             isfloppy()
-             NTQueryVolInfo()
-             IsVolumeOldFAT()
-             do_wild()
-             mapattr()
-             mapname()
-             mapnamew()
-             maskDOSdevice()
-             map2fat()
-             checkdir()
-             dateformat()
-             dateseparator()
-             version()
-             screensize()
-             zstat_win32()
-             conv_to_rule()
-             GetPlatformLocalTimezone()
-             getch_win32()
-
-  ---------------------------------------------------------------------------*/
-
-
-#define UNZIP_INTERNAL
-#include "../unzip.h"
-#include <windows.h>    /* must be AFTER unzip.h to avoid struct G problems */
-#ifdef __RSXNT__
-#  include "../win32/rsxntwin.h"
-#endif
-#include "../win32/nt.h"
-
-#ifndef FUNZIP          /* most of this file is not used with fUnZip */
-
-/* some non-MS runtime headers (e.g. lcc) may miss this definition */
-# ifndef FILE_WRITE_ATTRIBUTES
-#  define FILE_WRITE_ATTRIBUTES 0x0100
-# endif
-
-# if (defined(__EMX__) || defined(__CYGWIN__))
-#  define MKDIR(path,mode)   mkdir(path,mode)
-# else
-#  define MKDIR(path,mode)   mkdir(path)
-# endif
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-#  if (defined(__EMX__) || defined(__CYGWIN__))
-#  define MKDIRW(pathw,mode)   _wmkdir(pathw,mode)
-#  else
-#  define MKDIRW(pathw,mode)   _wmkdir(pathw)
-#  endif
-# endif
-
-# ifdef HAVE_WORKING_DIRENT_H
-#  undef HAVE_WORKING_DIRENT_H
-# endif
-/* The emxrtl dirent support of (__GO32__ || __EMX__) converts to lowercase! */
-# if defined(__CYGWIN__)
-#  define HAVE_WORKING_DIRENT_H
-# endif
-
-# ifndef SFX
-#  ifdef HAVE_WORKING_DIRENT_H
-#    include <dirent.h>         /* use readdir() */
-#    define zdirent  dirent
-#    define zDIR     DIR
-#    define Opendir  opendir
-#    define Readdir  readdir
-#    define Closedir closedir
-#  else /* !HAVE_WORKING_DIRENT_H */
-     typedef struct zdirent {
-         char    reserved [21];
-         char    ff_attrib;
-         short   ff_ftime;
-         short   ff_fdate;
-         long    size;
-         char    d_name[MAX_PATH];
-         int     d_first;
-         HANDLE  d_hFindFile;
-     } zDIR;
-
-     static zDIR           *Opendir  (const char *n);
-     static struct zdirent *Readdir  (zDIR *d);
-     static void            Closedir (zDIR *d);
-#  endif /* ?HAVE_WORKING_DIRENT_H */
-# endif /* !SFX */
-
-# ifdef SET_DIR_ATTRIB
-typedef struct NTdirattr {      /* struct for holding unix style directory */
-    struct NTdirattr *next;     /*  info until can be sorted and set at end */
-    char *fn;                   /* filename of directory */
-    FILETIME Modft;    /* File time type defined in NT, `last modified' time */
-    FILETIME Accft;    /* NT file time type, `last access' time */
-    FILETIME Creft;    /* NT file time type, `file creation' time */
-    int gotTime;
-    unsigned perms;             /* same as min_info.file_attr */
-#  ifdef NTSD_EAS
-    unsigned SDlen;             /* length of SD data in buf */
-#  endif
-    char buf[1];                /* buffer stub for directory SD and name */
-} NTdirattr;
-#define NtAtt(d)  ((NTdirattr *)d)    /* typecast shortcut */
-
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
- typedef struct NTdirattrw {     /* struct for holding unix style directory */
-    struct NTdirattrw *next;     /*  info until can be sorted and set at end */
-    wchar_t *fnw;                /* filename of directory */
-    FILETIME Modft;    /* File time type defined in NT, `last modified' time */
-    FILETIME Accft;    /* NT file time type, `last access' time */
-    FILETIME Creft;    /* NT file time type, `file creation' time */
-    int gotTime;
-    unsigned perms;             /* same as min_info.file_attr */
-#   ifdef NTSD_EAS
-    unsigned SDlen;             /* length of SD data in buf */
-#   endif
-    wchar_t buf[1];                /* buffer stub for directory SD and name */
- } NTdirattrw;
-#  define NtAttw(dw)  ((NTdirattrw *)dw)    /* typecast shortcut */
-#  endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-# endif /* SET_DIR_ATTRIB */
-
-
-/* Function prototypes */
-# ifdef NTSD_EAS
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-   static int  SetSD(__GPRO__ wchar_t *path, unsigned fperms,
-                     uch *eb_ptr, unsigned eb_len);
-#  else
-   static int  SetSD(__GPRO__ char *path, unsigned fperms,
-                     uch *eb_ptr, unsigned eb_len);
-#  endif
-   static int  FindSDExtraField(__GPRO__
-                                uch *ef_ptr, unsigned ef_len,
-                                uch **p_ebSD_ptr, unsigned *p_ebSD_len);
-# endif /* NTSD_EAS */
-
-# ifndef NO_W32TIMES_IZFIX
-   static void utime2NtfsFileTime(time_t ut, FILETIME *pft);
-# endif
-static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin);
-# if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX))
-   static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);
-# endif
-# ifdef W32_STAT_BANDAID
-   static int VFatFileTime2utime(const FILETIME *pft, time_t *ut);
-# endif
-static int FStampIsLocTime(__GPRO__ const char *path);
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-   static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw);
-# endif
-
-
-static int  getNTfiletime   (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT,
-                             FILETIME *pCreFT);
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-static int  getNTfiletimeW  (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT,
-                             FILETIME *pCreFT);
-# endif
-static int  isfloppy        (int nDrive);
-static int  NTQueryVolInfo  (__GPRO__ const char *name);
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-   static int  NTQueryVolInfoW  (__GPRO__ const wchar_t *namew);
-# endif
-static int  IsVolumeOldFAT  (__GPRO__ const char *name);
-static void maskDOSdevice   (__GPRO__ char *pathcomp);
-static void map2fat         (char *pathcomp, char **pEndFAT);
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-  static void maskDOSdevicew (__GPRO__ wchar_t *pathcompw);
-  static void map2fatw      (wchar_t *pathcompw, wchar_t **pEndFATw);
-# endif
-
-
-# if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING))
-   int _CRT_glob = 0;   /* suppress command line globbing by C RTL */
-# endif
-
-# ifdef ACORN_FTYPE_NFS
-/* Acorn bits for NFS filetyping */
-typedef struct {
-  uch ID[2];
-  uch size[2];
-  uch ID_2[4];
-  uch loadaddr[4];
-  uch execaddr[4];
-  uch attr[4];
-} RO_extra_block;
-
-# endif /* ACORN_FTYPE_NFS */
-
-/* static int created_dir;      */     /* used by mapname(), checkdir() */
-/* static int renamed_fullpath; */     /* ditto */
-/* static int fnlen;            */     /* ditto */
-/* static unsigned nLabelDrive; */     /* ditto */
-
-
-
-# ifdef SFX
-
-/**************************/
-/* Function GetLoadPath() */
-/**************************/
-
-char *GetLoadPath(__GPRO)
-{
-#  ifdef MSC
-    extern char *_pgmptr;
-    return _pgmptr;
-
-#  else    /* use generic API call */
-
-    GetModuleFileName(NULL, G.filename, FILNAMSIZ);
-    _ISO_INTERN(G.filename);    /* translate to codepage of C rtl's stdio */
-    return G.filename;
-#  endif
-
-} /* end function GetLoadPath() */
-
-
-
-
-
-# else /* !SFX */
-
-#  ifndef HAVE_WORKING_DIRENT_H
-
-/**********************/        /* Borrowed from ZIP 2.0 sources            */
-/* Function Opendir() */        /* Difference: no special handling for      */
-/**********************/        /*             hidden or system files.      */
-
-static zDIR *Opendir(n)
-    const char *n;          /* directory to open */
-{
-    zDIR *d;                /* malloc'd return value */
-    char *p;                /* malloc'd temporary string */
-    WIN32_FIND_DATAA fd;
-    extent len = strlen(n);
-
-    /* Start searching for files in directory n */
-
-    if ((d = (zDIR *)izu_malloc(sizeof(zDIR))) == NULL ||
-        (p = izu_malloc(strlen(n) + 5)) == NULL)
-    {
-        if (d != (zDIR *)NULL)
-            izu_free((void *)d);
-        return (zDIR *)NULL;
-    }
-    INTERN_TO_ISO(n, p);
-    if (len > 0) {
-        if (p[len-1] == ':')
-            p[len++] = '.';     /* x: => x:. */
-        else if (p[len-1] == '/' || p[len-1] == '\\')
-            --len;              /* foo/ => foo */
-    }
-    strcpy(p+len, "/*");
-
-    if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFileA(p, &fd))) {
-        izu_free((zvoid *)d);
-        izu_free((zvoid *)p);
-        return NULL;
-    }
-    strcpy(d->d_name, fd.cFileName);
-
-    izu_free((zvoid *)p);
-    d->d_first = 1;
-    return d;
-
-} /* end of function Opendir() */
-
-
-
-
-/**********************/        /* Borrowed from ZIP 2.0 sources            */
-/* Function Readdir() */        /* Difference: no special handling for      */
-/**********************/        /*             hidden or system files.      */
-
-static struct zdirent *Readdir(d)
-    zDIR *d;                    /* directory stream from which to read */
-{
-    /* Return pointer to first or next directory entry, or NULL if end. */
-
-    if ( d->d_first )
-        d->d_first = 0;
-    else
-    {
-        WIN32_FIND_DATAA fd;
-
-        if ( !FindNextFileA(d->d_hFindFile, &fd) )
-            return NULL;
-
-        ISO_TO_INTERN(fd.cFileName, d->d_name);
-    }
-    return (struct zdirent *)d;
-
-} /* end of function Readdir() */
-
-
-
-
-/***********************/
-/* Function Closedir() */       /* Borrowed from ZIP 2.0 sources */
-/***********************/
-
-static void Closedir(d)
-    zDIR *d;                    /* directory stream to close */
-{
-    FindClose(d->d_hFindFile);
-    izu_free(d);
-}
-
-#  endif /* !HAVE_WORKING_DIRENT_H */
-# endif /* ?SFX */
-
-
-
-
-# ifdef NTSD_EAS
-
-/**********************/
-/*  Function SetSD()  */   /* return almost-PK errors */
-/**********************/
-
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-static int SetSD(__G__ path, fperms, eb_ptr, eb_len)
-    __GDEF
-    wchar_t *path;
-#  else
-static int SetSD(__G__ path, fperms, eb_ptr, eb_len)
-    __GDEF
-    char *path;
-#  endif
-    unsigned fperms;
-    uch *eb_ptr;
-    unsigned eb_len;
-{
-    ulg ntsd_ucSize;
-    VOLUMECAPS VolumeCaps;
-    uch *security_data;
-    int error;
-
-    ntsd_ucSize = makelong(eb_ptr + (EB_HEADSIZE+EB_UCSIZE_P));
-    if (ntsd_ucSize > 0L && eb_len <= (EB_NTSD_L_LEN + EB_CMPRHEADLEN))
-        return IZ_EF_TRUNC;               /* no compressed data! */
-
-    /* provide useful input */
-    VolumeCaps.dwFileAttributes = fperms;
-    VolumeCaps.bUsePrivileges = (uO.X_flag > 1);
-
-    /* check target volume capabilities - just fall through
-     * and try if fail */
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-    if (GetVolumeCaps(G.rootpathw, path, &VolumeCaps) &&
-        !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS))
-        return PK_OK;
-#  else
-    if (GetVolumeCaps(G.rootpath, path, &VolumeCaps) &&
-        !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS))
-        return PK_OK;
-#  endif
-
-    /* allocate storage for uncompressed data */
-    security_data = (uch *)izu_malloc((extent)ntsd_ucSize);
-    if (security_data == (uch *)NULL)
-        return PK_MEM4;
-
-    error = memextract(__G__ security_data, ntsd_ucSize,
-      (eb_ptr + (EB_HEADSIZE+EB_NTSD_L_LEN)), (ulg)(eb_len - EB_NTSD_L_LEN));
-
-    if (error == PK_OK) {
-        if (SecuritySet(path, &VolumeCaps, security_data)) {
-            error = PK_COOL;
-            if (!uO.tflag && QCOND2)
-                Info(slide, 0, ((char *)slide, " (%lu bytes security)",
-                  ntsd_ucSize));
-        }
-    }
-
-    izu_free(security_data);
-    return error;
-}
-
-
-
-
-/********************************/   /* scan extra fields for something */
-/*  Function FindSDExtraField() */   /*  we happen to know */
-/********************************/
-/* Returns TRUE when a valid NTFS SD block is found.
- * Address and size of the NTSD e.f. block are passed up to the caller.
- * In case of more than one valid NTSD block in the e.f., the last block
- * found is passed up.
- * Returns FALSE and leaves the content of the ebSD_ptr and ebSD_len
- * parameters untouched when no valid NTFS SD block is found. */
-static int FindSDExtraField(__GPRO__
-                            uch *ef_ptr, unsigned ef_len,
-                            uch **p_ebSD_ptr, unsigned *p_ebSD_len)
-{
-    int rc = FALSE;
-
-    if (!uO.X_flag)
-        return FALSE;  /* user said don't process ACLs; for now, no other
-                          extra block types are handled here */
-
-    while (ef_len >= EB_HEADSIZE)
-    {
-        unsigned eb_id = makeword(EB_ID + ef_ptr);
-        unsigned eb_len = makeword(EB_LEN + ef_ptr);
-
-        if (eb_len > (ef_len - EB_HEADSIZE)) {
-            /* discovered some extra field inconsistency! */
-            Trace((stderr,
-              "FindSDExtraField: block length %u > rest ef_size %u\n", eb_len,
-              ef_len - EB_HEADSIZE));
-            break;
-        }
-
-        switch (eb_id)
-        {
-            /* process security descriptor extra data if:
-                 Caller is WinNT AND
-                 Target local/remote drive supports acls AND
-                 Target file is not a directory (else we defer processing
-                   until later)
-             */
-            case EF_NTSD:
-                if (!IsWinNT())
-                    break; /* OS not capable of handling NTFS attributes */
-
-                if (eb_len < EB_NTSD_L_LEN)
-                    break; /* not a valid NTSD extra field */
-
-                /* check if we know how to handle this version */
-                if (*(ef_ptr + (EB_HEADSIZE+EB_NTSD_VERSION))
-                    > (uch)EB_NTSD_MAX_VER)
-                    break;
-
-                *p_ebSD_ptr = ef_ptr;
-                *p_ebSD_len = eb_len;
-                rc = TRUE;
-                break;
-
-#  ifdef DEBUG
-            case EF_OS2:
-            case EF_AV:
-            case EF_PKVMS:
-            case EF_PKW32:
-            case EF_PKUNIX:
-            case EF_IZVMS:
-            case EF_IZUNIX:
-            case EF_IZUNIX2:
-            case EF_TIME:
-            case EF_MAC3:
-            case EF_JLMAC:
-            case EF_ZIPIT:
-            case EF_VMCMS:
-            case EF_MVS:
-            case EF_ACL:
-            case EF_ATHEOS:
-            case EF_BEOS:
-            case EF_QDOS:
-            case EF_AOSVS:
-            case EF_SPARK:
-            case EF_MD5:
-            case EF_ASIUNIX:
-                break;          /* shut up for other known e.f. blocks  */
-#  endif /* DEBUG */
-
-            default:
-                Trace((stderr,
-                  "FindSDExtraField: unknown extra field block, ID=%u\n",
-                  eb_id));
-                break;
-        }
-
-        ef_ptr += (eb_len + EB_HEADSIZE);
-        ef_len -= (eb_len + EB_HEADSIZE);
-    }
-
-    return rc;
-}
-
-
-
-
-#  ifndef SFX
-
-/**************************/
-/*  Function test_NTSD()  */   /*  returns PK_WARN when NTSD data is invalid */
-/**************************/
-
-#   ifdef __BORLANDC__
-/* Turn off warning about not using all parameters for this function only */
-#  pragma argsused
-#   endif
-int test_NTSD(__G__ eb, eb_size, eb_ucptr, eb_ucsize)
-    __GDEF
-    uch *eb;
-    long eb_size;
-    uch *eb_ucptr;
-    ulg eb_ucsize;
-{
-    return (ValidateSecurity(eb_ucptr) ? PK_OK : PK_WARN);
-} /* end function test_NTSD() */
-
-#  endif /* !SFX */
-# endif /* NTSD_EAS */
-
-
-
-
-/**********************/
-/* Function IsWinNT() */
-/**********************/
-
-int IsWinNT(void)       /* returns TRUE if real NT, FALSE if Win9x or Win32s */
-{
-    static DWORD g_PlatformId = 0xFFFFFFFF; /* saved platform indicator */
-
-    if (g_PlatformId == 0xFFFFFFFF) {
-        /* note: GetVersionEx() doesn't exist on WinNT 3.1 */
-        if (GetVersion() < 0x80000000)
-            g_PlatformId = TRUE;
-        else
-            g_PlatformId = FALSE;
-    }
-    return (int)g_PlatformId;
-}
-
-
-/* DEBUG_TIME insertion: */
-# ifdef DEBUG_TIME
-static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft);
-
-static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft)
-{
-    SYSTEMTIME w32tm;
-    int rval;
-
-    rval = FileTimeToSystemTime(pft, &w32tm);
-    if (!rval) {
-        fprintf(hdo, "%s\n %08lX,%08lX (%s) -> Conversion failed !!!\n",
-                TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime),
-                (isloc ? "local" : "UTC"));
-    } else {
-        fprintf(hdo, "%s\n %08lx,%08lx -> %04u-%02u-%02u, %02u:%02u:%02u %s\n",
-                TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime),
-                w32tm.wYear, w32tm.wMonth, w32tm.wDay, w32tm.wHour,
-                w32tm.wMinute, w32tm.wSecond, (isloc ? "local" : "UTC"));
-    }
-    return rval;
-}
-#define FTTrace(x)   show_NTFileTime x
-# else
-#define FTTrace(x)
-# endif /* DEBUG_TIME */
-/* end of DEBUG_TIME insertion */
-
-# ifndef IZ_USE_INT64
-#  if (defined(__GNUC__) || defined(ULONG_LONG_MAX))
-     typedef long long            LLONG64;
-     typedef unsigned long long   ULLNG64;
-#    define IZ_USE_INT64
-#  elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
-     typedef __int64              LLONG64;
-     typedef unsigned __int64     ULLNG64;
-#    define IZ_USE_INT64
-#  elif (defined(_MSC_VER) && (_MSC_VER >= 1100))
-     typedef __int64              LLONG64;
-     typedef unsigned __int64     ULLNG64;
-#    define IZ_USE_INT64
-#  elif (defined(__IBMC__) && (__IBMC__ >= 350))
-     typedef __int64              LLONG64;
-     typedef unsigned __int64     ULLNG64;
-#    define IZ_USE_INT64
-#  elif defined(HAVE_INT64)
-     typedef __int64              LLONG64;
-     typedef unsigned __int64     ULLNG64;
-#    define IZ_USE_INT64
-#  endif
-# endif
-
-/* scale factor and offset for conversion time_t -> FILETIME */
-#define NT_QUANTA_PER_UNIX 10000000L
-#define UNIX_TIME_ZERO_HI  0x019DB1DEUL
-#define UNIX_TIME_ZERO_LO  0xD53E8000UL
-/* special FILETIME values for bound-checks */
-#define UNIX_TIME_UMAX_HI  0x0236485EUL
-#define UNIX_TIME_UMAX_LO  0xD4A5E980UL
-#define UNIX_TIME_SMIN_HI  0x0151669EUL
-#define UNIX_TIME_SMIN_LO  0xD53E8000UL
-#define UNIX_TIME_SMAX_HI  0x01E9FD1EUL
-#define UNIX_TIME_SMAX_LO  0xD4A5E980UL
-#define DOSTIME_MIN_FT_HI  0x01A8E79FUL
-#define DOSTIME_MIN_FT_LO  0xE1D58000UL
-/* time_t equivalent of DOSTIME_MINIMUM */
-#define UTIME_1980_JAN_01_00_00   315532800L
-
-
-# ifndef NO_W32TIMES_IZFIX
-/*********************************/
-/* Function utime2NtfsFileTime() */ /* convert Unix time_t format into the */
-/*********************************/ /* form used by SetFileTime() in NT/9x */
-
-static void utime2NtfsFileTime(time_t ut, FILETIME *pft)
-{
-#  ifdef IZ_USE_INT64
-    ULLNG64 NTtime;
-
-    /* NT_QUANTA_PER_UNIX is small enough so that "ut * NT_QUANTA_PER_UNIX"
-     * cannot overflow in 64-bit signed calculation, regardless whether "ut"
-     * is signed or unsigned.  */
-    NTtime = ((LLONG64)ut * NT_QUANTA_PER_UNIX) +
-             ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32));
-    pft->dwLowDateTime = (DWORD)NTtime;
-    pft->dwHighDateTime = (DWORD)(NTtime >> 32);
-
-#  else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */
-    unsigned int b1, b2, carry = 0;
-    unsigned long r0, r1, r2, r3;
-    long r4;            /* signed, to catch environments with signed time_t */
-
-    b1 = ut & 0xFFFF;
-    b2 = (ut >> 16) & 0xFFFF;       /* if ut is over 32 bits, too bad */
-    r1 = b1 * (NT_QUANTA_PER_UNIX & 0xFFFF);
-    r2 = b1 * (NT_QUANTA_PER_UNIX >> 16);
-    r3 = b2 * (NT_QUANTA_PER_UNIX & 0xFFFF);
-    r4 = b2 * (NT_QUANTA_PER_UNIX >> 16);
-    r0 = (r1 + (r2 << 16)) & 0xFFFFFFFFL;
-    if (r0 < r1)
-        carry++;
-    r1 = r0;
-    r0 = (r0 + (r3 << 16)) & 0xFFFFFFFFL;
-    if (r0 < r1)
-        carry++;
-    pft->dwLowDateTime = r0 + UNIX_TIME_ZERO_LO;
-    if (pft->dwLowDateTime < r0)
-        carry++;
-    pft->dwHighDateTime = r4 + (r2 >> 16) + (r3 >> 16)
-                            + UNIX_TIME_ZERO_HI + carry;
-#  endif /* ?IZ_USE_INT64 */
-
-} /* end function utime2NtfsFileTime() */
-# endif /* !NO_W32TIMES_IZFIX */
-
-
-
-/*********************************/
-/* Function utime2VFatFileTime() */ /* convert Unix time_t format into the */
-/*********************************/ /* form used by SetFileTime() in NT/9x */
-
-static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin)
-{
-    time_t utc = ut;
-    struct tm *ltm;
-    SYSTEMTIME w32tm;
-    FILETIME lft;
-
-    /* The milliseconds field gets always initialized to 0. */
-    w32tm.wMilliseconds = 0;
-
-# ifdef __BORLANDC__   /* Borland C++ 5.x crashes when trying to reference tm */
-    if (utc < UTIME_1980_JAN_01_00_00)
-        utc = UTIME_1980_JAN_01_00_00;
-# endif
-    ltm = localtime(&utc);
-    if (ltm == (struct tm *)NULL)
-        /* localtime() did not accept given utc time value; try to use
-           the UTC value */
-        ltm = gmtime(&utc);
-    if (ltm == (struct tm *)NULL) {
-        if (ut <= (UTIME_1980_JAN_01_00_00 + 86400)) {
-            /* use DOSTIME_MINIMUM date instead of "early" failure dates */
-            w32tm.wYear = 1980;
-            w32tm.wMonth = 1;
-            w32tm.wDay = 1;
-            w32tm.wHour = 0;
-            w32tm.wMinute = 0;
-            w32tm.wSecond = 0;
-        } else {
-            /* as a last resort, use the current system time */
-            GetLocalTime(&w32tm);
-        }
-    } else if (clipDosMin && (ltm->tm_year < 80)) {
-        w32tm.wYear = 1980;
-        w32tm.wMonth = 1;
-        w32tm.wDay = 1;
-        w32tm.wHour = 0;
-        w32tm.wMinute = 0;
-        w32tm.wSecond = 0;
-    } else {
-        w32tm.wYear = ltm->tm_year + 1900; /* year + 1900 -> year */
-        w32tm.wMonth = ltm->tm_mon + 1;    /* 0..11 -> 1..12 */
-        w32tm.wDay = ltm->tm_mday;         /* 1..31 */
-        w32tm.wHour = ltm->tm_hour;        /* 0..23 */
-        w32tm.wMinute = ltm->tm_min;       /* 0..59 */
-        w32tm.wSecond = ltm->tm_sec;       /* 0..61 in ANSI C */
-    }
-
-    SystemTimeToFileTime(&w32tm, &lft);
-    LocalFileTimeToFileTime(&lft, pft);
-
-} /* end function utime2VFatFileTime() */
-
-
-
- /* nonzero if `y' is a leap year, else zero */
-#define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0)
- /* number of leap years from 1970 to `y' (not including `y' itself) */
-#define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400)
-
-extern ZCONST ush ydays[];              /* defined in fileio.c */
-
-# if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX))
-/*********************************/
-/* Function NtfsFileTime2utime() */
-/*********************************/
-
-static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut)
-{
-#  ifdef IZ_USE_INT64
-    ULLNG64 NTtime;
-
-    NTtime = ((ULLNG64)pft->dwLowDateTime +
-              ((ULLNG64)pft->dwHighDateTime << 32));
-
-#   ifndef TIME_T_TYPE_DOUBLE
-    /* underflow and overflow handling */
-#    ifdef CHECK_UTIME_SIGNED_UNSIGNED
-    if ((time_t)0x80000000L < (time_t)0L)
-    {
-        if (NTtime < ((ULLNG64)UNIX_TIME_SMIN_LO +
-                      ((ULLNG64)UNIX_TIME_SMIN_HI << 32))) {
-            *ut = (time_t)LONG_MIN;
-            return FALSE;
-        }
-        if (NTtime > ((ULLNG64)UNIX_TIME_SMAX_LO +
-                      ((ULLNG64)UNIX_TIME_SMAX_HI << 32))) {
-            *ut = (time_t)LONG_MAX;
-            return FALSE;
-        }
-    }
-    else
-#    endif /* CHECK_UTIME_SIGNED_UNSIGNED */
-    {
-        if (NTtime < ((ULLNG64)UNIX_TIME_ZERO_LO +
-                      ((ULLNG64)UNIX_TIME_ZERO_HI << 32))) {
-            *ut = (time_t)0;
-            return FALSE;
-        }
-        if (NTtime > ((ULLNG64)UNIX_TIME_UMAX_LO +
-                      ((ULLNG64)UNIX_TIME_UMAX_HI << 32))) {
-            *ut = (time_t)ULONG_MAX;
-            return FALSE;
-        }
-    }
-#   endif /* !TIME_T_TYPE_DOUBLE */
-
-    NTtime -= ((ULLNG64)UNIX_TIME_ZERO_LO +
-               ((ULLNG64)UNIX_TIME_ZERO_HI << 32));
-    *ut = (time_t)(NTtime / (unsigned long)NT_QUANTA_PER_UNIX);
-    return TRUE;
-#  else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */
-    time_t days;
-    SYSTEMTIME w32tm;
-
-#   ifndef TIME_T_TYPE_DOUBLE
-    /* underflow and overflow handling */
-#    ifdef CHECK_UTIME_SIGNED_UNSIGNED
-    if ((time_t)0x80000000L < (time_t)0L)
-    {
-        if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
-             (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
-            *ut = (time_t)LONG_MIN;
-            return FALSE;
-        if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
-             (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
-            *ut = (time_t)LONG_MAX;
-            return FALSE;
-        }
-    }
-    else
-#    endif /* CHECK_UTIME_SIGNED_UNSIGNED */
-    {
-        if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
-             (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
-            *ut = (time_t)0;
-            return FALSE;
-        }
-        if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
-             (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
-            *ut = (time_t)ULONG_MAX;
-            return FALSE;
-        }
-    }
-#   endif /* !TIME_T_TYPE_DOUBLE */
-
-    FileTimeToSystemTime(pft, &w32tm);
-
-    /* set `days' to the number of days into the year */
-    days = w32tm.wDay - 1 + ydays[w32tm.wMonth-1] +
-           (w32tm.wMonth > 2 && leap (w32tm.wYear));
-
-    /* now set `days' to the number of days since 1 Jan 1970 */
-    days += 365 * (time_t)(w32tm.wYear - 1970) +
-            (time_t)(nleap(w32tm.wYear));
-
-    *ut = (time_t)(86400L * days + 3600L * (time_t)w32tm.wHour +
-                   (time_t)(60 * w32tm.wMinute + w32tm.wSecond));
-    return TRUE;
-#  endif /* ?IZ_USE_INT64 */
-} /* end function NtfsFileTime2utime() */
-# endif /* W32_STAT_BANDAID && !NO_W32TIMES_IZFIX */
-
-
-
-# ifdef W32_STAT_BANDAID
-/*********************************/
-/* Function VFatFileTime2utime() */
-/*********************************/
-
-static int VFatFileTime2utime(const FILETIME *pft, time_t *ut)
-{
-    FILETIME lft;
-#  ifndef HAVE_MKTIME
-    WORD wDOSDate, wDOSTime;
-#  else
-    SYSTEMTIME w32tm;
-    struct tm ltm;
-#  endif
-
-    if (!FileTimeToLocalFileTime(pft, &lft)) {
-        /* if pft cannot be converted to local time, set ut to current time */
-        time(ut);
-        return FALSE;
-    }
-    FTTrace((stdout, "VFatFT2utime, feed for mktime()", 1, &lft));
-#  ifndef HAVE_MKTIME
-    /* This version of the FILETIME-to-UNIXTIME conversion function
-     * uses DOS-DATE-TIME format as intermediate stage. For modification
-     * and access times, this is no problem. But, the extra fine resolution
-     * of the VFAT-stored creation time gets lost.
-     */
-    if (!FileTimeToDosDateTime(&lft, &wDOSDate, &wDOSTime)) {
-        static const FILETIME dosmin_ft =
-                {DOSTIME_MIN_FT_LO, DOSTIME_MIN_FT_HI};
-        if (CompareFileTime(&lft, &dosmin_ft) <= 0) {
-            /* underflow -> set to minimum DOS time */
-            wDOSDate = (WORD)((DWORD)DOSTIME_MINIMUM >> 16);
-            wDOSTime = (WORD)DOSTIME_MINIMUM;
-        } else {
-            /* overflow -> set to maximum DOS time */
-            wDOSDate = (WORD)0xFF9F;    /* 2107-12-31 */
-            wDOSTime = (WORD)0xBF7D;    /* 23:59:58 */
-        }
-    }
-    TTrace((stdout,"DosDateTime is %04u-%02u-%02u %02u:%02u:%02u\n",
-      (unsigned)((wDOSDate>>9)&0x7f)+1980,(unsigned)((wDOSDate>>5)&0x0f),
-      (unsigned)(wDOSDate&0x1f),(unsigned)((wDOSTime>>11)&0x1f),
-      (unsigned)((wDOSTime>>5)&0x3f),(unsigned)((wDOSTime<<1)&0x3e)));
-    *ut = dos_to_unix_time(((ulg)wDOSDate << 16) | (ulg)wDOSTime);
-
-    /* a cheap error check: dos_to_unix_time() only returns an odd time
-     * when clipping at maximum time_t value. DOS_DATE_TIME values have
-     * a resolution of 2 seconds and are therefore even numbers.
-     */
-    return (((*ut)&1) == (time_t)0);
-#  else /* HAVE_MKTIME */
-    FileTimeToSystemTime(&lft, &w32tm);
-#   ifndef TIME_T_TYPE_DOUBLE
-    /* underflow and overflow handling */
-    /* TODO: The range checks are not accurate, the actual limits may
-     *       be off by one daylight-saving-time shift (typically 1 hour),
-     *       depending on the current state of "is_dst".
-     */
-#    ifdef CHECK_UTIME_SIGNED_UNSIGNED
-    if ((time_t)0x80000000L < (time_t)0L)
-    {
-        if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
-             (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
-            *ut = (time_t)LONG_MIN;
-            return FALSE;
-        if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
-             (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
-            *ut = (time_t)LONG_MAX;
-            return FALSE;
-        }
-    }
-    else
-#    endif /* CHECK_UTIME_SIGNED_UNSIGNED */
-    {
-        if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
-             (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
-            *ut = (time_t)0;
-            return FALSE;
-        }
-        if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
-            ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
-             (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
-            *ut = (time_t)ULONG_MAX;
-            return FALSE;
-        }
-    }
-#   endif /* !TIME_T_TYPE_DOUBLE */
-    ltm.tm_year = w32tm.wYear - 1900;
-    ltm.tm_mon = w32tm.wMonth - 1;
-    ltm.tm_mday = w32tm.wDay;
-    ltm.tm_hour = w32tm.wHour;
-    ltm.tm_min = w32tm.wMinute;
-    ltm.tm_sec = w32tm.wSecond;
-    ltm.tm_isdst = -1;  /* let mktime determine if DST is in effect */
-    *ut = mktime(&ltm);
-
-    /* a cheap error check: mktime returns "(time_t)-1L" on conversion errors.
-     * Normally, we would have to apply a consistency check because "-1"
-     * could also be a valid time. But, it is quite unlikely to read back odd
-     * time numbers from file systems that store time stamps in DOS format.
-     * (The only known exception is creation time on VFAT partitions.)
-     */
-    return (*ut != (time_t)-1L);
-#  endif /* ?HAVE_MKTIME */
-
-} /* end function VFatFileTime2utime() */
-# endif /* W32_STAT_BANDAID */
-
-
-
-/******************************/
-/* Function FStampIsLocTime() */
-/******************************/
-
-static int FStampIsLocTime(__GPRO__ const char *path)
-{
-    return (NTQueryVolInfo(__G__ path) ? G.lastVolLocTim : FALSE);
-}
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw)
-{
-    return (NTQueryVolInfoW(__G__ pathw) ? G.lastVolLocTim : FALSE);
-}
-# endif
-
-
-
-
-# ifndef NO_W32TIMES_IZFIX
-# define UTIME_2_IZFILETIME(ut, pft) \
-   if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \
-   else {utime2NtfsFileTime(ut, pft);}
-# else
-# define UTIME_2_IZFILETIME(ut, pft) \
-   utime2VFatFileTime(ut, pft, fs_uses_loctime);
-# endif
-
-
-
-
-
-
-
-/****************************/      /* Get the file time in a format that */
-/* Function getNTfiletime() */      /*  can be used by SetFileTime() in NT */
-/****************************/
-
-static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT)
-    __GDEF
-    FILETIME *pModFT;
-    FILETIME *pAccFT;
-    FILETIME *pCreFT;
-{
-# ifdef USE_EF_UT_TIME
-    unsigned eb_izux_flg;
-    iztimes z_utime;   /* struct for Unix-style actime & modtime, + creatime */
-# endif
-    int fs_uses_loctime = FStampIsLocTime(__G__ G.filename);
-
-    /* Copy and/or convert time and date variables, if necessary;
-     * return a flag indicating which time stamps are available. */
-# ifdef USE_EF_UT_TIME
-    if (G.extra_field &&
-#  ifdef IZ_CHECK_TZ
-        G.tz_is_valid &&
-#  endif
-        ((eb_izux_flg = ef_scan_for_izux(G.extra_field,
-          G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
-          &z_utime, NULL)) & EB_UT_FL_MTIME))
-    {
-        TTrace((stderr, "getNTfiletime:  Unix e.f. modif. time = %lu\n",
-          z_utime.mtime));
-        UTIME_2_IZFILETIME(z_utime.mtime, pModFT)
-        if (eb_izux_flg & EB_UT_FL_ATIME) {
-            UTIME_2_IZFILETIME(z_utime.atime, pAccFT)
-        }
-        if (eb_izux_flg & EB_UT_FL_CTIME) {
-            UTIME_2_IZFILETIME(z_utime.ctime, pCreFT)
-        }
-        return (int)eb_izux_flg;
-    }
-# endif /* USE_EF_UT_TIME */
-# ifndef NO_W32TIMES_IZFIX
-    if (!fs_uses_loctime) {
-        time_t ux_modtime;
-
-        ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
-        utime2NtfsFileTime(ux_modtime, pModFT);
-    } else
-# endif /* NO_W32TIMES_IZFIX */
-    {
-        FILETIME lft;
-
-        DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16),
-                              (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL),
-                              &lft);
-        LocalFileTimeToFileTime(&lft, pModFT);
-    }
-    *pAccFT = *pModFT;
-    return (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
-
-} /* end function getNTfiletime() */
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-  static int getNTfiletimeW(__G__ pModFT, pAccFT, pCreFT)
-      __GDEF
-      FILETIME *pModFT;
-      FILETIME *pAccFT;
-      FILETIME *pCreFT;
-  {
-#  ifdef USE_EF_UT_TIME
-      unsigned eb_izux_flg;
-      iztimes z_utime;   /* struct for Unix-style actime & modtime, + creatime */
-#  endif
-      int fs_uses_loctime = FStampIsLocTimeW(__G__ G.unipath_widefilename);
-
-      /* Copy and/or convert time and date variables, if necessary;
-       * return a flag indicating which time stamps are available. */
-#  ifdef USE_EF_UT_TIME
-      if (G.extra_field &&
-#   ifdef IZ_CHECK_TZ
-          G.tz_is_valid &&
-#   endif
-          ((eb_izux_flg = ef_scan_for_izux(G.extra_field,
-            G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
-            &z_utime, NULL)) & EB_UT_FL_MTIME))
-      {
-          TTrace((stderr, "getNTfiletime:  Unix e.f. modif. time = %lu\n",
-            z_utime.mtime));
-          UTIME_2_IZFILETIME(z_utime.mtime, pModFT)
-          if (eb_izux_flg & EB_UT_FL_ATIME) {
-              UTIME_2_IZFILETIME(z_utime.atime, pAccFT)
-          }
-          if (eb_izux_flg & EB_UT_FL_CTIME) {
-              UTIME_2_IZFILETIME(z_utime.ctime, pCreFT)
-          }
-          return (int)eb_izux_flg;
-      }
-#  endif /* USE_EF_UT_TIME */
-#  ifndef NO_W32TIMES_IZFIX
-      if (!fs_uses_loctime) {
-          time_t ux_modtime;
-
-          ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
-          utime2NtfsFileTime(ux_modtime, pModFT);
-      } else
-#  endif /* NO_W32TIMES_IZFIX */
-      {
-          FILETIME lft;
-
-          DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16),
-                                (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL),
-                                &lft);
-          LocalFileTimeToFileTime(&lft, pModFT);
-      }
-      *pAccFT = *pModFT;
-      return (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
-
-  } /* end function getNTfiletime() */
-# endif /* (UNICODE_SUPPORT && WIN32_WIDE) */
-
-
-
-
-/**************************/
-/* Function SetFileSize() */
-/**************************/
-
-int SetFileSize(FILE *file, zusz_t filesize)
-{
-# ifdef __RSXNT__
-    /* RSXNT environment lacks a translation function from C file pointer
-       to Win32-API file handle. So, simply do nothing. */
-    return 0;
-# else /* !__RSXNT__ */
-    /* not yet verified, if that really creates an unfragmented file
-      rommel@ars.de
-     */
-    HANDLE os_fh;
-#  ifdef Z_UINT8_DEFINED
-    LARGE_INTEGER fsbuf;
-#  endif
-
-    /* Win9x supports FAT file system, only; presetting file size does
-       not help to prevent fragmentation. */
-    if (!IsWinNT()) return 0;
-
-    /* Win32-API calls require access to the Win32 file handle.
-       The interface function used to retrieve the Win32 handle for
-       a file opened by the C rtl is non-standard and may not be
-       available for every Win32 compiler environment.
-       (see also win32/win32.c of the Zip distribution)
-     */
-    os_fh = (HANDLE)_get_osfhandle(fileno(file));
-    /* move file pointer behind the last byte of the expected file size */
-#  ifdef Z_UINT8_DEFINED
-    fsbuf.QuadPart = filesize;
-    if ((SetFilePointer(os_fh, fsbuf.LowPart, &fsbuf.HighPart, FILE_BEGIN)
-         == 0xFFFFFFFF) && GetLastError() != NO_ERROR)
-#  else
-    if (SetFilePointer(os_fh, (ulg)filesize, 0, FILE_BEGIN) == 0xFFFFFFFF)
-#  endif
-        return -1;
-    /* extend/truncate file to the current position */
-    if (SetEndOfFile(os_fh) == 0) {
-        SetFilePointer(os_fh, 0, 0, FILE_BEGIN);
-        return -1;
-    }
-    /* move file position pointer back to the start of the file! */
-    return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0;
-# endif /* ?__RSXNT__ */
-} /* end function SetFileSize() */
-
-
-
-
-/****************************/
-/* Function close_outfile() */
-/****************************/
-
-void close_outfile(__G)
-    __GDEF
-{
-    FILETIME Modft;    /* File time type defined in NT, `last modified' time */
-    FILETIME Accft;    /* NT file time type, `last access' time */
-    FILETIME Creft;    /* NT file time type, `file creation' time */
-    HANDLE hFile = INVALID_HANDLE_VALUE;        /* File handle defined in NT */
-    int gotTime;
-# ifdef NTSD_EAS
-    uch *ebSDptr;
-    unsigned ebSDlen;
-# endif
-
-/* 2013-07-08 SMS.  See note below. */
-# ifdef RETRY_CREATEFILE
-    int cf_tries;
-# endif
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-    if (!G.has_win32_wide) {
-# endif
-# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-      char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
-
-      INTERN_TO_ISO(G.filename, ansi_name);
-#     define Ansi_Fname  ansi_name
-# else
-#     define Ansi_Fname  G.filename
-# endif
-
-/*---------------------------------------------------------------------------
-    If symbolic links are supported, allocate storage for a symlink
-    control structure, put the uncompressed "data" and other required
-    info into it, and add the structure to the "deferred symlinks"
-    chain.  Because we know it's a symbolic link, we shouldn't need to
-    worry about overflowing unsigned ints with unsigned longs.
- ---------------------------------------------------------------------------*/
-
-# ifdef SYMLINKS
-    if (G.symlnk) {
-        extent ucsize = (extent)G.lrec.ucsize;
-#  ifdef SET_SYMLINK_ATTRIBS
-        /* 2013-12-05 SMS.
-         * Note that z_uidgid is not (yet?) declared for WIN32, and must
-         * be an array/ponter for this usage to make sense.  See
-         * unix/unix.c.
-         */
-        extent attribsize = sizeof(unsigned) +
-                            (have_uidgid_flg ? sizeof( z_uidgid) : 0);
-#  else
-        extent attribsize = 0;
-#  endif
-        /* Size of the symlink entry is the sum of:
-         *  struct size (includes 1 (buf[1]) for target text NUL),
-         *  system specific attribute data size (might be 0),
-         *  target text length (only -- NUL already counted, above),
-         *  link name length + 1 (NUL).
-         */
-        extent slnk_entrysize = sizeof( slinkentry) + attribsize +
-         ucsize + strlen( G.filename) + 1;
-
-        slinkentry *slnk_entry;
-
-        if (slnk_entrysize < ucsize) {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed: mem alloc overflow\n",
-              FnFilter1(G.filename)));
-            fclose(G.outfile);
-            return;
-        }
-
-        if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed: no mem\n",
-              FnFilter1(G.filename)));
-            fclose(G.outfile);
-            return;
-        }
-        slnk_entry->next = NULL;
-        slnk_entry->targetlen = ucsize;
-        slnk_entry->attriblen = attribsize;
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-        slnk_entry->wide = 0;
-#  endif
-#  ifdef SET_SYMLINK_ATTRIBS
-        memcpy( slnk_entry->buf, &(G.pInfo->file_attr),
-         sizeof( G.pInfo->file_attr));
-        if (have_uidgid_flg)
-            memcpy( (slnk_entry->buf+ sizeof( unsigned)), z_uidgid,
-             sizeof( z_uidgid));
-#  endif
-        slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen;
-        slnk_entry->fname = slnk_entry->target + ucsize + 1;
-        strcpy(slnk_entry->fname, G.filename);
-
-        /* If symlink name ends in '/', then flag as directory. */
-        slnk_entry->is_dir = 0;
-        if (G.filename[ strlen( G.filename)- 1] == '/')
-            slnk_entry->is_dir = 1;
-
-        /* move back to the start of the file to re-read the "link data" */
-        rewind(G.outfile);
-
-        if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
-        {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed\n",
-              FnFilter1(G.filename)));
-            free(slnk_entry);
-            fclose(G.outfile);
-            return;
-        }
-        slnk_entry->target[ucsize] = '\0';
-        if (QCOND2)
-            Info(slide, 0, ((char *)slide, "-> %s ",
-              FnFilter1(slnk_entry->target)));
-        /* add this symlink record to the list of deferred symlinks */
-        if (G.slink_last != NULL)
-            G.slink_last->next = slnk_entry;
-        else
-            G.slink_head = slnk_entry;
-        G.slink_last = slnk_entry;
-        fclose( G.outfile);
-        return;
-    }
-# endif /* def SYMLINKS */
-
-# ifndef __RSXNT__
-#  if !(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE))
-      if (IsWinNT()) {
-        /* Truncate the file to the current position.
-         * This is needed to remove excess allocation in case the
-         * extraction has failed or stopped prematurely. */
-        SetEndOfFile((HANDLE)_get_osfhandle(fileno(G.outfile)));
-      }
-#  endif /* !(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-# endif
-
-      /* Close the file and then re-open it using the Win32
-       * CreateFile call, so that the file can be created
-       * with GENERIC_WRITE access, otherwise the SetFileTime
-       * call will fail. */
-      fclose(G.outfile);
-
-      /* don't set the time stamp and attributes on standard output */
-      if (uO.cflag)
-          return;
-
-      gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
-
-      /* open a handle to the file before processing extra fields;
-         we do this in case new security on file prevents us from updating
-         time stamps */
-
-      /* 2013-07-08 SMS.
-       * Some anti-virus programs may temporarily lock a newly created
-       * file, causing transient failures of CreateFile[AW]() when
-       * setting date-time (win32/win32.c:close_outfile()).
-       * We try up to IZ_CREATEFILE_TRY_COUNT times, at intervals of
-       * IZ_CREATEFILE_TRY_TIME_MS (millisecond).  To disable the
-       * retries, define IZ_CREATEFILE_TRY_COUNT as zero.  (win32/w32cfg.h).
-       * http://sourceforge.net/p/infozip/bugs/44/
-       * http://support.microsoft.com/kb/316609
-       *
-       * Perhaps the count or time interval should depend on the file
-       * size?
-       */
-#ifdef RETRY_CREATEFILE
-      for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--)
-      {
-#endif /* def RETRY_CREATEFILE */
-
-         hFile = CreateFileA( Ansi_Fname,
-          GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
-          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
-#ifdef RETRY_CREATEFILE
-         if (hFile == INVALID_HANDLE_VALUE)
-         {
-            if (GetLastError() != ERROR_SHARING_VIOLATION)
-               break;   /* Not a sharing error.  Get out now.  Otherwise: */
-            Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */
-         }
-         else
-         {
-             break;     /* Not a sharing error.  (Success?)  Get out now. */
-         }
-      }
-#endif /* def RETRY_CREATEFILE */
-
-      /* sfield@microsoft.com: set attributes before time in case we decide to
-         support other filetime members later.  This also allows us to apply
-         attributes before the security is changed, which may prevent this
-         from succeeding otherwise.  Also, since most files don't have
-         any interesting attributes, only change them if something other than
-         FILE_ATTRIBUTE_ARCHIVE appears in the attributes.  This works well
-         as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the
-         file anyway, when it's created new. */
-      if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) {
-          if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
-              Info(slide, 1, ((char *)slide,
-                "\nwarning (%d): could not set file attributes (1)\n",
-                (int)GetLastError()));
-      }
-
-
-# ifdef NTSD_EAS
-      /* set NTFS SD extra fields */
-      if (G.extra_field &&    /* zipfile extra field may have extended attribs */
-          FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
-                           &ebSDptr, &ebSDlen))
-      {
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-        /* no win32_wide implies "no NT SD support", so FindSDExtraField
-         * will never return "success".
-         */
-#  else /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-        int err = SetSD(__G__ Ansi_Fname, G.pInfo->file_attr,
-                        ebSDptr, ebSDlen);
-
-        if (err == IZ_EF_TRUNC) {
-            if (uO.qflag)
-                Info(slide, 1, ((char *)slide, "%-22s ",
-                  FnFilter1(G.filename)));
-            Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
-              ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":""));
-        }
-#  endif /* ? (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-      }
-# endif /* NTSD_EAS */
-
-      /* skip restoring time stamps on user's request */
-      if (uO.D_flag <= 1) {
-        if ( hFile == INVALID_HANDLE_VALUE )
-            Info(slide, 1, ((char *)slide,
-              "\nCreateFile(1) error %d when trying to set file time\n",
-              (int)GetLastError()));
-        else {
-            if (gotTime) {
-                FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
-                FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
-                FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
-
-                if (!SetFileTime(hFile, pCreft, pAccft, pModft))
-                    Info(slide, 0, ((char *)slide,
-                      "\nSetFileTime(1) failed: %d\n", (int)GetLastError()));
-            }
-            CloseHandle(hFile);
-        }
-    }
-
-    return;
-
-#undef Ansi_Fname
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-    } else {
-      /* wide version */
-
-/*---------------------------------------------------------------------------
-    If symbolic links are supported, allocate storage for a symlink
-    control structure, put the uncompressed "data" and other required
-    info into it, and add the structure to the "deferred symlinks"
-    chain.  Because we know it's a symbolic link, we shouldn't need to
-    worry about overflowing unsigned ints with unsigned longs.
- ---------------------------------------------------------------------------*/
-
-# ifdef SYMLINKS
-    if (G.symlnk) {
-        extent ucsize = (extent)G.lrec.ucsize;
-#  ifdef SET_SYMLINK_ATTRIBS
-        extent attribsize = sizeof(unsigned) +
-                            (have_uidgid_flg ? sizeof( z_uidgid) : 0);
-#  else
-        extent attribsize = 0;
-#  endif
-        /* Note: Hard-coded assumption that sizeof( wchar_t) = 2. */
-        int fname_aligner = (attribsize+ ucsize+ 1)& 1; /* Necessary? */
-
-        /* Size of the symlink entry is the sum of:
-         *  struct size (includes 1 (buf[1]) for target text NUL),
-         *  system specific attribute data size (might be 0),
-         *  target text length (only -- NUL already counted, above),
-         *  1 (optional) to align wide link name,
-         *  link name length + 1 (NUL).
-         */
-        extent slnk_entrysize = sizeof(slinkentry) + attribsize +
-         ucsize + fname_aligner +
-         sizeof( wchar_t)* (wcslen( G.unipath_widefilename)+ 1);
-
-        slinkentry *slnk_entry;
-
-        if (slnk_entrysize < ucsize) {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed: mem alloc overflow\n",
-              FnFilter1(G.filename)));
-            fclose(G.outfile);
-            return;
-        }
-
-        if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed: no mem\n",
-              FnFilter1(G.filename)));
-            fclose(G.outfile);
-            return;
-        }
-        slnk_entry->next = NULL;
-        slnk_entry->targetlen = ucsize;
-        slnk_entry->attriblen = attribsize;
-        slnk_entry->wide = 1;
-#  ifdef SET_SYMLINK_ATTRIBS
-        memcpy(slnk_entry->buf, &(G.pInfo->file_attr),
-               sizeof(unsigned));
-        if (have_uidgid_flg)
-            memcpy( (slnk_entry->buf + sizeof( unsigned)), z_uidgid,
-             sizeof( z_uidgid));
-#  endif
-        slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen;
-        slnk_entry->fname = slnk_entry->target + ucsize + 1 + fname_aligner;
-        wcscpy( (wchar_t *)slnk_entry->fname, G.unipath_widefilename);
-
-        slnk_entry->is_dir = 0;
-        if (G.filename[strlen(G.filename) - 1] == '/')
-          slnk_entry->is_dir = 1;
-
-        /* move back to the start of the file to re-read the "link data" */
-        rewind(G.outfile);
-
-        if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
-        {
-            Info(slide, 0x201, ((char *)slide,
-              "warning:  symbolic link (%s) failed\n",
-              FnFilter1(G.filename)));
-            free(slnk_entry);
-            fclose(G.outfile);
-            return;
-        }
-        slnk_entry->target[ucsize] = '\0';
-        if (QCOND2)
-            Info(slide, 0, ((char *)slide, "-> %s ",
-              FnFilter1(slnk_entry->target)));
-        /* add this symlink record to the list of deferred symlinks */
-        if (G.slink_last != NULL)
-            G.slink_last->next = slnk_entry;
-        else
-            G.slink_head = slnk_entry;
-        G.slink_last = slnk_entry;
-        fclose( G.outfile);
-        return;
-    }
-# endif /* def SYMLINKS */
-
-#  ifndef __RSXNT__
-      if (IsWinNT()) {
-          /* Truncate the file to the current position.
-           * This is needed to remove excess allocation in case the
-           * extraction has failed or stopped prematurely. */
-          SetEndOfFile((HANDLE)_get_osfhandle(fileno(G.outfile)));
-      }
-#  endif
-
-      /* Close the file and then re-open it using the Win32
-       * CreateFile call, so that the file can be created
-       * with GENERIC_WRITE access, otherwise the SetFileTime
-       * call will fail. */
-      fclose(G.outfile);
-
-      /* don't set the time stamp and attributes on standard output */
-      if (uO.cflag)
-          return;
-
-      gotTime = getNTfiletimeW(__G__ &Modft, &Accft, &Creft);
-
-      /* open a handle to the file before processing extra fields;
-         we do this in case new security on file prevents us from updating
-         time stamps */
-
-      /* 2013-07-08 SMS.  See note above. */
-#ifdef RETRY_CREATEFILE
-      for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--)
-      {
-#endif /* def RETRY_CREATEFILE */
-
-         hFile = CreateFileW(G.unipath_widefilename,
-          GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
-          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
-#ifdef RETRY_CREATEFILE
-         if (hFile == INVALID_HANDLE_VALUE)
-         {
-            if (GetLastError() != ERROR_SHARING_VIOLATION)
-               break;   /* Not a sharing error.  Get out now.  Otherwise: */
-            Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */
-         }
-         else
-         {
-             break;     /* Not a sharing error.  (Success?)  Get out now. */
-         }
-      }
-#endif /* def RETRY_CREATEFILE */
-
-      /* sfield@microsoft.com: set attributes before time in case we decide to
-         support other filetime members later.  This also allows us to apply
-         attributes before the security is changed, which may prevent this
-         from succeeding otherwise.  Also, since most files don't have
-         any interesting attributes, only change them if something other than
-         FILE_ATTRIBUTE_ARCHIVE appears in the attributes.  This works well
-         as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the
-         file anyway, when it's created new. */
-      if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) {
-          if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F))
-              Info(slide, 1, ((char *)slide,
-                "\nwarning (%d): could not set file attributes (2)\n",
-                (int)GetLastError()));
-      }
-
-#  ifdef NTSD_EAS
-      /* set NTFS SD extra fields */
-      if (G.extra_field &&    /* zipfile extra field may have extended attribs */
-          FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
-                           &ebSDptr, &ebSDlen))
-      {
-          int err = SetSD(__G__ G.unipath_widefilename, G.pInfo->file_attr,
-                          ebSDptr, ebSDlen);
-
-          if (err == IZ_EF_TRUNC) {
-              if (uO.qflag)
-                  Info(slide, 1, ((char *)slide, "%-22s ",
-                    FnFilter1(G.filename)));
-              Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
-                ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":""));
-          }
-      }
-#  endif /* NTSD_EAS */
-
-      /* skip restoring time stamps on user's request */
-      if (uO.D_flag <= 1) {
-        if ( hFile == INVALID_HANDLE_VALUE )
-            Info(slide, 1, ((char *)slide,
-              "\nCreateFile(2) error %d when trying to set file time\n",
-              (int)GetLastError()));
-        else {
-            if (gotTime) {
-                FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
-                FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
-                FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
-
-                if (!SetFileTime(hFile, pCreft, pAccft, pModft))
-                    Info(slide, 0, ((char *)slide,
-                      "\nSetFileTime(2) failed: %d\n", (int)GetLastError()));
-            }
-            CloseHandle(hFile);
-        }
-      }
-
-      return;
-
-    }
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-} /* end function close_outfile() */
-
-
-
-
-# ifdef SET_DIR_ATTRIB
-
-int defer_dir_attribs(__G__ pd)
-    __GDEF
-    direntry **pd;
-{
-    NTdirattr *d_entry;
-#  ifdef NTSD_EAS
-    uch *ebSDptr;
-    unsigned ebSDlen;
-#  endif
-
-    /* Win9x does not support setting directory time stamps. */
-    if (!IsWinNT()) {
-        *pd = (direntry *)NULL;
-        return PK_OK;
-    }
-
-#  ifdef NTSD_EAS
-    /* set extended attributes from extra fields */
-    if (G.extra_field &&  /* zipfile e.f. may have extended attribs */
-        FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
-                         &ebSDptr, &ebSDlen)) {
-        /* ebSDlen contains the payload size of the e.f. block, but
-           we store it including the e.b. header. */
-        ebSDlen += EB_HEADSIZE;
-    } else {
-        /* no NTSD e.f. block -> no space needed to allocate */
-        ebSDlen = 0;
-    }
-#  endif /* NTSD_EAS */
-
-#  ifdef NTSD_EAS
-#   define ASIZE1 sizeof(NTdirattr)+ ebSDlen+ strlen(G.filename)
-#  else /* def NTSD_EAS */
-#   define ASIZE1 sizeof(NTdirattr)+ strlen(G.filename)
-#  endif /* def NTSD_EAS [else] */
-
-    d_entry = (NTdirattr *)izu_malloc(ASIZE1);
-    *pd = (direntry *)d_entry;
-    if (d_entry == (NTdirattr *)NULL) {
-        return PK_MEM;
-    }
-#  ifdef NTSD_EAS
-    if (ebSDlen > 0)
-        memcpy(d_entry->buf, ebSDptr, ebSDlen);
-    d_entry->SDlen = ebSDlen;
-    d_entry->fn = d_entry->buf + ebSDlen;
-#  else
-    d_entry->fn = d_entry->buf;
-#  endif
-
-    strcpy(d_entry->fn, G.filename);
-
-    d_entry->perms = G.pInfo->file_attr;
-
-    d_entry->gotTime = (uO.D_flag <= 0
-                        ? getNTfiletime(__G__ &(d_entry->Modft),
-                                        &(d_entry->Accft), &(d_entry->Creft))
-                        : 0);
-    return PK_OK;
-} /* end function defer_dir_attribs() */
-
-
-
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-int defer_dir_attribsw(__G__ pdw)
-    __GDEF
-    direntryw **pdw;
-{
-    NTdirattrw *d_entryw;
-#   ifdef NTSD_EAS
-    uch *ebSDptr;
-    unsigned ebSDlen;
-#   endif
-
-    /* Win9x does not support setting directory time stamps. */
-    if (!IsWinNT()) {
-        *pdw = (direntryw *)NULL;
-        return PK_OK;
-    }
-
-#   ifdef NTSD_EAS
-    /* set extended attributes from extra fields */
-    if (G.extra_field &&  /* zipfile e.f. may have extended attribs */
-        FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
-                         &ebSDptr, &ebSDlen)) {
-        /* ebSDlen contains the payload size of the e.f. block, but
-           we store it including the e.b. header. */
-        ebSDlen += EB_HEADSIZE;
-    } else {
-        /* no NTSD e.f. block -> no space needed to allocate */
-        ebSDlen = 0;
-    }
-#   endif /* NTSD_EAS */
-
-#   ifdef NTSD_EAS
-#    define ASIZE2 sizeof(NTdirattrw)+ ebSDlen+ \
-     (wcslen(G.unipath_widefilename)* sizeof(wchar_t))
-#   else /* def NTSD_EAS */
-#    define ASIZE2 sizeof(NTdirattrw)+ \
-     (wcslen(G.unipath_widefilename)* sizeof(wchar_t))
-#   endif /* def NTSD_EAS [else] */
-
-    d_entryw = (NTdirattrw *)izu_malloc(ASIZE2);
-    *pdw = (direntryw *)d_entryw;
-    if (d_entryw == (NTdirattrw *)NULL) {
-        return PK_MEM;
-    }
-#   ifdef NTSD_EAS
-    if (ebSDlen > 0)
-        memcpy(d_entryw->buf, ebSDptr, ebSDlen);
-    d_entryw->SDlen = ebSDlen;
-    d_entryw->fnw = d_entryw->buf + ebSDlen;
-#   else
-    d_entryw->fnw = d_entryw->buf;
-#   endif
-
-    wcscpy(d_entryw->fnw, G.unipath_widefilename);
-
-    d_entryw->perms = G.pInfo->file_attr;
-
-    d_entryw->gotTime = (uO.D_flag <= 0
-                         ? getNTfiletimeW(__G__ &(d_entryw->Modft),
-                                          &(d_entryw->Accft),
-                                          &(d_entryw->Creft))
-                         : 0);
-    return PK_OK;
-} /* end function defer_dir_attribsw() */
-#  endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-
-int set_direc_attribs(__G__ d)
-    __GDEF
-    direntry *d;
-{
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-    /* Win9x does not support setting directory time stamps. */
-    return PK_OK;
-#  else /* ! (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
-    int errval;
-    HANDLE hFile = INVALID_HANDLE_VALUE;        /* File handle defined in NT */
-#   ifdef __RSXNT__
-    char *ansi_name;
-#   endif
-
-    /* Win9x does not support setting directory time stamps. */
-    if (!IsWinNT())
-        return PK_OK;
-
-    errval = PK_OK;
-#   ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-    ansi_name = (char *)alloca(strlen(d->fn) + 1);
-    INTERN_TO_ISO(d->fn, ansi_name);
-#   define Ansi_Dirname  ansi_name
-#   else
-#   define Ansi_Dirname  d->fn
-#   endif
-
-    /* Skip restoring directory time stamps on user' request. */
-    if (uO.D_flag <= 0) {
-        /* Open a handle to the directory before processing extra fields;
-           we do this in case new security on file prevents us from updating
-           time stamps.
-           Although the WIN32 documentation recommends to use GENERIC_WRITE
-           access flag to create the handle for SetFileTime(), this is too
-           demanding for directories with the "read-only" attribute bit set.
-           So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
-           request the minimum required access rights. (This problem is a
-           Windows bug that has been silently fixed in Windows XP SP2.) */
-        hFile = CreateFileA(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
-                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
-                            OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-    }
-
-#   ifdef NTSD_EAS
-    if (NtAtt(d)->SDlen > 0) {
-        int err;
-
-        if (QCOND2) {
-            Info(slide, 1, ((char *)slide, " set attrib: %-22s  ",
-              FnFilter1(d->fn)));
-        }
-
-        /* set NTFS SD extra fields */
-        err = SetSD(__G__ Ansi_Dirname, NtAtt(d)->perms,
-                        NtAtt(d)->buf, NtAtt(d)->SDlen - EB_HEADSIZE);
-        if (err == IZ_EF_TRUNC) {
-            if (!QCOND2)
-                Info(slide, 1, ((char *)slide, "%-22s  ",
-                  FnFilter1(d->fn)));
-            Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
-              NtAtt(d)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
-        } else if (QCOND2) {
-            Info(slide, 0, ((char *)slide, "\n"));
-        }
-        if (errval < err)
-            errval = err;
-    }
-#   endif /* NTSD_EAS */
-
-    /* Skip restoring directory time stamps on user' request. */
-    if (uO.D_flag <= 0) {
-        if (hFile == INVALID_HANDLE_VALUE) {
-            Info(slide, 1, ((char *)slide,
-              "warning: CreateFile(3) error %d (set file times for %s)\n",
-              (int)GetLastError(), FnFilter1(d->fn)));
-            if (!errval)
-                errval = PK_WARN;
-        } else {
-            if (NtAtt(d)->gotTime) {
-                FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
-                                  ? &(NtAtt(d)->Modft) : NULL;
-                FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
-                                  ? &(NtAtt(d)->Accft) : NULL;
-                FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
-                                  ? &(NtAtt(d)->Creft) : NULL;
-
-                if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
-                    Info(slide, 0, ((char *)slide,
-                      "warning: SetFileTime(3) for %s error %d\n",
-                      FnFilter1(d->fn), (int)GetLastError()));
-                    if (!errval)
-                        errval = PK_WARN;
-                }
-            }
-            CloseHandle(hFile);
-        }
-    }
-
-    return errval;
-
-#  endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-} /* end function set_direc_attribs() */
-
-
-
-
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-int set_direc_attribsw(__G__ dw)
-    __GDEF
-    direntryw *dw;
-{
-    int errval;
-    HANDLE hFile = INVALID_HANDLE_VALUE;        /* File handle defined in NT */
-
-    /* Win9x does not support setting directory time stamps. */
-    if (!IsWinNT())
-        return PK_OK;
-
-    errval = PK_OK;
-
-    /* Skip restoring directory time stamps on user' request. */
-    if (uO.D_flag <= 0) {
-        /* Open a handle to the directory before processing extra fields;
-           we do this in case new security on file prevents us from updating
-           time stamps.
-           Although the WIN32 documentation recommends to use GENERIC_WRITE
-           access flag to create the handle for SetFileTime(), this is too
-           demanding for directories with the "read-only" attribute bit set.
-           So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
-           request the minimum required access rights. (This problem is a
-           Windows bug that has been silently fixed in Windows XP SP2.) */
-        hFile = CreateFileW(dw->fnw, FILE_WRITE_ATTRIBUTES,
-                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
-                            OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-    }
-
-#   ifdef NTSD_EAS
-    if (NtAtt(dw)->SDlen > 0) {
-        int err;
-
-        if (QCOND2) {
-            char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all);
-            Info(slide, 1, ((char *)slide, " set attrib: %-22s  ",
-              FnFilter1(fn)));
-            izu_free(fn);
-        }
-
-        /* set NTFS SD extra fields */
-        err = SetSD(__G__ dw->fnw, NtAtt(dw)->perms,
-                        NtAtt(dw)->buf, NtAtt(dw)->SDlen - EB_HEADSIZE);
-        if (err == IZ_EF_TRUNC) {
-            if (!QCOND2) {
-                char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all);
-                Info(slide, 1, ((char *)slide, "%-22s  ",
-                  FnFilter1(fn)));
-                izu_free(fn);
-            }
-            Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
-              NtAtt(dw)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
-        } else if (QCOND2) {
-            Info(slide, 0, ((char *)slide, "\n"));
-        }
-        if (errval < err)
-            errval = err;
-    }
-#   endif /* NTSD_EAS */
-
-    /* Skip restoring directory time stamps on user' request. */
-    if (uO.D_flag <= 0) {
-        if (hFile == INVALID_HANDLE_VALUE) {
-            char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all);
-            Info(slide, 1, ((char *)slide,
-              "warning: CreateFile(4) error %d (set file times for %s)\n",
-              (int)GetLastError(), FnFilter1(fn)));
-            izu_free(fn);
-            if (!errval)
-                errval = PK_WARN;
-        } else {
-            if (NtAtt(dw)->gotTime) {
-                FILETIME *pModft = (NtAtt(dw)->gotTime & EB_UT_FL_MTIME)
-                                  ? &(NtAtt(dw)->Modft) : NULL;
-                FILETIME *pAccft = (NtAtt(dw)->gotTime & EB_UT_FL_ATIME)
-                                  ? &(NtAtt(dw)->Accft) : NULL;
-                FILETIME *pCreft = (NtAtt(dw)->gotTime & EB_UT_FL_CTIME)
-                                  ? &(NtAtt(dw)->Creft) : NULL;
-
-                if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
-                    char *fn = wchar_to_local_string(dw->fnw,
-                                                     G.unicode_escape_all);
-                    Info(slide, 0, ((char *)slide,
-                      "warning: SetFileTime(4) for %s error %d\n",
-                      FnFilter1(fn), (int)GetLastError()));
-                    izu_free(fn);
-                    if (!errval)
-                        errval = PK_WARN;
-                }
-            }
-            CloseHandle(hFile);
-        }
-    }
-
-    return errval;
-} /* end function set_direc_attribsw() */
-
-#  endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-# endif /* SET_DIR_ATTRIB */
-
-
-
-# ifdef TIMESTAMP
-
-/*************************/
-/* Function stamp_file() */
-/*************************/
-
-int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime)
-{
-    FILETIME Modft;    /* File time type defined in NT, `last modified' time */
-    HANDLE hFile;      /* File handle defined in NT    */
-    int errstat = 0;   /* return status: 0 == "OK", -1 == "Failure" */
-    int fs_uses_loctime = FStampIsLocTime(__G__ fname);
-
-/* 2013-07-08 SMS.  See note above. */
-# ifdef RETRY_CREATEFILE
-    int cf_tries;
-# endif
-
-# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-    char *ansi_name = (char *)alloca(strlen(fname) + 1);
-
-    INTERN_TO_ISO(fname, ansi_name);
-#   define Ansi_Fname  ansi_name
-#  else
-#   define Ansi_Fname  fname
-#  endif
-
-    /* open a handle to the file to prepare setting the mod-time stamp */
-
-#ifdef RETRY_CREATEFILE
-    for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--)
-    {
-#endif /* def RETRY_CREATEFILE */
-
-        hFile = CreateFileA( Ansi_Fname,
-         GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
-         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
-#ifdef RETRY_CREATEFILE
-        if (hFile == INVALID_HANDLE_VALUE)
-        {
-            if (GetLastError() != ERROR_SHARING_VIOLATION)
-                break;  /* Not a sharing error.  Get out now.  Otherwise: */
-            Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */
-        }
-        else
-        {
-            break;      /* Not a sharing error.  (Success?)  Get out now. */
-        }
-    }
-#endif /* def RETRY_CREATEFILE */
-
-    if ( hFile == INVALID_HANDLE_VALUE ) {
-        errstat = -1;
-    } else {
-        /* convert time_t modtime into WIN32 native 64bit format */
-        UTIME_2_IZFILETIME(modtime, &Modft)
-        /* set Access and Modification times of the file to modtime */
-        if (!SetFileTime(hFile, NULL, &Modft, &Modft)) {
-            errstat = -1;
-        }
-        CloseHandle(hFile);
-    }
-
-    return errstat;
-
-#undef Ansi_Fname
-} /* end function stamp_file() */
-
-# endif /* TIMESTAMP */
-
-
-
-
-/***********************/
-/* Function isfloppy() */   /* more precisely, is it removable? */
-/***********************/
-
-static int isfloppy(int nDrive)   /* 1 == A:, 2 == B:, etc. */
-{
-    char rootPathName[4];
-
-    rootPathName[0] = (char)('A' + nDrive - 1);   /* build the root path */
-    rootPathName[1] = ':';                        /*  name, e.g. "A:/" */
-    rootPathName[2] = '/';
-    rootPathName[3] = '\0';
-
-    return (GetDriveTypeA(rootPathName) == DRIVE_REMOVABLE);
-
-} /* end function isfloppy() */
-
-
-
-
-/*****************************/
-/* Function NTQueryVolInfo() */
-/*****************************/
-
-/*
- * Note:  8.3 limits on filenames apply only to old-style FAT filesystems.
- *        More recent versions of Windows (Windows NT 3.5 / Windows 4.0)
- *        can support long filenames (LFN) on FAT filesystems.  Check the
- *        filesystem maximum component length field to detect LFN support.
- */
-
-static int NTQueryVolInfo(__GPRO__ const char *name)
-{
- /* static char lastRootPath[4] = ""; */
- /* static int lastVolOldFAT; */
- /* static int lastVolLocTim; */
-    char *tmp0;
-    char tmp1[MAX_PATH], tmp2[MAX_PATH];
-    DWORD volSerNo, maxCompLen, fileSysFlags;
-# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-    char *ansi_name = (char *)alloca(strlen(name) + 1);
-
-    INTERN_TO_ISO(name, ansi_name);
-    name = ansi_name;
-# endif
-
-    if ((!strncmp(name, "//", 2) || !strncmp(name, "\\\\", 2)) &&
-        (name[2] != '\0' && name[2] != '/' && name[2] != '\\')) {
-        /* GetFullPathname() and GetVolumeInformation() do not work
-         * on UNC names. For now, we return "error".
-         * **FIXME**: check if UNC name is mapped to a drive letter
-         *            and use mapped drive for volume info query.
-         */
-        return FALSE;
-    }
-    if (isalpha((uch)name[0]) && (name[1] == ':'))
-        tmp0 = (char *)name;
-    else
-    {
-        if (!GetFullPathNameA(name, MAX_PATH, tmp1, &tmp0))
-            return FALSE;
-        tmp0 = &tmp1[0];
-    }
-    if (strncmp(G.lastRootPath, tmp0, 2) != 0) {
-        /* For speed, we skip repeated queries for the same device */
-        strncpy(G.lastRootPath, tmp0, 2);   /* Build the root path name, */
-        G.lastRootPath[2] = '/';            /* e.g. "A:/"                */
-        G.lastRootPath[3] = '\0';
-
-        if (!GetVolumeInformationA((LPCSTR)G.lastRootPath,
-              (LPSTR)tmp1, (DWORD)MAX_PATH,
-              &volSerNo, &maxCompLen, &fileSysFlags,
-              (LPSTR)tmp2, (DWORD)MAX_PATH)) {
-            G.lastRootPath[0] = '\0';
-            return FALSE;
-        }
-
-        /*  LFNs are available if the component length is > 12 */
-        G.lastVolOldFAT = (maxCompLen <= 12);
-/*      G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3);   old version */
-
-        /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
-         * local time!
-         */
-        G.lastVolLocTim = !strncmp(strupr(tmp2), "VFAT", 4) ||
-                          !strncmp(tmp2, "HPFS", 4) ||
-                          !strncmp(tmp2, "FAT", 3);
-    }
-
-    return TRUE;
-
-} /* end function NTQueryVolInfo() */
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-static int NTQueryVolInfoW(__GPRO__ const wchar_t *namew)
-{
- /* static char lastRootPath[4] = ""; */
- /* static int lastVolOldFAT; */
- /* static int lastVolLocTim; */
-    wchar_t *tmp0w;
-    wchar_t tmp1w[MAX_PATH], tmp2w[MAX_PATH];
-    DWORD volSerNo, maxCompLen, fileSysFlags;
-
-    if ((!wcsncmp(namew, L"//", 2) || !wcsncmp(namew, L"\\\\", 2)) &&
-        (namew[2] != '\0' && namew[2] != '/' && namew[2] != '\\')) {
-        /* GetFullPathname() and GetVolumeInformation() do not work
-         * on UNC names. For now, we return "error".
-         * **FIXME**: check if UNC name is mapped to a drive letter
-         *            and use mapped drive for volume info query.
-         */
-        return FALSE;
-    }
-    if (iswalpha(namew[0]) && (namew[1] == ':'))
-        tmp0w = (wchar_t *)namew;
-    else
-    {
-        if (!GetFullPathNameW(namew, MAX_PATH, tmp1w, &tmp0w))
-            return FALSE;
-        tmp0w = &tmp1w[0];
-    }
-    if (wcsncmp(G.lastRootPathw, tmp0w, 2) != 0) {
-        /* For speed, we skip repeated queries for the same device */
-        wcsncpy(G.lastRootPathw, tmp0w, 2); /* Build the root path name, */
-        G.lastRootPathw[2] = '/';           /* e.g. "A:/"                */
-        G.lastRootPathw[3] = '\0';
-
-        if (!GetVolumeInformationW(G.lastRootPathw,
-              tmp1w, (DWORD)MAX_PATH,
-              &volSerNo, &maxCompLen, &fileSysFlags,
-              tmp2w, (DWORD)MAX_PATH)) {
-            G.lastRootPathw[0] = '\0';
-            return FALSE;
-        }
-
-        /*  LFNs are available if the component length is > 12 */
-        G.lastVolOldFAT = (maxCompLen <= 12);
-/*      G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3);   old version */
-
-        /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
-         * local time!
-         */
-        G.lastVolLocTim = !wcsncmp(_wcsupr(tmp2w), L"VFAT", 4) ||
-                          !wcsncmp(tmp2w, L"HPFS", 4) ||
-                          !wcsncmp(tmp2w, L"FAT", 3);
-    }
-
-    return TRUE;
-
-} /* end function NTQueryVolInfoW() */
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-
-/*****************************/
-/* Function IsVolumeOldFAT() */
-/*****************************/
-
-static int IsVolumeOldFAT(__GPRO__ const char *name)
-{
-    return (NTQueryVolInfo(__G__ name) ? G.lastVolOldFAT : FALSE);
-}
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-static int IsVolumeOldFATw(__GPRO__ const wchar_t *namew)
-{
-    return (NTQueryVolInfoW(__G__ namew) ? G.lastVolOldFAT : FALSE);
-}
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-
-# ifndef SFX
-
-/************************/
-/*  Function do_wild()  */   /* identical to OS/2 version */
-/************************/
-
-char *do_wild(__G__ wildspec)
-    __GDEF
-    ZCONST char *wildspec;  /* only used first time on a given dir */
-{
-/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in w32cfg.h:
-    static zDIR *wild_dir = NULL;
-    static ZCONST char *wildname;
-    static char *dirname, matchname[FILNAMSIZ];
-    static int notfirstcall=FALSE, have_dirname, dirnamelen;
-*/
-    char *fnamestart;
-    struct zdirent *file;
-
-    /* Even when we're just returning wildspec, we *always* do so in
-     * matchname[]--calling routine is allowed to append four characters
-     * to the returned string, and wildspec may be a pointer to argv[].
-     */
-    if (!G.notfirstcall) {  /* first call:  must initialize everything */
-        G.notfirstcall = TRUE;
-
-        if (!iswild(wildspec)) {
-            strncpy(G.matchname, wildspec, FILNAMSIZ);
-            G.matchname[FILNAMSIZ-1] = '\0';
-            G.have_dirname = FALSE;
-            G.wild_dir = NULL;
-            return G.matchname;
-        }
-
-        /* Break the wildspec into a directory part and a wildcard filename. */
-        /* 2014-02-14 SMS.  Added test for "\". */
-        if ((G.wildname = MBSRCHR(wildspec, '/')) == (ZCONST char *)NULL &&
-         (G.wildname = MBSRCHR(wildspec, '\\')) == (ZCONST char *)NULL &&
-         (G.wildname = MBSRCHR(wildspec, ':')) == (ZCONST char *)NULL) {
-            G.dirname = ".";
-            G.dirnamelen = 1;
-            G.have_dirname = FALSE;
-            G.wildname = wildspec;
-        } else {
-            ++G.wildname;       /* Point at char after last '/', '\', or ':'. */
-            G.dirnamelen = G.wildname - wildspec;
-            if ((G.dirname = (char *)izu_malloc(G.dirnamelen+1)) == NULL) {
-                Info(slide, 1, ((char *)slide,
-                  "warning: cannot allocate wildcard buffers\n"));
-                strncpy(G.matchname, wildspec, FILNAMSIZ);
-                G.matchname[FILNAMSIZ-1] = '\0';
-                return G.matchname; /* but maybe filespec was not a wildcard */
-            }
-            strncpy(G.dirname, wildspec, G.dirnamelen);
-            G.dirname[G.dirnamelen] = '\0';   /* terminate for strcpy below */
-            G.have_dirname = TRUE;
-        }
-        Trace((stderr, "do_wild:  dirname = [%s]\n", FnFilter1(G.dirname)));
-
-        if ((G.wild_dir = (zvoid *)Opendir(G.dirname)) != NULL) {
-            if (G.have_dirname) {
-                strcpy(G.matchname, G.dirname);
-                fnamestart = G.matchname + G.dirnamelen;
-            } else
-                fnamestart = G.matchname;
-            while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) {
-                Trace((stderr, "do_wild:  Readdir returns %s\n",
-                  FnFilter1(file->d_name)));
-                strcpy(fnamestart, file->d_name);
-                if (MBSRCHR(fnamestart, '.') == (char *)NULL)
-                    strcat(fnamestart, ".");
-                if (match(fnamestart, G.wildname, TRUE WISEP) &&
-                    /* skip "." and ".." directory entries */
-                    strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) {
-                    Trace((stderr, "do_wild:  match() succeeds\n"));
-                    /* remove trailing dot */
-                    fnamestart = plastchar(fnamestart, strlen(fnamestart));
-                    if (*fnamestart == '.')
-                        *fnamestart = '\0';
-                    return G.matchname;
-                }
-            }
-            /* if we get to here directory is exhausted, so close it */
-            Closedir((zDIR *)G.wild_dir);
-            G.wild_dir = NULL;
-        }
-        Trace((stderr, "do_wild:  Opendir(%s) returns NULL\n",
-          FnFilter1(G.dirname)));
-
-        /* return the raw wildspec in case that works (e.g., directory not
-         * searchable, but filespec was not wild and file is readable) */
-        strncpy(G.matchname, wildspec, FILNAMSIZ);
-        G.matchname[FILNAMSIZ-1] = '\0';
-        return G.matchname;
-    }
-
-    /* last time through, might have failed opendir but returned raw wildspec */
-    if (G.wild_dir == NULL) {
-        G.notfirstcall = FALSE;    /* reset for new wildspec */
-        if (G.have_dirname)
-            izu_free(G.dirname);
-        return (char *)NULL;
-    }
-
-    /* If we've gotten this far, we've read and matched at least one entry
-     * successfully (in a previous call), so dirname has been copied into
-     * matchname already.
-     */
-    if (G.have_dirname) {
-        /* strcpy(G.matchname, G.dirname); */
-        fnamestart = G.matchname + G.dirnamelen;
-    } else
-        fnamestart = G.matchname;
-    while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) {
-        Trace((stderr, "do_wild:  readdir returns %s\n",
-          FnFilter1(file->d_name)));
-        strcpy(fnamestart, file->d_name);
-        if (MBSRCHR(fnamestart, '.') == (char *)NULL)
-            strcat(fnamestart, ".");
-        if (match(fnamestart, G.wildname, TRUE WISEP)) {
-            Trace((stderr, "do_wild:  match() succeeds\n"));
-            /* remove trailing dot */
-            fnamestart = plastchar(fnamestart, strlen(fnamestart));
-            if (*fnamestart == '.')
-                *fnamestart = '\0';
-            return G.matchname;
-        }
-    }
-
-    Closedir((zDIR *)G.wild_dir);  /* at least one entry read; nothing left */
-    G.wild_dir = NULL;
-    G.notfirstcall = FALSE;        /* reset for new wildspec */
-    if (G.have_dirname)
-        izu_free(G.dirname);
-    return (char *)NULL;
-
-} /* end function do_wild() */
-
-# endif /* !SFX */
-
-
-
-/**********************/
-/* Function mapattr() */
-/**********************/
-
-/* Identical to MS-DOS, OS/2 versions.  However, NT has a lot of extra
- * permission stuff, so this function should probably be extended in the
- * future. */
-
-int mapattr(__G)
-    __GDEF
-{
-    /* set archive bit for file entries (file is not backed up): */
-    G.pInfo->file_attr = ((unsigned)G.crec.external_file_attributes |
-      (G.crec.external_file_attributes & FILE_ATTRIBUTE_DIRECTORY ?
-       0 : FILE_ATTRIBUTE_ARCHIVE)) & 0xff;
-
-# ifdef SYMLINKS
-    if (SYMLINK_HOST( G.pInfo->hostnum))
-    {
-        unsigned int uxattr;
-
-        uxattr = (G.crec.external_file_attributes >> 16);   /* drwxrwxrwx */
-
-        G.pInfo->symlink = S_ISLNK( uxattr);
-    }
-# endif /* def SYMLINKS */
-
-    return 0;
-
-} /* end function mapattr() */
-
-
-
-
-/************************/
-/*  Function mapname()  */
-/************************/
-
-int mapname(__G__ renamed)
-    __GDEF
-    int renamed;
-/*
- * returns:
- *  MPN_OK          - no problem detected
- *  MPN_INF_TRUNC   - caution (truncated filename)
- *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist)
- *  MPN_ERR_SKIP    - error -> skip entry
- *  MPN_ERR_TOOLONG - error -> path is too long
- *  MPN_NOMEM       - error (memory allocation failed) -> skip entry
- *  [also MPN_VOL_LABEL, MPN_CREATED_DIR]
- */
-{
-    char pathcomp[FILNAMSIZ];   /* path-component buffer */
-# ifdef SYMLINKS
-    char pathcopy[FILNAMSIZ];   /* Copy of path we can alter. */
-# endif
-    char *pp, *cp=NULL;         /* character pointers */
-    char *lastsemi = NULL;      /* pointer to last semi-colon in pathcomp */
-# ifdef ACORN_FTYPE_NFS
-    char *lastcomma=(char *)NULL;  /* pointer to last comma in pathcomp */
-    RO_extra_block *ef_spark;      /* pointer Acorn FTYPE ef block */
-# endif
-    int killed_ddot = FALSE;    /* is set when skipping "../" pathcomp */
-    int error;
-    register unsigned workch;   /* hold the character being tested */
-
-/*---------------------------------------------------------------------------
-    Initialize various pointers and counters and stuff.
-  ---------------------------------------------------------------------------*/
-
-    /* can create path as long as not just freshening, or if user told us */
-    G.create_dirs = (!uO.fflag || renamed);
-
-    G.created_dir = FALSE;      /* not yet */
-    G.renamed_fullpath = FALSE;
-    G.fnlen = strlen(G.filename);
-
-    if (renamed) {
-        cp = G.filename;                /* Point to start of renamed name. */
-        if (*cp) do {
-            if (*cp == '\\')            /* Convert backslashes to slashes. */
-                *cp = '/';
-        } while (*PREINCSTR(cp));
-        cp = G.filename;
-        /* use temporary rootpath if user gave full pathname */
-        if (G.filename[0] == '/') {
-            G.renamed_fullpath = TRUE;
-            pathcomp[0] = '/';          /* Copy the '/', and NUL-terminate. */
-            pathcomp[1] = '\0';
-            ++cp;
-        } else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') {
-            G.renamed_fullpath = TRUE;
-            pp = pathcomp;
-            *pp++ = *cp++;              /* Copy the "d:" (+ '/', possibly). */
-            *pp++ = *cp++;
-            if (*cp == '/')
-                *pp++ = *cp++;          /* Otherwise add "./"? */
-            *pp = '\0';
-        }
-    }
-
-    /* pathcomp is ignored unless renamed_fullpath is TRUE: */
-    if ((error = checkdir(__G__ pathcomp, INIT)) != 0)  /* init path buffer */
-        return error;           /* ...unless no mem or vol label on hard disk */
-
-    *pathcomp = '\0';           /* initialize translation buffer */
-    pp = pathcomp;              /* point to translation buffer */
-    if (!renamed) {             /* cp already set if renamed */
-        cp = G.jdir_filename;   /* Start at beginning of non-junked path. */
-    }
-
-# ifdef SYMLINKS
-    /* If a symlink with a trailing "/", then use a copy without the "/". */
-    if (G.pInfo->symlink)
-    {
-        size_t lenm1;
-
-        lenm1 = strlen( cp)- 1;
-        if (cp[ lenm1] == '/')
-        {
-            strncpy( pathcopy, cp, lenm1);
-            pathcopy[ lenm1] = '\0';
-            cp = pathcopy;
-        }
-    }
-# endif /* def SYMLINKS */
-
-/*---------------------------------------------------------------------------
-    Begin main loop through characters in filename.
-  ---------------------------------------------------------------------------*/
-
-    for (; (workch = (uch)*cp) != 0; INCSTR(cp)) {
-
-        switch (workch) {
-            case '/':                   /* Can assume -j flag not given. */
-                *pp = '\0';
-                maskDOSdevice(__G__ pathcomp);
-                if (strcmp(pathcomp, ".") == 0) {
-                    /* Don't bother appending "./" to the path. */
-                    *pathcomp = '\0';
-                } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {
-                    /* "../" dir traversal detected.  Skip over it. */
-                    *pathcomp = '\0';
-                    killed_ddot = TRUE;         /* Set "show message" flag. */
-                }
-                /* When path component is not empty, append it now. */
-                if (*pathcomp != '\0' &&
-                    ((error = checkdir(__G__ pathcomp, APPEND_DIR))
-                     & MPN_MASK) > MPN_INF_TRUNC)
-                    return error;
-                pp = pathcomp;  /* Reset conversion buffer for next piece. */
-                lastsemi = (char *)NULL; /* Leave dir semi-colons alone. */
-                break;
-
-            case ':':             /* drive spec not stored, so no colon allowed */
-            case '\\':            /* '\\' may come as normal filename char (not */
-            case '<':             /*  dir sep char!) from unix-like file system */
-            case '>':             /* no redirection symbols allowed either */
-            case '|':             /* no pipe signs allowed */
-            case '"':             /* no double quotes allowed */
-            case '?':             /* no wildcards allowed */
-            case '*':
-                *pp++ = '_';      /* these rules apply equally to FAT and NTFS */
-                break;
-            case ';':             /* start of VMS version? */
-                lastsemi = pp;    /* remove VMS version later... */
-                *pp++ = ';';      /*  but keep semicolon for now */
-                break;
-
-# ifdef ACORN_FTYPE_NFS
-            case ',':             /* NFS filetype extension */
-                lastcomma = pp;
-                *pp++ = ',';      /* keep for now; may need to remove */
-                break;            /*  later, if requested */
-# endif
-
-            case ' ':             /* keep spaces unless specifically */
-                /* NT cannot create filenames with spaces on FAT volumes */
-                if (uO.sflag || IsVolumeOldFAT(__G__ G.filename))
-                    *pp++ = '_';
-                else
-                    *pp++ = ' ';
-                break;
-
-            default:
-                /* allow European characters in filenames: */
-                if (isprint(workch) || workch >= 127)
-# ifdef _MBCS
-                {
-                    memcpy(pp, cp, CLEN(cp));
-                    INCSTR(pp);
-                }
-# else
-                    *pp++ = (char)workch;
-# endif
-        } /* end switch */
-
-    } /* end while loop */
-
-    /* Show warning when stripping insecure "parent dir" path components */
-    if (killed_ddot && QCOND2) {
-        Info(slide, 0, ((char *)slide,
-          "warning: skipped \"../\" path component(s) (1) in %s\n",
-          FnFilter1(G.filename)));
-        if (!(error & ~MPN_MASK))
-            error = (error & MPN_MASK) | PK_WARN;
-    }
-
-/*---------------------------------------------------------------------------
-    Report if directory was created (and no file to create:  filename ended
-    in '/'), check name to be sure it exists, and combine path and name be-
-    fore exiting.
-  ---------------------------------------------------------------------------*/
-
-    if ((lastchar(G.filename, G.fnlen) == '/')
-# ifdef SYMLINKS
-     /* Process a symlink as a file, even if it looks like a directory.
-      * (Which a Windows directory symlink might do.)
-      */
-     && !G.pInfo->symlink
-# endif /* def SYMLINKS */
-     )
-    {
-# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-        char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
-
-        INTERN_TO_ISO(G.filename, ansi_name);
-#       define Ansi_Fname  ansi_name
-# else
-#       define Ansi_Fname  G.filename
-# endif
-        checkdir(__G__ G.filename, GETPATH);
-        if (G.created_dir) {
-            if (QCOND2) {
-                Info(slide, 0, ((char *)slide, "   creating: %-22s\n",
-                  FnFilter1(G.filename)));
-            }
-
-            /* set file attributes:
-               The default for newly created directories is "DIR attribute
-               flags set", so there is no need to change attributes unless
-               one of the DOS style attribute flags is set. The readonly
-               attribute need not be masked, since it does not prevent
-               modifications in the new directory. */
-            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
-                if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
-                    Info(slide, 1, ((char *)slide,
- "\nwarning (%d): could not set file attributes (3) for %s\n",
-                      (int)GetLastError(), FnFilter1(G.filename)));
-            }
-
-            /* set dir time (note trailing '/') */
-            return (error & ~MPN_MASK) | MPN_CREATED_DIR;
-        } else if (IS_OVERWRT_ALL) {
-            /* overwrite attributes of existing directory on user's request */
-
-            /* set file attributes: */
-            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
-                if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
-                    Info(slide, 1, ((char *)slide,
- "\nwarning (%d): could not set file attributes (4) for %s\n",
-                      (int)GetLastError(), FnFilter1(G.filename)));
-            }
-        }
-        /* dir existed already; don't look for data to extract */
-        return (error & ~MPN_MASK) | MPN_INF_SKIP;
-    }
-
-    *pp = '\0';                   /* done with pathcomp:  terminate it */
-
-    /* If not saving them, remove a VMS version number (ending: ";###"). */
-    if (lastsemi &&
-     ((uO.V_flag < 0) || ((uO.V_flag == 0) && (G.pInfo->hostnum == VMS_)))) {
-        pp = lastsemi + 1;        /* semi-colon was kept:  expect #'s after */
-        if (*pp != '\0') {        /* At least one digit is required. */
-            while (isdigit((uch)(*pp)))
-                ++pp;
-            if (*pp == '\0')      /* only digits between ';' and end:  nuke */
-                *lastsemi = '\0';
-        }
-    }
-
-# ifdef ACORN_FTYPE_NFS
-    /* translate Acorn filetype information if asked to do so */
-    if (uO.acorn_nfs_ext &&
-        (ef_spark = (RO_extra_block *)
-                    getRISCOSexfield(G.extra_field, G.lrec.extra_field_length))
-        != (RO_extra_block *)NULL)
-    {
-        /* file *must* have a RISC OS extra field */
-        long ft = (long)makelong(ef_spark->loadaddr);
-        /*32-bit*/
-        if (lastcomma) {
-            pp = lastcomma + 1;
-            while (isxdigit((uch)(*pp))) ++pp;
-            if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */
-        }
-        if ((ft & 1<<31)==0) ft=0x000FFD00;
-        sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF);
-    }
-# endif /* ACORN_FTYPE_NFS */
-
-    maskDOSdevice(__G__ pathcomp);
-
-    if (*pathcomp == '\0') {
-        Info(slide, 1, ((char *)slide, "mapname(1): conversion of %s failed\n",
-          FnFilter1(G.filename)));
-        return (error & ~MPN_MASK) | MPN_ERR_SKIP;
-    }
-
-    checkdir(__G__ pathcomp, APPEND_NAME);  /* returns 1 if truncated: care? */
-    checkdir(__G__ G.filename, GETPATH);
-
-    if (G.pInfo->vollabel) {    /* set the volume label now */
-        char drive[4] = "?:\\";
-# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-        char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
-        INTERN_TO_ISO(G.filename, ansi_name);
-#       define Ansi_Fname  ansi_name
-# else
-#       define Ansi_Fname  G.filename
-# endif
-
-        /* Insert the drive letter into the drive string.  E.g. "b:\". */
-        drive[0] = (char)(('a'- 1)+ G.nLabelDrive);
-        if (QCOND2)
-            Info(slide, 0, ((char *)slide, "labeling %s %-22s\n", drive,
-              FnFilter1(G.filename)));
-        if (!SetVolumeLabelA(drive, Ansi_Fname)) {
-            Info(slide, 1, ((char *)slide,
-              "mapname(1): error setting volume label\n"));
-            return (error & ~MPN_MASK) | MPN_ERR_SKIP;
-        }
-        /* success: skip the "extraction" quietly */
-        return (error & ~MPN_MASK) | MPN_INF_SKIP;
-#undef Ansi_Fname
-    }
-    Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",
-      FnFilter1(G.filename), error));
-    return error;
-
-} /* end function mapname() */
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-
-
-int mapnamew(__G__ renamed)
-    __GDEF
-    int renamed;
-/*
- * returns:
- *  MPN_OK          - no problem detected
- *  MPN_INF_TRUNC   - caution (truncated filename)
- *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist)
- *  MPN_ERR_SKIP    - error -> skip entry
- *  MPN_ERR_TOOLONG - error -> path is too long
- *  MPN_NOMEM       - error (memory allocation failed) -> skip entry
- *  [also MPN_VOL_LABEL, MPN_CREATED_DIR]
- */
-{
-    wchar_t pathcompw[FILNAMSIZ];   /* path-component buffer */
-#  ifdef SYMLINKS
-    wchar_t pathcopy[FILNAMSIZ];
-#  endif /* def SYMLINKS */
-    wchar_t *ppw, *cpw=NULL;        /* character pointers */
-    wchar_t *lastsemiw = NULL;  /* pointer to last semi-colon in pathcomp */
-    int killed_ddot = FALSE;    /* is set when skipping "../" pathcomp */
-    int error;
-    register wchar_t workchw;   /* hold the character being tested */
-
-/*---------------------------------------------------------------------------
-    Initialize various pointers and counters and stuff.
-  ---------------------------------------------------------------------------*/
-
-    /* can create path as long as not just freshening, or if user told us */
-    G.create_dirs = (!uO.fflag || renamed);
-
-    G.created_dir = FALSE;      /* not yet */
-    G.renamed_fullpath = FALSE;
-    G.fnlen = wcslen(G.unipath_widefilename);
-
-    if (renamed) {
-        cpw = G.unipath_widefilename;   /* Point to start of renamed name. */
-        if (*cpw) do {
-            if (*cpw == '\\')           /* Convert backslashes to slashes. */
-                *cpw = '/';
-        } while (*(++cpw));
-        cpw = G.unipath_widefilename;
-        /* use temporary rootpath if user gave full pathname */
-        if (G.unipath_widefilename[0] == '/') {
-            G.renamed_fullpath = TRUE;
-            pathcompw[0] = '/';         /* Copy the '/', and NUL-terminate. */
-            pathcompw[1] = '\0';
-            ++cpw;
-        } else if (iswalpha(G.unipath_widefilename[0]) && G.unipath_widefilename[1] == ':') {
-            G.renamed_fullpath = TRUE;
-            ppw = pathcompw;
-            *ppw++ = *cpw++;            /* Copy the "d:" (+ '/', possibly). */
-            *ppw++ = *cpw++;
-            if (*cpw == '/')
-                *ppw++ = *cpw++;        /* Otherwise add "./"? */
-            *ppw = '\0';
-        }
-    }
-
-    /* pathcomp is ignored unless renamed_fullpath is TRUE: */
-    if ((error = checkdirw(__G__ pathcompw, INIT)) != 0) /* init path buffer */
-        return error;           /* ...unless no mem or vol label on hard disk */
-
-    *pathcompw = '\0';          /* initialize translation buffer */
-    ppw = pathcompw;            /* point to translation buffer */
-    if (!renamed) {             /* cp already set if renamed */
-        cpw = G.unipath_jdir_widefilename;  /* Beginning of non-junked path. */
-    }
-
-#  ifdef SYMLINKS
-    /* If a symlink with a trailing "/", then use a copy without the "/". */
-    if (G.pInfo->symlink)
-    {
-        size_t lenm1;
-
-        lenm1 = wcslen( cpw)- 1;
-        if (cpw[ lenm1] == L'/')
-        {
-            wcsncpy( pathcopy, cpw, lenm1);
-            pathcopy[ lenm1] = L'\0';
-            cpw = pathcopy;
-        }
-    }
-#  endif /* def SYMLINKS */
-
-/*---------------------------------------------------------------------------
-    Begin main loop through characters in filename.
-  ---------------------------------------------------------------------------*/
-
-    for (; (workchw = *cpw) != 0; cpw++) {
-
-        switch (workchw) {
-            case '/':                   /* Can assume -j flag not given. */
-                *ppw = '\0';
-                maskDOSdevicew(__G__ pathcompw);
-                if (wcscmp(pathcompw, L".") == 0) {
-                    /* Don't bother appending "./" to the path. */
-                    *pathcompw = '\0';
-                } else if (!uO.ddotflag && wcscmp(pathcompw, L"..") == 0) {
-                    /* "../" dir traversal detected.  Skip over it. */
-                    *pathcompw = '\0';
-                    killed_ddot = TRUE;         /* Set "show message" flag. */
-                }
-                /* When path component is not empty, append it now. */
-                if (*pathcompw != '\0' &&
-                    ((error = checkdirw(__G__ pathcompw, APPEND_DIR))
-                     & MPN_MASK) > MPN_INF_TRUNC)
-                    return error;
-                ppw = pathcompw; /* Reset conversion buffer for next piece. */
-                lastsemiw = (wchar_t *)NULL; /* Leave dir semi-colons alone. */
-                break;
-
-            case ':':             /* drive spec not stored, so no colon allowed */
-            case '\\':            /* '\\' may come as normal filename char (not */
-            case '<':             /*  dir sep char!) from unix-like file system */
-            case '>':             /* no redirection symbols allowed either */
-            case '|':             /* no pipe signs allowed */
-            case '"':             /* no double quotes allowed */
-            case '?':             /* no wildcards allowed */
-            case '*':
-                *ppw++ = '_';     /* these rules apply equally to FAT and NTFS */
-                break;
-            case ';':             /* start of VMS version? */
-                lastsemiw = ppw;  /* remove VMS version later... */
-                *ppw++ = ';';     /*  but keep semicolon for now */
-                break;
-
-
-            case ' ':             /* keep spaces unless specifically */
-                /* NT cannot create filenames with spaces on FAT volumes */
-                if (uO.sflag || IsVolumeOldFATw(__G__ G.unipath_widefilename))
-                    *ppw++ = '_';
-                else
-                    *ppw++ = ' ';
-                break;
-
-            default:
-                /* allow European characters in filenames: */
-                if (iswprint(workchw) || workchw >= 127)
-                    *ppw++ = workchw;
-        } /* end switch */
-
-    } /* end while loop */
-
-    /* Show warning when stripping insecure "parent dir" path components */
-    /* For now use standard path for output messages */
-    if (killed_ddot && QCOND2) {
-        Info(slide, 0, ((char *)slide,
-          "warning: skipped \"../\" path component(s) (2) in %s\n",
-          FnFilter1(G.filename)));
-        if (!(error & ~MPN_MASK))
-            error = (error & MPN_MASK) | PK_WARN;
-    }
-
-/*---------------------------------------------------------------------------
-    Report if directory was created (and no file to create:  filename ended
-    in '/'), check name to be sure it exists, and combine path and name be-
-    fore exiting.
-  ---------------------------------------------------------------------------*/
-
-    if ((G.unipath_widefilename[wcslen(G.unipath_widefilename) - 1] == '/')
-#  ifdef SYMLINKS
-     /* Process a symlink as a file, even if it looks like a directory.
-      * (Which a Windows directory symlink might do.)
-      */
-     && !G.pInfo->symlink
-#  endif /* def SYMLINKS */
-     )
-    {
-        checkdirw(__G__ G.unipath_widefilename, GETPATH);
-        if (G.created_dir) {
-            if (QCOND2) {
-                Info(slide, 0, ((char *)slide, "   creating: %-22s\n",
-                  FnFilter1(G.filename)));
-            }
-
-            /* set file attributes:
-               The default for newly created directories is "DIR attribute
-               flags set", so there is no need to change attributes unless
-               one of the DOS style attribute flags is set. The readonly
-               attribute need not be masked, since it does not prevent
-               modifications in the new directory. */
-            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
-                if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F))
-                    Info(slide, 1, ((char *)slide,
- "\nwarning (%d): could not set file attributes (5) for %s\n",
-                      (int)GetLastError(), FnFilter1(G.filename)));
-            }
-
-            /* set dir time (note trailing '/') */
-            return (error & ~MPN_MASK) | MPN_CREATED_DIR;
-        } else if (IS_OVERWRT_ALL) {
-            /* overwrite attributes of existing directory on user's request */
-
-            /* set file attributes: */
-            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
-                if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F))
-                    Info(slide, 1, ((char *)slide,
- "\nwarning (%d): could not set file attributes (6) for %s\n",
-                      (int)GetLastError(), FnFilter1(G.filename)));
-            }
-        }
-        /* dir existed already; don't look for data to extract */
-        return (error & ~MPN_MASK) | MPN_INF_SKIP;
-    }
-
-    *ppw = '\0';                   /* done with pathcomp:  terminate it */
-
-    /* If not saving them, remove a VMS version number (ending: ";###"). */
-    if (lastsemiw &&
-     ((uO.V_flag < 0) || ((uO.V_flag == 0) && (G.pInfo->hostnum == VMS_)))) {
-        ppw = lastsemiw + 1;      /* semi-colon was kept:  expect #'s after */
-        if (*ppw != '\0') {       /* At least one digit is required. */
-            while (iswdigit(*ppw))
-                ++ppw;
-            if (*ppw == '\0')     /* only digits between ';' and end:  nuke */
-                *lastsemiw = '\0';
-        }
-    }
-
-    maskDOSdevicew(__G__ pathcompw);
-
-    if (*pathcompw == '\0') {
-        Info(slide, 1, ((char *)slide, "mapname(2): conversion of %s failed\n",
-          FnFilter1(G.filename)));
-        return (error & ~MPN_MASK) | MPN_ERR_SKIP;
-    }
-
-    checkdirw(__G__ pathcompw, APPEND_NAME);  /* returns 1 if truncated: care? */
-
-#  ifdef DYNAMIC_WIDE_NAME
-    if ((unsigned int)(G.endFATw- G.buildpathFATw) >
-     wcslen( G.unipath_widefilename))
-    {
-      /* 2013-03-18 SMS.
-       * Need more storage for the constructed name.
-       * It might make more sense to allocate FILNAMSIZ* sizeof( wchar_t)
-       * in the first place, but utf8_to_wchar_string() allocates the
-       * exact size of the leaf name.
-       */
-      if ((G.unipath_widefilename = izu_realloc( G.unipath_widefilename,
-       ((G.endFATw- G.buildpathFATw+ 1)* sizeof( wchar_t)))) == NULL)
-      {
-        return MPN_NOMEM;
-      }
-    }
-#  endif /* def DYNAMIC_WIDE_NAME */
-    /* Get the constructed name. */
-    checkdirw(__G__ G.unipath_widefilename, GETPATH);
-
-    if (G.pInfo->vollabel) {    /* set the volume label now */
-        char drive[4] = "?:\\";
-        wchar_t drivew[4] = L"?:\\";
-
-        /* Insert the drive letter into the drive string.  E.g. "b:\". */
-        drive[0] = (char)(('a'- 1)+ G.nLabelDrive);
-        drivew[0] = (wchar_t)(('a'- 1)+ G.nLabelDrive);
-        if (QCOND2)
-            Info(slide, 0, ((char *)slide, "labeling %s %-22s\n", drive,
-              FnFilter1(G.filename)));
-        if (!SetVolumeLabelW(drivew, G.unipath_widefilename)) {
-            Info(slide, 1, ((char *)slide,
-              "mapname(2): error setting volume label\n"));
-            return (error & ~MPN_MASK) | MPN_ERR_SKIP;
-        }
-        /* success: skip the "extraction" quietly */
-        return (error & ~MPN_MASK) | MPN_INF_SKIP;
-    }
-    Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",
-      FnFilter1(G.filename), error));
-    return error;
-
-} /* end function mapnamew() */
-
-
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-
-/****************************/
-/* Function maskDOSdevice() */
-/****************************/
-
-static void maskDOSdevice(__G__ pathcomp)
-    __GDEF
-    char *pathcomp;
-{
-/*---------------------------------------------------------------------------
-    Put an underscore in front of the file name if the file name is a
-    DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to
-    extract such a file would fail at best and wedge us at worst.
-  ---------------------------------------------------------------------------*/
-# if !defined(S_IFCHR) && defined(_S_IFCHR)
-#  define S_IFCHR _S_IFCHR
-# endif
-# if !defined(S_ISCHR)
-#  if defined(_S_ISCHR)
-#   define S_ISCHR(m) _S_ISCHR(m)
-#  elif defined(S_IFCHR)
-#   define S_ISCHR(m) ((m) & S_IFCHR)
-#  endif
-# endif
-
-# ifdef DEBUG
-    if (zstat(pathcomp, &G.statbuf) == 0) {
-        Trace((stderr,
-               "maskDOSdevice() stat(\"%s\", buf) st_mode result: %X, %o\n",
-               FnFilter1(pathcomp), G.statbuf.st_mode, G.statbuf.st_mode));
-    } else {
-        Trace((stderr, "maskDOSdevice() stat(\"%s\", buf) failed\n",
-               FnFilter1(pathcomp)));
-    }
-# endif
-    if (zstat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {
-        extent i;
-
-        /* pathcomp contains a name of a DOS character device (builtin or
-         * installed device driver).
-         * Prepend a '_' to allow creation of the item in the file system.
-         */
-        for (i = strlen(pathcomp) + 1; i > 0; --i)
-            pathcomp[i] = pathcomp[i - 1];
-        pathcomp[0] = '_';
-    }
-} /* end function maskDOSdevice() */
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-
-static void maskDOSdevicew(__G__ pathcompw)
-    __GDEF
-    wchar_t *pathcompw;
-{
-/*---------------------------------------------------------------------------
-    Put an underscore in front of the file name if the file name is a
-    DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to
-    extract such a file would fail at best and wedge us at worst.
-  ---------------------------------------------------------------------------*/
-#  if !defined(S_IFCHR) && defined(_S_IFCHR)
-#   define S_IFCHR _S_IFCHR
-#  endif
-#  if !defined(S_ISCHR)
-#   if defined(_S_ISCHR)
-#    define S_ISCHR(m) _S_ISCHR(m)
-#   elif defined(S_IFCHR)
-#    define S_ISCHR(m) ((m) & S_IFCHR)
-#   endif
-#  endif
-
-    if (zstatw(pathcompw, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {
-        extent i;
-
-        /* pathcomp contains a name of a DOS character device (builtin or
-         * installed device driver).
-         * Prepend a '_' to allow creation of the item in the file system.
-         */
-        for (i = wcslen(pathcompw) + 1; i > 0; --i)
-            pathcompw[i] = pathcompw[i - 1];
-        pathcompw[0] = '_';
-    }
-} /* end function maskDOSdevicew() */
-
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-/**********************/
-/* Function map2fat() */        /* Not quite identical to OS/2 version */
-/**********************/
-
-static void map2fat(pathcomp, pEndFAT)
-    char *pathcomp, **pEndFAT;
-{
-    char *ppc = pathcomp;       /* variable pointer to pathcomp */
-    char *pEnd = *pEndFAT;      /* variable pointer to buildpathFAT */
-    char *pBegin = *pEndFAT;    /* constant pointer to start of this comp. */
-    char *last_dot = NULL;      /* last dot not converted to underscore */
-    register unsigned workch;   /* hold the character being tested */
-
-
-    /* Only need check those characters which are legal in NTFS but not
-     * in FAT:  to get here, must already have passed through mapname.
-     * Also must truncate path component to ensure 8.3 compliance.
-     */
-    while ((workch = (uch)*ppc++) != 0) {
-        switch (workch) {
-            case '[':
-            case ']':
-            case '+':
-            case ',':
-            case ';':
-            case '=':
-                *pEnd++ = '_';      /* convert brackets to underscores */
-                break;
-
-            case '.':
-                if (pEnd == *pEndFAT) {   /* nothing appended yet... */
-                    if (*ppc == '\0')     /* don't bother appending a */
-                        break;            /*  "./" component to the path */
-                    else if (*ppc == '.' && ppc[1] == '\0') {   /* "../" */
-                        *pEnd++ = '.';    /*  add first dot, */
-                        *pEnd++ = '.';    /*  add second dot, and */
-                        ++ppc;            /*  skip over to pathcomp's end */
-                    } else {              /* FAT doesn't allow null filename */
-                        *pEnd++ = '_';    /*  bodies, so map .exrc -> _exrc */
-                    }                     /*  (_.exr would keep max 3 chars) */
-                } else {                  /* found dot within path component */
-                    last_dot = pEnd;      /*  point at last dot so far... */
-                    *pEnd++ = '_';        /*  convert to underscore for now */
-                }
-                break;
-
-            default:
-                *pEnd++ = (char)workch;
-
-        } /* end switch */
-    } /* end while loop */
-
-    *pEnd = '\0';                 /* terminate buildpathFAT */
-
-    /* NOTE:  keep in mind that pEnd points to the end of the path
-     * component, and *pEndFAT still points to the *beginning* of it...
-     * Also note that the algorithm does not try to get too fancy:
-     * if there are no dots already, the name either gets truncated
-     * at 8 characters or the last underscore is converted to a dot
-     * (only if more characters are saved that way).  In no case is
-     * a dot inserted between existing characters.
-     */
-    if (last_dot == NULL) {       /* no dots:  check for underscores... */
-        char *plu = MBSRCHR(pBegin, '_');   /* pointer to last underscore */
-
-        if ((plu != NULL) &&      /* found underscore: convert to dot? */
-            (IZ_MIN(plu - pBegin, 8) + IZ_MIN(pEnd - plu - 1, 3) > 8)) {
-            last_dot = plu;       /* be lazy:  drop through to next if-blk */
-        } else if ((pEnd - *pEndFAT) > 8) {
-            /* no underscore; or converting underscore to dot would save less
-               chars than leaving everything in the basename */
-            *pEndFAT += 8;        /* truncate at 8 chars */
-            **pEndFAT = '\0';
-        } else
-            *pEndFAT = pEnd;      /* whole thing fits into 8 chars or less */
-    }
-
-    if (last_dot != NULL) {       /* one dot is OK: */
-        *last_dot = '.';          /* put it back in */
-
-        if ((last_dot - pBegin) > 8) {
-            char *p, *q;
-            int i;
-
-            p = last_dot;
-            q = last_dot = pBegin + 8;
-            for (i = 0;  (i < 4) && *p;  ++i)  /* too many chars in basename: */
-                *q++ = *p++;                   /*  shift .ext left and trun- */
-            *q = '\0';                         /*  cate/terminate it */
-            *pEndFAT = q;
-        } else if ((pEnd - last_dot) > 4) {    /* too many chars in extension */
-            *pEndFAT = last_dot + 4;
-            **pEndFAT = '\0';
-        } else
-            *pEndFAT = pEnd;   /* filename is fine; point at terminating zero */
-
-        if ((last_dot - pBegin) > 0 && last_dot[-1] == ' ')
-            last_dot[-1] = '_';                /* NO blank in front of '.'! */
-    }
-} /* end function map2fat() */
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-
-static void map2fatw(pathcompw, pEndFATw)
-    wchar_t *pathcompw, **pEndFATw;
-{
-    wchar_t *ppcw = pathcompw;       /* variable pointer to pathcomp */
-    wchar_t *pEndw = *pEndFATw;      /* variable pointer to buildpathFAT */
-    wchar_t *pBeginw = *pEndFATw;    /* constant pointer to start of this comp. */
-    wchar_t *last_dotw = NULL;      /* last dot not converted to underscore */
-    register wchar_t workchw;   /* hold the character being tested */
-
-
-    /* Only need check those characters which are legal in NTFS but not
-     * in FAT:  to get here, must already have passed through mapname.
-     * Also must truncate path component to ensure 8.3 compliance.
-     */
-    while ((workchw = *ppcw++) != 0) {
-        switch (workchw) {
-            case '[':
-            case ']':
-            case '+':
-            case ',':
-            case ';':
-            case '=':
-                *pEndw++ = '_';      /* convert brackets to underscores */
-                break;
-
-            case '.':
-                if (pEndw == *pEndFATw) {   /* nothing appended yet... */
-                    if (*ppcw == '\0')     /* don't bother appending a */
-                        break;            /*  "./" component to the path */
-                    else if (*ppcw == '.' && ppcw[1] == '\0') {   /* "../" */
-                        *pEndw++ = '.';    /*  add first dot, */
-                        *pEndw++ = '.';    /*  add second dot, and */
-                        ++ppcw;            /*  skip over to pathcomp's end */
-                    } else {              /* FAT doesn't allow null filename */
-                        *pEndw++ = '_';    /*  bodies, so map .exrc -> _exrc */
-                    }                     /*  (_.exr would keep max 3 chars) */
-                } else {                  /* found dot within path component */
-                    last_dotw = pEndw;      /*  point at last dot so far... */
-                    *pEndw++ = '_';        /*  convert to underscore for now */
-                }
-                break;
-
-            default:
-                *pEndw++ = workchw;
-
-        } /* end switch */
-    } /* end while loop */
-
-    *pEndw = '\0';                 /* terminate buildpathFAT */
-
-    /* NOTE:  keep in mind that pEnd points to the end of the path
-     * component, and *pEndFAT still points to the *beginning* of it...
-     * Also note that the algorithm does not try to get too fancy:
-     * if there are no dots already, the name either gets truncated
-     * at 8 characters or the last underscore is converted to a dot
-     * (only if more characters are saved that way).  In no case is
-     * a dot inserted between existing characters.
-     */
-    if (last_dotw == NULL) {       /* no dots:  check for underscores... */
-        wchar_t *pluw = wcschr(pBeginw, '_');   /* pointer to last underscore */
-
-        if ((pluw != NULL) &&      /* found underscore: convert to dot? */
-            (IZ_MIN(pluw - pBeginw, 8) + IZ_MIN(pEndw - pluw - 1, 3) > 8)) {
-            last_dotw = pluw;       /* be lazy:  drop through to next if-blk */
-        } else if ((pEndw - *pEndFATw) > 8) {
-            /* no underscore; or converting underscore to dot would save less
-               chars than leaving everything in the basename */
-            *pEndFATw += 8;        /* truncate at 8 chars */
-            **pEndFATw = '\0';
-        } else
-            *pEndFATw = pEndw;      /* whole thing fits into 8 chars or less */
-    }
-
-    if (last_dotw != NULL) {       /* one dot is OK: */
-        *last_dotw = '.';          /* put it back in */
-
-        if ((last_dotw - pBeginw) > 8) {
-            wchar_t *pw, *qw;
-           int i;
-
-            pw = last_dotw;
-            qw = last_dotw = pBeginw + 8;
-            for (i = 0;  (i < 4) && *pw;  ++i)  /* too many chars in basename: */
-                *qw++ = *pw++;                   /*  shift .ext left and trun- */
-            *qw = '\0';                         /*  cate/terminate it */
-            *pEndFATw = qw;
-        } else if ((pEndw - last_dotw) > 4) {    /* too many chars in extension */
-            *pEndFATw = last_dotw + 4;
-            **pEndFATw = '\0';
-        } else
-            *pEndFATw = pEndw;   /* filename is fine; point at terminating zero */
-
-        if ((last_dotw - pBeginw) > 0 && last_dotw[-1] == ' ')
-            last_dotw[-1] = '_';                /* NO blank in front of '.'! */
-    }
-} /* end function map2fatw() */
-
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-/***********************/       /* Borrowed from os2.c for UnZip 5.1.        */
-/* Function checkdir() */       /* Difference: no EA stuff                   */
-/***********************/       /*             HPFS stuff works on NTFS too  */
-
-int checkdir(__G__ pathcomp, flag)
-    __GDEF
-    char *pathcomp;
-    int flag;
-/*
- * returns:
- *  MPN_OK          - no problem detected
- *  MPN_INF_TRUNC   - (on APPEND_NAME) truncated filename
- *  MPN_INF_SKIP    - path doesn't exist, not allowed to create
- *  MPN_ERR_SKIP    - path doesn't exist, tried to create and failed; or path
- *                    exists and is not a directory, but is supposed to be
- *  MPN_ERR_TOOLONG - path is too long
- *  MPN_NOMEM       - can't allocate memory for filename buffers
- */
-{
- /* static int rootlen = 0;     */   /* length of rootpath */
- /* static char *rootpath;      */   /* user's "extract-to" directory */
- /* static char *buildpathHPFS; */   /* full path (so far) to extracted file, */
- /* static char *buildpathFAT;  */   /*  both HPFS/EA (main) and FAT versions */
- /* static char *endHPFS;       */   /* corresponding pointers to end of */
- /* static char *endFAT;        */   /*  buildpath ('\0') */
-
-#   define FN_MASK   7
-#   define FUNCTION  (flag & FN_MASK)
-
-
-
-/*---------------------------------------------------------------------------
-    APPEND_DIR:  append the path component to the path being built and check
-    for its existence.  If doesn't exist and we are creating directories, do
-    so for this one; else signal success or error as appropriate.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == APPEND_DIR) {
-        char *p = pathcomp;
-        int too_long = FALSE;
-
-        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
-        while ((*G.endHPFS = *p++) != '\0')     /* copy to HPFS filename */
-            ++G.endHPFS;
-        if (!IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
-            p = pathcomp;
-            while ((*G.endFAT = *p++) != '\0')  /* copy to FAT filename, too */
-                ++G.endFAT;
-        } else
-            map2fat(pathcomp, &G.endFAT);   /* map into FAT fn, update endFAT */
-
-        /* GRR:  could do better check, see if overrunning buffer as we go:
-         * check endHPFS-buildpathHPFS after each append, set warning variable
-         * if within 20 of FILNAMSIZ; then if var set, do careful check when
-         * appending.  Clear variable when begin new path. */
-
-        /* next check:  need to append '/', at least one-char name, '\0' */
-        if ((G.endHPFS-G.buildpathHPFS) > FILNAMSIZ-3)
-            too_long = TRUE;                    /* check if extracting dir? */
-# ifdef FIX_STAT_BUG
-        /* Borland C++ 5.0 does not handle a call to stat() well if the
-         * directory does not exist (it tends to crash in strange places.)
-         * This is apparently a problem only when compiling for GUI rather
-         * than console. The code below attempts to work around this problem.
-         */
-        if (access(G.buildpathFAT, 0) != 0) {
-            if (!G.create_dirs) { /* told not to create (freshening) */
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* path doesn't exist:  nothing to do */
-                return MPN_INF_SKIP;
-            }
-            if (too_long) {   /* GRR:  should allow FAT extraction w/o EAs */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(1) error: path too long: %s\n",
-                  FnFilter1(G.buildpathHPFS)));
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* no room for filenames:  fatal */
-                return MPN_ERR_TOOLONG;
-            }
-            if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(1) error: cannot create %s\n\
- unable to process %s.\n",
-                  FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* path didn't exist, tried to create, failed */
-                return MPN_ERR_SKIP;
-            }
-            G.created_dir = TRUE;
-        }
-# endif /* FIX_STAT_BUG */
-        if (SSTAT(G.buildpathFAT, &G.statbuf))   /* path doesn't exist */
-        {
-            if (!G.create_dirs) { /* told not to create (freshening) */
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* path doesn't exist: nothing to do */
-                return MPN_INF_SKIP;
-            }
-            if (too_long) {   /* GRR:  should allow FAT extraction w/o EAs */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(2) error: path too long: %s\n",
-                  FnFilter1(G.buildpathHPFS)));
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* no room for filenames:  fatal */
-                return MPN_ERR_TOOLONG;
-            }
-            if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(2) error: cannot create %s\n\
- unable to process %s.\n",
-                  FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                /* path didn't exist, tried to create, failed */
-                return MPN_ERR_SKIP;
-            }
-            G.created_dir = TRUE;
-        } else if (!S_ISDIR(G.statbuf.st_mode)) {
-            Info(slide, 1, ((char *)slide,
-              "checkdir(1) error: %s exists but is not directory\n\
- unable to process %s.\n",
-              FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
-            izu_free(G.buildpathHPFS);
-            izu_free(G.buildpathFAT);
-            /* path existed but wasn't dir */
-            return MPN_ERR_SKIP;
-        }
-        if (too_long) {
-            Info(slide, 1, ((char *)slide,
-              "checkdir(3) error: path too long: %s\n",
-               FnFilter1(G.buildpathHPFS)));
-            izu_free(G.buildpathHPFS);
-            izu_free(G.buildpathFAT);
-            /* no room for filenames:  fatal */
-            return MPN_ERR_TOOLONG;
-        }
-        *G.endHPFS++ = '/';
-        *G.endFAT++ = '/';
-        *G.endHPFS = *G.endFAT = '\0';
-        Trace((stderr, "buildpathHPFS now = [%s]\nbuildpathFAT now =  [%s]\n",
-          FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
-        return MPN_OK;
-
-    } /* end if (FUNCTION == APPEND_DIR) */
-
-/*---------------------------------------------------------------------------
-    GETPATH:  copy full FAT path to the string pointed at by pathcomp (want
-    filename to reflect name used on disk, not EAs; if full path is HPFS,
-    buildpathFAT and buildpathHPFS will be identical).  Also free both paths.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == GETPATH) {
-        Trace((stderr, "getting and freeing FAT path [%s]\n",
-          FnFilter1(G.buildpathFAT)));
-        strcpy(pathcomp, G.buildpathFAT);
-        izu_free(G.buildpathFAT);
-        Trace((stderr, "freeing HPFS path [%s]\n",
-          FnFilter1(G.buildpathHPFS)));
-        izu_free(G.buildpathHPFS);
-        G.buildpathHPFS = G.buildpathFAT = G.endHPFS = G.endFAT = NULL;
-        return MPN_OK;
-    }
-
-/*---------------------------------------------------------------------------
-    APPEND_NAME:  assume the path component is the filename; append it and
-    return without checking for existence.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == APPEND_NAME) {
-        char *p = pathcomp;
-        int error = MPN_OK;
-
-        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
-        /* The buildpathHPFS buffer has been allocated large enough to
-         * hold the complete combined name, so there is no need to check
-         * for OS filename size limit overflow within the copy loop.
-         */
-        while ((*G.endHPFS = *p++) != '\0') {   /* copy to HPFS filename */
-            ++G.endHPFS;
-        }
-        /* Now, check for OS filename size overflow.  When detected, the
-         * mapped HPFS name is truncated and a warning message is shown.
-         */
-        if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
-            G.buildpathHPFS[FILNAMSIZ-1] = '\0';
-            Info(slide, 1, ((char *)slide,
-              "checkdir(1) warning: path too long; truncating\n\
-    %s\n\
- -> %s\n",
-              FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
-            error = MPN_INF_TRUNC;  /* filename truncated */
-        }
-
-        /* The buildpathFAT buffer has the same allocated size as the
-         * buildpathHPFS buffer, so there is no need for an overflow check
-         * within the following copy loop, either.
-         */
-        if (G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
-            /* copy to FAT filename, too */
-            p = pathcomp;
-            while ((*G.endFAT = *p++) != '\0')
-                ++G.endFAT;
-        } else
-            /* map into FAT fn, update endFAT */
-            map2fat(pathcomp, &G.endFAT);
-
-        /* Check that the FAT path does not exceed the FILNAMSIZ limit, and
-         * truncate when neccessary.
-         * Note that truncation can only happen when the HPFS path (which is
-         * never shorter than the FAT path) has been already truncated.
-         * So, emission of the warning message and setting the error code
-         * has already happened.
-         */
-        if ((G.endFAT-G.buildpathFAT) >= FILNAMSIZ)
-            G.buildpathFAT[FILNAMSIZ-1] = '\0';
-        Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT:  %s\n",
-          FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
-
-        return error;  /* could check for existence, prompt for new name... */
-
-    } /* end if (FUNCTION == APPEND_NAME) */
-
-/*---------------------------------------------------------------------------
-    INIT:  allocate and initialize buffer space for the file currently being
-    extracted.  If file was renamed with an absolute path, don't prepend the
-    extract-to path.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == INIT) {
-        Trace((stderr, "initializing buildpathHPFS and buildpathFAT to "));
-# ifdef ACORN_FTYPE_NFS
-        if ((G.buildpathHPFS = (char *)izu_malloc(G.fnlen+G.rootlen+
-                                              (uO.acorn_nfs_ext ? 5 : 1)))
-# else
-        if ((G.buildpathHPFS = (char *)izu_malloc(G.fnlen+G.rootlen+1))
-# endif
-            == NULL)
-            return MPN_NOMEM;
-# ifdef ACORN_FTYPE_NFS
-        if ((G.buildpathFAT = (char *)izu_malloc(G.fnlen+G.rootlen+
-                                             (uO.acorn_nfs_ext ? 5 : 1)))
-# else
-        if ((G.buildpathFAT = (char *)izu_malloc(G.fnlen+G.rootlen+1))
-# endif
-            == NULL) {
-            izu_free(G.buildpathHPFS);
-            return MPN_NOMEM;
-        }
-        if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */
-/* GRR:  for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
-            if (G.renamed_fullpath && pathcomp[1] == ':')
-                *G.buildpathHPFS = (char)ToLower(*pathcomp);
-            else if (!G.renamed_fullpath && G.rootlen > 1 &&
-                     G.rootpath[1] == ':')
-                *G.buildpathHPFS = (char)ToLower(*G.rootpath);
-            else {
-                char tmpN[MAX_PATH], *tmpP;
-                if (GetFullPathNameA(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH)
-                { /* by definition of MAX_PATH we should never get here */
-                    Info(slide, 1, ((char *)slide,
-                      "checkdir(1) warning: current dir path too long\n"));
-                    return MPN_INF_TRUNC;   /* can't get drive letter */
-                }
-                G.nLabelDrive = *tmpN - 'a' + 1;
-                *G.buildpathHPFS = (char)(G.nLabelDrive - 1 + 'a');
-            }
-            G.nLabelDrive = *G.buildpathHPFS - 'a' + 1; /* save for mapname() */
-            if (uO.volflag == 0 || *G.buildpathHPFS < 'a' /* no labels/bogus? */
-                || (uO.volflag == 1 && !isfloppy(G.nLabelDrive))) { /* !fixed */
-                izu_free(G.buildpathHPFS);
-                izu_free(G.buildpathFAT);
-                return MPN_VOL_LABEL;  /* skipping with message */
-            }
-            *G.buildpathHPFS = '\0';
-        } else if (G.renamed_fullpath) /* pathcomp = valid data */
-            strcpy(G.buildpathHPFS, pathcomp);
-        else if (G.rootlen > 0)
-            strcpy(G.buildpathHPFS, G.rootpath);
-        else
-            *G.buildpathHPFS = '\0';
-        G.endHPFS = G.buildpathHPFS;
-        G.endFAT = G.buildpathFAT;
-        while ((*G.endFAT = *G.endHPFS) != '\0') {
-            ++G.endFAT;
-            ++G.endHPFS;
-        }
-        Trace((stderr, "[%s]\n", FnFilter1(G.buildpathHPFS)));
-        return MPN_OK;
-    }
-
-/*---------------------------------------------------------------------------
-    ROOT:  if appropriate, store the path in rootpath and create it if neces-
-    sary; else assume it's a zipfile member and return.  This path segment
-    gets used in extracting all members from every zipfile specified on the
-    command line.  Note that under OS/2 and MS-DOS, if a candidate extract-to
-    directory specification includes a drive letter (leading "x:"), it is
-    treated just as if it had a trailing '/'--that is, one directory level
-    will be created if the path doesn't exist, unless this is otherwise pro-
-    hibited (e.g., freshening).
-  ---------------------------------------------------------------------------*/
-
-# if (!defined(SFX) || defined(SFX_EXDIR))
-    if (FUNCTION == ROOT) {
-        Trace((stderr, "initializing root path to [%s]\n",
-          FnFilter1(pathcomp)));
-        if (pathcomp == NULL) {
-            G.rootlen = 0;
-            return MPN_OK;
-        }
-        if (G.rootlen > 0)      /* rootpath was already set, nothing to do */
-            return MPN_OK;
-        if ((G.rootlen = strlen(pathcomp)) > 0) {
-            int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE;
-            char *tmproot;
-
-            if ((tmproot = (char *)izu_malloc(G.rootlen+3)) == (char *)NULL) {
-                G.rootlen = 0;
-                return MPN_NOMEM;
-            }
-            strcpy(tmproot, pathcomp);
-            if (isalpha((uch)tmproot[0]) && tmproot[1] == ':')
-                has_drive = TRUE;   /* drive designator */
-            if (tmproot[G.rootlen-1] == '/' || tmproot[G.rootlen-1] == '\\') {
-                tmproot[--G.rootlen] = '\0';
-                had_trailing_pathsep = TRUE;
-            }
-            if (has_drive && (G.rootlen == 2)) {
-                if (!had_trailing_pathsep)   /* i.e., original wasn't "x:/" */
-                    add_dot = TRUE;    /* relative path: add '.' before '/' */
-            } else if (G.rootlen > 0) {   /* need not check "x:." and "x:/" */
-                if (SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))
-                {
-                    /* path does not exist */
-                    if (!G.create_dirs /* || iswild(tmproot) */ ) {
-                        izu_free(tmproot);
-                        G.rootlen = 0;
-                        /* treat as stored file */
-                        return MPN_INF_SKIP;
-                    }
-                    /* create directory (could add loop here scanning tmproot
-                     * to create more than one level, but really necessary?) */
-                    if (MKDIR(tmproot, 0777) == -1) {
-                        Info(slide, 1, ((char *)slide,
- "checkdir(1): cannot create extraction directory: %s\n",
-                          FnFilter1(tmproot)));
-                        izu_free(tmproot);
-                        G.rootlen = 0;
-                        /* path didn't exist, tried to create, failed: */
-                        /* file exists, or need 2+ subdir levels */
-                        return MPN_ERR_SKIP;
-                    }
-                }
-            }
-            if (add_dot)                    /* had just "x:", make "x:." */
-                tmproot[G.rootlen++] = '.';
-            tmproot[G.rootlen++] = '/';
-            tmproot[G.rootlen] = '\0';
-            if ((G.rootpath = (char *)izu_realloc(
-             tmproot, G.rootlen+1)) == NULL) {
-                izu_free(tmproot);
-                G.rootlen = 0;
-                return MPN_NOMEM;
-            }
-            Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath)));
-        }
-        return MPN_OK;
-    }
-# endif /* !SFX || SFX_EXDIR */
-
-/*---------------------------------------------------------------------------
-    END:  free rootpath, immediately prior to program exit.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == END) {
-        Trace((stderr, "freeing rootpath\n"));
-        if (G.rootlen > 0) {
-            izu_free(G.rootpath);
-            G.rootlen = 0;
-        }
-        return MPN_OK;
-    }
-
-    return MPN_INVALID; /* should never reach */
-
-} /* end function checkdir() */
-
-
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-
-/* WIN32 wide version */
-
-int checkdirw(__G__ pathcompw, flag)
-    __GDEF
-    wchar_t *pathcompw;
-    int flag;
-/*
- * returns:
- *  MPN_OK          - no problem detected
- *  MPN_INF_TRUNC   - (on APPEND_NAME) truncated filename
- *  MPN_INF_SKIP    - path doesn't exist, not allowed to create
- *  MPN_ERR_SKIP    - path doesn't exist, tried to create and failed; or path
- *                    exists and is not a directory, but is supposed to be
- *  MPN_ERR_TOOLONG - path is too long
- *  MPN_NOMEM       - can't allocate memory for filename buffers
- */
-{
- /* static int rootlen = 0;     */   /* length of rootpath */
- /* static char *rootpath;      */   /* user's "extract-to" directory */
- /* static char *buildpathHPFS; */   /* full path (so far) to extracted file, */
- /* static char *buildpathFAT;  */   /*  both HPFS/EA (main) and FAT versions */
- /* static char *endHPFS;       */   /* corresponding pointers to end of */
- /* static char *endFAT;        */   /*  buildpath ('\0') */
-
-#  define FN_MASK   7
-#  define FUNCTION  (flag & FN_MASK)
-
-
-
-/*---------------------------------------------------------------------------
-    APPEND_DIR:  append the path component to the path being built and check
-    for its existence.  If doesn't exist and we are creating directories, do
-    so for this one; else signal success or error as appropriate.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == APPEND_DIR) {
-        wchar_t *pw = pathcompw;
-        int too_long = FALSE;
-        char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all);
-        char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all);
-        /* Could use G.filename from the standard path, but may
-           not work well on this port */
-        char *fn = wchar_to_local_string(G.unipath_widefilename, G.unicode_escape_all);
-
-        while ((*G.endHPFSw = *pw++) != '\0')     /* copy to HPFS filename */
-            ++G.endHPFSw;
-        if (!IsVolumeOldFATw(__G__ G.buildpathHPFSw)) {
-            pw = pathcompw;
-            while ((*G.endFATw = *pw++) != '\0')  /* copy to FAT filename, too */
-                ++G.endFATw;
-        } else
-            map2fatw(pathcompw, &G.endFATw);   /* map into FAT fn, update endFAT */
-
-        /* GRR:  could do better check, see if overrunning buffer as we go:
-         * check endHPFS-buildpathHPFS after each append, set warning variable
-         * if within 20 of FILNAMSIZ; then if var set, do careful check when
-         * appending.  Clear variable when begin new path. */
-
-        /* next check:  need to append '/', at least one-char name, '\0' */
-        if ((G.endHPFSw-G.buildpathHPFSw) > FILNAMSIZ-3)
-            too_long = TRUE;                    /* check if extracting dir? */
-#  ifdef FIX_STAT_BUG
-        /* Borland C++ 5.0 does not handle a call to stat() well if the
-         * directory does not exist (it tends to crash in strange places.)
-         * This is apparently a problem only when compiling for GUI rather
-         * than console. The code below attempts to work around this problem.
-         */
-        if (_waccess(G.buildpathFATw, 0) != 0) {
-            if (!G.create_dirs) { /* told not to create (freshening) */
-                izu_free(buildpathHPFS);
-                izu_free(buildpathFAT);
-                izu_free(fn);
-                izu_free(G.buildpathHPFSw);
-                izu_free(G.buildpathFATw);
-                /* path doesn't exist:  nothing to do */
-                return MPN_INF_SKIP;
-            }
-            if (too_long) {   /* GRR:  should allow FAT extraction w/o EAs */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(4) error: path too long: %s\n",
-                  FnFilter1(fn)));
-                izu_free(buildpathHPFS);
-                izu_free(buildpathFAT);
-                izu_free(fn);
-                izu_free(G.buildpathHPFSw);
-                izu_free(G.buildpathFATw);
-                /* no room for filenames:  fatal */
-                return MPN_ERR_TOOLONG;
-            }
-            {
-                int i = MKDIRW(G.buildpathFATw, 0777);
-                if (i == -1) { /* create the directory */
-                    Info(slide, 1, ((char *)slide,
-                        "checkdir(3) error: cannot create %s\n\
- unable to process %s.\n",
-                    FnFilter2(buildpathFAT), FnFilter1(fn)));
-                    izu_free(buildpathHPFS);
-                    izu_free(buildpathFAT);
-                    izu_free(fn);
-                    izu_free(G.buildpathHPFSw);
-                    izu_free(G.buildpathFATw);
-                    /* path didn't exist, tried to create, failed */
-                    return MPN_ERR_SKIP;
-                }
-              G.created_dir = TRUE;
-              }
-        }
-#  endif /* FIX_STAT_BUG */
-        if (SSTATW(G.buildpathFATw, &G.statbuf))   /* path doesn't exist */
-        {
-            if (!G.create_dirs) { /* told not to create (freshening) */
-                izu_free(buildpathHPFS);
-                izu_free(buildpathFAT);
-                izu_free(fn);
-                izu_free(G.buildpathHPFSw);
-                izu_free(G.buildpathFATw);
-                /* path doesn't exist:  nothing to do */
-                return MPN_INF_SKIP;
-            }
-            if (too_long) {   /* GRR:  should allow FAT extraction w/o EAs */
-                Info(slide, 1, ((char *)slide,
-                  "checkdir(5) error: path too long: %s\n",
-                  FnFilter1(buildpathHPFS)));
-                izu_free(buildpathHPFS);
-                izu_free(buildpathFAT);
-                izu_free(fn);
-                izu_free(G.buildpathHPFSw);
-                izu_free(G.buildpathFATw);
-                /* no room for filenames:  fatal */
-                return MPN_ERR_TOOLONG;
-            }
-            {
-                char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all);
-                int i = MKDIRW(G.buildpathFATw, 0777);
-                if (i == -1) { /* create the directory */
-                    Info(slide, 1, ((char *)slide,
-                        "checkdir(4) error: cannot create %s\n\
- unable to process %s.\n",
-                    FnFilter2(buildpathFAT), FnFilter1(fn)));
-                    izu_free(buildpathHPFS);
-                    izu_free(buildpathFAT);
-                    izu_free(fn);
-                    izu_free(G.buildpathHPFSw);
-                    izu_free(G.buildpathFATw);
-                    /* path didn't exist, tried to create, failed */
-                    return MPN_ERR_SKIP;
-                }
-                G.created_dir = TRUE;
-                }
-        } else if (!S_ISDIR(G.statbuf.st_mode)) {
-            Info(slide, 1, ((char *)slide,
-              "checkdir(2) error: %s exists but is not directory\n\
- unable to process %s.\n",
-            FnFilter2(buildpathFAT), FnFilter1(fn)));
-            izu_free(buildpathHPFS);
-            izu_free(buildpathFAT);
-            izu_free(fn);
-            izu_free(G.buildpathHPFSw);
-            izu_free(G.buildpathFATw);
-            /* path existed but wasn't dir */
-            return MPN_ERR_SKIP;
-        }
-        if (too_long) {
-            Info(slide, 1, ((char *)slide,
-              "checkdir(6) error: path too long: %s\n",
-            FnFilter1(buildpathHPFS)));
-            izu_free(buildpathHPFS);
-            izu_free(buildpathFAT);
-            izu_free(fn);
-            izu_free(G.buildpathHPFSw);
-            izu_free(G.buildpathFATw);
-            /* no room for filenames:  fatal */
-            return MPN_ERR_TOOLONG;
-        }
-        *G.endHPFSw++ = '/';
-        *G.endFATw++ = '/';
-        *G.endHPFSw = *G.endFATw = '\0';
-        Trace((stderr, "buildpathHPFS now = [%s]\nbuildpathFAT now =  [%s]\n",
-          FnFilter1(buildpathHPFS), FnFilter2(buildpathFAT)));
-        izu_free(buildpathHPFS);
-        izu_free(buildpathFAT);
-        izu_free(fn);
-        //izu_free(G.buildpathHPFSw);
-        //izu_free(G.buildpathFATw);
-        return MPN_OK;
-
-    } /* end if (FUNCTION == APPEND_DIR) */
-
-/*---------------------------------------------------------------------------
-    GETPATH:  copy full FAT path to the string pointed at by pathcomp (want
-    filename to reflect name used on disk, not EAs; if full path is HPFS,
-    buildpathFAT and buildpathHPFS will be identical).  Free both local paths.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == GETPATH) {
-#  ifdef Tracing
-        char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all);
-        char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all);
-        Trace((stderr, "getting and freeing FAT path [%s]\n",
-          FnFilter1(buildpathFAT)));
-        izu_free(buildpathFAT);
-#  endif /* def Tracing */
-        wcscpy(pathcompw, G.buildpathFATw);
-        izu_free(G.buildpathFATw);
-#  ifdef Tracing
-        Trace((stderr, "freeing HPFS path [%s]\n",
-          FnFilter1(buildpathHPFS)));
-        izu_free(buildpathHPFS);
-#  endif /* def Tracing */
-        izu_free(G.buildpathHPFSw);
-        G.buildpathHPFSw = G.buildpathFATw = G.endHPFSw = G.endFATw = NULL;
-        return MPN_OK;
-    }
-
-/*---------------------------------------------------------------------------
-    APPEND_NAME:  assume the path component is the filename; append it and
-    return without checking for existence.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == APPEND_NAME) {
-        wchar_t *pw = pathcompw;
-        int error = MPN_OK;
-        char *fn = wchar_to_local_string(G.unipath_widefilename, G.unicode_escape_all);
-#  ifdef Tracing
-        char *pathcomp = wchar_to_local_string(pathcompw, G.unicode_escape_all);
-        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
-        izu_free( pathcomp);
-#  endif /* def Tracing */
-        /* The buildpathHPFS buffer has been allocated large enough to
-         * hold the complete combined name, so there is no need to check
-         * for OS filename size limit overflow within the copy loop.
-         */
-        while ((*G.endHPFSw = *pw++) != '\0') {   /* copy to HPFS filename */
-            ++G.endHPFSw;
-        }
-        /* Now, check for OS filename size overflow.  When detected, the
-         * mapped HPFS name is truncated and a warning message is shown.
-         */
-        if ((G.endHPFSw-G.buildpathHPFSw) >= FILNAMSIZ) {
-            char *buildpathHPFS;
-            G.buildpathHPFSw[FILNAMSIZ-1] = '\0';
-            buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all);
-            Info(slide, 1, ((char *)slide,
-              "checkdir(2) warning: path too long; truncating\n\
-    %s\n\
- -> %s\n",
-              FnFilter1(fn), FnFilter2(buildpathHPFS)));
-            izu_free(buildpathHPFS);
-            izu_free( fn);
-            error = MPN_INF_TRUNC;  /* filename truncated */
-        }
-
-        /* The buildpathFAT buffer has the same allocated size as the
-         * buildpathHPFS buffer, so there is no need for an overflow check
-         * within the following copy loop, either.
-         */
-        if (G.pInfo->vollabel || !IsVolumeOldFATw(__G__ G.buildpathHPFSw)) {
-            /* copy to FAT filename, too */
-            pw = pathcompw;
-            while ((*G.endFATw = *pw++) != '\0')
-                ++G.endFATw;
-        } else
-            /* map into FAT fn, update endFAT */
-            map2fatw(pathcompw, &G.endFATw);
-
-        /* Check that the FAT path does not exceed the FILNAMSIZ limit, and
-         * truncate when neccessary.
-         * Note that truncation can only happen when the HPFS path (which is
-         * never shorter than the FAT path) has been already truncated.
-         * So, emission of the warning message and setting the error code
-         * has already happened.
-         */
-        if ((G.endFATw-G.buildpathFATw) >= FILNAMSIZ)
-            G.buildpathFATw[FILNAMSIZ-1] = '\0';
-#  ifdef Tracing
-        {
-          char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all);
-          char *buildpathFAT = wchar_to_local_string(G.buildpathFATw,G.unicode_escape_all);
-          Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT:  %s\n",
-            FnFilter1(buildpathHPFS), FnFilter2(buildpathFAT)));
-          izu_free(buildpathHPFS);
-          izu_free(buildpathFAT);
-        }
-#  endif /* def Tracing */
-        izu_free(fn);
-
-        return error;  /* could check for existence, prompt for new name... */
-
-    } /* end if (FUNCTION == APPEND_NAME) */
-
-/*---------------------------------------------------------------------------
-    INIT:  allocate and initialize buffer space for the file currently being
-    extracted.  If file was renamed with an absolute path, don't prepend the
-    extract-to path.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == INIT) {
-        Trace((stderr, "initializing buildpathHPFSw and buildpathFATw to "));
-        if ((G.buildpathHPFSw = (wchar_t *)izu_malloc(
-         (G.fnlen+G.rootlen+1) * sizeof(wchar_t))) == NULL)
-            return MPN_NOMEM;
-        if ((G.buildpathFATw = (wchar_t *)izu_malloc(
-         (G.fnlen+G.rootlen+1) * sizeof(wchar_t))) == NULL) {
-            izu_free(G.buildpathHPFSw);
-            return MPN_NOMEM;
-        }
-        if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */
-/* GRR:  for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
-            if (G.renamed_fullpath && pathcompw[1] == ':')
-                *G.buildpathHPFSw = (wchar_t)towlower(*pathcompw);
-            else if (!G.renamed_fullpath && G.rootlen > 1 &&
-                     G.rootpathw[1] == ':')
-                *G.buildpathHPFSw = (wchar_t)towlower(*G.rootpathw);
-            else {
-                wchar_t tmpNw[MAX_PATH], *tmpPw;
-                if (GetFullPathNameW(L".", MAX_PATH, tmpNw, &tmpPw) > MAX_PATH)
-                { /* by definition of MAX_PATH we should never get here */
-                    Info(slide, 1, ((char *)slide,
-                      "checkdir(2) warning: current dir path too long\n"));
-                    return MPN_INF_TRUNC;   /* can't get drive letter */
-                }
-                G.nLabelDrive = (char)(*G.buildpathHPFSw - 'a' + 1); /* save for mapname() */
-                *G.buildpathHPFSw = (wchar_t)(G.nLabelDrive - 1 + 'a');
-            }
-            if (uO.volflag == 0 || *G.buildpathHPFSw < 'a' /* no labels/bogus? */
-                || (uO.volflag == 1 && !isfloppy(G.nLabelDrive))) { /* !fixed */
-                izu_free(G.buildpathHPFSw);
-                izu_free(G.buildpathFATw);
-                return MPN_VOL_LABEL;  /* skipping with message */
-            }
-            *G.buildpathHPFSw = '\0';
-        } else if (G.renamed_fullpath) /* pathcomp = valid data */
-            wcscpy(G.buildpathHPFSw, pathcompw);
-        else if (G.rootlen > 0)
-            wcscpy(G.buildpathHPFSw, G.rootpathw);
-        else
-            *G.buildpathHPFSw = '\0';
-        G.endHPFSw = G.buildpathHPFSw;
-        G.endFATw = G.buildpathFATw;
-        while ((*G.endFATw = *G.endHPFSw) != '\0') {
-            ++G.endFATw;
-            ++G.endHPFSw;
-        }
-#  ifdef Tracing
-        {
-          char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all);
-          Trace((stderr, "[%s]\n", FnFilter1(buildpathHPFS)));
-          izu_free(buildpathHPFS);
-        }
-#  endif /* def Tracing */
-
-        return MPN_OK;
-    }
-
-/*---------------------------------------------------------------------------
-    ROOT:  if appropriate, store the path in rootpath and create it if neces-
-    sary; else assume it's a zipfile member and return.  This path segment
-    gets used in extracting all members from every zipfile specified on the
-    command line.  Note that under OS/2 and MS-DOS, if a candidate extract-to
-    directory specification includes a drive letter (leading "x:"), it is
-    treated just as if it had a trailing '/'--that is, one directory level
-    will be created if the path doesn't exist, unless this is otherwise pro-
-    hibited (e.g., freshening).
-  ---------------------------------------------------------------------------*/
-
-#  if (!defined(SFX) || defined(SFX_EXDIR))
-    if (FUNCTION == ROOT) {
-#   ifdef Tracing
-        char *pathcomp = wchar_to_local_string(pathcompw, G.unicode_escape_all);
-        Trace((stderr, "initializing root path to [%s]\n",
-          FnFilter1(pathcomp)));
-        izu_free(pathcomp);
-#   endif /* def Tracing */
-        if (pathcompw == NULL) {
-            G.rootlen = 0;
-            return MPN_OK;
-        }
-        if (G.rootlen > 0)      /* rootpath was already set, nothing to do */
-            return MPN_OK;
-        if ((G.rootlen = wcslen(pathcompw)) > 0) {
-            int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE;
-            wchar_t *tmprootw;
-
-            if ((tmprootw = (wchar_t *)izu_malloc(
-             (G.rootlen+3) * sizeof(wchar_t))) == (wchar_t *)NULL) {
-                G.rootlen = 0;
-                return MPN_NOMEM;
-            }
-            wcscpy(tmprootw, pathcompw);
-            if (iswalpha(tmprootw[0]) && tmprootw[1] == ':')
-                has_drive = TRUE;   /* drive designator */
-            if (tmprootw[G.rootlen-1] == '/' || tmprootw[G.rootlen-1] == '\\') {
-                tmprootw[--G.rootlen] = '\0';
-                had_trailing_pathsep = TRUE;
-            }
-            if (has_drive && (G.rootlen == 2)) {
-                if (!had_trailing_pathsep)   /* i.e., original wasn't "x:/" */
-                    add_dot = TRUE;    /* relative path: add '.' before '/' */
-            } else if (G.rootlen > 0) {   /* need not check "x:." and "x:/" */
-                if (SSTATW(tmprootw, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))
-                {
-                    /* path does not exist */
-                    if (!G.create_dirs /* || iswild(tmproot) */ ) {
-                        izu_free(tmprootw);
-                        G.rootlen = 0;
-                        /* treat as stored file */
-                        return MPN_INF_SKIP;
-                    }
-                    /* create directory (could add loop here scanning tmproot
-                     * to create more than one level, but really necessary?) */
-                    if (MKDIRW(tmprootw, 0777) == -1) {
-                        char *tmproot = wchar_to_local_string(tmprootw, G.unicode_escape_all);
-                        Info(slide, 1, ((char *)slide,
- "checkdir(2): cannot create extraction directory: %s\n",
-                          FnFilter1(tmproot)));
-                        izu_free(tmproot);
-                        izu_free(tmprootw);
-                        G.rootlen = 0;
-                        /* path didn't exist, tried to create, failed: */
-                        /* file exists, or need 2+ subdir levels */
-                        /* 2013-03-12 SMS.
-                         * izu_free(pathcomp);
-                         * Should be "izu_free(pathcompw);"???
-                         */
-                        return MPN_ERR_SKIP;
-                    }
-                }
-            }
-            if (add_dot)                    /* had just "x:", make "x:." */
-                tmprootw[G.rootlen++] = '.';
-            tmprootw[G.rootlen++] = '/';
-            tmprootw[G.rootlen] = '\0';
-            if ((G.rootpathw = (wchar_t *)izu_realloc(
-             tmprootw, (G.rootlen+1) * sizeof(wchar_t))) == NULL) {
-                izu_free(tmprootw);
-                G.rootlen = 0;
-                return MPN_NOMEM;
-            }
-#   ifdef Tracing
-            {
-              char *rootpath = wchar_to_local_string(G.rootpathw, G.unicode_escape_all);
-              Trace((stderr, "rootpath now = [%s]\n", FnFilter1(rootpath)));
-              izu_free(rootpath);
-            }
-#   endif /* def Tracing */
-        }
-        return MPN_OK;
-    }
-#  endif /* !SFX || SFX_EXDIR */
-
-/*---------------------------------------------------------------------------
-    END:  free rootpath, immediately prior to program exit.
-  ---------------------------------------------------------------------------*/
-
-    if (FUNCTION == END) {
-        Trace((stderr, "freeing rootpath\n"));
-        if (G.rootlen > 0) {
-            izu_free(G.rootpathw);
-            G.rootlen = 0;
-        }
-        return MPN_OK;
-    }
-
-    return MPN_INVALID; /* should never reach */
-
-} /* end function checkdirw() */
-
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-
-
-
-# ifndef SFX
-
-/*************************/
-/* Function dateformat() */
-/*************************/
-
-int dateformat()
-{
-  char df[2];   /* LOCALE_IDATE has a maximum value of 2 */
-
-  if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE, df, 2) != 0) {
-    switch (df[0])
-    {
-      case '0':
-        return DF_MDY;
-      case '1':
-        return DF_DMY;
-      case '2':
-        return DF_YMD;
-    }
-  }
-  return DF_MDY;
-}
-
-
-/****************************/
-/* Function dateseparator() */
-/****************************/
-
-char dateseparator()
-{
-  char df[2];   /* use only if it is one character */
-
-  if ((GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, df, 2) != 0) &&
-      (df[0] != '\0'))
-    return df[0];
-  else
-    return '-';
-}
-
-
-#  ifndef WINDLL_OLD
-
-/************************/
-/*  Function version()  */
-/************************/
-
-void version(__G)
-    __GDEF
-{
-    int len;
-#   if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DJGPP__))
-    char buf[80];
-#    if (defined(_MSC_VER) && (_MSC_VER > 900))
-    char buf2[80];
-#    endif
-#   endif
-
-    len = sprintf((char *)slide, CompiledWith,
-
-#   if defined(_MSC_VER)  /* MSC == VC++, but what about SDK compiler? */
-      (sprintf(buf, "Microsoft C %d.%02d ", _MSC_VER/100, _MSC_VER%100), buf),
-#    if (_MSC_VER == 800)
-      "(Visual C++ v1.1)",
-#    elif (_MSC_VER == 850)
-      "(Windows NT v3.5 SDK)",
-#    elif (_MSC_VER == 900)
-      "(Visual C++ v2.x)",
-#    elif (_MSC_VER > 900)
-      (sprintf(buf2, "(Visual C++ %d.%d)", _MSC_VER/100 - 6, _MSC_VER%100/10),
-        buf2),
-#    else
-      "(bad version)",
-#    endif
-#   elif defined(__WATCOMC__)
-#    if (__WATCOMC__ % 10 > 0)
-      (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100,
-       __WATCOMC__ % 100), buf), "",
-#    else
-      (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100,
-       (__WATCOMC__ % 100) / 10), buf), "",
-#    endif
-#   elif defined(__BORLANDC__)
-      "Borland C++",
-#    if (__BORLANDC__ < 0x0200)
-      " 1.0",
-#    elif (__BORLANDC__ == 0x0200)
-      " 2.0",
-#    elif (__BORLANDC__ == 0x0400)
-      " 3.0",
-#    elif (__BORLANDC__ == 0x0410)   /* __TURBOC__ = 0x0310 */
-      " 3.1",
-#    elif (__BORLANDC__ == 0x0452)   /* __TURBOC__ = 0x0320 */
-      " 4.0 or 4.02",
-#    elif (__BORLANDC__ == 0x0460)   /* __TURBOC__ = 0x0340 */
-      " 4.5",
-#    elif (__BORLANDC__ == 0x0500)   /* __TURBOC__ = 0x0340 */
-      " 5.0",
-#    elif (__BORLANDC__ == 0x0520)   /* __TURBOC__ = 0x0520 */
-      " 5.2 (C++ Builder 1.0)",
-#    elif (__BORLANDC__ == 0x0530)   /* __TURBOC__ = 0x0530 */
-      " 5.3 (C++ Builder 3.0)",
-#    elif (__BORLANDC__ == 0x0540)   /* __TURBOC__ = 0x0540 */
-      " 5.4 (C++ Builder 4.0)",
-#    elif (__BORLANDC__ == 0x0550)   /* __TURBOC__ = 0x0550 */
-      " 5.5 (C++ Builder 5.0)",
-#    elif (__BORLANDC__ == 0x0551)   /* __TURBOC__ = 0x0551 */
-      " 5.5.1 (C++ Builder 5.0.1)",
-#    elif (__BORLANDC__ == 0x0560)   /* __TURBOC__ = 0x0560 */
-      " 6.0 (C++ Builder 6.0)",
-#    else
-      " later than 6.0",
-#    endif
-#   elif defined(__LCC__)
-      "LCC-Win32", "",
-#   elif defined(__GNUC__)
-#    if defined(__RSXNT__)
-#     if (defined(__DJGPP__) && !defined(__EMX__))
-      (sprintf(buf, "rsxnt(djgpp v%d.%02d) / gcc ",
-        __DJGPP__, __DJGPP_MINOR__), buf),
-#     elif defined(__DJGPP__)
-      (sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ",
-        __DJGPP__, __DJGPP_MINOR__), buf),
-#     elif (defined(__GO32__) && !defined(__EMX__))
-      "rsxnt(djgpp v1.x) / gcc ",
-#     elif defined(__GO32__)
-      "rsxnt(emx + djgpp v1.x) / gcc ",
-#     elif defined(__EMX__)
-      "rsxnt(emx)+gcc ",
-#     else
-      "rsxnt(unknown) / gcc ",
-#     endif
-#    elif defined(__CYGWIN__)
-      "cygnus win32 / gcc ",
-#    elif defined(__MINGW32__)
-      "mingw32 / gcc ",
-#    else
-      "gcc ",
-#    endif
-      __VERSION__,
-#   else /* !_MSC_VER, !__WATCOMC__, !__BORLANDC__, !__LCC__, !__GNUC__ */
-      "unknown compiler (SDK?)", "",
-#   endif /* ?compilers */
-
-      "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)",
-
-#   ifdef __DATE__
-      " on ", __DATE__
-#   else
-      "", ""
-#   endif
-    );
-
-    (*G.message)((zvoid *)&G, slide, (ulg)len, 0);
-
-    return;
-
-} /* end function version() */
-
-#  endif /* ndef WINDLL_OLD */
-# endif /* !SFX */
-
-
-
-# ifdef MORE
-
-int screensize(int *tt_rows, int *tt_cols)
-{
-    HANDLE hstdout;
-    CONSOLE_SCREEN_BUFFER_INFO scr;
-
-    hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
-    GetConsoleScreenBufferInfo(hstdout, &scr);
-    if (tt_rows != NULL) *tt_rows = scr.srWindow.Bottom - scr.srWindow.Top + 1;
-    if (tt_cols != NULL) *tt_cols = scr.srWindow.Right - scr.srWindow.Left + 1;
-    return 0;           /* signal success */
-}
-
-# endif /* MORE */
-
-
-
-# ifdef W32_STAT_BANDAID
-
-/* All currently known variants of WIN32 operating systems (Windows 95/98,
- * WinNT 3.x, 4.0, 5.x) have a nasty bug in the OS kernel concerning
- * conversions between UTC and local time: In the time conversion functions
- * of the Win32 API, the timezone offset (including seasonal daylight saving
- * shift) between UTC and local time evaluation is erratically based on the
- * current system time. The correct evaluation must determine the offset
- * value as it {was/is/will be} for the actual time to be converted.
- *
- * Newer versions of MS C runtime lib's stat() returns utc time-stamps so
- * that localtime(timestamp) corresponds to the (potentially false) local
- * time shown by the OS' system programs (Explorer, command shell dir, etc.)
- * The RSXNT port follows the same strategy, but fails to recognize the
- * access-time attribute.
- *
- * For the NTFS file system (and other filesystems that store time-stamps
- * as UTC values), this results in st_mtime (, st_{c|a}time) fields which
- * are not stable but vary according to the seasonal change of "daylight
- * saving time in effect / not in effect".
- *
- * Other C runtime libs (CygWin), or the crtdll.dll supplied with Win9x/NT
- * return the unix-time equivalent of the UTC FILETIME values as got back
- * from the Win32 API call. This time, return values from NTFS are correct
- * whereas utimes from files on (V)FAT volumes vary according to the DST
- * switches.
- *
- * To achieve timestamp consistency of UTC (UT extra field) values in
- * Zip archives, the Info-ZIP programs require work-around code for
- * proper time handling in stat() (and other time handling routines).
- *
- * However, nowadays most other programs on Windows systems use the
- * time conversion strategy of Microsofts C runtime lib "msvcrt.dll".
- * To improve interoperability in environments where a "consistent" (but
- * false) "UTC<-->LocalTime" conversion is preferred over "stable" time
- * stamps, the Info-ZIP specific time conversion handling can be
- * deactivated by defining the preprocessor flag NO_W32TIMES_IZFIX.
- */
-/* stat() functions under Windows95 tend to fail for root directories.   *
- * Watcom and Borland, at least, are affected by this bug.  Watcom made  *
- * a partial fix for 11.0 but still missed some cases.  This substitute  *
- * detects the case and fills in reasonable values.  Otherwise we get    *
- * effects like failure to extract to a root dir because it's not found. */
-
-int zstat_win32(__W32STAT_GLOBALS__ const char *path, z_stat *buf)
-{
-    if (!zstat(path, buf))
-    {
-        /* stat was successful, now redo the time-stamp fetches */
-#  ifndef NO_W32TIMES_IZFIX
-        int fs_uses_loctime = FStampIsLocTime(__G__ path);
-#  endif
-        HANDLE h;
-        FILETIME Modft, Accft, Creft;
-#  ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-        char *ansi_path = (char *)alloca(strlen(path) + 1);
-
-        INTERN_TO_ISO(path, ansi_path);
-#       define Ansi_Path  ansi_path
-#  else
-#       define Ansi_Path  path
-#  endif
-
-        TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
-        h = CreateFileA(Ansi_Path, GENERIC_READ,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-        if (h != INVALID_HANDLE_VALUE) {
-            BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
-            CloseHandle(h);
-
-            if (ftOK) {
-                FTTrace((stdout, "GetFileTime returned Modft", 0, &Modft));
-                FTTrace((stdout, "GetFileTime returned Creft", 0, &Creft));
-#  ifndef NO_W32TIMES_IZFIX
-                if (!fs_uses_loctime) {
-                    /*  On a filesystem that stores UTC timestamps, we refill
-                     *  the time fields of the struct stat buffer by directly
-                     *  using the UTC values as returned by the Win32
-                     *  GetFileTime() API call.
-                     */
-                    NtfsFileTime2utime(&Modft, &(buf->st_mtime));
-                    if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
-                        NtfsFileTime2utime(&Accft, &(buf->st_atime));
-                    else
-                        buf->st_atime = buf->st_mtime;
-                    if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
-                        NtfsFileTime2utime(&Creft, &(buf->st_ctime));
-                    else
-                        buf->st_ctime = buf->st_mtime;
-                    TTrace((stdout,"NTFS, recalculated modtime %08lx\n",
-                            buf->st_mtime));
-                } else
-#  endif /* NO_W32TIMES_IZFIX */
-                {
-                    /*  On VFAT and FAT-like filesystems, the FILETIME values
-                     *  are converted back to the stable local time before
-                     *  converting them to UTC unix time-stamps.
-                     */
-                    VFatFileTime2utime(&Modft, &(buf->st_mtime));
-                    if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
-                        VFatFileTime2utime(&Accft, &(buf->st_atime));
-                    else
-                        buf->st_atime = buf->st_mtime;
-                    if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
-                        VFatFileTime2utime(&Creft, &(buf->st_ctime));
-                    else
-                        buf->st_ctime = buf->st_mtime;
-                    TTrace((stdout, "VFAT, recalculated modtime %08lx\n",
-                            buf->st_mtime));
-                }
-            }
-        }
-#       undef Ansi_Path
-        return 0;
-    }
-#  ifdef W32_STATROOT_FIX
-    else
-    {
-        DWORD flags;
-#   ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */
-        char *ansi_path = (char *)alloca(strlen(path) + 1);
-
-        INTERN_TO_ISO(path, ansi_path);
-#       define Ansi_Path  ansi_path
-#   else
-#       define Ansi_Path  path
-#   endif
-
-        flags = GetFileAttributesA(Ansi_Path);
-        if ((flags != INVALID_FILE_ATTRIBUTES) &&
-         (flags & FILE_ATTRIBUTE_DIRECTORY)) {
-            Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
-                   FnFilter1(path)));
-            memset(buf, 0, sizeof(z_stat));
-            buf->st_atime = buf->st_ctime = buf->st_mtime =
-              dos_to_unix_time(DOSTIME_MINIMUM);        /* 1-1-80 */
-            buf->st_mode = S_IFDIR | S_IREAD |
-                           ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE);
-            return 0;
-        } /* assumes: stat() won't fail on non-dirs without good reason */
-#       undef Ansi_Path
-    }
-#  endif /* W32_STATROOT_FIX */
-    return -1;
-}
-
-
-
-#  if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-
-int zstat_win32w(__W32STAT_GLOBALS__ const wchar_t *pathw, z_stat *buf)
-{
-    if (!zstatw(pathw, buf))
-    {
-        char *path = wchar_to_local_string((wchar_t *)pathw, G.unicode_escape_all);
-        /* stat was successful, now redo the time-stamp fetches */
-#   ifndef NO_W32TIMES_IZFIX
-        int fs_uses_loctime = FStampIsLocTimeW(__G__ pathw);
-#   endif
-        HANDLE h;
-        FILETIME Modft, Accft, Creft;
-
-        TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
-        h = CreateFileW(pathw, GENERIC_READ,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-        if (h != INVALID_HANDLE_VALUE) {
-            BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
-            CloseHandle(h);
-
-            if (ftOK) {
-                FTTrace((stdout, "GetFileTime returned Modft", 0, &Modft));
-                FTTrace((stdout, "GetFileTime returned Creft", 0, &Creft));
-#   ifndef NO_W32TIMES_IZFIX
-                if (!fs_uses_loctime) {
-                    /*  On a filesystem that stores UTC timestamps, we refill
-                     *  the time fields of the struct stat buffer by directly
-                     *  using the UTC values as returned by the Win32
-                     *  GetFileTime() API call.
-                     */
-                    NtfsFileTime2utime(&Modft, &(buf->st_mtime));
-                    if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
-                        NtfsFileTime2utime(&Accft, &(buf->st_atime));
-                    else
-                        buf->st_atime = buf->st_mtime;
-                    if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
-                        NtfsFileTime2utime(&Creft, &(buf->st_ctime));
-                    else
-                        buf->st_ctime = buf->st_mtime;
-                    TTrace((stdout,"NTFS, recalculated modtime %08lx\n",
-                            buf->st_mtime));
-                } else
-#   endif /* NO_W32TIMES_IZFIX */
-                {
-                    /*  On VFAT and FAT-like filesystems, the FILETIME values
-                     *  are converted back to the stable local time before
-                     *  converting them to UTC unix time-stamps.
-                     */
-                    VFatFileTime2utime(&Modft, &(buf->st_mtime));
-                    if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
-                        VFatFileTime2utime(&Accft, &(buf->st_atime));
-                    else
-                        buf->st_atime = buf->st_mtime;
-                    if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
-                        VFatFileTime2utime(&Creft, &(buf->st_ctime));
-                    else
-                        buf->st_ctime = buf->st_mtime;
-                    TTrace((stdout, "VFAT, recalculated modtime %08lx\n",
-                            buf->st_mtime));
-                }
-            }
-        }
-        izu_free(path);
-
-        return 0;
-    }
-#   ifdef W32_STATROOT_FIX
-    else
-    {
-        DWORD flags;
-
-        flags = GetFileAttributesW(pathw);
-        if ((flags != INVALID_FILE_ATTRIBUTES) &&
-         (flags & FILE_ATTRIBUTE_DIRECTORY)) {
-#    ifdef Tracing
-            char *path = wchar_to_local_string((wchar_t *)pathw, G.unicode_escape_all);
-            Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
-            
-
-       FnFilter1(path)));
-            izu_free(path);
-#    endif /* def Tracing */
-            memset(buf, 0, sizeof(z_stat));
-            buf->st_atime = buf->st_ctime = buf->st_mtime =
-              dos_to_unix_time(DOSTIME_MINIMUM);        /* 1-1-80 */
-            buf->st_mode = S_IFDIR | S_IREAD |
-                           ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE);
-            return 0;
-        } /* assumes: stat() won't fail on non-dirs without good reason */
-    }
-#   endif /* W32_STATROOT_FIX */
-    return -1;
-}
-
-#  endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-# endif /* W32_STAT_BANDAID */
-
-
-
-# ifdef W32_USE_IZ_TIMEZONE
-#include "timezone.h"
-#define SECSPERMIN      60
-#define MINSPERHOUR     60
-#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)
-static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule);
-
-static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule)
-{
-    if (lpw32tm->wYear != 0) {
-        ptrule->r_type = JULIAN_DAY;
-        ptrule->r_day = ydays[lpw32tm->wMonth - 1] + lpw32tm->wDay;
-    } else {
-        ptrule->r_type = MONTH_NTH_DAY_OF_WEEK;
-        ptrule->r_mon = lpw32tm->wMonth;
-        ptrule->r_day = lpw32tm->wDayOfWeek;
-        ptrule->r_week = lpw32tm->wDay;
-    }
-    ptrule->r_time = (long)lpw32tm->wHour * SECSPERHOUR +
-                     (long)(lpw32tm->wMinute * SECSPERMIN) +
-                     (long)lpw32tm->wSecond;
-}
-
-int GetPlatformLocalTimezone(register struct state * ZCONST sp,
-        void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res,
-                                        ZCONST struct rule * ZCONST start,
-                                        ZCONST struct rule * ZCONST end))
-{
-    TIME_ZONE_INFORMATION tzinfo;
-    DWORD res;
-
-    /* read current timezone settings from registry if TZ envvar missing */
-    res = GetTimeZoneInformation(&tzinfo);
-    if (res != TIME_ZONE_ID_INVALID)
-    {
-        struct rule startrule, stoprule;
-
-        conv_to_rule(&(tzinfo.StandardDate), &stoprule);
-        conv_to_rule(&(tzinfo.DaylightDate), &startrule);
-        sp->timecnt = 0;
-        sp->ttis[0].tt_abbrind = 0;
-        if ((sp->charcnt =
-             WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1,
-                                 sp->chars, sizeof(sp->chars), NULL, NULL))
-            == 0)
-            sp->chars[sp->charcnt++] = '\0';
-        sp->ttis[1].tt_abbrind = sp->charcnt;
-        sp->charcnt +=
-            WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1,
-                                sp->chars + sp->charcnt,
-                                sizeof(sp->chars) - sp->charcnt, NULL, NULL);
-        if ((sp->charcnt - sp->ttis[1].tt_abbrind) == 0)
-            sp->chars[sp->charcnt++] = '\0';
-        sp->ttis[0].tt_gmtoff = - (tzinfo.Bias + tzinfo.StandardBias)
-                                * MINSPERHOUR;
-        sp->ttis[1].tt_gmtoff = - (tzinfo.Bias + tzinfo.DaylightBias)
-                                * MINSPERHOUR;
-        sp->ttis[0].tt_isdst = 0;
-        sp->ttis[1].tt_isdst = 1;
-        sp->typecnt = (startrule.r_mon == 0 && stoprule.r_mon == 0) ? 1 : 2;
-
-        if (sp->typecnt > 1)
-            (*fill_tzstate_from_rules)(sp, &startrule, &stoprule);
-        return TRUE;
-    }
-    return FALSE;
-}
-# endif /* W32_USE_IZ_TIMEZONE */
-
-#endif /* !FUNZIP */
-
-
-
-#ifndef WINDLL
-/* This replacement getch() function was originally created for Watcom C
- * and then additionally used with CYGWIN. Since UnZip 5.4, all other Win32
- * ports apply this replacement rather that their supplied getch() (or
- * alike) function.  There are problems with unabsorbed LF characters left
- * over in the keyboard buffer under Win95 (and 98) when ENTER was pressed.
- * (Under Win95, ENTER returns two(!!) characters: CR-LF.)  This problem
- * does not appear when run on a WinNT console prompt!
- */
-
-/* Watcom 10.6's getch() does not handle Alt+<digit><digit><digit>. */
-/* Note that if PASSWD_FROM_STDIN is defined, the file containing   */
-/* the password must have a carriage return after the word, not a   */
-/* Unix-style newline (linefeed only).  This discards linefeeds.    */
-
-int getch_win32(void)
-{
-  HANDLE stin;
-  DWORD rc;
-  unsigned char buf[2];
-  int ret = -1;
-  DWORD odemode = ~(DWORD)0;
-
-# ifdef PASSWD_FROM_STDIN
-  stin = GetStdHandle(STD_INPUT_HANDLE);
-# else
-  stin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE,
-                     FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
-  if (stin == INVALID_HANDLE_VALUE)
-    return -1;
-# endif
-  if (GetConsoleMode(stin, &odemode))
-    SetConsoleMode(stin, ENABLE_PROCESSED_INPUT);  /* raw except ^C noticed */
-  if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
-    ret = buf[0];
-  /* when the user hits return we get CR LF.  We discard the LF, not the CR,
-   * because when we call this for the first time after a previous input
-   * such as the one for "replace foo? [y]es, ..." the LF may still be in
-   * the input stream before whatever the user types at our prompt. */
-  if (ret == '\n')
-    if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
-      ret = buf[0];
-  if (odemode != ~(DWORD)0)
-    SetConsoleMode(stin, odemode);
-# ifndef PASSWD_FROM_STDIN
-  CloseHandle(stin);
-# endif
-  return ret;
-}
-#endif /* !WINDLL */
-
-
-
-#if (defined(UNICODE_SUPPORT) && !defined(FUNZIP))
-/* convert wide character string to multi-byte character string */
-char *wide_to_local_string(wide_string, escape_all)
-  ZCONST zwchar *wide_string;
-  int escape_all;
-{
-  int i;
-  wchar_t wc;
-  int bytes_char;
-  int default_used;
-  int wsize = 0;
-  int max_bytes = 9;
-  char buf[9];
-  char *buffer = NULL;
-  char *local_string = NULL;
-
-  for (wsize = 0; wide_string[wsize]; wsize++) ;
-
-  if (max_bytes < MB_CUR_MAX)
-    max_bytes = MB_CUR_MAX;
-
-  if ((buffer = (char *)izu_malloc(wsize * max_bytes + 1)) == NULL) {
-    return NULL;
-  }
-
-  /* convert it */
-  buffer[0] = '\0';
-  for (i = 0; i < wsize; i++) {
-    if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
-      /* wchar_t probably 2 bytes */
-      /* could do surrogates if state_dependent and wctomb can do */
-      wc = zwchar_to_wchar_t_default_char;
-    } else {
-      wc = (wchar_t)wide_string[i];
-    }
-    /* Under some vendor's C-RTL, the Wide-to-MultiByte conversion functions
-     * (like wctomb() et. al.) do not use the same codepage as the other
-     * string arguments I/O functions (fopen, mkdir, rmdir etc.).
-     * Therefore, we have to fall back to the underlying Win32-API call to
-     * achieve a consistent behaviour for all supported compiler environments.
-     * Failing RTLs are for example:
-     *   Borland (locale uses OEM-CP as default, but I/O functions expect ANSI
-     *            names)
-     *   Watcom  (only "C" locale, wctomb() always uses OEM CP)
-     * (in other words: all supported environments except the Microsoft RTLs)
-     */
-    bytes_char = WideCharToMultiByte(
-                          CP_ACP, WC_COMPOSITECHECK,
-                          &wc, 1,
-                          (LPSTR)buf, sizeof(buf),
-                          NULL, &default_used);
-    if (default_used)
-      bytes_char = -1;
-    if (escape_all) {
-      if (bytes_char == 1 && (uch)buf[0] <= 0x7f) {
-        /* ASCII */
-        strncat(buffer, buf, 1);
-      } else {
-        /* use escape for wide character */
-        char *escape_string = wide_to_escape_string(wide_string[i]);
-        strcat(buffer, escape_string);
-        izu_free(escape_string);
-      }
-    } else if (bytes_char > 0) {
-      /* multi-byte char */
-      strncat(buffer, buf, bytes_char);
-    } else {
-      /* no MB for this wide */
-      /* use escape for wide character */
-      char *escape_string = wide_to_escape_string(wide_string[i]);
-      strcat(buffer, escape_string);
-      izu_free(escape_string);
-    }
-  }
-  if ((local_string = (char *)izu_realloc(
-   buffer, strlen(buffer) + 1)) == NULL) {
-    izu_free(buffer);
-    return NULL;
-  }
-
-  return local_string;
-}
-
-
-wchar_t *local_to_wchar_string(local_string)
-  char *local_string;       /* path of local name */
-{
-  wchar_t  *qw;
-  int       ulen;
-  int       ulenw;
-
-  if (local_string == NULL)
-    return NULL;
-
-    /* get length */
-    ulenw = MultiByteToWideChar(
-                CP_ACP,            /* ANSI code page */
-                0,                 /* flags for character-type options */
-                local_string,      /* string to convert */
-                -1,                /* string length (-1 = NULL terminated) */
-                NULL,              /* buffer */
-                0 );               /* buffer length (0 = return length) */
-
-    if (ulenw == 0) {
-      /* failed */
-      return NULL;
-    }
-    /* Allocate bytes for returned wide char count (which includes NUL). */
-    if ((qw = (wchar_t *)izu_malloc( ulenw* sizeof(wchar_t))) == NULL) {
-      return NULL;
-    }
-    /* convert multibyte to wide */
-    ulen = MultiByteToWideChar(
-               CP_ACP,            /* ANSI code page */
-               0,                 /* flags for character-type options */
-               local_string,      /* string to convert */
-               -1,                /* string length (-1 = NULL terminated) */
-               qw,                /* buffer */
-               ulenw);            /* buffer length (0 = return length) */
-    if (ulen == 0) {
-      /* failed */
-      izu_free(qw);
-      return NULL;
-    }
-
-  return qw;
-}
-
-# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)
-#  if defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS)
-wchar_t *utf8_to_wchar_string_dyn(utf8_string)
-  const char *utf8_string;      /* path to get utf-8 name for */
-{
-  wchar_t  *qw;
-  int       ulen;
-  int       ulenw;
-
-  if (utf8_string == NULL)
-    return NULL;
-
-  /* get length */
-  ulenw = MultiByteToWideChar(
-                CP_UTF8,        /* UTF-8 code page */
-                0,              /* flags for character-type options */
-                utf8_string,    /* string to convert */
-                -1,             /* string length (-1 = NULL terminated) */
-                NULL,           /* buffer */
-                0);             /* buffer length (0 = return length) */
-
-  if (ulenw == 0) {
-    /* failed */
-    return NULL;
-  }
-
-  /* Allocate bytes for returned wide char count (which includes NUL). */
-  if ((qw = (wchar_t *)izu_malloc( ulenw* sizeof(wchar_t))) == NULL) {
-    return NULL;
-  }
-
-  /* convert multibyte to wide */
-  ulen = MultiByteToWideChar(
-                CP_UTF8,        /* UTF-8 code page */
-                0,              /* flags for character-type options */
-                utf8_string,    /* string to convert */
-                -1,             /* string length (-1 = NULL terminated) */
-                qw,             /* buffer */
-                ulenw);         /* buffer length (0 = return length) */
-
-  if (ulen == 0) {
-    /* failed */
-    izu_free(qw);
-    return NULL;
-  }
-
-  return qw;
-}
-#  endif /* defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) */
-
-#  ifndef DYNAMIC_WIDE_NAME
-void utf8_to_wchar_string_stat( resultw, utf8_string)
-  wchar_t *resultw;             /* User's result buffer. */
-  const char *utf8_string;      /* path to get utf-8 name for */
-{
-  int       ulen;
-
-  *resultw = L'\0';             /* Default to failure (null result). */
-
-  if (utf8_string == NULL)
-    return;
-
-  /* Convert multibyte to wide. */
-  ulen = MultiByteToWideChar(
-                CP_UTF8,        /* UTF-8 code page. */
-                0,              /* Flags for character-type options. */
-                utf8_string,    /* String to convert. */
-                -1,             /* String length (-1 = NULL terminated). */
-                resultw,        /* User's buffer. */
-                FILNAMSIZ);     /* Buffer length (chars, incl. NUL). */
-
-  if (ulen == 0) {
-    /* failed */
-    *resultw = L'\0';           /* Unnecessessary? */
-  }
-
-  return;
-}
-#  endif /* ndef DYNAMIC_WIDE_NAME */
-
-int has_win32_wide()
-{
-  int is_win32_wide;
-
-  /* test if we have wide function support */
-  /* first guess: On "real" WinNT, the WIN32 wide API >>is<< supported. */
-  is_win32_wide = IsWinNT();
-
-  if (!is_win32_wide)
-  {
-    /* On a non-WinNT environment (Win9x or Win32s), wide functions
-     * might be supported when program is linked against the
-     * Win9x Unicode support library.
-     * => run a check whether a needed API function is supported.
-     */
-    DWORD r;
-    /* get attributes for this directory */
-    r = GetFileAttributesA(".");
-
-    /* r should include 16 = FILE_ATTRIBUTE_DIRECTORY */
-    if ((r != INVALID_FILE_ATTRIBUTES) && (r & FILE_ATTRIBUTE_DIRECTORY)) {
-      /* now see if it works for the wide version */
-      r = GetFileAttributesW(L".");
-      /* if this fails then we probably don't have wide functions */
-      /* error is probably "This function is only valid in Win32 mode." */
-      if ((r != INVALID_FILE_ATTRIBUTES) && (r & FILE_ATTRIBUTE_DIRECTORY)) {
-        /* worked, so conclude we have wide support */
-        is_win32_wide = TRUE;
-      }
-    }
-  }
-  return is_win32_wide;
-}
-
-# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */
-
-#endif /* (defined(UNICODE_SUPPORT) && !defined(FUNZIP)) */
-
-
-/* Symbolic link (symlink) support. */
-
-#ifdef SYMLINKS
-
-/* symlink[w](): Create a symbolic link.
- * Return zero, if success; non-zero, if failure.
- */
-
-int symlink( const char *target, const char *name, int is_dir)
-{
-  int sts;
-
-  /* Flags arg (3) is SYMBOLIC_LINK_FLAG_DIRECTORY if the target is a
-   * directory.
-   */
-  if (CreateSymbolicLinkA( name, target,
-   (is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0)))
-  {
-    sts = 0;
-  }
-  else
-  {
-    sts = GetLastError();
-  }
-  return sts;
-}
-
-
-# ifdef UNICODE_SUPPORT
-
-int symlinkw( const char *target, const wchar_t *namew, int is_dir)
-{
-  int sts;
-  wchar_t *targetw;
-
-  /* Convert UTF-8 target to UTF-16. */
-  targetw = utf8_to_wchar_string_dyn( target);
-  if (targetw == NULL)
-  {
-    sts = -1;
-  }
-  else
-  {
-    /* Flags arg (3) is SYMBOLIC_LINK_FLAG_DIRECTORY if the target is a
-     * directory.
-     */
-    if (CreateSymbolicLinkW( namew, targetw,
-     (is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0)))
-    {
-      sts = 0;
-    }
-    else
-    {
-      sts = GetLastError();
-    }
-    free( targetw);
-  }
-  return sts;
-}
-
-# endif /* def UNICODE_SUPPORT */
-
-#endif /* def SYMLINKS */
-
-
-/* --------------------------------------------------- */
-/* Large File Support
- *
- * Initial functions by E. Gordon and R. Nausedat
- * 9/10/2003
- * Lifted from Zip 3b, win32.c and place here by Myles Bennett
- * 7/6/2004
- *
- * These implement 64-bit file support for Windows.  The
- * defines and headers are in win32/w32cfg.h.
- *
- * Moved to win32i64.c by Mike White to avoid conflicts in
- * same name functions in WiZ using UnZip and Zip libraries.
- * 9/25/2003
- */
index 3ad0349..4c73ff7 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4f22612..9142f6c 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index c6271e4..06a92fa 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4f88643..6d32299 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 03bb8a2..feef658 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 44fd19c..00b9bfa 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 0d36fbb..18c2567 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 2404090..2e1a54e 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2004 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 19c2222..98ab04f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 07dfc65..2a1d6b1 100644 (file)
--- a/process.c
+++ b/process.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -27,6 +27,7 @@
              get_cdir_ent()
   (ext)      process_cdir_file_hdr()
   (ext)      process_local_file_hdr()
+  (ext)      process_cdir_digsig()
   (ext)      getZip64Data()
   (ext)      ef_scan_for_izux()
   (ext)      getRISCOSexfield()
@@ -257,7 +258,7 @@ static zoff_t file_size(fh)
 
 #ifdef USE_STRM_INPUT
     /* Seek to actual EOF. */
-    sts = zfseeko(file, 0, SEEK_END);
+    sts = zfseeko(file, (zoff_t)0, SEEK_END);
     if (sts != 0) {
         /* fseeko() failed.  (Unlikely.) */
         ofs = EOF;
@@ -287,8 +288,8 @@ static zoff_t file_size(fh)
     }
 #else /* def USE_STRM_INPUT */
     /* Seek to actual EOF. */
-    ofs = zlseek(fh, 0, SEEK_END);
-    if (ofs == (zoff_t) -1) {
+    ofs = zlseek(fh, (zoff_t)0, SEEK_END);
+    if (ofs == (zoff_t)(-1)) {
         /* zlseek() failed.  (Unlikely.) */
         ofs = EOF;
     } else if (ofs < 0) {
@@ -299,7 +300,7 @@ static zoff_t file_size(fh)
            Won't be at actual EOF if offset was truncated.
         */
         ofs = zlseek(fh, ofs, SEEK_SET);
-        if (ofs == (zoff_t) -1) {
+        if (ofs == (zoff_t)(-1)) {
             /* zlseek() failed.  (Unlikely.) */
             ofs = EOF;
         } else {
@@ -601,7 +602,7 @@ static int rec_find(__G__ searchlen, signature, rec_size)
     /* return 0 when rec found, 1 when not found, 2 in case of read error */
     __GDEF
     zoff_t searchlen;
-    char* signature;
+    uch* signature;
     int rec_size;
 {
     int i, numblks, found=FALSE;
@@ -661,7 +662,7 @@ static int rec_find(__G__ searchlen, signature, rec_size)
 
         for (G.inptr = G.inbuf+INBUFSIZ-1;  G.inptr >= G.inbuf; --G.inptr)
             if ( (*G.inptr == (uch)0x50) &&         /* ASCII 'P' */
-                 !memcmp((char *)G.inptr, signature, 4) ) {
+                 !memcmp(G.inptr, signature, 4) ) {
                 G.incnt -= (int)(G.inptr - G.inbuf);
                 found = TRUE;
                 break;
@@ -925,9 +926,9 @@ static int find_ecrec(__G__ searchlen)          /* return PK-class error */
 
     if (G.ziplen <= INBUFSIZ) {
 #ifdef USE_STRM_INPUT
-        zfseeko(G.zipfd, 0L, SEEK_SET);
+        zfseeko(G.zipfd, (zoff_t)0, SEEK_SET);
 #else /* def USE_STRM_INPUT */
-        zlseek(G.zipfd, 0L, SEEK_SET);
+        zlseek(G.zipfd, (zoff_t)0, SEEK_SET);
 #endif /* def USE_STRM_INPUT [else] */
         if ((G.incnt = read(G.zipfd,(char *)G.inbuf,(unsigned int)G.ziplen))
             == (int)G.ziplen)
@@ -986,7 +987,7 @@ static int find_ecrec(__G__ searchlen)          /* return PK-class error */
       G.inptr-G.inbuf, G.inptr-G.inbuf);
 #endif
 
-    if (readbuf(__G__ (char *)byterec, ECREC_SIZE+4) == 0)
+    if (readbuf(__G__ byterec, ECREC_SIZE+4) == 0)
         return PK_EOF;
 
     G.ecrec.number_this_disk =
@@ -1841,6 +1842,11 @@ int process_zipfiles(__G)    /* return PK-type error code */
     int NumMissFiles;
     int NumWarnFiles;
     int NumWinFiles;
+# ifndef VMS
+#  ifdef ZSUFX2
+    char *zipfn_sufx_p;
+#  endif
+# endif
 #endif /* ndef SFX */
 
     int error = 0;
@@ -1872,14 +1878,18 @@ int process_zipfiles(__G)    /* return PK-type error code */
     CRC_32_TAB = NULL;
 #endif /* 0 */
 
-    /* finish up initialization of magic signature strings */
-    local_hdr_sig[0]  /* = extd_local_sig[0] */ =       /* ASCII 'P', */
-      central_hdr_sig[0] = end_central_sig[0] =         /* not EBCDIC */
-      end_centloc64_sig[0] = end_central64_sig[0] = 0x50;
+    /* Finish initialization of magic signature strings.
+     * Insert (ASCII, not EBCDIC) 'P' and 'K'.
+     */
+    central_digsig_sig[ 0] = central_hdr_sig[ 0] =
+     end_centloc64_sig[ 0] = end_central_sig[ 0] =
+     end_central64_sig[ 0] = /* extd_local_sig[ 0] = */
+     local_hdr_sig[ 0] = 0x50;                          /* 'P'. */
 
-    local_hdr_sig[1]  /* = extd_local_sig[1] */ =       /* ASCII 'K', */
-      central_hdr_sig[1] = end_central_sig[1] =         /* not EBCDIC */
-      end_centloc64_sig[1] = end_central64_sig[1] = 0x4B;
+    central_digsig_sig[ 1] = central_hdr_sig[ 1] =
+     end_centloc64_sig[ 1] = end_central_sig[ 1] =
+     end_central64_sig[ 1] = /* extd_local_sig[ 1] = */
+     local_hdr_sig[ 1] = 0x4b;                          /* 'K'. */
 
 /*---------------------------------------------------------------------------
     Make sure timezone info is set correctly; localtime() returns GMT on some
@@ -2097,7 +2107,7 @@ int process_zipfiles(__G)    /* return PK-type error code */
                  */
                 /* Append ZSUFX to the archive name, and try again. */
 #  ifdef ZSUFX2
-                char *zipfn_sufx_p =    /* Save pointer for ZSUFX2, below. */
+                zipfn_sufx_p =          /* Save pointer for ZSUFX2, below. */
 #  endif
                  strcpy( zipfn_prev+ strlen( zipfn_prev), ZSUFX);
 
@@ -2247,7 +2257,7 @@ static int get_cdir_ent(__G)    /* return PK-type error code */
     usable struct (crec)).
   ---------------------------------------------------------------------------*/
 
-    if (readbuf(__G__ (char *)byterec, CREC_SIZE) == 0)
+    if (readbuf(__G__ byterec, CREC_SIZE) == 0)
         return PK_EOF;
 
     G.crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
@@ -2333,7 +2343,7 @@ int process_local_file_hdr(__G)    /* return PK-type error code */
     usable struct (lrec)).
   ---------------------------------------------------------------------------*/
 
-    if (readbuf(__G__ (char *)byterec, LREC_SIZE) == 0)
+    if (readbuf(__G__ byterec, LREC_SIZE) == 0)
         return PK_EOF;
 
     G.lrec.version_needed_to_extract[0] =
@@ -2364,6 +2374,71 @@ int process_local_file_hdr(__G)    /* return PK-type error code */
 } /* process_local_file_hdr(). */
 
 
+/**********************************/
+/* Function process_cdir_digsig() */
+/**********************************/
+
+int process_cdir_digsig(__G__ enddigsig_len_p)
+    __GDEF
+    long *enddigsig_len_p;
+{
+  uch *digsig_buf;
+  uch digsig_len[ 2];
+  long enddigsig_len;
+  int error = PK_OK;            /* Return PK-type status.  Assume success. */
+
+  /* Read the two-byte byte count. */
+  if (readbuf(__G__ digsig_len, 2) < 2)
+  {
+    Info(slide, 0x221, ((char *)slide,
+     LoadFarString( ErrorUnexpectedEOF), 2, G.zipfn));
+    error = PK_EOF;
+  }
+  else
+  { /* Good byte count data.  Assemble the value.  Return it, if requested. */
+    enddigsig_len = makeword( digsig_len);
+    if (enddigsig_len_p != NULL)
+    {
+      *enddigsig_len_p = enddigsig_len;
+    }
+    /* Allocate storage for data. */
+    digsig_buf = (uch *)izu_malloc( enddigsig_len);
+    if (digsig_buf == (uch *)NULL)
+    {
+      Info( slide, 0x401, ((char *)slide,
+       "Not enough memory for Central Dir digital signature"));
+      error = PK_MEM;
+    }
+    else
+    { /* Have storage.  Read the data. */
+      if ((long)readbuf(__G__ digsig_buf, enddigsig_len) < enddigsig_len)
+      {
+        Info(slide, 0x221, ((char *)slide,
+         LoadFarString( ErrorUnexpectedEOF), 21, G.zipfn));
+        error = PK_EOF;
+      }
+      else
+      {
+        /* Process digital signature here.  (Currently not done.) */
+        /* Then free its storage. */
+        izu_free( digsig_buf);
+
+        /* Read what should be the EOCD[64] signature. */
+        if (readbuf(__G__ G.sig, 4) < 4)
+        {
+          Info(slide, 0x221, ((char *)slide,
+           LoadFarString( ErrorUnexpectedEOF), 22, G.zipfn));
+          error = PK_EOF;
+        }
+      }
+    }
+  }
+
+  return error;
+
+} /* process_cdir_digsig(). */
+
+
 /*******************************/
 /* Function getZip64Data() */
 /*******************************/
@@ -2976,7 +3051,7 @@ char *wide_to_local_string(wide_string, escape_all)
   wchar_t wc;
   int b;
   int state_dependent;
-  int wsize = 0;
+  int wsize;
   int max_bytes = MB_CUR_MAX;
   char buf[9];
   char *buffer = NULL;
@@ -3312,23 +3387,31 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
 # endif
 
 /*---------------------------------------------------------------------------
- *    This function scans the extra field for EF_TIME ("UT"), EF_IZUNIX2
- * ("Ux"), EF_IZUNIX ("UX"), or EF_PKUNIX (0x000d) blocks containing
- * Unix-style time_t (GMT) values for the entry's access, creation, and
- * modification time.
+ *    This function scans the extra field for the following blocks,
+ * containing Unix-compatible (time_t, UTC) file times and/or UID/GID.
+ *
+ * EF_PKUNIX  0x000d)     : 32-bit atime, mtime; 16-bit UID, GID;
+ *                          other, optional data (which we ignore?).
+ * EF_IZUNIX  0x5855 "UX"): 32-bit atime, mtime; 16-bit UID, GID.
+ *                          (Same as fixed part of EF_PKUNIX.)
+ * EF_IZUNIX2 0x7855 "Ux"): 16-bit UID, GID.  (No data in cent. dir.)
+ * EF_IZUNIX3 0x7875 "ux"): Variable-length UID, GID.
+ * EF_TIME    0x5455 "UT"): flags, 32-bit mtime?, atime?, ctime?.
+ *                          (Only mtime in central directory.)
+ *
  *    If a valid block is found (and the z_utim pointer is not NULL),
  * then the time stamps are copied to the iztimes structure.
- *    If an IZUNIX2 ("Ux") block is found or the IZUNIX ("UX") block
- * contains UID/GID fields, and the z_uidgid array pointer is not NULL,
- * then the owner info is transfered as well.
- *    The presence of an EF_TIME ("UT") or EF_IZUNIX2 ("Ux") block
- * results in ignoring all data from probably present, obsolete
- * EF_IZUNIX ("UX") blocks.
+ *    If an IZUNIX2 ("Ux") block is found or the IZUNIX ("UX") or PKUNIX
+ * block contains UID/GID fields, and the z_uidgid array pointer is not
+ * NULL, then the UID/GID data are also transfered.
+ *    The presence of an EF_TIME ("UT"), EF_IZUNIX2 ("Ux"), or
+ * EF_IZUNIX3 ("ux") block results in ignoring all data from probably
+ * present, obsolete EF_IZUNIX ("UX") blocks.
  *    If multiple blocks of the same type are found, then only the
  * information from the last block is used.
  *    The return value is a combination of the EF_TIME ("UT") Flags
- * field with an additional flag bit indicating the presence of valid
- * UID/GID info, or 0 in case of failure.
+ * field with an additional flag bit (EB_UX2_VALID) indicating the
+ * presence of valid UID/GID info (or 0 in case of failure).
   ---------------------------------------------------------------------------*/
 
     if (ef_len == 0 || ef_buf == NULL || (z_utim == 0 && z_uidgid == NULL))
@@ -3351,12 +3434,12 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
 
         switch (eb_id) {
           case EF_TIME:         /* "UT" */
-            flags &= ~0x0ff;    /* ignore previous IZUNIX or EF_TIME fields */
+            flags &= ~EB_UT_FL_TIMES;   /* Ignore any previous times. */
             have_new_type_eb = 1;
             if ( eb_len >= EB_UT_MINLEN && z_utim != NULL) {
                 unsigned eb_idx = EB_UT_TIME1;
                 TTrace((stderr, "ef_scan_for_izux: found TIME extra field\n"));
-                flags |= (ef_buf[EB_HEADSIZE+EB_UT_FLAGS] & 0x0ff);
+                flags |= (ef_buf[EB_HEADSIZE+EB_UT_FLAGS] & EB_UT_FL_TIMES);
                 if ((flags & EB_UT_FL_MTIME)) {
                     if ((long)(eb_idx+4) <= eb_len) {
                         i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
@@ -3378,7 +3461,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                               ut_in_archive_sgn = 0;
                               /* cannot determine sign of mtime;
                                  without modtime: ignore complete UT field */
-                              flags &= ~0x0ff;  /* no time_t times available */
+                              flags &= ~EB_UT_FL_TIMES;  /* No times. */
                               TTrace((stderr,
                                "  UT modtime range error; ignore e.f.!\n"));
                               break;            /* stop scanning this field */
@@ -3397,7 +3480,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                             if (!ut_zip_unzip_compatible) {
                               /* UnZip interprets mtime differently than Zip;
                                  without modtime: ignore complete UT field */
-                              flags &= ~0x0ff;  /* no time_t times available */
+                              flags &= ~EB_UT_FL_TIMES;  /* No times. */
                               TTrace((stderr,
                                "  UT modtime range error; ignore e.f.!\n"));
                               break;            /* stop scanning this field */
@@ -3493,11 +3576,14 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
             }
             break;
 
-          case EF_IZUNIX2:      /* "Ux" */
-            if (have_new_type_eb == 0) {
-                flags &= ~0x0ff;        /* ignore any previous IZUNIX field */
+          case EF_IZUNIX2:      /* "Ux", 16-bit UID, GID. */
+            if (have_new_type_eb == 0) {        /* (< 1) */
                 have_new_type_eb = 1;
             }
+            if (have_new_type_eb <= 1) {
+                /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
+                flags &= EB_UT_FL_TIMES;
+            }
 # ifdef IZ_HAVE_UXUIDGID
             if (have_new_type_eb > 1)
                 break;          /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
@@ -3509,10 +3595,11 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
 # endif
             break;
 
-          case EF_IZUNIX3:      /* "ux" */
+          case EF_IZUNIX3:      /* "ux", Variable-length UID, GID. */
             /* new 3rd generation Unix ef */
-            have_new_type_eb = 2;
-
+            have_new_type_eb = 2;       /* (Maximum newness, so no tests.) */
+            /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
+            flags &= EB_UT_FL_TIMES;
         /*
           Version       1 byte      version of this extra field, currently 1
           UIDSize       1 byte      Size of UID field (min = 2)
@@ -3538,8 +3625,6 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                 unsigned uid_size;
                 unsigned gid_size;
 
-                flags &= ~0x0ff;        /* Ignore any previous UNIX field. */
-
                 uid_size = *((EB_HEADSIZE + 1) + ef_buf);
 
                 /* Valid: 1 (Version) + 1 (UIDSize) + UIDSize +
@@ -3565,7 +3650,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
 # endif /* def IZ_HAVE_UXUIDGID */
             break;
 
-          case EF_IZUNIX:       /* "UX" */
+          case EF_IZUNIX:       /* "UX", atime, mtime; 16-bit UID, GID. */
           case EF_PKUNIX:       /* 0x000d (Same layout as IZUNIX) */
             if (eb_len >= EB_UX_MINLEN) {
                 TTrace((stderr, "ef_scan_for_izux: found %s extra field\n",
@@ -3591,7 +3676,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                             ut_in_archive_sgn = 0;
                             /* cannot determine sign of mtime;
                                without modtime: ignore complete UT field */
-                            flags &= ~0x0ff;    /* no time_t times available */
+                            flags &= ~EB_UT_FL_TIMES;   /* No times. */
                             TTrace((stderr,
                              "  UX modtime range error: ignore e.f.!\n"));
                         }
@@ -3609,7 +3694,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                         if (!ut_zip_unzip_compatible) {
                             /* UnZip interpretes mtime differently than Zip;
                                without modtime: ignore complete UT field */
-                            flags &= ~0x0ff;    /* no time_t times available */
+                            flags &= ~EB_UT_FL_TIMES;   /* No times. */
                             TTrace((stderr,
                              "  UX modtime range error: ignore e.f.!\n"));
                         }
@@ -3629,7 +3714,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                         } else if (ut_in_archive_sgn == 1) {
                             z_utim->atime =
                               (time_t)((ulg)i_time & (ulg)0xffffffffL);
-                        } else if (flags & 0x0ff) {
+                        } else if (flags & EB_UT_FL_TIMES) {
                             /* sign of 32-bit time is unknown -> ignore it */
                             flags &= ~EB_UT_FL_ATIME;
                             TTrace((stderr,
@@ -3640,7 +3725,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
                     }
 # else /* def TIME_T_TYPE_DOUBLE */
                     if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
-                        !ut_zip_unzip_compatible && (flags & 0x0ff)) {
+                        !ut_zip_unzip_compatible && (flags & EB_UT_FL_TIMES)) {
                         /* atime not in range of UnZip's time_t */
                         flags &= ~EB_UT_FL_ATIME;
                         TTrace((stderr,
index c0b0886..73425be 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 441f96e..e2761fa 100644 (file)
@@ -1,8 +1,8 @@
 #
 ;===========================================================================
-; Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in unzip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9ee9df3..1d8d79e 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 20250cc..8ef45a9 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4a908ae..dd344c5 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/query.c b/query.c
deleted file mode 100644 (file)
index 172368e..0000000
--- a/query.c
+++ /dev/null
@@ -1,257 +0,0 @@
-
-        /*
-         * just about to extract file:  if extracting to disk, check if
-         * already exists, and if so, take appropriate action according to
-         * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
-         * loop because we don't store the possibly renamed filename[] in
-         * info[])
-         */
-#ifdef DLL
-        if (!uO.tflag && !uO.cflag && !G.redirect_data)
-#else
-        if (!uO.tflag && !uO.cflag)
-#endif
-        {
-            renamed = FALSE;   /* user hasn't renamed output file yet */
-
-startover:
-            query = FALSE;
-            skip_entry = SKIP_NO;
-            /* for files from DOS FAT, check for use of backslash instead
-             *  of slash as directory separator (bug in some zipper(s); so
-             *  far, not a problem in HPFS, NTFS or VFAT systems)
-             */
-#ifndef SFX
-            if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
-                char *p=G.filename;
-
-                if (*p) do {
-                    if (*p == '\\') {
-                        if (!G.reported_backslash) {
-                            Info(slide, 0x21, ((char *)slide,
-                              LoadFarString(BackslashPathSep), G.zipfn));
-                            G.reported_backslash = TRUE;
-                            if (!error_in_archive)
-                                error_in_archive = PK_WARN;
-                        }
-                        *p = '/';
-                    }
-                } while (*PREINCSTR(p));
-            }
-#endif /* !SFX */
-
-            if (!renamed)
-            {
-              /* Transform absolute path to relative path, and warn user. */
-              error = name_abs_rel( __G);
-              if (error != PK_OK)
-                error_in_archive = error;
-            }
-
-            name_junk( __G);
-
-            /* mapname() can create dirs if not freshening or if renamed. */
-            error = mapname_dir_vollab( __G__ renamed,
-#ifdef SET_DIR_ATTRIB
-             pnum_dirs, pdirlist,
-#endif
-             &error_in_archive);
-
-            if (error != 0)
-                continue;       /* No more to do with this one.  Go to next. */
-
-#ifdef QDOS
-            QFilename(__G__ G.filename);
-#endif
-
-#if defined( UNIX) && defined( __APPLE__)
-            /* If we are doing special AppleDouble file processing,
-             * and this is an AppleDouble file,
-             * then we should ignore a file-exists test, which may be
-             * expected to succeed.
-             */
-
-            if (G.apple_double && (!uO.J_flag))
-            {
-                /* Fake a does-not-exist value for this AppleDouble file. */
-                cfn = DOES_NOT_EXIST;
-            }
-            else
-            {
-                /* Do the real test. */
-                cfn = check_for_newer(__G__ G.filename);
-            }
-
-            /* Use "cfn" on Mac, plain check_for_newer() elsewhere. */
-            switch (cfn)
-#else /* defined( UNIX) && defined( __APPLE__) */
-            switch (check_for_newer(__G__ G.filename))
-#endif /* defined( UNIX) && defined( __APPLE__) */
-            {
-                case DOES_NOT_EXIST:
-#ifdef NOVELL_BUG_FAILSAFE
-                    G.dne = TRUE;   /* stat() says file DOES NOT EXIST */
-#endif
-                    /* freshen (no new files): skip unless just renamed */
-                    if (uO.fflag && !renamed)
-                        skip_entry = SKIP_Y_NONEXIST;
-                    break;
-                case EXISTS_AND_OLDER:
-#ifdef UNIXBACKUP
-                    if (!uO.B_flag)
-#endif
-                    {
-                        if (IS_OVERWRT_NONE)
-                            /* never overwrite:  skip file */
-                            skip_entry = SKIP_Y_EXISTING;
-                        else if (!IS_OVERWRT_ALL)
-                            query = TRUE;
-                    }
-                    break;
-                case EXISTS_AND_NEWER:             /* (or equal) */
-#ifdef UNIXBACKUP
-                    if ((!uO.B_flag && IS_OVERWRT_NONE) ||
-#else
-                    if (IS_OVERWRT_NONE ||
-#endif
-                        (uO.uflag && !renamed)) {
-                        /* skip if update/freshen & orig name */
-                        skip_entry = SKIP_Y_EXISTING;
-                    } else {
-#ifdef UNIXBACKUP
-                        if (!IS_OVERWRT_ALL && !uO.B_flag)
-#else
-                        if (!IS_OVERWRT_ALL)
-#endif
-                            query = TRUE;
-                    }
-                    break;
-                }
-#ifdef VMS
-            /* 2008-07-24 SMS.
-             * On VMS, if the file name includes a version number,
-             * and "-V" ("retain VMS version numbers", V_flag) is in
-             * effect, then the VMS-specific code will handle any
-             * conflicts with an existing file, making this query
-             * redundant.  (Implicit "y" response here.)
-             */
-            if (query && (uO.V_flag > 0)) {
-                /* Not discarding file versions.  Look for one. */
-                int cndx = strlen(G.filename) - 1;
-
-                while ((cndx > 0) && (isdigit(G.filename[cndx])))
-                    cndx--;
-                if (G.filename[cndx] == ';')
-                    /* File version found; skip the generic query,
-                     * proceeding with its default response "y".
-                     */
-                    query = FALSE;
-            }
-#endif /* VMS */
-            if (query) {
-#ifdef WINDLL
-                switch (G.lpUserFunctions->replace != NULL ?
-                        (*G.lpUserFunctions->replace)(G.filename, FILNAMSIZ) :
-                        IDM_REPLACE_NONE) {
-                    case IDM_REPLACE_RENAME:
-                        _ISO_INTERN(G.filename);
-                        renamed = TRUE;
-                        goto startover;
-                    case IDM_REPLACE_ALL:
-                        G.overwrite_mode = OVERWRT_ALWAYS;
-                        /* FALL THROUGH, extract */
-                    case IDM_REPLACE_YES:
-                        break;
-                    case IDM_REPLACE_NONE:
-                        G.overwrite_mode = OVERWRT_NEVER;
-                        /* FALL THROUGH, skip */
-                    case IDM_REPLACE_NO:
-                        skip_entry = SKIP_Y_EXISTING;
-                        break;
-                }
-#else /* !WINDLL */
-                extent fnlen;
-reprompt:
-                Info(slide, 0x81, ((char *)slide,
-                  LoadFarString(ReplaceQuery),
-                  FnFilter1(G.filename)));
-                if (fgets_ans( __G) < 0)
-                {
-                    Info(slide, 1, ((char *)slide,
-                      LoadFarString(AssumeNone)));
-                    *G.answerbuf = 'N';
-                    if (!error_in_archive)
-                        error_in_archive = 1;  /* not extracted:  warning */
-                }
-                switch (*G.answerbuf) {
-                    case 'r':
-                    case 'R':
-                        do
-                        {
-                            Info(slide, 0x81, ((char *)slide,
-                              LoadFarString(NewNameQuery)));
-                            if (fgets( G.filename, FILNAMSIZ, stdin) == NULL)
-                            {   /* read() error.  Try again. */
-                                goto reprompt;
-                            }
-                            else
-                            {
-                                /* Usually get \n here.  Check for it. */
-                                fnlen = strlen(G.filename);
-                                if (lastchar(G.filename, fnlen) == '\n')
-                                    G.filename[--fnlen] = '\0';
-                            }
-                        } while (fnlen == 0);
-# ifdef WIN32  /* WIN32 fgets( ... , stdin) returns OEM coded strings */
-                        _OEM_INTERN(G.filename);
-# endif
-                        renamed = TRUE;
-                        goto startover;   /* sorry for a goto */
-                    case 'A':   /* dangerous option:  force caps */
-                        G.overwrite_mode = OVERWRT_ALWAYS;
-                        /* FALL THROUGH, extract */
-                    case 'y':
-                    case 'Y':
-                        break;
-                    case 'N':
-                        G.overwrite_mode = OVERWRT_NEVER;
-                        /* FALL THROUGH, skip */
-                    case 'n':
-                        /* skip file */
-                        skip_entry = SKIP_Y_EXISTING;
-                        break;
-                    case '\n':
-                    case '\r':
-                        /* Improve echo of '\n' and/or '\r'
-                           (sizeof(G.answerbuf) == 10 (see globals.h), so
-                           there is enough space for the provided text...) */
-                        strcpy(G.answerbuf, "{ENTER}");
-                        /* fall through ... */
-                    default:
-                        /* usually get \n here:  remove it for nice display
-                           (fnlen can be re-used here, we are outside the
-                           "enter new filename" loop) */
-                        fnlen = strlen(G.answerbuf);
-                        if (lastchar(G.answerbuf, fnlen) == '\n')
-                            G.answerbuf[--fnlen] = '\0';
-                        Info(slide, 1, ((char *)slide,
-                          LoadFarString(InvalidResponse), G.answerbuf));
-                        goto reprompt;   /* yet another goto? */
-                } /* end switch (*answerbuf) */
-#endif /* ?WINDLL */
-            } /* end if (query) */
-            if (skip_entry != SKIP_NO) {
-#ifdef WINDLL
-                if (skip_entry == SKIP_Y_EXISTING) {
-                    /* report skipping of an existing entry */
-                    Info(slide, 0, ((char *)slide,
-                      ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
-                       "Target file exists.\nSkipping %s\n" :
-                       "Target file newer.\nSkipping %s\n"),
-                      FnFilter1(G.filename)));
-                }
-#endif /* WINDLL */
-                continue;
-            }
-        } /* end if (extracting to disk) */
-
index 0aebd2c..1d7b4e2 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 7296d26..c8dacc3 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2006 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 34ad49c..89d4f60 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 36a21a6..36a1747 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3283e90..a51ee6a 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 8304128..f73640b 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4aa4272..81d06de 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 38fec54..b993554 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3189170..0b51e34 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9b23644..6a77aeb 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3cf58ca..7fc4cd7 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4a91812..a0445c5 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index b61cc7b..b8b9e2b 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3e0033f..21a92b1 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 3eb9f58..6fa7c31 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index c8ec9c6..cbdfa6e 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 1a62e68..364f752 100644 (file)
--- a/ubz2err.c
+++ b/ubz2err.c
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2007-Mar-04 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
@@ -16,8 +16,8 @@
   The fatal bzip2 error bail-out routine is provided in a separate code
   module, so that it can be easily overridden when the UnZip package is
   used as a static link library. One example is the WinDLL static library
-  usage for building a monolythic binary of the Windows application "WiZ"
-  that supports bzip2 both in compression and decompression operations.
+  usage for building a monolithic binary of the Windows application "WiZ"
+  that supports bzip2 in both compression and decompression operations.
 
   Contains:  bz_internal_error()      (BZIP2_SUPPORT only)
 
index bda9b37..aa889d0 100644 (file)
@@ -1,8 +1,8 @@
 #==============================================================================
 # unix/Makefile
-# - For UnZip, fUnZip, UnZipSFX, and ZipInfo            Revised: 2015-01-09
+# - For UnZip, fUnZip, UnZipSFX, and ZipInfo            Revised: 2017-04-28
 #
-# Copyright (c) 2004-2014 Info-ZIP.  All rights reserved.
+# Copyright (c) 2004-2017 Info-ZIP.  All rights reserved.
 #
 # See the accompanying file LICENSE, version 2009-Jan-2 or later (the
 # contents of which are also included in zip.h) for terms of use.  If,
 #
 # Optional features include (see INSTALL for installation instructions):
 #
-# AES encryption - See the files INSTALL and aes_wg/README_AES_WG.txt
-#   for more information.  To include AES_WG (WinZip/Gladman) encryption
-#   support, unpack a compatible AES_WG source kit (iz_aes_wg13.zip, or
-#   the latest compatible kit available on the Info-ZIP server) to
-#   populate the local ./aes_wg subdirectory.  To disable AES_WG
-#   encryption support (when the source kit is present), set the "make"
-#   macro NO_AES_WG to 1.
+# AES_WG encryption - See the files INSTALL and aes_wg/README_AES_WG.txt
+#   for more information.  To include AES_WG encryption support, unpack
+#   a compatible AES_WG source kit (iz_aes_wg16.zip, or the latest
+#   compatible kit available on the Info-ZIP server) to populate the
+#   local ./aes_wg subdirectory.  To disable AES_WG encryption support
+#   (when the source kit is present), set the "make" macro NO_AES_WG to
+#   1.
 #
 # LZMA compression - See the files INSTALL and szip/README_LZMA.txt for
 #   more information.  To disable LZMA compression support, set the
@@ -289,7 +289,7 @@ PROD = .
 
 # Build Dependencies for "make"
 # - Optional object library names
-#    AES (WinZip/Gladman) encryption
+#    AES_WG encryption
 #    BZIP2 compression
 #    LZMA compression
 #    PPMd compression
@@ -407,7 +407,7 @@ H_UNZIP  = unzip.h          \
 
 H_UNZIPL = api.h $(H_UNZIP)
 
-# C header files: AES (WinZip/Gladman) encryption
+# C header files: AES_WG encryption
 H_AES    = aes_wg/aes.h     \
            aes_wg/aesopt.h  \
            aes_wg/fileenc.h \
@@ -520,7 +520,7 @@ O_CRC_I  = $(PROD)/crc_i86.o
 O_CRC_G  = $(PROD)/crc_gcc.o
 O_CRC_SV = $(PROD)/crc_sysv.o
 
-# object files: AES (WinZip/Gladman) encryption
+# object files: AES_WG encryption
 O_AES    = $(PROD)/aescrypt.o   \
            $(PROD)/aeskey.o     \
            $(PROD)/aestab.o     \
@@ -545,7 +545,7 @@ O_PPMD   = $(PROD)/Ppmd8.o      \
 #  Build configuration:  object libraries
 #----------------------------------------------------------------------------
 
-# object library: AES (WinZip/Gladman) encryption
+# object library: AES_WG encryption
 AR_AES   = $(PROD)/libiz_aes_wg.a
 
 # object library: BZIP2 compression
@@ -919,7 +919,7 @@ $(PROD)/win32i64_f.o:  win32/win32i64.c  $(H_UNZIP)
 
 #----------------------------------------------------------------------------
 
-# C Compile rules: AES (WinZip/Gladman) encryption
+# C Compile rules: AES_WG encryption
 
 $(PROD)/aescrypt.o: aes_wg/aescrypt.c $(H_AES)
        $(CC) -c $(CF) -o $@ aes_wg/aescrypt.c
@@ -993,10 +993,10 @@ $(O_CRC_SV): crc_i386.S $(ACONF_DEP)
 #  Build rules: Object libraries (.o -> .a)
 #----------------------------------------------------------------------------
 
-# Object library rule: AES (WinZip/Gladman) encryption
+# Object library rule: AES_WG encryption
 
 $(AR_AES): $(O_AES)
-       @echo 'Building/updating AES (WinZip/Gladman) object library...'
+       @echo 'Building/updating AES_WG object library...'
        -$(RM) $@
        $(AR) $@ $(O_AES)
        -$(RANLIB) $@
@@ -1107,42 +1107,52 @@ $(PROD)/manout:
 #    /bin/man does not support "-x".  Specify "COL=/usr/5bin/col".
 
 $(DOC_UNZIP): man/man1/unzip.1
-       man -M ` pwd `/man unzip    | $(COL) -bx | uniq | expand > $@
+       LANG=C man -M ` pwd `/man unzip | \
+         $(COL) -bx | uniq | expand > $@
        @echo ''
 
 $(DOC_SFX):   man/man1/unzipsfx.1
-       man -M ` pwd `/man unzipsfx | $(COL) -bx | uniq | expand > $@
+       LANG=C man -M ` pwd `/man unzipsfx | \
+         $(COL) -bx | uniq | expand > $@
        @echo ''
 
 $(DOC_FUZ):   man/man1/funzip.1
-       man -M ` pwd `/man funzip   | $(COL) -bx | uniq | expand > $@
+       LANG=Cman -M ` pwd `/man funzip | \
+         $(COL) -bx | uniq | expand > $@
        @echo ''
 
 $(DOC_ZINFO): man/man1/zipinfo.1
-       man -M ` pwd `/man zipinfo  | $(COL) -bx | uniq | expand > $@
+       LANG=C man -M ` pwd `/man zipinfo | \
+         $(COL) -bx | uniq | expand > $@
        @echo ''
 
 $(DOC_ZGREP): man/man1/zipgrep.1
-       man -M ` pwd `/man zipgrep  | $(COL) -bx | uniq | expand > $@
+       LANG=C man -M ` pwd `/man zipgrep | \
+         $(COL) -bx | uniq | expand > $@
        @echo ''
 
 # UnZip alternate documentation generation rules
 # - Requires nroff, or GNU groff package.
 
 $(PMAN_UNZIP): man/man1/unzip.1
-       nroff -man man/man1/unzip.1    | $(COL) -bx | uniq > $@
+       LANG=Cnroff -man man/man1/unzip.1 | \
+         $(COL) -bx | uniq > $@
 
 $(PMAN_SFX):   man/man1/unzipsfx.1
-       nroff -man man/man1/unzipsfx.1 | $(COL) -bx | uniq > $@
+       LANG=C nroff -man man/man1/unzipsfx.1 | \
+         $(COL) -bx | uniq > $@
 
 $(PMAN_FUZ):   man/man1/funzip.1
-       nroff -man man/man1/funzip.1   | $(COL) -bx | uniq > $@
+       LANG=C nroff -man man/man1/funzip.1 | \
+         $(COL) -bx | uniq > $@
 
 $(PMAN_ZINFO): man/man1/zipinfo.1
-       nroff -man man/man1/zipinfo.1  | $(COL) -bx | uniq > $@
+       LANG=C nroff -man man/man1/zipinfo.1 | \
+         $(COL) -bx | uniq > $@
 
 $(PMAN_ZGREP): man/man1/zipgrep.1
-       nroff -man man/man1/zipgrep.1  | $(COL) -bx | uniq > $@
+       LANG=C nroff -man man/man1/zipgrep.1 | \
+         $(COL) -bx | uniq > $@
 
 #----------------------------------------------------------------------------
 #  Build rules: Standard build targets
@@ -1162,8 +1172,7 @@ MU:         $(UNZIP_PPGMS)
 U:          $(PPGM_FUZ) $(PPGM_SFX)
 
 #----------------------------------------------------------------------------
-#  Build rules: ???????
-#  FIX_ME: ??????
+#  Build rules: Alternative (non-generic).
 #----------------------------------------------------------------------------
 unix_make:
 # @echo \
index c8a8375..5285072 100644 (file)
@@ -1,9 +1,9 @@
 /*
   macosx.h - UnZip 6.1
 
-  Copyright (c) 2008-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 2008-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2007-Mar-4 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index f53cf4f..d7620ab 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index d054a4a..5d15683 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2013 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/unzip.c b/unzip.c
index cfdccc2..2ac33d3 100644 (file)
--- a/unzip.c
+++ b/unzip.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
 
   unzip.c
 
-  UnZip - a zipfile extraction utility.  See below for make instructions, or
-  read the comments in Makefile and the various Contents files for more de-
-  tailed explanations.  To report a bug, submit a *complete* description via
-  //www.info-zip.org/zip-bug.html; include machine type, operating system and
-  version, compiler and version, and reasonably detailed error messages or
-  problem report.  To join Info-ZIP, see the instructions in README.
-
-  UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
-  which in turn was almost a complete rewrite of version 3.x.  For a detailed
-  revision history, see UnzpHist.zip at quest.jpl.nasa.gov.  For a list of
-  the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
-  distribution.  (Some of this information is outdated and needs to be
-  updated.)
-
-  UnZip 6.0 adds support for archives larger than 4 GiB using the Zip64
+  UnZip - a zipfile extraction utility.  See below for make
+  instructions, or read the comments in Makefile and the various
+  Contents files for more detailed explanations.  To report a bug,
+  submit a *complete* description via //www.info-zip.org/zip-bug.html;
+  include machine type, operating system and version, compiler and
+  version, and reasonably detailed error messages or problem report.
+  To join Info-ZIP, see the instructions in README.
+
+  UnZip 5.x was a greatly expanded and partially rewritten successor to
+  4.x, which in turn was almost a complete rewrite of version 3.x.  For
+  a detailed revision history, see UnzpHist.zip at quest.jpl.nasa.gov.
+  For a list of the many (near infinite) contributors, see "CONTRIBS" in
+  the UnZip source distribution.  (Some of this information is outdated
+  and needs to be updated.)
+
+  UnZip 6.0 added support for archives larger than 4 GiB using the Zip64
   extensions as well as support for Unicode information embedded per the
   latest zip standard additions.
 
 
   [from original zipinfo.c]
 
-  This program reads great gobs of totally nifty information, including the
-  central directory stuff, from ZIP archives ("zipfiles" for short).  It
-  started as just a testbed for fooling with zipfiles, but at this point it
-  is actually a useful utility.  It also became the basis for the rewrite of
-  UnZip (3.16 -> 4.0), using the central directory for processing rather than
-  the individual (local) file headers.
+  This program reads great gobs of totally nifty information, including
+  the central directory stuff, from ZIP archives ("zipfiles" for short).
+  It started as just a testbed for fooling with zipfiles, but at this
+  point it is actually a useful utility.  It also became the basis for
+  the rewrite of UnZip (3.16 -> 4.0), using the central directory for
+  processing rather than the individual (local) file headers.
 
-  As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
-  If the executable is named "unzip" (or "unzip.exe", depending), it behaves
-  like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
-  ZipInfo.  The ZipInfo behavior may also be triggered by use of unzip's -Z
-  option; for example, "unzip -Z [zipinfo_options] archive.zip".
+  As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into
+  one.  If the executable is named "unzip" (or "unzip.exe", depending),
+  it behaves like UnZip by default; if it is named "zipinfo" or "ii", it
+  behaves like ZipInfo.  The ZipInfo behavior may also be triggered by
+  use of unzip's -Z option; for example:
+    unzip -Z [zipinfo_options] archive.zip
 
   Another dandy product from your buddies at Newtware!
 
@@ -58,7 +60,6 @@
   ---------------------------------------------------------------------------*/
 
 
-
 #define __UNZIP_C       /* identifies this source module */
 #define UNZIP_INTERNAL
 #include "unzip.h"      /* includes, typedefs, macros, prototypes, etc. */
@@ -126,10 +127,10 @@ USER_PROGRESS_CLASS void user_progress OF((int));
 /* Constants */
 /*************/
 
-# include "consts.h" /* all constant global variables are in here */
-                     /* (non-constant globals were moved to globals.c) */
+# include "consts.h" /* All constant global variables are in here. */
+                     /* (Non-constant globals were moved to globals.c.) */
 
-/* constant local variables: */
+/* Constant local variables: */
 
 # if !defined( SFX) || defined( DIAG_SFX)
 #  ifndef _WIN32_WCE /* Win CE does not support environment variables */
@@ -191,28 +192,30 @@ static ZCONST char Far BadJunkDirsValue[] =
 /* usage() strings */
 # ifndef SFX
 #  ifdef VMS
+static ZCONST char Far ExampleCmnt[] = "!";
 static ZCONST char Far Example3[] = "vms.c";
 static ZCONST char Far Example2[] = "  unzip \"-V\" foo \"Bar\"\
- (Quote names to preserve case, unless SET PROC/PARS=EXT)\n";
-#  else /* !VMS */
+ ! Use quotes to preserve case, unless SET PROC/PARS=EXTE\n";
+#  else /* def VMS */
+static ZCONST char Far ExampleCmnt[] = "#";
 static ZCONST char Far Example3[] = "ReadMe";
 #   ifdef RISCOS
 static ZCONST char Far Example2[] =
- "  unzip foo -d RAM:$   => extract all files from foo into RAMDisc\n";
-#   else /* !RISCOS */
+ "  unzip foo -d RAM:$   # Extract all files from foo into RAMDisc\n";
+#   else /* def RISCOS */
 #    if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
 static ZCONST char Far Example2[] =
  "";                /* no room:  too many local3[] items */
-#    else /* !OS2 */
+#    else /* (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE))) */
 #     ifdef MACOS
 static ZCONST char Far Example2[] = ""; /* not needed */
-#     else /* !MACOS */
+#     else /* def MACOS */
 static ZCONST char Far Example2[] = " \
- unzip -p foo | more  => send contents of foo.zip via pipe into program more\n";
-#     endif /* ?MACOS */
-#    endif /* ?OS2 */
-#   endif /* ?RISCOS */
-#  endif /* ?VMS */
+ unzip -p foo | more  # Pipe contents of foo.zip into program \"more\"\n";
+#     endif /* def MACOS [else] */
+#    endif /* (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE))) [else] */
+#   endif /* def RISCOS [else] */
+#  endif /* def VMS [else] */
 
 /* local1[]:  command options */
 #  if defined(TIMESTAMP)
@@ -280,13 +283,13 @@ static ZCONST char Far local2[] = " -X | -ka  restore UIC | ACL";
 #    ifdef MORE
 static ZCONST char Far local3[] = "\
   -Y  treat \".nnn\" as \";nnn\" version         -2  force ODS2 names\n\
-  -D- restore dir (-D: no) timestamps        -M  pipe through \"more\" pager\n\
+  -D- restore dir (-D: no) times             -M  pipe through \"more\" pager\n\
   (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
-\n\n";
+\n";
 #    else /* def MORE */
 static ZCONST char Far local3[] = "\n\
   -Y  treat \".nnn\" as \";nnn\" version         -2  force ODS2 names\n\
-  -D- restore dir (-D: no) timestamps\n\
+  -D- restore dir (-D: no) times\n\
   (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
 \n\n";
 #    endif /* def MORE [else] */
@@ -300,21 +303,23 @@ static ZCONST char Far local2[] = " -X  restore UID/GID info";
 #     ifdef __APPLE__
 #      ifdef MORE
 static ZCONST char Far local3[] = "\
-  -K  keep setuid/setgid/tacky permissions   -M  pipe through \"more\" pager\n\
+  -K  keep setuid/setgid/tacky permissions   -D- restore dir (-D: no) times\n\
   -J  No special AppleDouble file handling\n\
   -Je/-Jf/-Jq/-Jr  ignore extended attrs/Finder info/quarantine/resource fork\
-\n";
+\n\
+  -M  pipe through \"more\" pager\n";
 #      else /* def MORE */
 static ZCONST char Far local3[] = "\
-  -K  keep setuid/setgid/tacky permissions   -J  No spec'l AplDbl file handling\
-\n\
+  -K  keep setuid/setgid/tacky permissions   -D- restore dir (-D: no) times\n\
+  -J  No special AppleDouble file handling\n\
   -Je/-Jf/-Jq/-Jr  ignore extended attrs/Finder info/quarantine/resource fork\
 \n";
 #      endif /* def MORE [else] */
 #     else /* def __APPLE__ */
 #      ifdef MORE
 static ZCONST char Far local3[] = "\
-  -K  keep setuid/setgid/tacky permissions   -M  pipe through \"more\" pager\n";
+  -K  keep setuid/setgid/tacky permissions   -D- restore dir (-D: no) times\n\
+  -M  pipe through \"more\" pager\n";
 #      else /* def MORE */
 static ZCONST char Far local3[] = "\
   -K  keep setuid/setgid/tacky permissions\n";
@@ -362,39 +367,75 @@ static ZCONST char Far local3[] = "";
 #  endif /* ?DOS_FLX_OS2_W32 */
 # endif /* ndef SFX */
 
+/* UnZip Usage DCL suggestion strings. */
+# ifdef VMS
+#  ifdef VMSCLI        
+#   define USAGE_DCL_U "  DCL: unzip == \"$ dev:[dir]unzip_cli\""
+#  else /* def VMSCLI */
+#   define USAGE_DCL_U "  DCL: unzip == \"$ dev:[dir]unzip.exe\""
+#  endif /* def VMSCLI [else] */
+# else /* def VMS */
+#  define USAGE_DCL_U  ""
+# endif /* def VMS [else] */
+
+/* ZipInfo Usage DCL suggestion and example strings. */
 # ifndef NO_ZIPINFO
 #  ifdef VMS
+#   ifdef VMSCLI       
+#    define USAGE_DCL_Z "  DCL: zipinfo == \"$ dv:[dr]unzip_cli /zipi\""
+#   else /* def VMSCLI */
+#    define USAGE_DCL_Z "  DCL: zipinfo == \"$ dv:[dr]unzip \"\"-Z\"\"\""
+#   endif /* def VMSCLI [else] */
 static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
-#  else
+#  else /* def VMS */
+#   define USAGE_DCL_Z  ""
 static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
-#  endif
+#  endif /* def VMS [else] */
 
+/* ZipInfo Usage text strings.
+ *    Maintain consistency between these strings and the corresponding
+ *    VMS CLI strings in vms/cmdline.c.
+ */
+#  ifdef VMSCLI
+/* Used in vms/cmdline.c, so not static in VMS CLI.  "/lic" v. "--lic". */
+ZCONST char Far ZipInfoUsageLine1[] = "\
+Info-ZIP ZipInfo %s (%s)%s\n\
+ Copyright (c) 1990-2017 Info-ZIP.  License: unzip /license\n";
+#  else /* def VMSCLI */
 static ZCONST char Far ZipInfoUsageLine1[] = "\
-ZipInfo %s (%s) by Info-ZIP.  Maintainer: %s\n\
+Info-ZIP ZipInfo %s (%s)%s\n\
+ Copyright (c) 1990-2017 Info-ZIP.  License: unzip --license\n";
+#  endif /* def VMSCLI [else] */
+
+static ZCONST char Far ZipInfoUsageLine2[] = "\
+Usage: zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
+   or: unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
+\n\
+Action: List name, date/time, attribute, size, compression method, etc., for\n\
+files in list (excluding those in xlist) from the specified .zip archive(s).\n\
+\"file[.zip]\" may be a wildcard name containing %s.\n";
+
+static ZCONST char Far ZipInfoUsageLine3[] = "\n\
+Options (main listing format)            -s  short Unix \"ls -l\" format (def.)\
 \n\
-List name, date/time, attribute, size, compression method, etc., about files\n\
-in list (excluding those in xlist) contained in the specified .zip archive(s).\
-\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
-   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
-      or:  unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
-
-static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
- listing-format options:             -s  short Unix \"ls -l\" format (def.)\n\
   -1  filenames ONLY, one per line       -m  medium Unix \"ls -l\" format\n\
-  -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
+  -2  like -1, but allowing -h/-t/-z     -l  long Unix \"ls -l\" format\n\
                                          -v  verbose, multi-page format\n";
 
-static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+static ZCONST char Far ZipInfoUsageLine4[] = "\
+Options (modifiers):\n\
   -h  print header line       -t  print totals for listed files or for all\n\
   -z  print zipfile comment   -T  print file times in sortable decimal format\
-\n  -C  be case-insensitive   %s\
-  -x  exclude filenames that follow from listing\n";
+\n\
+  -C  be case-insensitive%s\
+  -x xlist  exclude from the listing the filenames in xlist\n";
+
 #  ifdef MORE
-static ZCONST char Far ZipInfoUsageLine4[] =
-     "  -M  page output through built-in \"more\"\n";
-#  else /* !MORE */
-static ZCONST char Far ZipInfoUsageLine4[] = "";
-#  endif /* ?MORE */
+static ZCONST char Far ZipInfoUsageLine4m[] =
+     "     -M  page output through built-in \"more\"\n";
+#  else /*  defMORE */
+static ZCONST char Far ZipInfoUsageLine4m[] = "";
+#  endif /* def MORE [else] */
 # endif /* !NO_ZIPINFO */
 
 # ifdef BETA
@@ -402,7 +443,7 @@ static ZCONST char Far ZipInfoUsageLine4[] = "";
 static                  /* Used in vms/cmdline.c, so not static in VMS CLI. */
 #  endif /* ndef VMSCLI */
 ZCONST char Far BetaVersion[] = "%s\
-        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+        THIS IS A BETA VERSION OF UNZIP%s -- NOT FOR GENERAL DISTRIBUTION.\n";
 # endif
 
 # ifndef VMSCLI
@@ -411,25 +452,32 @@ static                  /* Used in vms/cmdline.c, so not static in VMS CLI. */
 ZCONST char Far UnzipBanner[] =
  "%s %s (%s)  (c) %4.4s Info-ZIP  http://info-zip.org\n";
 
+/* UnZipSFX Usage text strings.
+ *    Maintain consistency between these strings and the corresponding
+ *    VMS CLI strings in vms/cmdline.c.
+ */
 # ifdef SFX
+static ZCONST char Far UnzipSFXUsage[] = "\n\
+Usage: %s%s %s\n\
+        [-opts[modifiers]] [members]\n\n";
 #  ifdef SFX_EXDIR
 static ZCONST char Far UnzipSFXOpts[] =
-   "Valid options are -cfptuz; modifiers are -abCdjLnoPq%sV%s.\n";
+   " Options (primary mode): -cfptuz  Modifiers: -abCdjLnoPq%sV%s\n";
 #  else
 static ZCONST char Far UnzipSFXOpts[] =
-     "Valid options are -cfptuz; modifiers are -abCjLnoPq%sV%s.\n";
+     " Options (primary mode): -cfptuz  Modifiers: -abCjLnoPq%sV%s\n";
 #  endif
 #  ifdef VMS
-static ZCONST char Far UnzipSFXOptsV[] =
-"(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\n";
+static ZCONST char Far UnzipSFXOptsV[] = "\
+ (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\n";
 #  endif /* def VMS */
 static ZCONST char Far UnzipSFXOpts2[] =
-     "For license info: \"--license\".\n";
+     " License: --license  More info: See UnZip documentation.\n";
 # endif /* def SFX */
 
 # if !defined( SFX) || defined( DIAG_SFX)
 static ZCONST char Far CompileOptions[] =
- "UnZip special compilation options:\n";
+ "UnZip special compilation options/features:\n";
 static ZCONST char Far CompileOptFormat[] = "        %s\n";
 #  ifndef _WIN32_WCE /* Win CE does not support environment variables */
 static ZCONST char Far EnvOptions[] =
@@ -524,7 +572,11 @@ static ZCONST char Far No_More[] =
 #  endif
 #  ifdef NO_ZIPINFO
 static ZCONST char Far No_ZipInfo[] =
+#   ifdef VMS
+ "NO_ZIPINFO           (ZipInfo -Z (/ZIPINFO) mode disabled)";
+#   else /* def VMS */
  "NO_ZIPINFO           (ZipInfo -Z mode disabled)";
+#   endif /* def VMS */
 #  endif
 #  ifdef NTSD_EAS
 static ZCONST char Far NTSDExtAttrib[] =
@@ -715,37 +767,41 @@ static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
 #  endif /* !__RSXNT__ */
 # endif /* !defined( SFX) || defined( DIAG_SFX) */
 
+/* UnZip Usage text strings.
+ *    Maintain consistency between these strings and the corresponding
+ *    VMS CLI strings in vms/cmdline.c.
+ */
 # ifndef SFX
 #  ifdef VMSCLI
-    /* Used in vms/cmdline.c, so not static in VMS CLI.  "/lic" v. "--lic". */
+/* Used in vms/cmdline.c, so not static in VMS CLI.  "/lic" v. "--lic". */
 ZCONST char Far UnzipUsageLine1[] = "\
-UnZip %s (%s) by Info-ZIP.  Maintainer: %s\n\
- Copyright (c) 1990-2015 Info-ZIP.  For software license: unzip /license\n";
+Info-ZIP UnZip %s (%s)%s\n\
+ Copyright (c) 1990-2017 Info-ZIP.  License: unzip /license\n";
 #  else /* def VMSCLI */
-    static ZCONST char Far UnzipUsageLine1[] = "\
-UnZip %s (%s) by Info-ZIP.  Maintainer: %s\n\
- Copyright (c) 1990-2015 Info-ZIP.  For software license: unzip --license\n";
+static ZCONST char Far UnzipUsageLine1[] = "\
+Info-ZIP UnZip %s (%s)%s\n\
+ Copyright (c) 1990-2017 Info-ZIP.  License: unzip --license\n";
 #  endif /* def VMSCLI [else] */
-#  define UnzipUsageLine1v       UnzipUsageLine1
 
-static ZCONST char Far UnzipUsageLine2v[] = "\
- See README for details.  More info: http://info-zip.org/UnZip.html\n\n";
+static ZCONST char Far UnzipVersionLine[] = "\
+ More info: http://info-zip.org  http://info-zip.org/UnZip.html\n\
+ Bugs: http://www.info-zip.org/zip-bug.html  See README for details.\n\n";
 
 #  ifdef MACOS
 static ZCONST char Far UnzipUsageLine2[] = "\
 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n\
- Default action is to extract files in list, to exdir;\n\
+ Default action: Extract files in list, to exdir;\n\
   file[.zip] may be a wildcard.  %s\n";
 #  else /* !MACOS */
 #   ifdef VM_CMS
 static ZCONST char Far UnzipUsageLine2[] = "\
 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n\
- Default action is to extract files in list, except those in xlist, to disk fm;\
+ Default action: Extract files in list, except those in xlist, to disk fm;\
 \n  file[.zip] may be a wildcard.  %s\n";
 #   else /* !VM_CMS */
 static ZCONST char Far UnzipUsageLine2[] = "\
 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n\
- Default action is to extract files in list, except those in xlist, to exdir;\n\
+ Default action: Extract files in list, except those in xlist, to exdir;\n\
  file[.zip] may be a wildcard.  %s\n";
 #   endif /* ?VM_CMS */
 #  endif /* ?MACOS */
@@ -753,42 +809,37 @@ Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n\
 #  ifdef NO_ZIPINFO
 #  define ZIPINFO_MODE_OPTION  ""
 static ZCONST char Far ZipInfoMode[] =
- "(ZipInfo mode is disabled in this version.)";
+ "(ZipInfo mode is disabled in this build.)";
 #  else
 #  define ZIPINFO_MODE_OPTION  "[-Z] "
 static ZCONST char Far ZipInfoMode[] =
  "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
 #  endif /* ?NO_ZIPINFO */
 
-#  ifdef VMS
-static ZCONST char Far VMSusageLine2b[] = "\
-=> Define foreign command symbol in LOGIN.COM: \
-unzip == \"$ dev:[dir]unzip.exe\"\n";
-#  endif
-
 #  ifdef MACOS
-static ZCONST char Far UnzipUsageLine3[] = "\n\
+static ZCONST char Far UnzipUsageLine3[] = "\
+Options (primary mode):\n\
   -d  extract files into exdir               -l  list files (short format)\n\
   -f  freshen existing files, create none    -t  test compressed archive data\n\
   -u  update files, create if necessary      -z  display archive comment only\n\
   -v  list verbosely/show version info     %s\n";
-#  else /* !MACOS */
+#  else /* def MACOS */
 #   ifdef VM_CMS
-static ZCONST char Far UnzipUsageLine3[] = "\n\
+static ZCONST char Far UnzipUsageLine3[] = "\
+Options (primary mode):\n\
   -p  extract files to pipe, no messages     -l  list files (short format)\n\
   -f  freshen existing files, create none    -t  test compressed archive data\n\
   -u  update files, create if necessary      -z  display archive comment only\n\
-  -v  list verbosely/show version info     %s\n\
-  -x  exclude files that follow (in xlist)   -d  extract files onto disk fm\n";
-#   else /* !VM_CMS */
-static ZCONST char Far UnzipUsageLine3[] = "\n\
+  -v  list verbosely/show version info     %s\n";
+#   else /* def VM_CMS */
+static ZCONST char Far UnzipUsageLine3[] = "\
+Options (primary mode):\n\
   -p  extract files to pipe, no messages     -l  list files (short format)\n\
   -f  freshen existing files, create none    -t  test compressed archive data\n\
   -u  update files, create if necessary      -z  display archive comment only\n\
-  -v  list verbosely/show version info     %s\n\
-  -x  exclude files that follow (in xlist)   -d  extract files into exdir\n";
-#   endif /* ?VM_CMS */
-#  endif /* ?MACOS */
+  -v  list verbosely/show version info     %s\n";
+#   endif /* def VM_CMS [else] */
+#  endif /* def MACOS [else] */
 
 /* There is not enough space on a standard 80x25 Windows console screen for
  * the additional line advertising the UTF-8 debugging options. This may
@@ -801,7 +852,8 @@ static ZCONST char Far UnzipUsageLine3[] = "\n\
 #  if (defined(UNICODE_SUPPORT) && !defined(WIN32))
 #   ifdef VMS
 static ZCONST char Far UnzipUsageLine4[] = "\
-Modifiers:\n\
+Options (modifiers):\n\
+  -x  exclude files that follow (in xlist)   -d  extract files into exdir\n\
   -n  never overwrite or make a new version of an existing file\n\
   -o  always make a new version (-oo: overwrite original) of an existing file\n\
   -q  quiet mode (-qq => quieter)            -a  auto-convert any text files\n\
@@ -809,86 +861,439 @@ Modifiers:\n\
   -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
   -C  match filenames case-insensitively     -L  make (some) names \
 lowercase\n %-42s  -V  retain VMS version numbers\n%s";
-#   else /* !VMS */
+#   else /* def VMS */
 static ZCONST char Far UnzipUsageLine4[] = "\
-Modifiers:\n\
+Options (modifiers):\n\
   -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
   -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
   -j[=N] junk paths (strip all/top-N dirs)   -aa treat ALL files as text\n\
   -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
   -C  match filenames case-insensitively     -L  make (some) names \
 lowercase\n %-42s  -V  retain VMS version numbers\n%s";
-#   endif /* ?VMS */
-#  else /* !UNICODE_SUPPORT */
+#   endif /* def VMS [else] */
+#  else /* (defined(UNICODE_SUPPORT) && !defined(WIN32)) */
 #   ifdef VMS
 static ZCONST char Far UnzipUsageLine4[] = "\
-Modifiers:\n\
+Options (modifiers):\n\
   -n  never overwrite or make a new version of an existing file\n\
   -o  always make a new version (-oo: overwrite original) of an existing file\n\
   -q  quiet mode (-qq => quieter)            -a  auto-convert any text files\n\
   -j[=N] junk paths (strip all/top-N dirs)   -aa treat ALL files as text\n\
   -C  match filenames case-insensitively     -L  make (some) names \
 lowercase\n %-42s  -V  retain VMS version numbers\n%s";
-#   else /* !VMS */
+#   else /* def VMS */
 static ZCONST char Far UnzipUsageLine4[] = "\
-Modifiers:\n\
+Options (modifiers):\n\
   -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
   -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
   -j[=N] junk paths (strip all/top-N dirs)   -aa treat ALL files as text\n\
   -C  match filenames case-insensitively     -L  make (some) names \
 lowercase\n %-42s  -V  retain VMS version numbers\n%s";
-#   endif /* ?VMS */
-#  endif /* ?UNICODE_SUPPORT */
+#   endif /* def VMS [else] */
+#  endif /* (defined(UNICODE_SUPPORT) && !defined(WIN32)) [else] */
 
 static ZCONST char Far UnzipUsageLine5[] = "\
-See \"unzip -hh\" for more help.  Examples:\n\
-  unzip data1 -x joe   => extract all files except joe from archive data1.zip\n\
+More help: unzip -hh   Examples:\n\
+  unzip data1 -x joe   %s Extract all files except joe from archive data1.zip\n\
 %s\
-  unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
+  unzip -fo foo %-6s %s Replace quietly existing %s if archive file newer\n";
 
 # endif /* ndef SFX */
 
 
 
-/*****************************/
-/*  main() / UzpMain() stub  */
-/*****************************/
+/*
+ * -------------------------------------------------------
+ * Command Line Options
+ * -------------------------------------------------------
+ *
+ * Valid command line options.
+ *
+ * get_option() uses one of these tables to check if an option is valid,
+ * and if it takes a value (also called an option parameter).
+ * To add an option to UnZip or ZipInfo, add it to the appropriate
+ * table, and add a case in the main switch to handle it.
+ *
+ *  The fields:
+ *      shortopt     - short option name (1 or 2 chars)
+ *      longopt      - long option name
+ *      value_type   - see unzpriv.h for constants
+ *      negatable    - option is negatable with trailing -
+ *      ID           - unsigned long int returned for option
+ *      name         - short description of option which is
+ *                       returned on some errors and when options
+ *                       are listed with -so option, can be NULL
+ *
+ * If shortopt or longopt is not used, then set it to "".
+ *
+ * Single-character short options use the shortopt character as an ID.
+ * Two-character short options use a non-ASCII code (o_XX), defined in
+ * unzpriv.h.  (Look for "Option ID".)
+ */
 
-int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
-    int argc;
-    char *argv[];
-{
-    int r;
+/* The tables below are based on the old main command line code, with
+ * some changes.
+ */
 
-    CONSTRUCTGLOBALS();
+static ZCONST struct option_struct far options_unzip[] =
+{
+/* UnZip options */
 
-/* Microsoft memory allocation debug.
- * Enable dump of memory leaks on program exit.
+/*   short longopt            value_type        negatable
+ *     ID    description
  */
-# if defined(_MSC_VER) && defined(_DEBUG) && !defined( NO_IZ_DEBUG_ALLOC)
-    _CrtSetDbgFlag(
-     _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF);
+    {"0",  "no-char-set",     o_NO_VALUE,       o_NEGATABLE,
+       '0',  "don't map FAT/NTFS names"},
+# ifdef VMS
+    {"2",  "force-ods2",      o_NO_VALUE,       o_NEGATABLE,
+       '2',  "Force ODS2-compliant names."},
 # endif
+    {"a",  "ascii",           o_NO_VALUE,       o_NEGATABLE,
+       'a',  "text convert (EOL char, ASCII->EBCDIC)"},
+# if (defined(DLL) && defined(API_DOC))
+    {"A",  "api-help",        o_OPTIONAL_VALUE, o_NOT_NEGATABLE,
+       'A',  "extended help for API"},
+# endif
+    {"b",  "binary",          o_NO_VALUE,       o_NEGATABLE,
+       'b',  "binary, no ASCII conversions"},
+# ifdef UNIXBACKUP
+    {"B",  "backup",          o_NO_VALUE,       o_NEGATABLE,
+       'B',  "back up existing files"},
+# endif
+# ifdef CMS_MVS
+    {"B",  "cms-mvs-binary",  o_NO_VALUE,       o_NEGATABLE,
+       'b',  "CMS/MVS binary"},
+# endif
+    {"c",  "to-stdout",       o_NO_VALUE,       o_NEGATABLE,
+       'c',  "output to stdout"},
+# ifdef CMS_MVS
+    /* for CMS_MVS map to lower case */
+    {"C",  "cms-mvs-lower",   o_NO_VALUE,       o_NEGATABLE,
+       'C',  "CMS/MVS lower case"},
+# else /* ifdef CMS_MVS */
+    {"C",  "ignore-case",     o_NO_VALUE,       o_NEGATABLE,
+       'C',  "ignore case"},
+# endif /* ifdef CMS_MVS [else] */
+# if (!defined(SFX) || defined(SFX_EXDIR))
+    {"d",  "extract-dir",     o_REQUIRED_VALUE, o_NEGATABLE,
+       'd',  "extraction root directory"},
+# endif
+# ifndef SFX
+    {"da", "auto-extract-dir", o_OPT_EQ_VALUE,  o_NEGATABLE,
+       o_da, "automatic extraction root directory"},
+# endif /* ndef SFX */
+# if (!defined(NO_TIMESTAMPS))
+       /* seems the best long option name I can think of */
+    {"D",  "dir-timestamps",  o_NO_VALUE,       o_NEGATABLE,
+       'D',  "restore no times (-D- = dir and file)"},
+# endif
+    {"e",  "extract",         o_NO_VALUE,       o_NEGATABLE,
+       'e',  "extract (not used?)"},
+# ifdef MACOS
+    {"E",  "mac-efs",         o_NO_VALUE,       o_NEGATABLE,
+       'E',  "show Mac e.f. when restoring"},
+# endif
+    {"f",  "freshen",         o_NO_VALUE,       o_NEGATABLE,
+       'f',  "freshen (extract only newer files)"},
+# if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+    {"F",  "keep-nfs",        o_NO_VALUE,       o_NEGATABLE,
+       'F',  "Acorn filetype & NFS extension handling"},
+# endif
+    {"h",  "help",            o_NO_VALUE,       o_NOT_NEGATABLE,
+       'h',  "help"},
+    {"hh", "long-help",       o_NO_VALUE,       o_NOT_NEGATABLE,
+       o_hh, "long help"},
+# ifdef MACOS
+    {"i",  "no-mac-ef-names", o_NO_VALUE,       o_NEGATABLE,
+       'i',  "ignore filenames stored in Mac ef"},
+# endif
+# ifdef ICONV_MAPPING
+#  ifdef UNIX
+    {"I",  "iso-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
+       'I',  "ISO char set to use"},
+#  endif /* def ICONV_MAPPING */
+# endif
+    {"j",  "junk-dirs",       o_OPT_EQ_VALUE,   o_NEGATABLE,
+       'j',  "junk directories, extract names only"},
+# ifdef J_FLAG
+    {"J",  "junk-attrs",      o_NO_VALUE,       o_NEGATABLE,
+       'J',  "Junk AtheOS, BeOS, or MacOS file attrs"},
+# endif
+# if defined( UNIX) && defined( __APPLE__)
+    {"Je", "junk-extattrs",   o_NO_VALUE,       o_NEGATABLE,
+       o_Je, "Junk Mac OS X extended attributes"},
+    {"Jf", "junk-finder",     o_NO_VALUE,       o_NEGATABLE,
+       o_Jf, "Junk Mac OS X Finder info"},
+    {"Jq", "junk-qtn",        o_NO_VALUE,       o_NEGATABLE,
+       o_Jq, "Junk Mac OS X quarantine"},
+    {"Jr", "junk-rsrc",       o_NO_VALUE,       o_NEGATABLE,
+       o_Jr, "Junk Mac OS X resource fork"},
+# endif /* defined( UNIX) && defined( __APPLE__) */
+    {"",   "jar",             o_NO_VALUE,       o_NEGATABLE,
+       o_ja, "Treat archive(s) as Java JAR (UTF-8)"},
+# ifdef ATH_BEO_UNX
+    {"K",  "keep-s-attrs",    o_NO_VALUE,       o_NEGATABLE,
+       'K',  "retain SUID/SGID/Tacky attrs"},
+# endif
+# ifdef KFLAG
+    {"k",  "keep-permissions", o_NO_VALUE,      o_NEGATABLE,
+       'k',  "retain permissions"},
+# endif
+# ifdef VMS
+    {"ka", "keep-acl",        o_NO_VALUE,       o_NEGATABLE,
+       o_ka, "restore (VMS) ACL"},
+# endif
+# ifndef SFX
+    {"l",  "list",            o_NO_VALUE,       o_NEGATABLE,
+        'l', "list archive members"},
+# endif
+# ifndef CMS_MVS
+    {"L",  "lowercase-names", o_NO_VALUE,       o_NEGATABLE,
+       'L',  "convert (some) names to lower"},
+# endif
+    {"",   "license",         o_NO_VALUE,   o_NOT_NEGATABLE,
+       o_LI, "Info-ZIP license"},
+# ifdef MORE
+#  ifdef CMS_MVS
+    {"m",  "more",            o_NO_VALUE,       o_NEGATABLE,
+       'm',  "pipe output through more"},
+#  endif
+    {"M",  "more",            o_NO_VALUE,       o_NEGATABLE,
+       'M',  "pipe output through more"},
+# endif /* MORE */
+    {"n",  "never-overwrite", o_NO_VALUE,       o_NEGATABLE,
+       'n',  "never overwrite files (no prompting)"},
+# ifdef AMIGA
+    {"N",  "comment-to-note", o_NO_VALUE,       o_NEGATABLE,
+       'N',  "restore comments as filenotes"},
+# endif
+# ifdef ICONV_MAPPING
+#  ifdef UNIX
+    {"O",  "oem-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
+       'O',  "OEM char set to use"},
+#  endif /* def ICONV_MAPPING */
+# endif
+    {"o",  "overwrite",       o_NO_VALUE,       o_NEGATABLE,
+       'o',  "overwrite files without prompting"},
+    {"p",  "pipe-to-stdout",  o_NO_VALUE,       o_NEGATABLE,
+       'p',  "pipe extraction to stdout, no messages"},
+# ifdef IZ_CRYPT_ANY
+    {"P",  "password",        o_REQUIRED_VALUE, o_NEGATABLE,
+       'P',  "password"},
+# endif
+    {"q",  "quiet",           o_NO_VALUE,       o_NEGATABLE,
+       'q',  "quiet mode (additional q's => more quiet)"},
+# ifdef QDOS
+    {"Q",  "QDOS",            o_NO_VALUE,       o_NEGATABLE,
+       'Q',  "QDOS flags"},
+# endif
+# ifdef TANDEM
+    {"r",  "remove-exts",     o_NO_VALUE,       o_NEGATABLE,
+       'r',  "remove file extensions"},
+# endif
+    {"s",  "space-to-uscore", o_NO_VALUE,       o_NEGATABLE,
+       's',  "spaces to underscores"},
+# ifdef VMS
+    {"S",  "streamlf",        o_NO_VALUE,       o_NEGATABLE,
+       'S',  "VMS extract text as Stream_LF"},
+# endif
+# ifndef SFX
+    {"sc", "show-command",    o_NO_VALUE,       o_NEGATABLE,
+       o_sc, "show processed command line and exit"},
+#  if !defined( VMS) && defined( ENABLE_USER_PROGRESS)
+    {"si", "show-pid",        o_NO_VALUE,       o_NEGATABLE,
+       o_si, "show process ID"},
+#  endif /* !defined( VMS) && defined( ENABLE_USER_PROGRESS) */
+    {"so", "show-options",    o_NO_VALUE,       o_NEGATABLE,
+       o_so, "show available options on this system"},
+# endif /* ndef SFX */
+    {"t",  "test",            o_NO_VALUE,       o_NEGATABLE,
+       't',  "test archive"},
+# ifdef TIMESTAMP
+    {"T",  "timestamp-new",   o_NO_VALUE,       o_NEGATABLE,
+       'T',  "timestamp archive same as newest file"},
+# endif
+    {"u",  "update",          o_NO_VALUE,       o_NEGATABLE,
+       'u',  "update (extract only new/newer files)"},
+# ifdef UNICODE_SUPPORT
+    {"U",  "unicode",         o_NO_VALUE,       o_NEGATABLE,
+       'U',  "escape non-ASCII Unicode, disable Unicode"},
+# endif /* ?UNICODE_SUPPORT */
+# if !defined( SFX) || defined( DIAG_SFX)
+    {"v",  "verbose",         o_NO_VALUE,       o_NEGATABLE,
+       'v',  "verbose"},
+    {"",   "version",         o_NO_VALUE,       o_NEGATABLE,
+       o_ve, "version"},
+    {"",   "version",         o_NO_VALUE,       o_NEGATABLE,
+       o_ve, "version"},
+    {"vq", "quick-version",   o_NO_VALUE,       o_NOT_NEGATABLE,
+       o_vq, "show brief/quick version"},
+# endif
+# ifndef CMS_MVS
+    {"V",  "keep-versions",  o_NO_VALUE,       o_NEGATABLE,
+       'V',  "don't strip VMS version numbers"},
+# endif
+# ifdef WILD_STOP_AT_DIR
+    {"W",  "wild-no-span",    o_NO_VALUE,       o_NEGATABLE,
+       'W',  "wildcard * doesn't span /"},
+# endif
+    {"x",  "exclude",         o_VALUE_LIST,     o_NOT_NEGATABLE,
+       'x',  "exclude this list of files"},
+# if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
+    {"X",  "restore-owner",   o_NO_VALUE,       o_NEGATABLE,
+       'X',  "restore owner/group (UID/GID, UIC, ...)"},
+# endif
+# ifdef VMS
+    {"Y",  "dot-version",     o_NO_VALUE,       o_NEGATABLE,
+       'Y',  "VMS treat .nnn as ;nnn version"},
+# endif
+    {"z",  "zipfile-comment", o_NO_VALUE,       o_NEGATABLE,
+       'z',  "show zipfile comment"},
+# if !defined( SFX) && !defined( NO_ZIPINFO)
+    {"Z",  "zipinfo-mode",    o_NO_VALUE,       o_NOT_NEGATABLE,
+       'Z',  "ZipInfo mode (must be first option)"},
+# endif
+# ifdef RISCOS
+    {"/",  "extensions",      o_REQUIRED_VALUE, o_NEGATABLE,
+       '/',  "override Unzip$Exts"},
+# endif
+# ifdef VOLFLAG
+    {"$",  "volume-labels",   o_NO_VALUE,       o_NEGATABLE,
+       '$',  "extract volume labels"},
+# endif
+# if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
+    {":",  "do-double-dots",  o_NO_VALUE,       o_NEGATABLE,
+       ':',  "don't skip ../ path elements"},
+# endif
+# ifdef UNIX
+    {"^",  "control-in-name", o_NO_VALUE,       o_NEGATABLE,
+       '^',  "allow control chars in filenames"},
+# endif
+    /* Array terminator. */
+    {NULL, NULL,              o_NO_VALUE,       o_NOT_NEGATABLE,
+       0,    NULL} /* end has option_ID = 0 */
+};
 
-    r = unzip(__G__ argc, argv);
-    DESTROYGLOBALS();
-    RETURN(r);
-}
-
-
-
+# ifndef NO_ZIPINFO
 
-/*******************************/
-/*  Primary UnZip entry point  */
-/*******************************/
+/* ZipInfo options */
 
-int unzip(__G__ argc, argv)
-    __GDEF
-    int argc;
-    char *argv[];
+static ZCONST struct option_struct far options_zipinfo[] =
 {
-/* Ignore argv[0] for DLL or object library.
- * (Must use "-Z" for ZipInfo mode.)
+/*   short longopt            value_type        negatable
+ *     ID    description
+ */
+    {"1",  "names-only",      o_NO_VALUE,       o_NEGATABLE,
+       '1',  "names-only list"},
+    {"2",  "names-mostly",    o_NO_VALUE,       o_NEGATABLE,
+       '2',  "names-mostly list"},
+#  ifndef CMS_MVS
+    {"C",  "ignore-case",     o_NO_VALUE,       o_NEGATABLE,
+       'C',  "ignore case"},
+#  endif
+    {"h",  "header",          o_NO_VALUE,       o_NEGATABLE,
+       'h',  "header line"},
+#  ifdef ICONV_MAPPING
+#   ifdef UNIX
+    {"I",  "iso-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
+       'I',  "ISO charset to use"},
+#   endif /* def ICONV_MAPPING */
+#  endif
+    {"l",  "long-list",       o_NO_VALUE,       o_NEGATABLE,
+       'l',  "long list"},
+    {"",   "license",         o_NO_VALUE,   o_NOT_NEGATABLE,
+       o_LI, "Info-ZIP license"},
+    {"m",  "medium-list",     o_NO_VALUE,       o_NEGATABLE,
+       'm',  "medium list"},
+#  ifdef MORE
+    {"M",  "more",            o_NO_VALUE,       o_NEGATABLE,
+       'M',  "output like more"},
+# endif
+    {"mc", "member-counts",   o_NO_VALUE,       o_NEGATABLE,
+       o_mc, "show separate dir/file/link member counts"},
+# ifdef ICONV_MAPPING
+#  ifdef UNIX
+    {"O",  "oem-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
+       'O',  "OEM charset to use"},
+#  endif /* def ICONV_MAPPING */
+# endif
+    {"s",  "short-list",      o_NO_VALUE,       o_NEGATABLE,
+       's',  "short list"},
+# ifndef SFX
+    {"sc", "show-command",    o_NO_VALUE,       o_NEGATABLE,
+       o_sc, "show processed command line and exit"},
+    {"so", "show-options",    o_NO_VALUE,       o_NEGATABLE,
+       o_so, "show available options on this system"},
+# endif /* ndef SFX */
+    {"t",  "totals",          o_NO_VALUE,       o_NEGATABLE,
+       't',  "totals line"},
+    {"T",  "decimal-time",    o_NO_VALUE,       o_NEGATABLE,
+       'T',  "decimal time format"},
+#  ifdef UNICODE_SUPPORT
+    {"U",  "unicode",         o_NO_VALUE,       o_NEGATABLE,
+       'U',  "escape non-ASCII Unicode, disable Unicode"},
+#  endif
+    {"v",  "verbose",         o_NO_VALUE,       o_NEGATABLE,
+       'v',  "very detailed list"},
+    {"",   "version",         o_NO_VALUE,       o_NEGATABLE,
+       o_ve, "version"},
+    {"vq", "quick-version",   o_NO_VALUE,       o_NOT_NEGATABLE,
+       o_vq, "show brief/quick version"},
+#  ifdef WILD_STOP_AT_DIR
+    {"W",  "wild-no-span",    o_NO_VALUE,       o_NEGATABLE,
+       'W',  "wildcard * doesn't span /"},
+#  endif
+    {"x",  "exclude",         o_VALUE_LIST,     o_NOT_NEGATABLE,
+       'x',  "exclude this list of files"},
+    {"z",  "zipfile-comment", o_NO_VALUE,       o_NEGATABLE,
+       'z',  "print zipfile comment"},
+    {"Z",  "zipinfo-mode",    o_NO_VALUE,       o_NEGATABLE,
+       'Z',  "ZipInfo mode"},
+
+    /* Array terminator. */
+    {NULL, NULL,              o_NO_VALUE,       o_NOT_NEGATABLE,
+       0,    NULL} /* end has option_ID = 0 */
+};
+# endif /* ndef NO_ZIPINFO */
+
+
+/*****************************/
+/*  main() / UzpMain() stub  */
+/*****************************/
+
+int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
+    int argc;
+    char *argv[];
+{
+    int r;
+
+    CONSTRUCTGLOBALS();
+
+/* Microsoft memory allocation debug.
+ * Enable dump of memory leaks on program exit.
+ */
+# if defined(_MSC_VER) && defined(_DEBUG) && !defined( NO_IZ_DEBUG_ALLOC)
+    _CrtSetDbgFlag(
+     _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF);
+# endif
+
+    r = unzip(__G__ argc, argv);
+    DESTROYGLOBALS();
+    RETURN(r);
+}
+
+
+/*******************************/
+/*  Primary UnZip entry point  */
+/*******************************/
+
+int unzip(__G__ argc, argv)
+    __GDEF
+    int argc;
+    char *argv[];
+{
+/* Ignore argv[0] for DLL or object library.
+ * (Must use "-Z" for ZipInfo mode.)
  */
 #  ifdef DLL
 #   ifndef IGNORE_ARGV0
@@ -1228,11 +1633,12 @@ int unzip(__G__ argc, argv)
             goto cleanup_and_exit;
         }
     }
-#  endif /* VMSCLI */
+#  endif /* def VMSCLI */
 
     uO.zipinfo_mode = FALSE;
-    error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
-    if (error) {
+    error = uz_opts(__G__ options_unzip, &argc, &argv);   /* UnZipSFX. */
+    if (error)
+    {
          /* Parsing error message already emitted.
           * Leave a blank line, and add the (brief) SFX usage message.
           */
@@ -1240,7 +1646,7 @@ int unzip(__G__ argc, argv)
         USAGE( error);
     }
 
-# else /* !SFX */
+# else /* def SFX */
 
 #  ifdef RISCOS
     /* get the extensions to swap from environment */
@@ -1260,7 +1666,7 @@ int unzip(__G__ argc, argv)
             goto cleanup_and_exit;
         }
     }
-#  endif /* VMSCLI */
+#  endif /* def VMSCLI */
 
     G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
 
@@ -1305,7 +1711,7 @@ int unzip(__G__ argc, argv)
             perror(LoadFarString(NoMemEnvArguments));
 #   endif
     } else
-#  endif /* !NO_ZIPINFO */
+#  endif /* ndef NO_ZIPINFO */
     {
         uO.zipinfo_mode = FALSE;
 #  ifndef _WIN32_WCE /* Win CE does not support environment variables */
@@ -1333,19 +1739,27 @@ int unzip(__G__ argc, argv)
         }
 #  ifndef NO_ZIPINFO
         if (uO.zipinfo_mode)
-            error = zi_opts(__G__ &argc, &argv);
+        {
+            error = zi_opts(__G__ options_zipinfo, &argc, &argv);
+        }
         else
-#  endif /* !NO_ZIPINFO */
-            error = uz_opts(__G__ &argc, &argv);
+#  endif /* ndef NO_ZIPINFO */
+        {
+            error = uz_opts(__G__ options_unzip, &argc, &argv);
+        }
     }
 
-# endif /* ?SFX */
+# endif /* def SFX [else] */
 
-    if ((argc < 0) || error) {
+    if ((argc < 0) || error)
+    {
         retcode = error;
         if ((argc < -1) || error)
         {
-            Info(slide, 0x401, ((char *)slide, "\n"));
+            if (error)
+            {   /* Leave a blank line after an error message. */
+                Info(slide, 0x401, ((char *)slide, "\n"));
+            }
             USAGE( error);
         }
         goto cleanup_and_exit;
@@ -1377,462 +1791,113 @@ int unzip(__G__ argc, argv)
 #  ifdef __human68k__
             extern char *_toslash(char *);
             _toslash(*G_pfnames);
-#  else /* !__human68k__ */
-            char *q = *G_pfnames;
-
-            while (*q != '\0') {
-                if (*q == '\\')
-                    *q = '/';
-                INCSTR(q);
-            }
-#  endif /* ?__human68k__ */
-            ++G_pfnames;
-        }
-    }
-# endif /* DOS_FLX_H68_NLM_OS2_W32 */
-
-# if !defined( SFX) || defined( SFX_EXDIR)
-    if (uO.exdir != (char *)NULL && !G.extract_flag)
-        /* Have "-d exdir", but not actually extracting, so -d is ignored. */
-        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
-# endif /* !defined( SFX) || defined( SFX_EXDIR) */
-
-# ifdef UNICODE_SUPPORT
-    /* set Unicode-escape-all if option -U used */
-    if (uO.U_flag == 1)
-#  ifdef UNICODE_WCHAR
-        G.unicode_escape_all = TRUE;
-#  else
-        Info(slide, 0x401, ((char *)slide, LoadFarString(UTF8EscapeUnSupp)));
-#  endif
-# endif
-
-# if defined( UNIX) && defined( __APPLE__)
-    /* Set flag according to the capabilities of the destination volume. */
-    G.exdir_attr_ok = vol_attr_ok( (uO.exdir == NULL) ? "." : uO.exdir);
-# endif /* defined( UNIX) && defined( __APPLE__) */
-
-# ifdef KFLAG
-    /* Get Unix umask value.  (Already have VMS default protection value.) */
-#  if defined( __ATHEOS__) || defined( __BEOS__) || defined( UNIX)
-    umask( G.umask_val = umask( 0));
-#  endif
-# endif /* def KFLAG */
-
-/*---------------------------------------------------------------------------
-    Okey dokey, we have everything we need to get started.  Let's roll.
-  ---------------------------------------------------------------------------*/
-
-    retcode = process_zipfiles(__G);
-
-cleanup_and_exit:
-# if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
-    /* restore all signal handlers back to their state at function entry */
-    while (oldsighandlers != NULL) {
-        savsigs_info *thissigsav = oldsighandlers;
-
-        signal(thissigsav->sigtype, thissigsav->sighandler);
-        oldsighandlers = thissigsav->previous;
-        izu_free(thissigsav);
-    }
-# endif
-
-# ifdef REENTRANT
-    free_args( argv);
-# endif /* def REENTRANT */
-
-# if (defined(MSDOS) && !defined(SFX) && !defined(WINDLL))
-    if (retcode != PK_OK)
-        check_for_windows("UnZip");
-# endif
-    return(retcode);
-
-} /* end main()/unzip() */
-
-
-
-# if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
-/*******************************/
-/* Function setsignalhandler() */
-/*******************************/
-
-static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
-                            newhandler)
-    __GDEF
-    savsigs_info **p_savedhandler_chain;
-    int signal_type;
-    void (*newhandler)(int);
-{
-    savsigs_info *savsig;
-
-    savsig = izu_malloc(sizeof(savsigs_info));
-    if (savsig == NULL) {
-        /* error message and break */
-        Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
-        return PK_MEM;
-    }
-    savsig->sigtype = signal_type;
-    savsig->sighandler = signal(SIGINT, newhandler);
-    if (savsig->sighandler == SIG_ERR) {
-        izu_free(savsig);
-    } else {
-        savsig->previous = *p_savedhandler_chain;
-        *p_savedhandler_chain = savsig;
-    }
-    return PK_OK;
-
-} /* end function setsignalhandler() */
-
-# endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
-
-
-/*
- * -------------------------------------------------------
- * Command Line Options
- * -------------------------------------------------------
- *
- * Valid command line options.
- *
- * The function get_option() uses this table to check if an option is
- * valid, and if it takes a value (also called an option parameter).
- * To add an option to UnZip, add it to this table, and add a case in
- * the main switch to handle it.
- *
- *  The fields:
- *      option_group - UZO for UnZip option, ZIO for ZipInfo option
- *      shortopt     - short option name (1 or 2 chars)
- *      longopt      - long option name
- *      value_type   - see unzpriv.h for constants
- *      negatable    - option is negatable with trailing -
- *      ID           - unsigned long int returned for option
- *      name         - short description of option which is
- *                       returned on some errors and when options
- *                       are listed with -so option, can be NULL
- *
- * If shortopt or longopt is not used, then set it to "".
- *
- * Most option IDs are set to the shortopt char.  For multichar short
- * options, ID is set to an arbitrary unused constant.  See list in
- * unzpriv.h.
- */
-
-/* The table below is based on the old main command line code, with a
- * few changes.  Note that UnZip and ZipInfo filter out their own
- * options based on the option_group value, so the same option letter
- * can be used for both.
- */
-
-static struct option_struct far options[] = {
-
-  /* UnZip options */
-
-  /*    short   longopt            value_type        negatable
-       ID    name */
-    {UZO, "0",  "no-char-set",     o_NO_VALUE,       o_NEGATABLE,
-       '0',  "don't map FAT/NTFS names"},
-# ifdef VMS
-    {UZO, "2",  "force-ods2",      o_NO_VALUE,       o_NEGATABLE,
-       '2',  "Force ODS2-compliant names."},
-# endif
-    {UZO, "a",  "ascii",           o_NO_VALUE,       o_NEGATABLE,
-       'a',  "text convert (EOL char, ASCII->EBCDIC)"},
-# if (defined(DLL) && defined(API_DOC))
-    {UZO, "A",  "api-help",        o_OPTIONAL_VALUE, o_NOT_NEGATABLE,
-       'A',  "extended help for API"},
-# endif
-    {UZO, "b",  "binary",          o_NO_VALUE,       o_NEGATABLE,
-       'b',  "binary, no ASCII conversions"},
-# ifdef UNIXBACKUP
-    {UZO, "B",  "backup",          o_NO_VALUE,       o_NEGATABLE,
-       'B',  "back up existing files"},
-# endif
-# ifdef CMS_MVS
-    {UZO, "B",  "cms-mvs-binary",  o_NO_VALUE,       o_NEGATABLE,
-       'b',  "CMS/MVS binary"},
-# endif
-    {UZO, "c",  "to-stdout",       o_NO_VALUE,       o_NEGATABLE,
-       'c',  "output to stdout"},
-# ifdef CMS_MVS
-    /* for CMS_MVS map to lower case */
-    {UZO, "C",  "cms-mvs-lower",   o_NO_VALUE,       o_NEGATABLE,
-       'C',  "CMS/MVS lower case"},
-# else /* ifdef CMS_MVS */
-    {UZO, "C",  "ignore-case",     o_NO_VALUE,       o_NEGATABLE,
-       'C',  "ignore case"},
-# endif /* ifdef CMS_MVS [else] */
-# if (!defined(SFX) || defined(SFX_EXDIR))
-    {UZO, "d",  "extract-dir",     o_REQUIRED_VALUE, o_NEGATABLE,
-       'd',  "extraction root directory"},
-# endif
-# ifndef SFX
-    {UZO, "da", "auto-extract-dir", o_OPT_EQ_VALUE,  o_NEGATABLE,
-       o_da, "automatic extraction root directory"},
-# endif /* ndef SFX */
-# if (!defined(NO_TIMESTAMPS))
-       /* seems the best long option name I can think of */
-    {UZO, "D",  "dir-timestamps",  o_NO_VALUE,       o_NEGATABLE,
-       'D',  "restore no times (-D- = dir and file)"},
-# endif
-    {UZO, "e",  "extract",         o_NO_VALUE,       o_NEGATABLE,
-       'e',  "extract (not used?)"},
-# ifdef MACOS
-    {UZO, "E",  "mac-efs",         o_NO_VALUE,       o_NEGATABLE,
-       'E',  "show Mac e.f. when restoring"},
-# endif
-    {UZO, "f",  "freshen",         o_NO_VALUE,       o_NEGATABLE,
-       'f',  "freshen (extract only newer files)"},
-# if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
-    {UZO, "F",  "keep-nfs",        o_NO_VALUE,       o_NEGATABLE,
-       'F',  "Acorn filetype & NFS extension handling"},
-# endif
-    {UZO, "h",  "help",            o_NO_VALUE,       o_NOT_NEGATABLE,
-       'h',  "help"},
-    {UZO, "hh", "long-help",       o_NO_VALUE,       o_NOT_NEGATABLE,
-       o_hh, "long help"},
-# ifdef MACOS
-    {UZO, "i",  "no-mac-ef-names", o_NO_VALUE,       o_NEGATABLE,
-       'i',  "ignore filenames stored in Mac ef"},
-# endif
-# ifdef ICONV_MAPPING
-#  ifdef UNIX
-    {UZO, "I",  "iso-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
-       'I',  "ISO char set to use"},
-#  endif /* def ICONV_MAPPING */
-# endif
-    {UZO, "j",  "junk-dirs",       o_OPT_EQ_VALUE,   o_NEGATABLE,
-       'j',  "junk directories, extract names only"},
-# ifdef J_FLAG
-    {UZO, "J",  "junk-attrs",      o_NO_VALUE,       o_NEGATABLE,
-       'J',  "Junk AtheOS, BeOS, or MacOS file attrs"},
-# endif
-# if defined( UNIX) && defined( __APPLE__)
-    {UZO, "Je", "junk-extattrs",   o_NO_VALUE,       o_NEGATABLE,
-       o_Je, "Junk Mac OS X extended attributes"},
-    {UZO, "Jf", "junk-finder",     o_NO_VALUE,       o_NEGATABLE,
-       o_Jf, "Junk Mac OS X Finder info"},
-    {UZO, "Jq", "junk-qtn",        o_NO_VALUE,       o_NEGATABLE,
-       o_Jq, "Junk Mac OS X quarantine"},
-    {UZO, "Jr", "junk-rsrc",       o_NO_VALUE,       o_NEGATABLE,
-       o_Jr, "Junk Mac OS X resource fork"},
-# endif /* defined( UNIX) && defined( __APPLE__) */
-    {UZO, "",   "jar",             o_NO_VALUE,       o_NEGATABLE,
-       o_ja, "Treat archive(s) as Java JAR (UTF-8)"},
-# ifdef ATH_BEO_UNX
-    {UZO, "K",  "keep-s-attrs",    o_NO_VALUE,       o_NEGATABLE,
-       'K',  "retain SUID/SGID/Tacky attrs"},
-# endif
-# ifdef KFLAG
-    {UZO, "k",  "keep-permissions", o_NO_VALUE,      o_NEGATABLE,
-       'k',  "retain permissions"},
-# endif
-# ifdef VMS
-    {UZO, "ka", "keep-acl",        o_NO_VALUE,       o_NEGATABLE,
-       o_ka, "restore (VMS) ACL"},
-# endif
-# ifndef SFX
-    {UZO, "l",  "list",            o_NO_VALUE,       o_NEGATABLE,
-        'l', "list archive members"},
-# endif
-# ifndef CMS_MVS
-    {UZO, "L",  "lowercase-names", o_NO_VALUE,       o_NEGATABLE,
-       'L',  "convert (some) names to lower"},
-# endif
-    {UZO, "",   "license",         o_NO_VALUE,   o_NOT_NEGATABLE,
-       o_LI, "Info-ZIP license"},
-# ifdef MORE
-#  ifdef CMS_MVS
-    {UZO, "m",  "more",            o_NO_VALUE,       o_NEGATABLE,
-       'm',  "pipe output through more"},
-#  endif
-    {UZO, "M",  "more",            o_NO_VALUE,       o_NEGATABLE,
-       'M',  "pipe output through more"},
-# endif /* MORE */
-    {UZO, "n",  "never-overwrite", o_NO_VALUE,       o_NEGATABLE,
-       'n',  "never overwrite files (no prompting)"},
-# ifdef AMIGA
-    {UZO, "N",  "comment-to-note", o_NO_VALUE,       o_NEGATABLE,
-       'N',  "restore comments as filenotes"},
-# endif
-# ifdef ICONV_MAPPING
-#  ifdef UNIX
-    {UZO, "O",  "oem-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
-       'O',  "OEM char set to use"},
-#  endif /* def ICONV_MAPPING */
-# endif
-    {UZO, "o",  "overwrite",       o_NO_VALUE,       o_NEGATABLE,
-       'o',  "overwrite files without prompting"},
-    {UZO, "p",  "pipe-to-stdout",  o_NO_VALUE,       o_NEGATABLE,
-       'p',  "pipe extraction to stdout, no messages"},
-# ifdef IZ_CRYPT_ANY
-    {UZO, "P",  "password",        o_REQUIRED_VALUE, o_NEGATABLE,
-       'P',  "password"},
-# endif
-    {UZO, "q",  "quiet",           o_NO_VALUE,       o_NEGATABLE,
-       'q',  "quiet mode (additional q's => more quiet)"},
-# ifdef QDOS
-    {UZO, "Q",  "QDOS",            o_NO_VALUE,       o_NEGATABLE,
-       'Q',  "QDOS flags"},
-# endif
-# ifdef TANDEM
-    {UZO, "r",  "remove-exts",     o_NO_VALUE,       o_NEGATABLE,
-       'r',  "remove file extensions"},
-# endif
-    {UZO, "s",  "space-to-uscore", o_NO_VALUE,       o_NEGATABLE,
-       's',  "spaces to underscores"},
-# ifdef VMS
-    {UZO, "S",  "streamlf",        o_NO_VALUE,       o_NEGATABLE,
-       'S',  "VMS extract text as Stream_LF"},
-# endif
-# ifndef SFX
-    {UZO, "sc", "show-command",    o_NO_VALUE,       o_NEGATABLE,
-       o_sc, "show processed command line and exit"},
-#  if !defined( VMS) && defined( ENABLE_USER_PROGRESS)
-    {UZO, "si", "show-pid",        o_NO_VALUE,       o_NEGATABLE,
-       o_si, "show process ID"},
-#  endif /* !defined( VMS) && defined( ENABLE_USER_PROGRESS) */
-    {UZO, "so", "show-options",    o_NO_VALUE,       o_NEGATABLE,
-       o_so, "show available options on this system"},
-# endif /* ndef SFX */
-    {UZO, "t",  "test",            o_NO_VALUE,       o_NEGATABLE,
-       't',  "test archive"},
-# ifdef TIMESTAMP
-    {UZO, "T",  "timestamp-new",   o_NO_VALUE,       o_NEGATABLE,
-       'T',  "timestamp archive same as newest file"},
-# endif
-    {UZO, "u",  "update",          o_NO_VALUE,       o_NEGATABLE,
-       'u',  "update (extract only new/newer files)"},
+#  else /* !__human68k__ */
+            char *q = *G_pfnames;
+
+            while (*q != '\0') {
+                if (*q == '\\')
+                    *q = '/';
+                INCSTR(q);
+            }
+#  endif /* ?__human68k__ */
+            ++G_pfnames;
+        }
+    }
+# endif /* DOS_FLX_H68_NLM_OS2_W32 */
+
+# if !defined( SFX) || defined( SFX_EXDIR)
+    if (uO.exdir != (char *)NULL && !G.extract_flag)
+        /* Have "-d exdir", but not actually extracting, so -d is ignored. */
+        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
+# endif /* !defined( SFX) || defined( SFX_EXDIR) */
+
 # ifdef UNICODE_SUPPORT
-    {UZO, "U",  "unicode",         o_NO_VALUE,       o_NEGATABLE,
-       'U',  "escape non-ASCII Unicode, disable Unicode"},
-# endif /* ?UNICODE_SUPPORT */
-# if !defined( SFX) || defined( DIAG_SFX)
-    {UZO, "v",  "verbose",         o_NO_VALUE,       o_NEGATABLE,
-       'v',  "verbose"},
-    {UZO, "",   "version",         o_NO_VALUE,       o_NEGATABLE,
-       o_ve, "version"},
-    {UZO, "",   "version",         o_NO_VALUE,       o_NEGATABLE,
-       o_ve, "version"},
-    {UZO, "vq", "quick-version",   o_NO_VALUE,       o_NOT_NEGATABLE,
-       o_vq, "show brief/quick version"},
-# endif
-# ifndef CMS_MVS
-    {UZO, "V",  "keep-versions",  o_NO_VALUE,       o_NEGATABLE,
-       'V',  "don't strip VMS version numbers"},
-# endif
-# ifdef WILD_STOP_AT_DIR
-    {UZO, "W",  "wild-no-span",    o_NO_VALUE,       o_NEGATABLE,
-       'W',  "wildcard * doesn't span /"},
-# endif
-    {UZO, "x",  "exclude",         o_VALUE_LIST,     o_NOT_NEGATABLE,
-       'x',  "exclude this list of files"},
-# if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
-    {UZO, "X",  "restore-owner",   o_NO_VALUE,       o_NEGATABLE,
-       'X',  "restore owner/group (UID/GID, UIC, ...)"},
-# endif
-# ifdef VMS
-    {UZO, "Y",  "dot-version",     o_NO_VALUE,       o_NEGATABLE,
-       'Y',  "VMS treat .nnn as ;nnn version"},
-# endif
-    {UZO, "z",  "zipfile-comment", o_NO_VALUE,       o_NEGATABLE,
-       'z',  "show zipfile comment"},
-# if !defined( SFX) && !defined( NO_ZIPINFO)
-    {UZO, "Z",  "zipinfo-mode",    o_NO_VALUE,       o_NOT_NEGATABLE,
-       'Z',  "ZipInfo mode (must be first option)"},
-# endif
-# ifdef RISCOS
-    {UZO, "/",  "extensions",      o_REQUIRED_VALUE, o_NEGATABLE,
-       '/',  "override Unzip$Exts"},
-# endif
-# ifdef VOLFLAG
-    {UZO, "$",  "volume-labels",   o_NO_VALUE,       o_NEGATABLE,
-       '$',  "extract volume labels"},
-# endif
-# if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
-    {UZO, ":",  "do-double-dots",  o_NO_VALUE,       o_NEGATABLE,
-       ':',  "don't skip ../ path elements"},
-# endif
-# ifdef UNIX
-    {UZO, "^",  "control-in-name", o_NO_VALUE,       o_NEGATABLE,
-       '^',  "allow control chars in filenames"},
+    /* set Unicode-escape-all if option -U used */
+    if (uO.U_flag == 1)
+#  ifdef UNICODE_WCHAR
+        G.unicode_escape_all = TRUE;
+#  else
+        Info(slide, 0x401, ((char *)slide, LoadFarString(UTF8EscapeUnSupp)));
+#  endif
 # endif
 
-# ifndef NO_ZIPINFO
-  /* ZipInfo options */
+# if defined( UNIX) && defined( __APPLE__)
+    /* Set flag according to the capabilities of the destination volume. */
+    G.exdir_attr_ok = vol_attr_ok( (uO.exdir == NULL) ? "." : uO.exdir);
+# endif /* defined( UNIX) && defined( __APPLE__) */
 
-  /* short longopt                 value_type        negatable
-       ID    name (help text) */
-    {ZIO, "1",  "names-only",      o_NO_VALUE,       o_NEGATABLE,
-       '1',  "names-only list"},
-    {ZIO, "2",  "names-mostly",    o_NO_VALUE,       o_NEGATABLE,
-       '2',  "names-mostly list"},
-#  ifndef CMS_MVS
-    {ZIO, "C",  "ignore-case",     o_NO_VALUE,       o_NEGATABLE,
-       'C',  "ignore case"},
-#  endif
-    {ZIO, "h",  "header",          o_NO_VALUE,       o_NEGATABLE,
-       'h',  "header line"},
-#  ifdef ICONV_MAPPING
-#   ifdef UNIX
-    {ZIO, "I",  "iso-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
-       'I',  "ISO charset to use"},
-#   endif /* def ICONV_MAPPING */
+# ifdef KFLAG
+    /* Get Unix umask value.  (Already have VMS default protection value.) */
+#  if defined( __ATHEOS__) || defined( __BEOS__) || defined( UNIX)
+    umask( G.umask_val = umask( 0));
 #  endif
-    {ZIO, "l",  "long-list",       o_NO_VALUE,       o_NEGATABLE,
-       'l',  "long list"},
-    {ZIO, "",   "license",         o_NO_VALUE,   o_NOT_NEGATABLE,
-       o_LI, "Info-ZIP license"},
-    {ZIO, "m",  "medium-list",     o_NO_VALUE,       o_NEGATABLE,
-       'm',  "medium list"},
-#  ifdef MORE
-    {ZIO, "M",  "more",            o_NO_VALUE,       o_NEGATABLE,
-       'M',  "output like more"},
+# endif /* def KFLAG */
+
+/*---------------------------------------------------------------------------
+    Okey dokey, we have everything we need to get started.  Let's roll.
+  ---------------------------------------------------------------------------*/
+
+    retcode = process_zipfiles(__G);
+
+cleanup_and_exit:
+# if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+    /* restore all signal handlers back to their state at function entry */
+    while (oldsighandlers != NULL) {
+        savsigs_info *thissigsav = oldsighandlers;
+
+        signal(thissigsav->sigtype, thissigsav->sighandler);
+        oldsighandlers = thissigsav->previous;
+        izu_free(thissigsav);
+    }
 # endif
-    {ZIO, "mc", "member-counts",   o_NO_VALUE,       o_NEGATABLE,
-       o_mc, "show separate dir/file/link member counts"},
-# ifdef ICONV_MAPPING
-#  ifdef UNIX
-    {ZIO, "O",  "oem-char-set",    o_REQUIRED_VALUE, o_NOT_NEGATABLE,
-       'O',  "OEM charset to use"},
-#  endif /* def ICONV_MAPPING */
+
+# ifdef REENTRANT
+    free_args( argv);
+# endif /* def REENTRANT */
+
+# if (defined(MSDOS) && !defined(SFX) && !defined(WINDLL))
+    if (retcode != PK_OK)
+        check_for_windows("UnZip");
 # endif
-    {ZIO, "s",  "short-list",      o_NO_VALUE,       o_NEGATABLE,
-       's',  "short list"},
-# ifndef SFX
-    {ZIO, "sc", "show-command",    o_NO_VALUE,       o_NEGATABLE,
-       o_sc, "show processed command line and exit"},
-    {ZIO, "so", "show-options",    o_NO_VALUE,       o_NEGATABLE,
-       o_so, "show available options on this system"},
-# endif /* ndef SFX */
-    {ZIO, "t",  "totals",          o_NO_VALUE,       o_NEGATABLE,
-       't',  "totals line"},
-    {ZIO, "T",  "decimal-time",    o_NO_VALUE,       o_NEGATABLE,
-       'T',  "decimal time format"},
-#  ifdef UNICODE_SUPPORT
-    {ZIO, "U",  "unicode",         o_NO_VALUE,       o_NEGATABLE,
-       'U',  "escape non-ASCII Unicode, disable Unicode"},
-#  endif
-    {ZIO, "v",  "verbose",         o_NO_VALUE,       o_NEGATABLE,
-       'v',  "very detailed list"},
-    {ZIO, "",   "version",         o_NO_VALUE,       o_NEGATABLE,
-       o_ve, "version"},
-    {ZIO, "vq", "quick-version",   o_NO_VALUE,       o_NOT_NEGATABLE,
-       o_vq, "show brief/quick version"},
-#  ifdef WILD_STOP_AT_DIR
-    {ZIO, "W",  "wild-no-span",    o_NO_VALUE,       o_NEGATABLE,
-       'W',  "wildcard * doesn't span /"},
-#  endif
-    {ZIO, "x",  "exclude",         o_VALUE_LIST,     o_NOT_NEGATABLE,
-       'x',  "exclude this list of files"},
-    {ZIO, "z",  "zipfile-comment", o_NO_VALUE,       o_NEGATABLE,
-       'z',  "print zipfile comment"},
-    {ZIO, "Z",  "zipinfo-mode",    o_NO_VALUE,       o_NEGATABLE,
-       'Z',  "ZipInfo mode"},
-# endif /* ndef NO_ZIPINFO */
+    return(retcode);
 
-    /* the end of the list */
-    {0,   NULL, NULL,                   o_NO_VALUE,       o_NOT_NEGATABLE,
-       0,    NULL} /* end has option_ID = 0 */
-  };
+} /* end main()/unzip() */
+
+
+
+# if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+/*******************************/
+/* Function setsignalhandler() */
+/*******************************/
+
+static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
+                            newhandler)
+    __GDEF
+    savsigs_info **p_savedhandler_chain;
+    int signal_type;
+    void (*newhandler)(int);
+{
+    savsigs_info *savsig;
+
+    savsig = izu_malloc(sizeof(savsigs_info));
+    if (savsig == NULL) {
+        /* error message and break */
+        Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
+        return PK_MEM;
+    }
+    savsig->sigtype = signal_type;
+    savsig->sighandler = signal(SIGINT, newhandler);
+    if (savsig->sighandler == SIG_ERR) {
+        izu_free(savsig);
+    } else {
+        savsig->previous = *p_savedhandler_chain;
+        *p_savedhandler_chain = savsig;
+    }
+    return PK_OK;
+
+} /* end function setsignalhandler() */
+
+# endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
 
 
 /* 2012-12-12 SMS.
@@ -1852,8 +1917,9 @@ static struct option_struct far options[] = {
 /* Function uz_opts() */
 /**********************/
 
-int uz_opts(__G__ pargc, pargv)
+int uz_opts(__G__ opts, pargc, pargv)
     __GDEF
+    ZCONST struct option_struct *opts;
     int *pargc;
     char ***pargv;
 {
@@ -1874,10 +1940,12 @@ int uz_opts(__G__ pargc, pargv)
     int negative = 0;     /* 1 = option negated */
     int fna = 0;          /* current first non-opt arg */
     int optnum = 0;       /* index in table */
+    int dashdash = 0;     /* Have seen "--". */
 
 
-    /* since get_option() returns xfiles and files one at a time, store them
-       in linked lists until have them all */
+    /* Because get_option() returns xfiles and files one at a time,
+     * store them in linked lists until we have them all.
+     */
 
     int file_count = 0;
     struct file_list *next_file;
@@ -1911,7 +1979,6 @@ int uz_opts(__G__ pargc, pargv)
     G.filespecs = 0;
     G.xfilespecs = 0;
 
-
     /*
     -------------------------------------------
     Process command line using get_option
@@ -1933,9 +2000,6 @@ int uz_opts(__G__ pargc, pargv)
            value    - char* to value (free() when done with it) or NULL if none
            negative - option was negated with trailing -
 
-       The first argument, UZO, tells get_option() that these are the UnZip
-       options (not ZipInfo options).
-
        See the comments for get_option() for the other parameters.
     */
 
@@ -1949,7 +2013,7 @@ int uz_opts(__G__ pargc, pargv)
      * the "while" loop, this storage will be free()'d.
      */
 
-    while ((option = get_option(__G__ UZO, &args, &argcnt, &argnum,
+    while ((option = get_option(__G__ opts, &args, &argcnt, &argnum,
                                 &optchar, &value, &negative,
                                 &fna, &optnum, 0)))
     {
@@ -2612,7 +2676,18 @@ int uz_opts(__G__ pargc, pargv)
             case o_NON_OPTION_ARG:
                 /* Not an option.  (Because of permutation, no more
                  * "-" options are expected henceforth.)
+                 * "--" also appears here.
                  */
+
+                /* First "--" is ignored (and stops arg processing for
+                 * remaining args).
+                 */
+                if ((strcmp( value, "--") == 0) && (dashdash == 0))
+                {
+                  dashdash = 1;
+                }
+                else
+
 # ifndef SFX
                 /* For non-SFX (only), the first non-option argument is
                  * the archive name.  (For SFX, every non-option argument
@@ -2622,16 +2697,17 @@ int uz_opts(__G__ pargc, pargv)
                 {
                     /* first non-option argument is zip file */
                     G.wildzipfn = value;
-
-                else
+                }
+                else
 # endif /* ndef SFX */
                 {
                     /* add include file to list */
-                    if (in_files_count == 0) {
+                    if (in_files_count == 0)
+                    {
                         /* first entry */
                         if ((next_file = (struct file_list *)
-                                         izu_malloc(sizeof(struct file_list))
-                            ) == NULL) {
+                         izu_malloc(sizeof(struct file_list)) ) == NULL)
+                        {
                             Info(slide, 0x401, ((char *)slide,
                               LoadFarString(NoMemArgsList)));
                             /* Leaving early.  Free it. */
@@ -2643,11 +2719,13 @@ int uz_opts(__G__ pargc, pargv)
                         next_file->next = NULL;
                         in_files = next_file;
                         next_in_files = next_file;
-                    } else {
+                    }
+                    else
+                    {
                         /* add next entry */
                         if ((next_file = (struct file_list *)
-                                         izu_malloc(sizeof(struct file_list))
-                            ) == NULL) {
+                         izu_malloc(sizeof(struct file_list))) == NULL)
+                        {
                             Info(slide, 0x401, ((char *)slide,
                               LoadFarString(NoMemArgsList)));
                             /* Leaving early.  Free it. */
@@ -2668,26 +2746,28 @@ int uz_opts(__G__ pargc, pargv)
                 uzo_err = TRUE;
                 break;
 
-        } /* end switch */
+        } /* switch (option) */
 
         FREE_NON_NULL( value);          /* Free it now, if it's not in use. */
 
-    } /* while get_option() */
+    } /* while (get_option()) */
 
 
     /* convert files and xfiles lists to arrays */
 
     /* convert files list to array */
-    if (in_files_count) {
-      if ((G.pfnames = (char **) izu_malloc(
-       (in_files_count + 1) * sizeof(char *))
-          ) == NULL) {
+    if (in_files_count)
+    {
+      if ((G.pfnames = (char **)
+       izu_malloc( (in_files_count + 1) * sizeof(char *))) == NULL)
+      {
           Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArgsList)));
           UPDATE_PARGV;                 /* See note 2013-01-17 SMS. */
           return PK_MEM;
       }
       file_count = 0;
-      for (next_file = in_files; next_file;) {
+      for (next_file = in_files; next_file;)
+      {
           G.pfnames[file_count] = next_file->name;
           in_files = next_file;
           next_file = next_file->next;
@@ -2699,16 +2779,18 @@ int uz_opts(__G__ pargc, pargv)
     }
 
     /* convert xfiles list to array */
-    if (in_xfiles_count) {
-      if ((G.pxnames = (char **) izu_malloc(
-       (in_xfiles_count + 1) * sizeof(char *))
-          ) == NULL) {
+    if (in_xfiles_count)
+    {
+      if ((G.pxnames = (char **)
+       izu_malloc( (in_xfiles_count + 1) * sizeof(char *))) == NULL)
+      {
           Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArgsList)));
           UPDATE_PARGV;                 /* See note 2013-01-17 SMS. */
           return PK_MEM;
       }
       file_count = 0;
-      for (next_file = in_xfiles; next_file;) {
+      for (next_file = in_xfiles; next_file;)
+      {
           G.pxnames[file_count] = next_file->name;
           in_xfiles = next_file;
           next_file = next_file->next;
@@ -2918,7 +3000,6 @@ int uz_opts(__G__ pargc, pargv)
 } /* end function uz_opts() */
 
 
-
 # if !defined( SFX) || defined( DIAG_SFX)
 #  ifndef _WIN32_WCE    /* Win CE does not support environment variables */
 
@@ -3092,19 +3173,31 @@ int usage(__G__ u_err)   /* return PK-type error code */
 {
     int flag = (u_err? 1 : 0);
 
-    Info(slide, flag, ((char *)slide, LoadFarString( UnzipBanner),
+    Info( slide, flag, ((char *)slide, LoadFarString( UnzipBanner),
      "UnZipSFX", UzpVersionStr(), UZ_VERSION_DATE, UZ_VERSION_DATE));
-    Info(slide, flag, ((char *)slide, LoadFarString(UnzipSFXOpts),
-      SFXOPT1, LOCAL));
-#  ifdef VMS
-    Info(slide, flag, ((char *)slide, LoadFarString(UnzipSFXOptsV)));
-#  endif /* def VMS */
-    Info(slide, flag, ((char *)slide, LoadFarString(UnzipSFXOpts2)));
 #  ifdef BETA
-    Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "\n",
+    Info( slide, flag, ((char *)slide, LoadFarString( BetaVersion), "\n",
      "SFX"));
 #  endif
 
+#  ifdef VMS
+#   define CMD_PREFIX "MCR "
+#   define CMD_CONTIN "-"
+#  else /* def VMS */
+#   define CMD_PREFIX ""
+#   define CMD_CONTIN "\\"
+#  endif /* def VMS [else] */
+
+    Info( slide, flag, ((char *)slide, LoadFarString( UnzipSFXUsage),
+     CMD_PREFIX, G.zipfn, CMD_CONTIN));
+
+    Info( slide, flag, ((char *)slide, LoadFarString( UnzipSFXOpts),
+     SFXOPT1, LOCAL));
+#  ifdef VMS
+    Info( slide, flag, ((char *)slide, LoadFarString( UnzipSFXOptsV)));
+#  endif /* def VMS */
+    Info(slide, flag, ((char *)slide, LoadFarString( UnzipSFXOpts2)));
+
     if (u_err)
         return PK_PARAM;
     else
@@ -3135,28 +3228,32 @@ int usage(__G__ u_err)   /* return PK-type error code */
     (Strings must be no longer than 512 bytes for Turbo C, apparently.)
   ---------------------------------------------------------------------------*/
 
-    if (uO.zipinfo_mode) {
-
+    if (uO.zipinfo_mode)
+    {
 #  ifndef NO_ZIPINFO
 
-        Info(slide, flag, ((char *)slide, LoadFarString( ZipInfoUsageLine1),
-         UzpVersionStr(), UZ_VERSION_DATE, UNZIP_MAINTAINER,
-         LoadFarStringSmall2( ZipInfoExample), QUOTS,QUOTS));
-        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
-        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
-         LoadFarStringSmall(ZipInfoUsageLine4)));
+        Info( slide, flag, ((char *)slide, LoadFarString( ZipInfoUsageLine1),
+         UzpVersionStr(), UZ_VERSION_DATE, USAGE_DCL_Z));
+#  ifdef BETA
+        Info( slide, flag, ((char *)slide, LoadFarString( BetaVersion), "",
+         ""));
+#  endif
+        Info( slide, flag, ((char *)slide, LoadFarString( ZipInfoUsageLine2),
+         QUOTS, QUOTS, LoadFarStringSmall2( ZipInfoExample)));
+        Info( slide, flag, ((char *)slide, LoadFarString( ZipInfoUsageLine3)));
+        Info( slide, flag, ((char *)slide, LoadFarString( ZipInfoUsageLine4),
+         LoadFarString( ZipInfoUsageLine4m)));
 #   ifdef VMS
         Info(slide, flag, ((char *)slide, "\n\
   (Must quote upper-case options and names, unless SET PROC/PARSE=EXTEND.)\
 \n"));
-#   endif
-
+#   endif /* def VMS */
 #  endif /* ndef NO_ZIPINFO */
-
-    } else {   /* UnZip mode */
-
+    }
+    else
+    {   /* UnZip mode */
         Info(slide, flag, ((char *)slide, LoadFarString( UnzipUsageLine1),
-         UzpVersionStr(), UZ_VERSION_DATE, UNZIP_MAINTAINER));
+         UzpVersionStr(), UZ_VERSION_DATE, USAGE_DCL_U));
 #  ifdef BETA
         Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
 #  endif
@@ -3164,11 +3261,6 @@ int usage(__G__ u_err)   /* return PK-type error code */
         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
           ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
 
-#  ifdef VMS
-        if (!u_err)  /* maybe no command-line tail found; show extra help */
-            Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
-#  endif
-
         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
           LoadFarStringSmall(local1)));
 
@@ -3178,9 +3270,11 @@ int usage(__G__ u_err)   /* return PK-type error code */
         /* This is extra work for SMALL_MEM, but it will work since
          * LoadFarStringSmall2 uses the same buffer.  Remember, this
          * is a hack. */
-        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
-          LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
-          LoadFarStringSmall2(Example3)));
+        Info(slide, flag, ((char *)slide,
+         LoadFarString( UnzipUsageLine5), LoadFarStringSmall( ExampleCmnt),
+          LoadFarStringSmall( Example2),
+          LoadFarStringSmall2( Example3), LoadFarStringSmall( ExampleCmnt),
+          LoadFarStringSmall2( Example3)));
 
     } /* end if (uO.zipinfo_mode) */
 
@@ -3205,7 +3299,7 @@ void show_license(__G)
 
     /* license array */
     static ZCONST char *text[] = {
-  "Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.",
+  "Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.",
   "",
   "This is version 2009-Jan-02 of the Info-ZIP license.",
   "",
@@ -3441,17 +3535,17 @@ static void help_extended(__G)
   "  If port supports [], must escape [ as [[]",
   "  For shells that expand wildcards, escape (\\* or \"*\") so UnZip can recurse.",
   "",
-  "Include and Exclude:",
-  "  -i pattern pattern ...   include files that match a pattern",
-  "  -x pattern pattern ...   exclude files that match a pattern",
+  "Include and Exclude archive members:",
+  "  pattern pattern ...      include members that match a pattern",
+  "  -x pattern pattern ...   exclude members that match a pattern",
   "  Patterns are paths with optional wildcards and match paths as stored in",
   "  archive.  Exclude and include lists end at next option or end of line.",
   "    unzip archive -x pattern pattern ...",
   "",
   "Segmented (split) archives (archives created as a set of split files):",
   "  Currently, all archive segments must be files on a single volume, with",
-  "  name extensions \".z01\", \".z02\", and so on, with the last segment"
-  "  \".zip.\"",
+  "  name extensions \".z01\", \".z02\", and so on, with the last segment",
+  "  \".zip\".",
   "",
   "Streaming (piping into UnZip):",
   "  Currently UnZip does not support streaming.  The FUnZip utility can be",
@@ -3564,76 +3658,87 @@ static void help_extended(__G)
 void show_options(__G)
     __GDEF
 {
-    extent i;
+    int i;
     size_t lolen;
-    char optiontext[200];
-    char gr[4];
     char sh[7];
     char lo[80];
-    char val_type[5];
-    char neg[2];
+    char *val_type;
+    char *neg;
+    ZCONST struct option_struct *opts;
 
-    sprintf(optiontext, "%s\n\n%s\n%s",
-      "Available options on this system",
-      "UNZ = UnZip option, INF = ZipInfo option",
-      "n = Negatable");
-    Info(slide, 0, ((char *)slide, "%s\n\n", optiontext));
+#  ifdef NO_ZIPINFO
+#   define CMD_NAME "UnZip"
+#  else /* def NO_ZIPINFO */
+#   define CMD_NAME (uO.zipinfo_mode ? "ZipInfo" : "UnZip")
+#  endif /* def NO_ZIPINFO [else] */
+
+    Info(slide, 0, ((char *)slide, "\
+Available %s options:\n", CMD_NAME));
 
-    sprintf(optiontext, "grp  sh   long             val   n  description");
   Info(slide, 0, ((char *)slide, "%s\n", optiontext));
+    Info(slide, 0, ((char *)slide, "\
sh  long               val  neg description\n"));
 
-    for (i = 0; options[i].option_ID != 0; i++)
+    Info(slide, 0, ((char *)slide, "\
+ --  ----               ---  --- -----------\n"));
+
+#  ifndef NO_ZIPINFO
+    if (uO.zipinfo_mode)
     {
-        if (options[i].option_group == UZO)
-            strcpy(gr, "UNZ");
-        else if (options[i].option_group == ZIO)
-            strcpy(gr, "INF");
-        else
-            strcpy(gr, "?  ");
+      opts = options_zipinfo;
+    }
+    else
+#  endif /* ndef NO_ZIPINFO */
+    {
+      opts = options_unzip;
+    }
 
-        strcpy(sh, options[i].shortopt);
+    for (i = 0; opts[i].option_ID != 0; i++)
+    {
+        strcpy(sh, opts[i].shortopt);
         strcat(sh, "  ");
         sh[2] = '\0';
 
-        strcpy(lo, options[i].longopt);
+        strcpy(lo, opts[i].longopt);
         lolen = strlen(lo);
         strcat(lo, "                      ");
-        if (lolen < 15)
-          lolen = 15;
+        if (lolen < 17)
+          lolen = 17;
         lo[lolen] = '\0';
 
-        switch (options[i].value_type) {
+        switch (opts[i].value_type)
+        {
             case o_NO_VALUE:
-                strcpy(val_type, "none"); break;
+                val_type = "    "; break;
             case o_REQUIRED_VALUE:
-                strcpy(val_type, "requ"); break;
+                val_type = "requ"; break;
             case o_OPTIONAL_VALUE:
-                strcpy(val_type, "optn"); break;
+                val_type = "optn"; break;
             case o_VALUE_LIST:
-                strcpy(val_type, "list"); break;
+                val_type = "list"; break;
             case o_ONE_CHAR_VALUE:
-                strcpy(val_type, "char"); break;
+                val_type = "char"; break;
             case o_NUMBER_VALUE:
-                strcpy(val_type, "numb"); break;
+                val_type = "numb"; break;
             case o_OPT_EQ_VALUE:
-                strcpy(val_type, "=val"); break;
+                val_type = "=val"; break;
             default:
-                strcpy(val_type, "?   ");
+                val_type = "????";
         }
 
-        if (options[i].negatable == 0)
-            strcpy(neg, "n");
-        else if (options[i].negatable == 1)
-            strcpy(neg, "y");
+        if (opts[i].negatable == 0)
+            neg = "   ";
+        else if (opts[i].negatable == 1)
+            neg = "neg";
         else
-            strcpy(neg, "?");
+            neg = "???";
 
-        sprintf(optiontext, "%s  %s   %s  %s  %s  %s", gr, sh, lo, val_type,
-          neg, options[i].name);
-        Info(slide, 0, ((char *)slide, "%s\n", optiontext));
+        Info(slide, 0, ((char *)slide, "\
+ %s  %s  %s %s %s\n",
+         sh, lo, val_type, neg, opts[i].name));
     }
 } /* end function show_options() */
 
+
 /* Print processed command line. */
 void show_commandline( args)
     char *args[];
@@ -3672,12 +3777,14 @@ extern char *getenv();
 
 char *UZ_EXP UzpVersionStr( OFT( void))
 {
-  static char vs[ 32] = "";
-  char pl_sufx[ 8] = "";
+  char pl_sufx[ 8];
   char *bt_sufx = "";
 
-  if (*vs == '\0')
+  GETGLOBALS();
+
+  if (*G.prog_vers_str == '\0')
   {
+    *pl_sufx = '\0';
     if (UZ_PATCHLEVEL != 0)
     {
       sprintf( pl_sufx, ".%d", UZ_PATCHLEVEL);
@@ -3686,11 +3793,29 @@ char *UZ_EXP UzpVersionStr( OFT( void))
     {
       bt_sufx = UZ_BETALEVEL;
     }
-    sprintf( vs, "%d.%d%s%s", UZ_MAJORVER, UZ_MINORVER, pl_sufx, bt_sufx);
+    sprintf( G.prog_vers_str, "%d.%d%s%s",
+     UZ_MAJORVER, UZ_MINORVER, pl_sufx, bt_sufx);
   }
 
-  return vs;
+  return G.prog_vers_str;
+}
+
+
+# ifndef SFX
+#  ifdef VMS
+char *UZ_EXP UzpDclStr( OFT( void))
+{
+  return USAGE_DCL_U;
+}
+
+#   ifndef NO_ZIPINFO
+char *UZ_EXP ZiDclStr( OFT( void))
+{
+  return USAGE_DCL_Z;
 }
+#   endif /* ndef NO_ZIPINFO */
+#  endif /* def VMS */
+# endif /* ifndef SFX */
 
 
 # if !defined( SFX) || defined( DIAG_SFX)
@@ -3712,10 +3837,16 @@ void show_version_info(__G)
         int numopts = 0;
 
 #  ifndef SFX
-        Info(slide, 0, ((char *)slide, LoadFarString( UnzipUsageLine1v),
-         UzpVersionStr(), UZ_VERSION_DATE, UNZIP_MAINTAINER));
+        Info(slide, 0, ((char *)slide, LoadFarString( UnzipUsageLine1),
+         UzpVersionStr(), UZ_VERSION_DATE,
+         "  Maintainer: Steven M. Schweda"));
         Info(slide, 0, ((char *)slide,
-          LoadFarString(UnzipUsageLine2v)));
+          LoadFarString(UnzipVersionLine)));
+#  ifdef BETA
+        Info( slide, 0, ((char *)slide, LoadFarString( BetaVersion),
+         "", ""));
+        Info( slide, 0, ((char *)slide, "%s", "\n"));
+#  endif
         version(__G);
 #  endif /* ndef SFX */
 
@@ -4130,12 +4261,6 @@ void show_version_info(__G)
 #define READ_REST_ARGS_VERBATIM  -8     /* 7/25/04 EG */
 
 
-/* global veriables */
-
-int enable_permute = 1;                     /* yes - return options first */
-/* 7/25/04 EG */
-int doubledash_ends_options = 1;            /* when -- what follows are not options */
-
 /* buffer for error messages (this sizing is a guess but must hold 2 paths) */
 #define OPTIONERR_BUF_SIZE (80+ 2* PATH_MAX)
 char optionerrbuf[OPTIONERR_BUF_SIZE + 1];
@@ -4171,8 +4296,8 @@ static ZCONST char Far no_arg_files_err[] = "argument files not enabled\n";
 
 
 /* copy error, option name, and option description if any to buf */
-static int optionerr(options, buf, err, optind, islong)
-  struct option_struct *options;
+static int optionerr( opts, buf, err, optind, islong)
+  ZCONST struct option_struct *opts;
   char *buf;
   ZCONST char Far *err;
   int optind;
@@ -4180,15 +4305,15 @@ static int optionerr(options, buf, err, optind, islong)
 {
   char optname[50];
 
-  if (options[optind].name && options[optind].name[0] != '\0') {
+  if (opts[optind].name && opts[optind].name[0] != '\0') {
     sprintf(optname, "'%s' (%s)",
-            LoadFarStringSmall2(islong ? options[optind].longopt
-                                       : options[optind].shortopt),
-            LoadFarStringSmall(options[optind].name));
+            LoadFarStringSmall2(islong ? opts[optind].longopt
+                                       : opts[optind].shortopt),
+            LoadFarStringSmall(opts[optind].name));
   } else {
     sprintf(optname, "'%s'",
-            LoadFarStringSmall2(islong ? options[optind].longopt
-                                       : options[optind].shortopt));
+            LoadFarStringSmall2(islong ? opts[optind].longopt
+                                       : opts[optind].shortopt));
   }
   sprintf(buf, LoadFarStringSmall(err), optname);
   return 0;
@@ -4382,7 +4507,6 @@ int insert_arg(__G__ pargs, arg, at_arg, free_args)
  * option_num so no static storage is used.  Returns the option_ID.
  *
  * parameters:
- *    option_group - either UZO for UnZip options or ZIO for ZipInfo options
  *    args         - argv array of arguments
  *    argnum       - index of current arg in args
  *    optchar      - pointer to index of next char to process.  Can be 0 or
@@ -4397,10 +4521,10 @@ int insert_arg(__G__ pargs, arg, at_arg, free_args)
  *                   value lists.
  *    depth        - recursion depth (0 at top level, 1 or more in arg files)
  */
-static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
+static unsigned long get_shortopt(__G__ opts, args, argnum, optchar,
                                   negated, value, option_num, depth)
   __GDEF
-  int option_group;
+  ZCONST struct option_struct *opts;
   ZCONST char **args;
   int argnum;
   int *optchar;
@@ -4440,10 +4564,8 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
 
   /* look for match in options */
   clen = MB_CLEN(shortopt);
-  for (op = 0; options[op].option_ID; op++) {
-    /* Only look at options in this option group */
-    if (options[op].option_group == option_group) {
-      s = options[op].shortopt;
+  for (op = 0; opts[op].option_ID; op++) {
+      s = opts[op].shortopt;
       if (s && s[0] == shortopt[0]) {
         if (s[1] == '\0' && clen == 1) {
           /* single char match */
@@ -4458,7 +4580,6 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
           }
         }
       }
-    }
   }
 
   if (match > -1) {
@@ -4468,9 +4589,9 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
     /* check for trailing dash negating option */
     if (*nextchar == '-') {
       /* negated */
-      if (options[match].negatable == o_NOT_NEGATABLE) {
-        if (options[match].value_type == o_NO_VALUE) {
-          optionerr(options, optionerrbuf, op_not_neg_err, match, 0);
+      if (opts[match].negatable == o_NOT_NEGATABLE) {
+        if (opts[match].value_type == o_NO_VALUE) {
+          optionerr( opts, optionerrbuf, op_not_neg_err, match, 0);
           if (depth > 0) {
             /* unwind */
             oWARN(optionerrbuf);
@@ -4491,13 +4612,13 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
     /* value */
     clen = MB_CLEN(arg + (*optchar));
     /* optional value, one char value, and number value must follow option */
-    if (options[match].value_type == o_ONE_CHAR_VALUE) {
+    if (opts[match].value_type == o_ONE_CHAR_VALUE) {
       /* one char value */
       if (arg[(*optchar) + clen]) {
         /* has value */
         if (MB_CLEN(arg + (*optchar) + clen) > 1) {
           /* multibyte value not allowed for now */
-          optionerr(options, optionerrbuf, oco_no_mbc_err, match, 0);
+          optionerr( opts, optionerrbuf, oco_no_mbc_err, match, 0);
           if (depth > 0) {
             /* unwind */
             oWARN(optionerrbuf);
@@ -4517,7 +4638,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
         clen = 1;
       } else {
         /* one char values require a value */
-        optionerr(options, optionerrbuf, oco_req_val_err, match, 0);
+        optionerr( opts, optionerrbuf, oco_req_val_err, match, 0);
         if (depth > 0) {
           oWARN(optionerrbuf);
           return o_ARG_FILE_ERR;
@@ -4526,7 +4647,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
           return o_BAD_ERR;
         }
       }
-    } else if (options[match].value_type == o_NUMBER_VALUE) {
+    } else if (opts[match].value_type == o_NUMBER_VALUE) {
       /* read chars until end of number */
       start = arg + (*optchar) + clen;
       if (*start == '+' || *start == '-') {
@@ -4536,7 +4657,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
       for (; isdigit(*s); MB_NEXTCHAR(s)) ;
       if (s == start) {
         /* no digits */
-        optionerr(options, optionerrbuf, num_req_val_err, match, 0);
+        optionerr( opts, optionerrbuf, num_req_val_err, match, 0);
         if (depth > 0) {
           oWARN(optionerrbuf);
           return o_ARG_FILE_ERR;
@@ -4554,7 +4675,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
       strncpy(*value, start, (int)(s - start));
       (*value)[(int)(s - start)] = '\0';
       clen = MB_CLEN(s);
-    } else if (options[match].value_type == o_OPTIONAL_VALUE) {
+    } else if (opts[match].value_type == o_OPTIONAL_VALUE) {
       /* optional value */
       /* This seemed inconsistent so now if no value attached to argument look
          to the next argument if that argument is not an option for option
@@ -4586,7 +4707,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
         strcpy(*value, args[argnum + 1]);
         *optchar = SKIP_VALUE_ARG;
       }
-    } else if (options[match].value_type == o_OPT_EQ_VALUE) {
+    } else if (opts[match].value_type == o_OPT_EQ_VALUE) {
       /* Optional value, but "=" required with detached value. */
       int have_eq = 0;
 
@@ -4657,8 +4778,8 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
         /* No "=", therefore no value. */
         *optchar = THIS_ARG_DONE;
       }
-    } else if (options[match].value_type == o_REQUIRED_VALUE ||
-               options[match].value_type == o_VALUE_LIST) {
+    } else if (opts[match].value_type == o_REQUIRED_VALUE ||
+               opts[match].value_type == o_VALUE_LIST) {
       /* see if follows option */
       if (arg[(*optchar) + clen]) {
         /* has value following option as -ovalue */
@@ -4683,14 +4804,14 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
             return o_BAD_ERR;
           }
           strcpy(*value, args[argnum + 1]);
-          if (options[match].value_type == o_VALUE_LIST) {
+          if (opts[match].value_type == o_VALUE_LIST) {
             *optchar = START_VALUE_LIST;
           } else {
             *optchar = SKIP_VALUE_ARG;
           }
         } else {
           /* no value found */
-          optionerr(options, optionerrbuf, op_req_val_err, match, 0);
+          optionerr( opts, optionerrbuf, op_req_val_err, match, 0);
           if (depth > 0) {
             oWARN(optionerrbuf);
             return o_ARG_FILE_ERR;
@@ -4703,7 +4824,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
     }
 
     *option_num = match;
-    return options[match].option_ID;
+    return opts[match].option_ID;
   }
   sprintf(optionerrbuf, LoadFarStringSmall(sh_op_not_sup_err), *shortopt);
   if (depth > 0) {
@@ -4723,10 +4844,10 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar,
  * Parameters same as for get_shortopt.
  */
 
-static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
+static unsigned long get_longopt(__G__ opts, args, argnum, optchar,
                                  negated, value, option_num, depth)
   __GDEF
-  int option_group;
+  ZCONST struct option_struct *opts;
   ZCONST char **args;
   int argnum;
   int *optchar;
@@ -4784,17 +4905,15 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
   }
 
   /* look for long option match */
-  for (op = 0; options[op].option_ID; op++) {
-    /* Only look at options in the option group */
-    if (options[op].option_group == option_group) {
-      if (options[op].longopt &&
-          strcmp(LoadFarStringSmall(options[op].longopt), longopt) == 0) {
+  for (op = 0; opts[op].option_ID; op++) {
+      if (opts[op].longopt &&
+          strcmp(LoadFarStringSmall(opts[op].longopt), longopt) == 0) {
         /* exact match */
         match = op;
         break;
       }
-      if (options[op].longopt &&
-          strncmp(LoadFarStringSmall(options[op].longopt),
+      if (opts[op].longopt &&
+          strncmp(LoadFarStringSmall(opts[op].longopt),
                   longopt, strlen(longopt)) == 0) {
         if (match > -1) {
           sprintf(optionerrbuf, LoadFarStringSmall(long_op_ambig_err),
@@ -4811,7 +4930,7 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
         }
         match = op;
       }
-    }
+
   }
 
   if (match == -1) {
@@ -4830,8 +4949,8 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
   *optchar = THIS_ARG_DONE;
 
   /* if negated then see if allowed */
-  if (*negated && options[match].negatable == o_NOT_NEGATABLE) {
-    optionerr(options, optionerrbuf, op_not_neg_err, match, 1);
+  if (*negated && opts[match].negatable == o_NOT_NEGATABLE) {
+    optionerr( opts, optionerrbuf, op_not_neg_err, match, 1);
     izu_free(arg);
     if (depth > 0) {
       /* unwind */
@@ -4843,7 +4962,7 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
     }
   }
   /* get value */
-  if (options[match].value_type == o_OPT_EQ_VALUE) {
+  if (opts[match].value_type == o_OPT_EQ_VALUE) {
     /* Optional value, but "=" required with detached value. */
     if (valuestart == NULL) {
       /* "--opt ="? */
@@ -4880,7 +4999,7 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
       }
       strcpy(*value, valuestart);
     }
-  } else if (options[match].value_type == o_OPTIONAL_VALUE) {
+  } else if (opts[match].value_type == o_OPTIONAL_VALUE) {
     /* optional value in form option=value */
     if (valuestart) {
       /* option=value */
@@ -4891,10 +5010,10 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
       }
       strcpy(*value, valuestart);
     }
-  } else if (options[match].value_type == o_REQUIRED_VALUE ||
-             options[match].value_type == o_NUMBER_VALUE ||
-             options[match].value_type == o_ONE_CHAR_VALUE ||
-             options[match].value_type == o_VALUE_LIST) {
+  } else if (opts[match].value_type == o_REQUIRED_VALUE ||
+             opts[match].value_type == o_NUMBER_VALUE ||
+             opts[match].value_type == o_ONE_CHAR_VALUE ||
+             opts[match].value_type == o_VALUE_LIST) {
     /* handle long option one char and number value as required value */
     if (valuestart) {
       /* option=value */
@@ -4915,14 +5034,14 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
         }
         /* using next arg as value */
         strcpy(*value, args[argnum + 1]);
-        if (options[match].value_type == o_VALUE_LIST) {
+        if (opts[match].value_type == o_VALUE_LIST) {
           *optchar = START_VALUE_LIST;
         } else {
           *optchar = SKIP_VALUE_ARG;
         }
       } else {
         /* no value found */
-        optionerr(options, optionerrbuf, op_req_val_err, match, 1);
+        optionerr( opts, optionerrbuf, op_req_val_err, match, 1);
         izu_free(arg);
         if (depth > 0) {
           /* unwind */
@@ -4934,11 +5053,11 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
         }
       }
     }
-  } else if (options[match].value_type == o_NO_VALUE) {
+  } else if (opts[match].value_type == o_NO_VALUE) {
     /* this option does not accept a value */
     if (valuestart) {
       /* --option=value */
-      optionerr(options, optionerrbuf, op_no_allow_val_err, match, 1);
+      optionerr( opts, optionerrbuf, op_no_allow_val_err, match, 1);
       izu_free(arg);
       if (depth > 0) {
         oWARN(optionerrbuf);
@@ -4952,7 +5071,7 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
   izu_free(arg);
 
   *option_num = match;
-  return options[match].option_ID;
+  return opts[match].option_ID;
 }
 
 
@@ -5026,7 +5145,7 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
  * Command line is read from left to right.  As get_option() finds non-option
  * arguments (arguments not starting with - and that are not values to options)
  * it moves later options and values in front of the non-option arguments.
- * This permuting is turned off by setting enable_permute to 0.  Then
+ * This permuting is turned off by setting G.permute_opts_args to 0.  Then
  * get_option() will return options and non-option arguments in the order
  * found.  Currently permuting is only done after an argument is completely
  * processed so that any value can be moved with options they go with.  All
@@ -5118,14 +5237,13 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
  *       back later.
  *
  *  non-option argument
- *       is any argument not given above.  If enable_permute is 1 then
+ *       is any argument not given above.  If G.permute_opts_args, then
  *       these are returned after all options, otherwise all options and
  *       args are returned in order.  Returns option ID o_NON_OPTION_ARG
  *       and sets value to the argument.
  *
  *
  * Arguments to get_option:
- *  int option_group       - either UZO for UnZip or ZIO for ZipInfo
  *  char ***pargs          - pointer to arg array in the argv form
  *  int *argc              - returns the current argc for args incl. args[0]
  *  int *argnum            - the index of the current argument (caller
@@ -5150,10 +5268,10 @@ static unsigned long get_longopt(__G__ option_group, args, argnum, optchar,
  *
  */
 
-unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value,
+unsigned long get_option(__G__ opts, pargs, argc, argnum, optchar, value,
                          negated, first_nonopt_arg, option_num, recursion_depth)
   __GDEF
-  int option_group;
+  ZCONST struct option_struct *opts;
   char ***pargs;
   int *argc;
   int *argnum;
@@ -5223,14 +5341,13 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
      value list */
   option_ID = 0;
   if (*option_num != o_NO_OPTION_MATCH) {
-    option_ID = options[*option_num].option_ID;
+    option_ID = opts[*option_num].option_ID;
   }
 
   /* get next option if any */
   for (;;)  {
     if (read_rest_args_verbatim) {
-      /* rest of args after "--" are non-option args if doubledash_ends_options
-         set */
+      /* Args after "--" are non-option args, if G.dashdash_ends_opts. */
       argn++;
       if (argn > argcnt || args[argn] == NULL) {
         /* done */
@@ -5249,7 +5366,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
 
     /* permute non-option args after option args so options are returned
        first */
-    } else if (enable_permute) {
+    } else if (G.permute_opts_args) {
       if (optc == SKIP_VALUE_ARG || optc == SKIP_VALUE_ARG2 ||
           optc == THIS_ARG_DONE ||
           optc == START_VALUE_LIST || optc == IN_VALUE_LIST ||
@@ -5394,7 +5511,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
         /* arg = - */
         /* treat like non-option arg */
         *option_num = o_NO_OPTION_MATCH;
-        if (enable_permute) {
+        if (G.permute_opts_args) {
           /* permute args to move all non-option args to end */
           if (first_nonoption_arg < 0) {
             first_nonoption_arg = argn;
@@ -5416,7 +5533,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
         /* long option */
         if (arg[2] == '\0') {
           /* arg = -- */
-          if (doubledash_ends_options) {
+          if (G.dashdash_ends_opts) {
             /* Now -- stops permuting and forces the rest of
                the command line to be read verbatim - 7/25/04 EG */
 
@@ -5437,7 +5554,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
           } else {
             /* treat like non-option arg */
             *option_num = o_NO_OPTION_MATCH;
-            if (enable_permute) {
+            if (G.permute_opts_args) {
               /* permute args to move all non-option args to end */
               if (first_nonoption_arg < 0) {
                 first_nonoption_arg = argn;
@@ -5457,7 +5574,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
           }
 
         } else {
-          option_ID = get_longopt(__G__ option_group, (ZCONST char **)args, argn,
+          option_ID = get_longopt(__G__ opts, (ZCONST char **)args, argn,
                                   &optc, negated,
                                   value, option_num, recursion_depth);
           if (option_ID == o_BAD_ERR) {
@@ -5471,7 +5588,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
 
       } else {
         /* short option */
-        option_ID = get_shortopt(__G__ option_group, (ZCONST char **)args, argn,
+        option_ID = get_shortopt(__G__ opts, (ZCONST char **)args, argn,
                                  &optc, negated,
                                  value, option_num, recursion_depth);
 
@@ -5491,7 +5608,7 @@ unsigned long get_option(__G__ option_group, pargs, argc, argnum, optchar, value
       }
     } else {
       /* non-option */
-      if (enable_permute) {
+      if (G.permute_opts_args) {
         /* permute args to move all non-option args to end */
         if (first_nonoption_arg < 0) {
           first_nonoption_arg = argn;
@@ -5559,9 +5676,7 @@ int arg;
 #  endif /* def CLK_TCK [else] */
 #  define U_P_NODENAME_LEN 32
 
-  static int not_first = 0;                             /* First time flag. */
-  static char u_p_nodename[ U_P_NODENAME_LEN+ 1];       /* "host::tty". */
-  static char u_p_prog_name[] = "unzip";                /* Program name. */
+  static char u_p_prog_name[] = "UnZip";                /* Program name. */
 
   struct utsname u_p_utsname;
   struct tm u_p_loc_tm;
@@ -5575,16 +5690,16 @@ int arg;
   GETGLOBALS();
 
   /* On the first time through, get the host name and tty name, and form
-   * the "host::tty" string (in u_p_nodename) for the intro line.
+   * the "host::tty" string (in G.u_p_nodename) for the intro line.
    */
-  if (not_first == 0)
+  if (G.u_p_not_first == 0)
   {
-    not_first = 1;
+    G.u_p_not_first = 1;
     /* Host name.  (Trim off any domain info.  (Needed on Tru64.)) */
     uname( &u_p_utsname);
-    strncpy( u_p_nodename, u_p_utsname.nodename, (U_P_NODENAME_LEN- 8));
-    u_p_nodename[ 24] = '\0';
-    cp = strchr( u_p_nodename, '.');
+    strncpy( G.u_p_nodename, u_p_utsname.nodename, (U_P_NODENAME_LEN- 8));
+    G.u_p_nodename[ 24] = '\0';
+    cp = strchr( G.u_p_nodename, '.');
     if (cp != NULL)
       *cp = '\0';
 
@@ -5596,9 +5711,9 @@ int arg;
       if (cp != NULL)
         tty_name += 5;
 
-      strcat( u_p_nodename, "::");
-      strncat( u_p_nodename, tty_name,
-       (U_P_NODENAME_LEN- strlen( u_p_nodename)));
+      strcat( G.u_p_nodename, "::");
+      strncat( G.u_p_nodename, tty_name,
+       (U_P_NODENAME_LEN- strlen( G.u_p_nodename)));
     }
   }
 
@@ -5616,7 +5731,7 @@ int arg;
 
   /* Put out intro line. */
   fprintf( stderr, "%s %02d:%02d:%02d %s CPU=%.2f\n",
-   u_p_nodename,
+   G.u_p_nodename,
    u_p_loc_tm.tm_hour, u_p_loc_tm.tm_min, u_p_loc_tm.tm_sec,
    u_p_prog_name,
    (stime_f+ utime_f));
diff --git a/unzip.h b/unzip.h
index d900640..f44c740 100644 (file)
--- a/unzip.h
+++ b/unzip.h
@@ -2,7 +2,7 @@
 
   unzip.h
 
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
   This header file contains the public macros and typedefs required by
   both the UnZip sources and by any application using the UnZip API.  If
@@ -751,6 +751,12 @@ int      UZ_EXP UzpFileTree        OF((char *name, cbList(callBack),
 
 unsigned UZ_EXP UzpVersion2        OF((UzpVer2 *version));
 char    *UZ_EXP UzpVersionStr      OF((void));
+# ifdef VMS
+char    *UZ_EXP UzpDclStr          OF((void));
+#  ifndef NO_ZIPINFO
+char    *UZ_EXP ZiDclStr           OF((void));
+#  endif /* ndef NO_ZIPINFO */
+# endif /* def VMS */
 int      UZ_EXP UzpValidate        OF((char *archive, int AllCodes));
 
 void     show_commandline          OF((char *args[]));
index a5a9c7f..e384832 100644 (file)
--- a/unzpriv.h
+++ b/unzpriv.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
 #ifndef __unzpriv_h   /* prevent multiple inclusions */
 #define __unzpriv_h
 
+#ifdef VMSCLI
+# include "unzvers.h"   /* Need BETA for some VMS CLI strings. */
+#endif /* def VMSCLI */
+
 /* First thing: Signal all following code that we compile UnZip utilities! */
 #ifndef UNZIP
 #  define UNZIP
@@ -1564,11 +1568,6 @@ void izu_md_check( void);
 
 /* The below is for use in the caller-provided options table */
 
-/* option groups */
-#define UZO 1   /* UnZip option */
-#define ZIO 2   /* ZipInfo option */
-
-
 /* value_type - value is always returned as a string. */
 #define o_NO_VALUE        0   /* this option does not take a value */
 #define o_REQUIRED_VALUE  1   /* this option requires a value */
@@ -1616,7 +1615,6 @@ void izu_md_check( void);
 
 /* options array is set in unzip.c */
 struct option_struct {
-  int option_group;         /* either UZO for UnZip or ZIO for ZipInfo syntax */
   char Far *shortopt;       /* pointer to short option string */
   char Far *longopt;        /* pointer to long option string */
   int  value_type;          /* from above */
@@ -1868,6 +1866,7 @@ struct file_list {
 #endif
 
 #ifndef NO_USER_PROGRESS
+# define U_P_NODENAME_LEN 32
 # ifndef VMS
 #  include <signal.h>
 # endif /* ndef VMS */
@@ -2161,6 +2160,7 @@ struct file_list {
 #define EB_UT_FL_MTIME    (1 << 0)      /* mtime present */
 #define EB_UT_FL_ATIME    (1 << 1)      /* atime present */
 #define EB_UT_FL_CTIME    (1 << 2)      /* ctime present */
+#define EB_UT_FL_TIMES    0xff /* Mask for all time flag bits. */
 
 #define EB_FLGS_OFFS      4    /* offset of flags area in generic compressed
                                   extra field blocks (BEOS, MAC, and others) */
@@ -2666,13 +2666,16 @@ typedef struct _APIDocStruct {
    int    MAIN                  OF((int argc, char **argv));
 #endif /* ndef WINDLL */
    int    unzip                 OF((__GPRO__ int argc, char **argv));
-   int    uz_opts               OF((__GPRO__ int *pargc, char ***pargv));
    int    usage                 OF((__GPRO__ int error));
+   int    uz_opts               OF((__GPRO__
+                                 ZCONST struct option_struct *opts,
+                                 int *pargc, char ***pargv));
 
 /* Command-line option function prototypes. */
 
 /* get_option() - Get the next option from args. */
-unsigned long get_option OF((__GPRO__ int option_group,
+unsigned long get_option OF((__GPRO__
+                             ZCONST struct option_struct *opts,
                              char ***pargs, int *argc, int *argnum,
                              int *optchar,
                              char **value, int *negated, int *first_nonopt_arg,
@@ -2716,6 +2719,7 @@ void     free_G_buffers          OF((__GPRO));
 int      process_file_hdr        OF((__GPRO));
 int      process_cdir_file_hdr   OF((__GPRO));
 int      process_local_file_hdr  OF((__GPRO));
+int      process_cdir_digsig     OF((__GPRO__ long *enddigsig_len_p));
 int      getZip64Data            OF((__GPRO__ ZCONST uch *ef_buf,
                                      long ef_len));
 #ifdef UNICODE_SUPPORT
@@ -2743,13 +2747,15 @@ int ef_scan_for_aes              OF((ZCONST uch *ef_buf, long ef_len,
   ---------------------------------------------------------------------------*/
 
 #ifndef NO_ZIPINFO
-int      zi_opts                 OF((__GPRO__ int *pargc, char ***pargv));
+int      zi_opts                 OF((__GPRO__
+                                  ZCONST struct option_struct *opts,
+                                  int *pargc, char ***pargv));
 void     zi_end_central          OF((__GPRO));
 int      zipinform               OF((__GPRO));
 /* static int      zi_long       OF((__GPRO__ zusz_t *pEndprev)); */
 /* static int      zi_short      OF((__GPRO)); */
 /* static char    *zi_time       OF((__GPRO__ ZCONST ulg *datetimez,
-                                     ZCONST time_t *modtimez, char *d_t_str));*/
+                                  ZCONST time_t *modtimez, char *d_t_str)); */
 #endif /* !NO_ZIPINFO */
 
 /*---------------------------------------------------------------------------
@@ -2776,7 +2782,7 @@ int      open_outfile         OF((__GPRO));                    /* also vms.c */
 int      set_zipfn_sgmnt_name OF((__GPRO__ zuvl_t sgmnt_nr));
 void     undefer_input        OF((__GPRO));
 void     defer_leftover_input OF((__GPRO));
-unsigned readbuf              OF((__GPRO__ char *buf, register unsigned len));
+unsigned readbuf              OF((__GPRO__ uch *buf, register unsigned len));
 int      readbyte             OF((__GPRO));
 int      fillinbuf            OF((__GPRO));
 int      seek_zipf            OF((__GPRO__ zoff_t abs_offset));
@@ -3550,51 +3556,65 @@ char    *GetLoadPath     OF((__GPRO));                              /* local */
 /*  Global constants  */
 /**********************/
 
-#define UNZIP_MAINTAINER "Steven M. Schweda"
-
-   extern ZCONST unsigned near mask_bits[17];
+    extern ZCONST unsigned near mask_bits[17];
 
 #ifdef EBCDIC
-   extern ZCONST uch ebcdic[];
+    extern ZCONST uch ebcdic[];
 #endif
 #ifdef IZ_ISO2OEM_ARRAY
-   extern ZCONST uch Far *iso2oem;
-   extern ZCONST uch Far iso2oem_850[];
+    extern ZCONST uch Far *iso2oem;
+    extern ZCONST uch Far iso2oem_850[];
 #endif
 #ifdef IZ_OEM2ISO_ARRAY
-   extern ZCONST uch Far *oem2iso;
-   extern ZCONST uch Far oem2iso_850[];
+    extern ZCONST uch Far *oem2iso;
+    extern ZCONST uch Far oem2iso_850[];
 #endif
 
-   extern ZCONST char Far  CentSigMsg[];
+    extern ZCONST char Far  CentSigMsg[];
 #ifndef SFX
-   extern ZCONST char Far  EndSigMsg[];
-#endif
-   extern ZCONST char Far  SeekMsg[];
-   extern ZCONST char Far  FilenameNotMatched[];
-   extern ZCONST char Far  ExclFilenameNotMatched[];
-   extern ZCONST char Far  ReportMsg[];
-   extern ZCONST char Far  ActionMsg[];
+    extern ZCONST char Far  DigSigMsg[];
+    extern ZCONST char Far  EndSigMsg[];
+#endif /* ndef SFX */
+    extern ZCONST char Far  ErrorUnexpectedEOF[];
+    extern ZCONST char Far  SeekMsg[];
+    extern ZCONST char Far  FilenameNotMatched[];
+    extern ZCONST char Far  ExclFilenameNotMatched[];
+    extern ZCONST char Far  ReportMsg[];
+    extern ZCONST char Far  ActionMsg[];
 #if (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE))
-   extern ZCONST char Far  ActionMsgw[];
+    extern ZCONST char Far  ActionMsgw[];
 #endif /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */
 
 #ifndef SFX
-   extern ZCONST char Far  Zipnfo[];
-   extern ZCONST char Far  CompiledWith[];
-#endif /* !SFX */
+    extern ZCONST char Far  Zipnfo[];
+    extern ZCONST char Far  CompiledWith[];
+#endif /* ndef SFX */
+
+#ifdef VMSCLI
+# ifdef BETA
+    extern ZCONST char BetaVersion[];
+# endif /* def BETA */
+# ifdef SFX
+    extern ZCONST char UnzipBanner[];
+# else /* def SFX */
+    extern ZCONST char UnzipUsageLine1[];
+#  ifndef NO_ZIPINFO
+    extern ZCONST char ZipInfoUsageLine1[];
+#  endif /* ndef NO_ZIPINFO */
+# endif /* def SFX [else] */
+#endif /* def VMSCLI */
 
 /* Defined in extract.c, used in os2/os2.c. */
-extern ZCONST char Far TruncEAs[];
+    extern ZCONST char Far TruncEAs[];
 /* Defined in extract.c, used in win32/win32.c. */
-extern ZCONST char Far TruncNTSD[];
+    extern ZCONST char Far TruncNTSD[];
 
 /***********************************/
 /*  Global (shared?) RTL variables */
 /***********************************/
 
 #ifdef DECLARE_ERRNO
-   extern int             errno;
+    extern int             errno;
 #endif
 
 /*---------------------------------------------------------------------
index 88e6d1f..03269a0 100644 (file)
--- a/unzvers.h
+++ b/unzvers.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
 # endif
 
 # ifdef BETA
-#  define UZ_BETALEVEL      "c20-BETA"
-#  define UZ_VERSION_DATE   "2016-03-16"        /* Internal beta version. */
+#  define UZ_BETALEVEL      "c21-BETA"
+#  define UZ_VERSION_DATE   "2017-05-15"        /* Internal beta version. */
 # else
 #  define UZ_BETALEVEL      ""
-#  define UZ_VERSION_DATE   "2016-XX-XX"        /* Official release version. */
+#  define UZ_VERSION_DATE   "2017-XX-XX"        /* Official release version. */
 #  define RELEASE
 # endif
 
@@ -38,7 +38,7 @@
 
 # define UZ_PATCHLEVEL  0
 
-# define UZ_VER_STRING  "6.1c20"        /* Sync with Version numbers! */
+# define UZ_VER_STRING  "6.1c21"        /* Sync with Version numbers! */
 
 # ifndef IZ_COMPANY_NAME
 #  define IZ_COMPANY_NAME "Info-ZIP"
index d37d6e9..1896053 100644 (file)
@@ -1,7 +1,7 @@
       INSTALL_VMS.txt -- UnZip Installation Supplement for VMS (OpenVMS)
       ==================================================================
 
-   UnZip version 6.1.  Revised: 2015-06-10.
+   UnZip version 6.1.  Revised: 2017-01-27.
 
 ------------------------------------------------------------------------
 
@@ -19,7 +19,7 @@ Info-ZIP server:
       ftp://ftp.info-zip.org/pub/infozip/vms/
 
    To unpack the UnZip source kit, choose a suitable working directory,
-and UnZip the UnZip kit there.  For example:
+and unzip the UnZip kit there.  For example:
 
       SET DEFAULT dev:[dir.unzip]       ! Some convenient directory.
       UNZIP unzip61.zip                 ! Unpack the UnZip source kit.
@@ -42,35 +42,22 @@ below.  For example:
    Advanced Encryption Standard (AES) Encryption
    ---------------------------------------------
 
-   To enable support for AES encryption, a separate IZ_AES_WG source kit
-is needed.  On the Info-ZIP FTP server, the IZ_AES_WG source kit should
-be found in:
+   All the source files needed to enable support for AES encryption are
+included in a normal UnZip source kit.  Information about AES encryption
+in Info-ZIP programs can normally be found in the file
+[.aes_wg]README_AES_WG.txt.
 
-      ftp://ftp.info-zip.org/pub/infozip/crypt/
+      For export control reasons, it may be possible to find an UnZip
+      source kit from which these files have been removed.  If the files
+      in the [.aes_wg] subdirectory are missing, then the simplest
+      solution is to fetch a complete source kit from any of the usual
+      places.  For more information if the [.aes_wg]README_AES_WG.txt
+      file is missing, it should also be available at:
 
-The latest kit should be:
-
-      ftp://ftp.info-zip.org/pub/infozip/crypt/iz_aes_wg.zip
-
-but other, older kits may also be available there.  Version
-compatibility information should be included in the IZ_AES_WG
-documentation.  The latest version of that should be:
-
-      ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
-
-It might be wise to read that before downloading any particular
-IZ_AES_WG kit.
-
-   The IZ_AES_WG kit should be unpacked in the main UnZip directory,
-where it should populate the [.aes_wg] subdirectory.  For example, if
-the proper IZ_AES_WG kit is "iz_aes_wg13.zip", then use commands like
-the following:
-
-      SET DEFAULT [.unzip61]            ! (If not already there.)
-      UNZIP [-]iz_aes_wg13.zip
+            ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt
 
    See the "Build" section, below, for details on how to build UnZip
-with AES encryption support.
+with or without AES encryption support.
 
      The IZ_AES_WG code may be too modern for VAX C.
 
@@ -91,7 +78,7 @@ bzip2 compression, or to download a different bzip2 source kit:
 
       http://antinode.info/dec/sw/bzip2.html
 
-   The UnZip builders for VMS wiil, by default, use the bzip2 source kit
+   By default, the UnZip builders for VMS will use the bzip2 source kit
 which is included in the UnZip source kit to create the required bzip2
 object library.  The builders can also use an existing bzip2 object
 library, which is supplied by the user.  For details on how to use an
@@ -173,13 +160,13 @@ like the following:
    Bzip2 Compression
    -----------------
 
-   The optional bzip2 compression method is enabled by default, and the
-required source code is included in the UnZip source kit.  By default,
-the builders will use the bzip2 source kit in the [.bzip2] subdirectory
-to build the required bzip2 object library.
+   By default, suppport for the bzip2 compression method is enabled, and
+the required source code is included in the UnZip source kit.  By
+default, the builders will use the bzip2 source kit in the [.bzip2]
+subdirectory to build the required bzip2 object library.
 
-   To disable bzip2 compression, add the appropriate option to the
-builder command line.  For example:
+   To disable it, add the appropriate option to the builder command
+line.  For example:
 
          @ [.vms]build_unzip NOIZ_BZIP2
       or:
@@ -234,15 +221,15 @@ like these:
    LZMA and PPMd Compression Methods
    ---------------------------------
 
-   The optional LZMA and PPMd compression methods (new in UnZip version
-6.1) are enabled by default, and the required source code is included
+   By default, support for the LZMA and PPMd compression methods (new in
+UnZip version 6.1) is enabled.  The required source code is included
 in the UnZip source kit.  The code used to implement these compression
 methods is generally written to newer C language standards than the base
 Info-ZIP code, so some very old compilers may be unable to build UnZip
 if these features are enabled.
 
-   To disable LZMA and/or PPMd compression, add the appropriate option
-to the builder command line.  For example:
+   To disable support for LZMA and/or PPMd compression, add the
+appropriate option to the builder command line.  For example:
 
          @ [.vms]build_unzip NOLZMA NOPPMD
       or:
@@ -253,15 +240,13 @@ to the builder command line.  For example:
    Advanced Encryption Standard (AES) Encryption
    ---------------------------------------------
 
-   By default, AES encryption is not enabled.  To enable it, first
-download and unpack the separate IZ_AES_WG source kit, as explained
-above.  With the IZ_AES_WG source kit unpacked into its [.aes_wg]
-subdirectory, add the appropriate AES_WG option to the builder command
-line.  For example:
+   By default, support for AES_WG encryption is enabled if the AES_WG
+source files are present in the [.aes_wg] subdirectory.  To disable it,
+add the appropriate option to the builder command line.  For example:
 
-         @ [.vms]build_unzip AES_WG
+         @ [.vms]build_unzip NO_AES_WG
       or:
-         MMS /DESC = [.vms] /MACRO = (AES_WG=1)
+         MMS /DESC = [.vms] /MACRO = (NO_AES_WG=1)
 
    The code used to implement AES_WG encryption is generally written to
 newer C language standards than the base Info-ZIP code, so some very old
@@ -272,9 +257,10 @@ compilers may be unable to build UnZip if this feature is enabled.
    Traditional Zip Encryption
    --------------------------
 
-   By default, Traditional Zip encryption is enabled.  To disable it,
-the C macro NO_CRYPT must be defined at build time.  This can be done by
-adding NO_CRYPT to the LOCAL_UNZIP symbol/macro.  For example:
+   By default, support for Traditional Zip encryption is enabled.  To
+disable it, the C macro NO_CRYPT must be defined at build time.  This
+can be done by adding NO_CRYPT to the LOCAL_UNZIP symbol/macro.  For
+example:
 
          LOCAL_UNZIP == "NO_CRYPT"
          @ [.vms]build_unzip
@@ -353,7 +339,7 @@ variants with different options using the same source tree.
 
       Note that if PROD=dest_dir is specified for a build, then it must
       also be specified for other builder operations, such as TEST or
-      CLEAN, which also need to know which destination directory to use.
+      CLEAN, which use the destination directory.
 
       Note that PROD=dest_dir has no effect on any automatically built
       bzip2 object library, so it's generally safer to use a pre-built
index a090f20..cb2410c 100755 (executable)
@@ -2,10 +2,10 @@ $! BUILD_UNZIP.COM
 $!
 $!     UnZip 6.1 for VMS -- DCL Build procedure.
 $!
-$!     Last revised:  2015-05-18  SMS.
+$!     Last revised:  2016-11-18  SMS.
 $!
 $!----------------------------------------------------------------------
-$! Copyright (c) 2004-2015 Info-ZIP.  All rights reserved.
+$! Copyright (c) 2004-2016 Info-ZIP.  All rights reserved.
 $!
 $! See the accompanying file LICENSE, version 2009-Jan-2 or later (the
 $! contents of which are also included in zip.h) for terms of use.  If,
@@ -136,7 +136,8 @@ $ on error then goto error
 $ on control_y then goto error
 $ OLD_VERIFY = f$verify( 0)
 $!
-$ edit := edit                  ! override customized edit commands
+$ arch = ""                     ! Prepare for early abort.
+$ edit := edit                  ! Override customized edit commands.
 $ say := write sys$output
 $!
 $! Get LOCAL_UNZIP symbol options.
@@ -153,8 +154,7 @@ $     endif
 $ endif
 $!
 $! Check for the presence of "VMSCLI" in LOCAL_UNZIP.  If yes, we will
-$! define the foreign command for "unzip" to use the executable
-$! containing the VMS CLI interface.
+$! define the foreign command for "unzip" to use the VMS CLI executable.
 $!
 $ pos_cli = f$locate( "VMSCLI", LOCAL_UNZIP)
 $ len_local_unzip = f$length( LOCAL_UNZIP)
@@ -598,7 +598,7 @@ $ libunzip_opt = "[.''dest']LIB_IZUNZIP.OPT"
 $!
 $! If DASHV was requested, then run "unzip -v" (and exit).
 $!
-$ if (dashv)
+$ if (DASHV)
 $ then
 $     mcr [.'dest']unzip -v
 $     goto error
@@ -606,7 +606,7 @@ $ endif
 $!
 $! If SLASHV was requested, then run "unzip_cli /verbose" (and exit).
 $!
-$ if (slashv)
+$ if (SLASHV)
 $ then
 $     mcr [.'dest']unzip_cli /verbose
 $     goto error
@@ -614,7 +614,7 @@ $ endif
 $!
 $! If TEST was requested, then run the basic tests (and exit).
 $!
-$ if (test)
+$ if (TEST)
 $ then
 $     @ [.vms]test_unzip.com "" [.'dest']
 $     goto error
@@ -622,7 +622,7 @@ $ endif
 $!
 $! If TEST_PPMD was requested, then run the PPMd tests (and exit).
 $!
-$ if (test_ppmd)
+$ if (TEST_PPMD)
 $ then
 $     @ [.vms]test_unzip.com "" [.'dest'] NOSFX
 $     goto error
@@ -814,6 +814,7 @@ $         say "   BZIP2 include dir: ''f$trnlnm( "incl_bzip2")'"
 $     endif
 $     say "   BZIP2 library dir: ''f$trnlnm( "lib_bzip2")'"
 $ endif
+$!
 $ if (IZ_ZLIB .nes. "")
 $ then
 $     if (MAKE_EXE)
@@ -831,6 +832,23 @@ $!
 $ if (MAKE_HELP)
 $ then
 $!
+$! Ensure that [.vms] exists at the start of a search-list SYS$DISK.
+$! (Used for UNZIP_DEF.RNH copy here, and UNZIP_CLI.HELP below.)
+$!
+$     vms_dest_dir = f$parse( "SYS$DISK:", , , "device") + "[]vms.dir"
+$     if (f$search( vms_dest_dir) .eqs "")
+$     then
+$         create /directory /log [.vms]
+$     endif
+$!
+$! Accommodate an ODS2+NFS-encoded ".RNH" source file name.
+$!
+$     if ((f$search( "[.VMS]UNZIP_DEF.RNH") .eqs. "") .and. -
+       (f$search( "[.VMS]$UNZIP_DEF.RNH") .nes. ""))
+$     then
+$         copy [.VMS]$UNZIP_DEF.RNH SYS$DISK:[.VMS]UNZIP_DEF.RNH
+$     endif
+$!
 $! Process the Unix-style help file.
 $!
 $     runoff /out = UNZIP.HLP [.VMS]UNZIP_DEF.RNH
@@ -943,10 +961,9 @@ $! Create the callable library link options file, if needed.
 $!
 $     if (LIBUNZIP .ne. 0)
 $     then
-$         def_dev_dir_orig = f$environment( "default")
 $         set default [.'dest']
 $         def_dev_dir = f$environment( "default")
-$         set default 'def_dev_dir_orig'
+$         set default [-]
 $         create /fdl = [.VMS]STREAM_LF.FDL 'libunzip_opt'
 $         open /append opt_file_lib 'libunzip_opt'
 $         write opt_file_lib "! DEFINE LIB_IZUNZIP ''def_dev_dir'"
@@ -1125,8 +1142,8 @@ $!
 $ if (MAKE_HELP)
 $ then
 $     set default [.VMS]
-$     edit /tpu /nosection /nodisplay /command = CVTHELP.TPU -
-       UNZIP_CLI.HELP
+$     edit /tpu /nosection /nodisplay /command = cvthelp.tpu -
+       'f$search( "UNZIP_CLI.HELP")' /output = SYS$DISK:[]
 $     set default [-]
 $     runoff /output = UNZIP_CLI.HLP [.VMS]UNZIP_CLI.RNH
 $ endif
@@ -1349,8 +1366,8 @@ $ then
 $!
 $     there = here- "]"+ ".''dest']"
 $!
-$!    Define the foreign command symbols.  Similar commands may be useful
-$!    in SYS$MANAGER:SYLOGIN.COM and/or users' LOGIN.COM.
+$!    Define the foreign command symbols.  Similar commands may be
+$!    useful in SYS$MANAGER:SYLOGIN.COM and/or users' LOGIN.COM.
 $!
 $     unzip   == "$''there'''unzexec'.EXE"
 $     zipinfo == "$''there'''unzexec'.EXE ""-Z"""
index e21a4a8..035d6a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
 
 #define UNZIP_INTERNAL
 #include "unzip.h"
-#ifndef TEST
-#  include "unzvers.h"  /* for VMSCLI_usage() */
-#endif /* !TEST */
 
 /* Workaround for broken header files of older DECC distributions
  * that are incompatible with the /NAMES=AS_IS qualifier. */
@@ -180,8 +177,8 @@ globalvalue CLI$_COMMA;
     if ((requested) > (reserved)) { \
         char *save_buf = (buf); \
         (reserved) += ARGBSIZE_UNIT; \
-        if (((buf) = (char *) realloc( (buf), (reserved))) == NULL) { \
-            if (save_buf != NULL) free( save_buf); \
+        if (((buf) = (char *)izu_realloc( (buf), (reserved))) == NULL) { \
+            if (save_buf != NULL)izu_free( save_buf); \
             return SS$_INSFMEM; \
         } \
     } \
@@ -417,7 +414,7 @@ vms_unzip_cmdline (int *argc_p, char ***argv_p)
     /*
      *  There will always be a new_argv[] because of the image name.
      */
-    if ((the_cmd_line = (char *) malloc(cmdl_size = ARGBSIZE_UNIT)) == NULL)
+    if ((the_cmd_line = (char *)izu_malloc(cmdl_size = ARGBSIZE_UNIT)) == NULL)
         return SS$_INSFMEM;
 
 #define UNZIP_COMMAND_NAME "unzip"
@@ -479,6 +476,17 @@ vms_unzip_cmdline (int *argc_p, char ***argv_p)
     exclude_list = ((status & 1) != 0);
 
     /*
+     * Show license text.
+     */
+#define OPT_LI   "--license"    /* "--license  Show license text. */
+
+    status = cli$present( &cli_license);
+    if (status & 1)
+    {
+        ADD_ARG( OPT_LI);
+    }
+
+    /*
      * Verbose command-line translation.
      */
     status = cli$present( &cli_verbose_command);
@@ -996,17 +1004,6 @@ vms_unzip_cmdline (int *argc_p, char ***argv_p)
         }
 
         /*
-         * Show license text.
-         */
-#define OPT_LI   "--license"    /* "--license  Show license text. */
-
-        status = cli$present( &cli_license);
-        if (status & 1)
-        {
-            ADD_ARG( OPT_LI);
-        }
-
-        /*
          * Deprecated.  Use /NAMES = [NO]DOWNCASE.
          * Make (some) names lowercase.
          * Clear any existing "-L" option with "-L-L-", then add
@@ -1811,7 +1808,7 @@ vms_unzip_cmdline (int *argc_p, char ***argv_p)
     **  We have finished collecting the strings for the argv vector,
     **  release unused space.
     */
-    if ((the_cmd_line = (char *) realloc(the_cmd_line, cmdl_len)) == NULL)
+    if ((the_cmd_line = (char *)izu_realloc(the_cmd_line, cmdl_len)) == NULL)
         return SS$_INSFMEM;
 
     /*
@@ -1902,7 +1899,7 @@ get_list (struct dsc$descriptor_s *qual, struct dsc$descriptor_d *rawtail,
         */
         if (*p_str == NULL) {
             *p_size = ARGBSIZE_UNIT;
-            if ((*p_str = (char *) malloc(*p_size)) == NULL)
+            if ((*p_str = (char *)izu_malloc(*p_size)) == NULL)
                 return SS$_INSFMEM;
             len = 0;
         } else {
@@ -1973,10 +1970,6 @@ int VMSCLI_usage(__GPRO__ int error)    /* returns PK-type error code */
 
     /* UnZipSFX Usage Guide. */
 
-    extern ZCONST char UnzipBanner[];
-#  ifdef BETA
-    extern ZCONST char BetaVersion[];
-#  endif
     int flag;
 
     if (!show_VMSCLI_usage)
@@ -1985,11 +1978,11 @@ int VMSCLI_usage(__GPRO__ int error)    /* returns PK-type error code */
     flag = (error? 1 : 0);
 
     Info(slide, flag, ((char *)slide, UnzipBanner,
-     "UnZip",
-     UzpVersionStr(),
-     UZ_VERSION_DATE,
-     UZ_VERSION_DATE));
-
+     "UnZip", UzpVersionStr(), UZ_VERSION_DATE, UZ_VERSION_DATE));
+#  ifdef BETA
+    Info( slide, flag, ((char *)slide, LoadFarString( BetaVersion),
+     "\n", ""));
+#  endif
     Info(slide, flag, ((char *)slide, "\
 \n\
 Usage: MCR %s -\n\
@@ -2064,10 +2057,6 @@ UnZip program instead of this built-in (limited) UnZipSFX self-extractor.\n\
 ));
 #  endif /* def MORE [else] */
 
-#  ifdef BETA
-    Info(slide, flag, ((char *)slide, BetaVersion, "\n", "SFX"));
-#  endif
-
     if (error)
         return PK_PARAM;
     else
@@ -2077,10 +2066,6 @@ UnZip program instead of this built-in (limited) UnZipSFX self-extractor.\n\
 
     /* Normal UnZip or ZipInfo Usage Guide. */
 
-    extern ZCONST char UnzipUsageLine1[];
-#  ifdef BETA
-    extern ZCONST char BetaVersion[];
-#  endif
     int flag;
 
     if (!show_VMSCLI_usage)
@@ -2096,16 +2081,15 @@ UnZip program instead of this built-in (limited) UnZipSFX self-extractor.\n\
     Print either ZipInfo usage or UnZip usage, depending on incantation.
   ---------------------------------------------------------------------------*/
 
-    if (uO.zipinfo_mode) {
-
+    if (uO.zipinfo_mode)
+    {
 #  ifndef NO_ZIPINFO
 
-        /* ZipInfo Usage guide. */
-
-        Info(slide, flag, ((char *)slide, "\
-ZipInfo %d.%d%d%s %s, by Info-ZIP.  Maintainer: <Apply Within>\n\n",
-          ZI_MAJORVER, ZI_MINORVER,
-          UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE));
+        /* ZipInfo Usage guide.
+         *    Compare: unzip.c: ZipInfoUsageLine1, et al.
+         */
+        Info( slide, flag, ((char *)slide, ZipInfoUsageLine1,
+          UzpVersionStr(), UZ_VERSION_DATE, ZiDclStr()));
 
         Info(slide, flag, ((char *)slide, "\
 Usage:  ZIPINFO [/zipinfo_qualifiers] [file[.zip]] [member [,...]]\n\
@@ -2141,18 +2125,19 @@ General qualifiers:\n\
 "));
 
         Info(slide, flag, ((char *)slide, "\n\
-Type 'unzip \"-Z\"' for Unix-style usage guide.\n\
-Quote member names if /MATCH=CASE=SENSITIVE (default).\n\
+Unix-style usage guide: unzip \"-Z\"\n\
+Quote archive member names if /MATCH=CASE=SENSITIVE (default).\n\
 "));
 
 #  endif /* ndef NO_ZIPINFO */
-
-    } else {   /* UnZip mode */
+    }
+    else
+    {   /* UnZip mode */
 
         /* Normal UnZip Usage Guide. */
 
         Info(slide, flag, ((char *)slide, UnzipUsageLine1,
-          UzpVersionStr(), UZ_VERSION_DATE, UNZIP_MAINTAINER));
+          UzpVersionStr(), UZ_VERSION_DATE, UzpDclStr()));
 
 #  ifdef BETA
         Info(slide, flag, ((char *)slide, BetaVersion, "", ""));
@@ -2160,17 +2145,17 @@ Quote member names if /MATCH=CASE=SENSITIVE (default).\n\
 
         Info(slide, flag, ((char *)slide, "\
 Usage: UNZIP [/unzip_qualifiers] [file[.zip]] [member [,...]]\n\
-  Default action is to extract specified (or all) members from file.zip\n\
+  Default action: Extract specified (or all) members from file.zip\n\
 %s\n",
 #  ifdef NO_ZIPINFO
-          "  (ZipInfo mode is disabled in this version.)"
+          "  (ZipInfo mode is disabled in this build.)"
 #  else
-          "  Do \"UNZIP /ZIPINFO\" for ZipInfo-mode usage."
+          "  ZipInfo-mode usage: \"UNZIP /ZIPINFO\""
 #  endif
 ));
 
         Info(slide, flag, ((char *)slide, "\
-Primary mode qualifiers (Do \"unzip -h\" for Unix-style options):\n\
+Primary mode qualifiers (For Unix-style options: \"unzip -h\"):\n\
   /COMMENT, /FRESHEN, /HELP[=EXTENDED], /LICENSE, /LIST, /PIPE, /SCREEN,\n\
   /TEST, /TIMESTAMP, /UPDATE, /VERBOSE\n\
 General qualifiers:\n\
index 1ca65c5..e3881d8 100644 (file)
@@ -2,10 +2,10 @@
 #
 #    UnZip 6.1 for VMS -- MMS (or MMK) Source Description File.
 #
-#    Last revised:  2015-05-18
+#    Last revised:  2017-01-27
 #
 #----------------------------------------------------------------------
-# Copyright (c) 2004-2015 Info-ZIP.  All rights reserved.
+# Copyright (c) 2004-2017 Info-ZIP.  All rights reserved.
 #
 # See the accompanying file LICENSE, version 2009-Jan-2 or later (the
 # contents of which are also included in zip.h) for terms of use.  If,
@@ -88,8 +88,8 @@ UNK_DEST = 1
 .ENDIF                              # __IA64__
 .ENDIF                          # __ALPHA__
 
-# AES_WG support.  Default to disabled, but the .FIRST rule will detect
-# the presence of the optional source kit, and advise accordingly.
+# AES_WG support.  Default to enabled, but the .FIRST rule will detect
+# the absence of the optional source kit, and advise/fail accordingly.
 
 # Translate NO_AES_WG to NOAES_WG.
 .IFDEF NO_AES_WG                # NO_AES_WG
@@ -99,6 +99,12 @@ NOAES_WG = 1
 .ENDIF                              # NOAES_WG
 .ENDIF                          # NO_AES_WG
 
+# Default: AES_WG.
+.IFDEF NOAES_WG                 # NOAES_WG
+.ELSE                           # NOAES_WG
+AES_WG = 1
+.ENDIF                          # NO_AES_WG
+
 # Skip AES_WG check if AES_WG is explicitly disabled.
 .IFDEF NOAES_WG                 # NOAES_WG
 .IFDEF NOCHECK_AES_WG               # NOCHECK_AES_WG
@@ -448,6 +454,9 @@ NON_VAX_CMPL = 1
           write sys$output -
            "   Optional AES_WG source kit ([.aes_wg]) not found."
        @ if (no_aes_wg_kit) then -
+          write sys$output -
+           "   To disable AES_WG support, add ""/MACRO = NO_AES_WG=1""."
+       @ if (no_aes_wg_kit) then -
           write sys$output ""
        @ if (no_aes_wg_kit) then -
           I_WILL_DIE_NOW.  /$$$$INVALID$$$$
index 05723c4..2d661dc 100644 (file)
@@ -2,7 +2,7 @@
        Ident           "03-007"
 
 !-----------------------------------------------------------------------
-! Copyright (c) 2001-2015 Info-ZIP.  All rights reserved.
+! Copyright (c) 2001-2016 Info-ZIP.  All rights reserved.
 !
 ! See the accompanying file LICENSE, version 2009-Jan-2 or later (the
 ! contents of which are also included in zip.h) for terms of use.  If,
@@ -176,6 +176,7 @@ Define Syntax INFORMATION
        Parameter       P2, Label=INFILE, VALUE(LIST), Prompt="Files to display"
 
        Qualifier       ZIPINFO, NonNegatable, DEFAULT
+       Qualifier       LICENSE, NonNegatable
        Qualifier       LONG, Negatable
        Qualifier       MEDIUM, Negatable
        Qualifier       ONE_LINE, Negatable
index bb9d414..4b71726 100644 (file)
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -1354,16 +1354,18 @@ static int create_qio_output(__GPRO)
 #ifdef NAML$C_MAXRSS
 
         /* Enable fancy name characters.  Note that "fancy" here does
-           not include Unicode, for which there's no support elsewhere.
-        */
+         * not include Unicode, for which there's no support elsewhere.
+         * 2017-03-14 SMS.  Added fib$v_percent_literal to handle "%".
+         */
         pka_fib.fib$v_names_8bit = 1;
+        pka_fib.fib$v_percent_literal = 1;
         pka_fib.fib$b_name_format_in = FIB$C_ISL1;
 
         /* ODS5 Extended names used as input to QIO have peculiar
-           encoding (perhaps to minimize storage?), so the special
-           filesys_name result (typically containing fewer carets) must
-           be used here.
-        */
+         * encoding (perhaps to minimize storage?), so the special
+         * filesys_name result (typically containing fewer carets) must
+         * be used here.
+         */
         pka_fnam.dsc$a_pointer = nam.naml$l_filesys_name;
         pka_fnam.dsc$w_length = nam.naml$l_filesys_name_size;
 
@@ -1824,7 +1826,7 @@ static int find_vms_attrs(__GPRO__ int set_date_time)
                     Info(slide, 0, ((char *)slide,
                          " version made by %s ]\n", verbuf));
                 }
-                free(vers);
+                izu_free(vers);
 #endif /* CHECK_VERSIONS */
             } else {
                 Info(slide, 1, ((char *)slide,
@@ -1949,21 +1951,21 @@ static void free_up()
     /*
      * Free up all allocated XABs.
      */
-    if (xabdat != NULL) free(xabdat);
-    if (xabpro != NULL) free(xabpro);
-    if (xabrdt != NULL) free(xabrdt);
-    if (xabfhc != NULL) free(xabfhc);
+    if (xabdat != NULL) izu_free(xabdat);
+    if (xabpro != NULL) izu_free(xabpro);
+    if (xabrdt != NULL) izu_free(xabrdt);
+    if (xabfhc != NULL) izu_free(xabfhc);
     while (first_xab != NULL)
     {
         struct XAB *x;
 
         x = (struct XAB *) first_xab->xab$l_nxt;
-        free(first_xab);
+        izu_free(first_xab);
         first_xab = x;
     }
     /* Free FAB storage, if not the static one. */
     if (outfab != NULL && outfab != &fileblk)
-        free(outfab);
+        izu_free(outfab);
 }
 
 
@@ -2817,7 +2819,7 @@ static int _close_rms(__GPRO)
             if (QCOND2)
             {
                 /* Link text storage. */
-                char* link_target = malloc(ucsize + 1);
+                char* link_target = izu_malloc( ucsize + 1);
 
                 if (link_target == NULL)
                 {
@@ -2844,7 +2846,7 @@ static int _close_rms(__GPRO)
                           FnFilter1(link_target)));
                     }
 
-                    free(link_target);
+                    izu_free(link_target);
                 }
             }
         }
@@ -2870,7 +2872,7 @@ static int _close_rms(__GPRO)
             }
             else
             {
-                if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize))
+                if ((slnk_entry = (slinkentry *)izu_malloc( slnk_entrysize))
                     == NULL) {
                     Info(slide, 0x201, ((char *)slide,
                       "warning:  symbolic link (%s) failed, no mem\n",
@@ -2895,7 +2897,7 @@ static int _close_rms(__GPRO)
                         Info(slide, 0x201, ((char *)slide,
                           "warning:  error reading symlink text (rms): %s\n",
                           strerror(EVMSERR, status)));
-                        free(slnk_entry);
+                        izu_free(slnk_entry);
                         retcode = PK_DISK;
                     }
                     else
@@ -3029,7 +3031,7 @@ static int _close_qio(__GPRO)
         extent ucsize = (extent)G.lrec.ucsize;
         char *link_target;   /* Link text storage. */
 
-        if ((link_target = malloc(ucsize + 1)) == NULL)
+        if ((link_target = izu_malloc( ucsize + 1)) == NULL)
         {
             Info(slide, 0x201, ((char *)slide,
               "warning:  cannot show symlink (%s) target, no mem\n",
@@ -3075,7 +3077,7 @@ static int _close_qio(__GPRO)
                   FnFilter1(link_target)));
             }
 
-            free(link_target);
+            izu_free(link_target);
 
         }
     }
@@ -3192,7 +3194,7 @@ int defer_dir_attribs(__G__ pd)
      */
     fnlen = strlen(G.filename);
     xlen = G.lrec.extra_field_length;
-    d_entry = (vmsdirattr *) malloc(sizeof(vmsdirattr) + fnlen + xlen);
+    d_entry = (vmsdirattr *)izu_malloc( sizeof(vmsdirattr) + fnlen + xlen);
     *pd = (direntry *) d_entry;
     if (d_entry == (vmsdirattr *) NULL)
     {
@@ -3465,16 +3467,18 @@ int set_direc_attribs(__G__ d)
 # ifdef NAML$C_MAXRSS
 
     /* Enable fancy name characters.  Note that "fancy" here does
-       not include Unicode, for which there's no support elsewhere.
-    */
+     * not include Unicode, for which there's no support elsewhere.
+     * 2017-03-14 SMS.  Added fib$v_percent_literal to handle "%".
+     */
     pka_fib.fib$v_names_8bit = 1;
+    pka_fib.fib$v_percent_literal = 1;
     pka_fib.fib$b_name_format_in = FIB$C_ISL1;
 
     /* ODS5 Extended names used as input to QIO have peculiar
-       encoding (perhaps to minimize storage?), so the special
-       filesys_name result (typically containing fewer carets) must
-       be used here.
-    */
+     * encoding (perhaps to minimize storage?), so the special
+     * filesys_name result (typically containing fewer carets) must
+     * be used here.
+     */
     pka_fnam.dsc$a_pointer = nam.naml$l_filesys_name;
     pka_fnam.dsc$w_length = nam.naml$l_filesys_name_size;
 
@@ -3586,7 +3590,7 @@ int set_direc_attribs(__G__ d)
     sys$dassgn(pka_devchn);
 cleanup_exit:
     free_up();                          /* Free FAB, XAB storage. */
-    free(d);                            /* Free directory attribute storage. */
+    izu_free(d);                        /* Free directory attribute storage. */
     G.extra_field = sav_ef_ptr;         /* Restore original pointer. */
     return retcode;
 } /* end function set_direc_attribs() */
@@ -3804,16 +3808,18 @@ int stamp_file(fname, modtime)
 # ifdef NAML$C_MAXRSS
 
     /* Enable fancy name characters.  Note that "fancy" here does
-       not include Unicode, for which there's no support elsewhere.
-    */
+     * not include Unicode, for which there's no support elsewhere.
+     * 2017-03-14 SMS.  Added fib$v_percent_literal to handle "%".
+     */
     pka_fib.fib$v_names_8bit = 1;
+    pka_fib.fib$v_percent_literal = 1;
     pka_fib.fib$b_name_format_in = FIB$C_ISL1;
 
     /* ODS5 Extended names used as input to QIO have peculiar
-       encoding (perhaps to minimize storage?), so the special
-       filesys_name result (typically containing fewer carets) must
-       be used here.
-    */
+     * encoding (perhaps to minimize storage?), so the special
+     * filesys_name result (typically containing fewer carets) must
+     * be used here.
+     */
     pka_fnam.dsc$a_pointer = nam.naml$l_filesys_name;
     pka_fnam.dsc$w_length = nam.naml$l_filesys_name_size;
 
index 73d013a..7430b37 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 19998ff..14fed04 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 971ee66..c282100 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 1538d32..4a9c5de 100644 (file)
@@ -1,7 +1,7 @@
 ;===========================================================================
-; Copyright (c) 1990-2006 Info-ZIP.  All rights reserved.
+; Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 ;
-; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; See the accompanying file LICENSE, version 2009-Jan-02 or later
 ; (the contents of which are also included in zip.h) for terms of use.
 ; If, for some reason, all these files are missing, the Info-ZIP license
 ; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9e0fd30..ecab67f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in zip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index fe0b9de..c97aea3 100755 (executable)
@@ -1,9 +1,8 @@
 @echo off
-
 rem #    UnZip test script (Windows command).
 rem #
 rem #-----------------------------------------------------------------------
-rem # Copyright (c) 2012-2013 Info-ZIP.  All rights reserved.
+rem # Copyright (c) 2012-2016 Info-ZIP.  All rights reserved.
 rem #
 rem # See the accompanying file LICENSE, version 2009-Jan-2 or later (the
 rem # contents of which are also included in zip.h) for terms of use.  If,
@@ -11,21 +10,37 @@ rem # for some reason, all these files are missing, the Info-ZIP license
 rem # may also be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
 rem #-----------------------------------------------------------------------
 rem #
+rem # Command-line arguments:
+rem #
 rem #    %1 = test archive name.  Default: testmake.zip
 rem #    %2 = program directory (relative).  Default: .
-rem #    %3 = non-null to skip funzip and SFX tests.
+rem #    %3 = Specific UnZip program name to test.  Default: Test unzip,
+rem #         funzip, and unzipsfx.  (Specifying a specific program
+rem #         skips the funzip and unzipsfx tests.)
+rem #
+rem # History:
+rem #
+rem #    2016-06-15  SMS.  Changed %3 from a non-null token to a
+rem #    specific UnZip program name.
+rem #    Changed to leave the temporary test directory
+rem #    ("test_dir_%RANDOM%") intact if the test-fail count is
+rem #    positive.
 rem #
 rem #    2013-06-12  SMS.  New.  Adapted from unix/test_unzip.sh
 rem #
 rem # Typical usage:
 rem #    win32\test_unzip.cmd testmake.zip win32\vc10\Debug
-rem #    win32\test_unzip.cmd testmake_ppmd.zip win32\vc10\Debug NOFUNSFX
+rem #    win32\test_unzip.cmd testmake_ppmd.zip win32\vc10\Debug unzip
+rem #    win32\test_unzip.cmd testmake.zip windll\vc10\Debug unzipstb
+rem #    win32\test_unzip.cmd testmake.zip winlib\vc10\Debug izunzip_example
 
 setlocal enabledelayedexpansion
 
 set t_a=testmake.zip
 set prd=.
 
+rem # Test archive name.
+
 if "%1" == "" (
     set test_archive=%t_a%
 ) else (
@@ -36,6 +51,8 @@ if "%1" == "" (
     )
 )
 
+rem # Program directory.
+
 if "%2" == "" (
     set prod=%prd%
 ) else (
@@ -46,23 +63,27 @@ if "%2" == "" (
     )
 )
 
+rem # Program list and UnZip program name.
+
+if "%3" == "" (
+    set program_list=unzip funzip unzipsfx
+    set unzip_prog=unzip
+) else (
+    set program_list=%3
+    set unzip_prog=%3
+)
+
 set /a pass=0
 set /a fail=0
 
-rem # Clean environment.
+rem # Arrange a clean test environment.
 
 set UNZIP=
 set UNZIPOPT=
 set ZIPINFO=
 set ZIPINFOOPT=
 
-rem # Check for existence of expected programs.
-
-if "%3" == "" (
-    set program_list=funzip unzip unzipsfx
-) else (
-    set program_list=unzip
-)
+rem # Check for existence of expected program(s).
 
 for %%p in (%program_list%) do (
     set prog=%%p
@@ -95,9 +116,9 @@ set member_2=testmake.zipinfo
 rem # Test simple UnZip extraction.
 
 echo.
-echo ^>^>^> UnZip extraction test...'
+echo ^>^>^> UnZip extraction test...
 
-..\%prod%\unzip -b ..\%test_archive% %member_1%
+..\%prod%\%unzip_prog% -b ..\%test_archive% %member_1%
 set status=!ERRORLEVEL!
 
 if not !status! == 0 (
@@ -122,7 +143,7 @@ rem # (Use "-a" to get proper local line endings for "-Z" test below.)
 echo.
 echo ^>^>^> UnZip "-x" extraction test...
 
-..\%prod%\unzip -ao ..\%test_archive% -x %member_1%
+..\%prod%\%unzip_prog% -ao ..\%test_archive% -x %member_1%
 set status=!ERRORLEVEL!
 
 if not !status! == 0 (
@@ -147,7 +168,7 @@ echo ^>^>^> UnZip "-d dest_dir" extraction test...
 
 if exist %member_1% (
 
-    ..\%prod%\unzip -bo ..\%test_archive% -d dest_dir %member_1%
+    ..\%prod%\%unzip_prog% -bo ..\%test_archive% -d dest_dir %member_1%
     set status=!ERRORLEVEL!
 
     if not !status! == 0 (
@@ -173,7 +194,7 @@ if exist %member_1% (
         )
     )
 ) else (
-    echo ^>^>^> Fail: The UnZip "-d" test relies on success in the UnZip "-x" test."
+    echo ^>^>^> Fail: The UnZip "-d" test relies on success in the UnZip "-x" test.
     set /a fail=%fail% + 1
 )
 
@@ -182,7 +203,7 @@ rem # Test UnZip extraction with "-o" option.
 echo.
 echo ^>^>^> UnZip "-o" extraction test...
 
-..\%prod%\unzip -bo ..\%test_archive% %member_1%
+..\%prod%\%unzip_prog% -bo ..\%test_archive% %member_1%
 set status=!ERRORLEVEL!
 
 if not !status! == 0 (
@@ -206,7 +227,7 @@ echo ^>^>^> ZipInfo ("unzip -Z") test...
 if exist %member_2% (
 
     cd ..
-    %prod%\unzip -Z -mc- %test_archive% > %tmp_dir%\testmake.unzip-Z
+    %prod%\%unzip_prog% -Z -mc- %test_archive% > %tmp_dir%\testmake.unzip-Z
     set status=!ERRORLEVEL!
     cd %tmp_dir%
 
@@ -223,7 +244,7 @@ if exist %member_2% (
             echo ^>^>^> Pass.
             set /a pass=%pass% + 1
         ) else (
-            echo ^>^>^> Fail: ZipInfo output mismatch."
+            echo ^>^>^> Fail: ZipInfo output mismatch.
 
 echo ^>^>^> ###   ZipInfo output does not match the expected output.
 echo ^>^>^> ###   ^(If the only difference is in the date-time values, then this may
@@ -233,7 +254,7 @@ echo ^>^>^> ###   be caused by a time-zone difference, which may not be importan
         )
     )
 ) else (
-    echo ^>^>^> Fail: The ZipInfo test relies on success in the UnZip test."
+    echo ^>^>^> Fail: The ZipInfo test relies on success in the UnZip test.
     set /a fail=%fail% + 1
 )
 
@@ -280,7 +301,6 @@ if "%3" == "" (
     )
 )
 
-
 rem # Test UnZipSFX.
 
 if "%3" == "" (
@@ -310,7 +330,7 @@ if "%3" == "" (
                     echo ^>^>^> Pass.
                     set /a pass=%pass% + 1
                 ) else (
-                    echo ^>^>^> Fail: Extracted file contents mismatch."
+                    echo ^>^>^> Fail: Extracted file contents mismatch.
                     set /a fail=%fail% + 1
                 )
             ) else (
@@ -324,7 +344,7 @@ if "%3" == "" (
     )
 )
 
-rem Expected results.
+rem Expected results.
 
 set fail_expected=0
 if "%3" == "" (
@@ -333,7 +353,7 @@ if "%3" == "" (
     set pass_expected=5
 )
 
-rem Result summary.
+rem Result summary.
 
 echo.
 echo ^>^>^> Test Results:   Pass: %pass%, Fail: %fail%
@@ -345,10 +365,17 @@ if not %exit_status% == 0 (
 )
 echo.
 
-rem # Clean up.
+rem # Clean up.  Delete the temporary test directory, unless a test
+rem # fails unexpectedly.
 
 cd %dir_orig%
-if exist %tmp_dir% rmdir /q /s %tmp_dir%
+if %fail% == %fail_expected% (
+    if exist %tmp_dir% rmdir /q /s %tmp_dir%
+) else (
+    echo ^>^>^> ###   See files in: %tmp_dir%
+    echo.
+)
+
 
 rem # Exit with an appropriate status value.
 
index d1c59e1..551ee60 100644 (file)
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
     <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
     <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
index a372e45..8a33c31 100644 (file)
@@ -70,7 +70,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
     <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <LibraryPath>$(SolutionDir)$(Platform)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
@@ -80,7 +80,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <LibraryPath>$(SolutionDir)$(Platform)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -88,7 +88,7 @@
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
index adb53f3..37cb002 100644 (file)
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
     <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\bzip2;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
index 0ce4829..521a6e7 100644 (file)
@@ -4577,7 +4577,6 @@ int zstat_win32w(__W32STAT_GLOBALS__ const wchar_t *pathw, z_stat *buf)
 #    ifdef Tracing
             char *path = wchar_to_local_string((wchar_t *)pathw, G.unicode_escape_all);
             Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
-            
 
        FnFilter1(path)));
             izu_free(path);
index 6af3c5d..b75b6cb 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 313c1e0..2c890f2 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2012 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index b7aef9d..b7b22e5 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index fbf59f0..007bc33 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2003 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 9d20b83..451d67d 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2003 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 94d7834..be2912b 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 64de0f8..30fc8bc 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2007-Mar-04 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 4f37677..b9b5aa7 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 56cf6b8..0260365 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -77,25 +77,30 @@ int main(int argc, char *argv[])
 
     pVersion = UzpVersion();
 
-    printf("UnZip DLL example: checking version numbers (DLL is dated %s)\n",
+    fprintf( stderr,
+      "UnZip DLL example: checking version numbers (DLL is dated %s)\n",
       pVersion->date);
-    printf("   UnZip versions:    expecting %u.%u%u, using %u.%u%u%s\n",
+    fprintf( stderr,
+      "   UnZip versions:    expecting %u.%u%u, using %u.%u%u%s\n",
       UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, pVersion->unzip.vmajor,
       pVersion->unzip.vminor, pVersion->unzip.patchlevel, pVersion->betalevel);
-    printf("   ZipInfo versions:  expecting %u.%u%u, using %u.%u%u\n",
+    fprintf( stderr,
+      "   ZipInfo versions:  expecting %u.%u%u, using %u.%u%u\n",
       ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, pVersion->zipinfo.vmajor,
       pVersion->zipinfo.vminor, pVersion->zipinfo.patchlevel);
 
 /*
     D2_M*VER and os2dll.* are obsolete, though retained for compatibility:
 
-    printf("   OS2 DLL versions:  expecting %u.%u%u, using %u.%u%u\n",
+    fprintf( stderr,
+      "   OS2 DLL versions:  expecting %u.%u%u, using %u.%u%u\n",
       D2_MAJORVER, D2_MINORVER, D2_PATCHLEVEL, pVersion->os2dll.vmajor,
       pVersion->os2dll.vminor, pVersion->os2dll.patchlevel);
  */
 
     if (pVersion->flag & 2)
-        printf("   using zlib version %s\n", pVersion->zlib_version);
+        fprintf( stderr,
+          "   using zlib version %s\n", pVersion->zlib_version);
 
     /* This example code only uses the dll calls UzpVersion() and
      * UzpMain().  The APIs for these two calls have maintained backward
@@ -115,7 +120,8 @@ int main(int argc, char *argv[])
           )
          ) )
     {
-        printf("  aborting because of too old UnZip DLL version!\n");
+        fprintf( stderr,
+          "  aborting because of too old UnZip DLL version!\n");
         return -1;
     }
 
@@ -146,7 +152,7 @@ int main(int argc, char *argv[])
 #  define UZ_API_COMP_REVIS             UZ_GENAPI_COMP_REVIS
 # endif /* def WINDLL [else] */
 #endif /* def OS2DLL [else] */
-        printf(
+        fprintf( stderr,
           "   UnZip API version: can handle <= %u.%u%u, DLL supplies %u.%u%u\n",
           UZ_API_COMP_MAJOR, UZ_API_COMP_MINOR, UZ_API_COMP_REVIS,
           pVersion->dllapimin.vmajor, pVersion->dllapimin.vminor,
@@ -160,11 +166,12 @@ int main(int argc, char *argv[])
               )
              ) )
         {
-            printf("  aborting because of unsupported dll api version!\n");
+            fprintf( stderr,
+              "  aborting because of unsupported dll api version!\n");
             return -1;
         }
     }
-    printf("\n");
+    fprintf( stderr, "\n");
 
     /* Call the UnZip entry point function, UzpMainI(), passing it an
      * UnZip command expressed as an argument vector.
index f4cefa6..c270cb6 100644 (file)
@@ -93,7 +93,7 @@
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
index a2ccacc..cab7316 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2003 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
diff --git a/winlib/vc10/izunzip_example/izunzip_example.vcxproj b/winlib/vc10/izunzip_example/izunzip_example.vcxproj
new file mode 100644 (file)
index 0000000..fcdaa59
--- /dev/null
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\libiz\izunzip_example.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\aes_wg\fileenc.h" />
+    <ClInclude Include="..\..\..\bzip2\bzlib.h" />
+    <ClInclude Include="..\..\..\globals.h" />
+    <ClInclude Include="..\..\..\szip\LzmaDec.h" />
+    <ClInclude Include="..\..\..\szip\Ppmd8.h" />
+    <ClInclude Include="..\..\..\szip\Types.h" />
+    <ClInclude Include="..\..\..\unzip.h" />
+    <ClInclude Include="..\..\..\unzpriv.h" />
+    <ClInclude Include="..\..\..\unzvers.h" />
+    <ClInclude Include="..\..\..\win32\w32cfg.h" />
+    <ClInclude Include="..\..\decs.h" />
+    <ClInclude Include="..\..\structs.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>izunzip_example</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>..\..\..;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>..\..\..;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(Platform)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(Platform)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/winlib/vc10/izunzip_example/izunzip_example.vcxproj.filters b/winlib/vc10/izunzip_example/izunzip_example.vcxproj.filters
new file mode 100644 (file)
index 0000000..331b109
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\libiz\izunzip_example.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\unzip.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\fileenc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\bzip2\bzlib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\globals.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\LzmaDec.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\Ppmd8.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\Types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\unzpriv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\unzvers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\win32\w32cfg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\decs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\structs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
diff --git a/winlib/vc10/libbz2/libbz2.vcxproj b/winlib/vc10/libbz2/libbz2.vcxproj
new file mode 100644 (file)
index 0000000..b7d1a21
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8691B0CB-E458-427F-9A82-17EA1910D7B6}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>libbz2</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\bzip2\bzlib.h" />
+    <ClInclude Include="..\..\..\bzip2\bzlib_private.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\bzip2\blocksort.c" />
+    <ClCompile Include="..\..\..\bzip2\bzlib.c" />
+    <ClCompile Include="..\..\..\bzip2\compress.c" />
+    <ClCompile Include="..\..\..\bzip2\crctable.c" />
+    <ClCompile Include="..\..\..\bzip2\decompress.c" />
+    <ClCompile Include="..\..\..\bzip2\huffman.c" />
+    <ClCompile Include="..\..\..\bzip2\randtable.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/winlib/vc10/libbz2/libbz2.vcxproj.filters b/winlib/vc10/libbz2/libbz2.vcxproj.filters
new file mode 100644 (file)
index 0000000..25e0678
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\bzip2\bzlib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\bzip2\bzlib_private.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\bzip2\blocksort.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\bzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\crctable.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\decompress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\huffman.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\bzip2\randtable.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
diff --git a/winlib/vc10/winlib.sln b/winlib/vc10/winlib.sln
new file mode 100644 (file)
index 0000000..bac9caa
--- /dev/null
@@ -0,0 +1,50 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winlib", "winlib\winlib.vcxproj", "{EA06B1B7-74D7-465F-9B97-624FFFE4EABE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "izunzip_example", "izunzip_example\izunzip_example.vcxproj", "{AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}"
+       ProjectSection(ProjectDependencies) = postProject
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE} = {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6} = {8691B0CB-E458-427F-9A82-17EA1910D7B6}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbz2", "libbz2\libbz2.vcxproj", "{8691B0CB-E458-427F-9A82-17EA1910D7B6}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Debug|x64 = Debug|x64
+               Release|Win32 = Release|Win32
+               Release|x64 = Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Debug|Win32.ActiveCfg = Debug|Win32
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Debug|Win32.Build.0 = Debug|Win32
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Debug|x64.ActiveCfg = Debug|x64
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Debug|x64.Build.0 = Debug|x64
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Release|Win32.ActiveCfg = Release|Win32
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Release|Win32.Build.0 = Release|Win32
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Release|x64.ActiveCfg = Release|x64
+               {EA06B1B7-74D7-465F-9B97-624FFFE4EABE}.Release|x64.Build.0 = Release|x64
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Debug|Win32.ActiveCfg = Debug|Win32
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Debug|Win32.Build.0 = Debug|Win32
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Debug|x64.ActiveCfg = Debug|x64
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Debug|x64.Build.0 = Debug|x64
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Release|Win32.ActiveCfg = Release|Win32
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Release|Win32.Build.0 = Release|Win32
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Release|x64.ActiveCfg = Release|x64
+               {AA9EDDD5-7CA2-466D-9732-ACE70DAF8884}.Release|x64.Build.0 = Release|x64
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Debug|Win32.ActiveCfg = Debug|Win32
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Debug|Win32.Build.0 = Debug|Win32
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Debug|x64.ActiveCfg = Debug|x64
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Debug|x64.Build.0 = Debug|x64
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Release|Win32.ActiveCfg = Release|Win32
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Release|Win32.Build.0 = Release|Win32
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Release|x64.ActiveCfg = Release|x64
+               {8691B0CB-E458-427F-9A82-17EA1910D7B6}.Release|x64.Build.0 = Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/winlib/vc10/winlib/winlib.vcxproj b/winlib/vc10/winlib/winlib.vcxproj
new file mode 100644 (file)
index 0000000..0a58429
--- /dev/null
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{EA06B1B7-74D7-465F-9B97-624FFFE4EABE}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>winlib</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IncludePath>..\..\..;..\..\..\bzip2;$(IncludePath)</IncludePath>
+    <TargetName>unzip32</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IncludePath>..\..\..;..\..\..\bzip2;$(IncludePath)</IncludePath>
+    <TargetName>unzip32</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IncludePath>..\..\..;..\..\..\bzip2;$(IncludePath)</IncludePath>
+    <TargetName>unzip32</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IncludePath>..\..\..;..\..\..\bzip2;$(IncludePath)</IncludePath>
+    <TargetName>unzip32</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;DLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;DLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+     
+<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;DLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;DLL;ASM_CRC;BZIP2_SUPPORT;CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\api.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\crypt.c" />
+    <ClCompile Include="..\..\..\envargs.c" />
+    <ClCompile Include="..\..\..\explode.c" />
+    <ClCompile Include="..\..\..\extract.c" />
+    <ClCompile Include="..\..\..\fileio.c" />
+    <ClCompile Include="..\..\..\globals.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\list.c" />
+    <ClCompile Include="..\..\..\match.c" />
+    <ClCompile Include="..\..\..\process.c" />
+    <ClCompile Include="..\..\..\ubz2err.c" />
+    <ClCompile Include="..\..\..\unreduce.c" />
+    <ClCompile Include="..\..\..\unshrink.c" />
+    <ClCompile Include="..\..\..\unzip.c" />
+    <ClCompile Include="..\..\..\win32\nt.c" />
+    <ClCompile Include="..\..\..\win32\win32.c" />
+    <ClCompile Include="..\..\..\win32\win32i64.c" />
+    <ClCompile Include="..\..\..\wrap\aescrypt.c" />
+    <ClCompile Include="..\..\..\wrap\aeskey.c" />
+    <ClCompile Include="..\..\..\wrap\aestab.c" />
+    <ClCompile Include="..\..\..\wrap\crc_i386.c" />
+    <ClCompile Include="..\..\..\wrap\fileenc.c" />
+    <ClCompile Include="..\..\..\wrap\hmac.c" />
+    <ClCompile Include="..\..\..\wrap\LzFind.c" />
+    <ClCompile Include="..\..\..\wrap\LzmaDec.c" />
+    <ClCompile Include="..\..\..\wrap\Ppmd8.c" />
+    <ClCompile Include="..\..\..\wrap\Ppmd8Dec.c" />
+    <ClCompile Include="..\..\..\wrap\prng.c" />
+    <ClCompile Include="..\..\..\wrap\pwd2key.c" />
+    <ClCompile Include="..\..\..\wrap\sha1.c" />
+    <ClCompile Include="..\..\..\zipinfo.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\windll32.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\aes_wg\aes.h" />
+    <ClInclude Include="..\..\..\aes_wg\aesopt.h" />
+    <ClInclude Include="..\..\..\aes_wg\brg_endian.h" />
+    <ClInclude Include="..\..\..\aes_wg\fileenc.h" />
+    <ClInclude Include="..\..\..\aes_wg\hmac.h" />
+    <ClInclude Include="..\..\..\aes_wg\iz_aes_wg.h" />
+    <ClInclude Include="..\..\..\aes_wg\prng.h" />
+    <ClInclude Include="..\..\..\aes_wg\pwd2key.h" />
+    <ClInclude Include="..\..\..\aes_wg\sha1.h" />
+    <ClInclude Include="..\..\..\api.h" />
+    <ClInclude Include="..\..\..\bzip2\bzlib.h" />
+    <ClInclude Include="..\..\..\consts.h" />
+    <ClInclude Include="..\..\..\crc32.h" />
+    <ClInclude Include="..\..\..\crypt.h" />
+    <ClInclude Include="..\..\..\ebcdic.h" />
+    <ClInclude Include="..\..\..\globals.h" />
+    <ClInclude Include="..\..\..\inflate.h" />
+    <ClInclude Include="..\..\..\szip\CpuArch.h" />
+    <ClInclude Include="..\..\..\szip\LzFind.h" />
+    <ClInclude Include="..\..\..\szip\LzHash.h" />
+    <ClInclude Include="..\..\..\szip\LzmaDec.h" />
+    <ClInclude Include="..\..\..\szip\Ppmd.h" />
+    <ClInclude Include="..\..\..\szip\Ppmd8.h" />
+    <ClInclude Include="..\..\..\szip\SzVersion.h" />
+    <ClInclude Include="..\..\..\szip\Types.h" />
+    <ClInclude Include="..\..\..\ttyio.h" />
+    <ClInclude Include="..\..\..\unzip.h" />
+    <ClInclude Include="..\..\..\unzpriv.h" />
+    <ClInclude Include="..\..\..\unzvers.h" />
+    <ClInclude Include="..\..\..\win32\nt.h" />
+    <ClInclude Include="..\..\..\win32\rsxntwin.h" />
+    <ClInclude Include="..\..\..\win32\w32cfg.h" />
+    <ClInclude Include="..\..\..\zip.h" />
+    <ClInclude Include="..\..\decs.h" />
+    <ClInclude Include="..\..\structs.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/winlib/vc10/winlib/winlib.vcxproj.filters b/winlib/vc10/winlib/winlib.vcxproj.filters
new file mode 100644 (file)
index 0000000..cd27055
--- /dev/null
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\api.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\crc32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\crypt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\aescrypt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\aeskey.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\aestab.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\crc_i386.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\fileenc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\hmac.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\LzFind.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\LzmaDec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\Ppmd8.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\Ppmd8Dec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\prng.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\pwd2key.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\wrap\sha1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\envargs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\explode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\extract.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\fileio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\globals.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\list.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\match.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\process.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\ubz2err.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\unreduce.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\unshrink.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\unzip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zipinfo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\win32\nt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\win32\win32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\win32\win32i64.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\aes_wg\aes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\aesopt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\brg_endian.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\fileenc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\hmac.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\iz_aes_wg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\prng.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\pwd2key.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\aes_wg\sha1.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\bzip2\bzlib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\api.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\consts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\crc32.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\crypt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\ebcdic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\globals.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\inflate.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\ttyio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\LzFind.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\LzHash.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\LzmaDec.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\Ppmd8.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\Ppmd.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\SzVersion.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\Types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\win32\nt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\win32\rsxntwin.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\win32\w32cfg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\decs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\structs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\szip\CpuArch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\unzip.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\unzpriv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\unzvers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\zip.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\windll32.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
+</Project>
index 029333a..1d636e2 100644 (file)
@@ -1,9 +1,9 @@
 
-Info-Zip UnZip -- Source kit.  Version 6.10c20 (pre-BETA)  2016-03-16.
+Info-Zip UnZip -- Source kit.  Version 6.10c21 (pre-BETA)  2017-05-15.
 
 See enclosed files INSTALL, LICENSE, and README.  For information on
 Info-Zip UnZip and Zip:
-    http://www.info-zip.org/pub/infozip/
+    http://info-zip.org/
     http://sourceforge.net/projects/infozip/
 Executables for some released versions may also be available:
     ftp://ftp.info-zip.org/pub/infozip/
diff --git a/zip.h b/zip.h
index 4043bf1..f55505f 100644 (file)
--- a/zip.h
+++ b/zip.h
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2003-May-08 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index e18bfb6..4b37fe3 100644 (file)
--- a/zipinfo.c
+++ b/zipinfo.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -494,7 +494,8 @@ static ZCONST char Far *method[NUM_METHODS] = {
 /*  Function zi_opts()  */
 /************************/
 
-int zi_opts(__G__ pargc, pargv)
+int zi_opts(__G__ opts, pargc, pargv)
+    ZCONST struct option_struct *opts;
     int *pargc;
     char ***pargv;
     __GDEF
@@ -523,6 +524,8 @@ int zi_opts(__G__ pargc, pargv)
     int fna = 0;          /* current first non-opt arg */
     int optnum = 0;       /* index in table */
     int showhelp = 0;     /* for --commandline */
+    int dashdash = 0;     /* Have seen "--". */
+
 
     /* since get_option() returns xfiles and files one at a time, store them in
        linked lists until have them all */
@@ -596,7 +599,7 @@ int zi_opts(__G__ pargc, pargv)
      * the "while" loop, this storage will be free()'d.
      */
 
-    while ((option = get_option( __G__ ZIO, &args, &argcnt, &argnum,
+    while ((option = get_option( __G__ opts, &args, &argcnt, &argnum,
                                 &optchar, &value, &negative,
                                 &fna, &optnum, 0)))
     {
@@ -609,124 +612,124 @@ int zi_opts(__G__ pargc, pargv)
 
         switch (option)
         {
-                case '1':      /* shortest listing:  JUST filenames */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 1;
-                    break;
-                case '2':      /* just filenames, plus headers if specified */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 2;
-                    break;
+            case '1':      /* shortest listing:  JUST filenames */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 1;
+                break;
+            case '2':      /* just filenames, plus headers if specified */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 2;
+                break;
 #ifndef CMS_MVS
-                case ('C'):    /* -C:  match filenames case-insensitively */
-                    if (negative)
-                        uO.C_flag = FALSE;
-                    else
-                        uO.C_flag = TRUE;
-                    break;
+            case ('C'):    /* -C:  match filenames case-insensitively */
+                if (negative)
+                    uO.C_flag = FALSE;
+                else
+                    uO.C_flag = TRUE;
+                break;
 #endif /* !CMS_MVS */
-                case 'h':      /* header line */
-                    if (negative)
-                        hflag_2 = hflag_slmv = FALSE;
-                    else {
-                        hflag_2 = hflag_slmv = explicit_h = TRUE;
-                        if (uO.lflag == -1)
-                            uO.lflag = 0;
-                    }
-                    break;
+            case 'h':      /* header line */
+                if (negative)
+                    hflag_2 = hflag_slmv = FALSE;
+                else {
+                    hflag_2 = hflag_slmv = explicit_h = TRUE;
+                    if (uO.lflag == -1)
+                        uO.lflag = 0;
+                }
+                break;
 #if defined( UNICODE_SUPPORT) && defined( ICONV_MAPPING)
 # ifdef UNIX
-                case ('I'):    /* -I:  map ISO name to internal */
-                    strncpy( G.iso_cp, value, sizeof( G.iso_cp));
-                    break;
+            case ('I'):    /* -I:  map ISO name to internal */
+                strncpy( G.iso_cp, value, sizeof( G.iso_cp));
+                break;
 # endif /* def UNIX */
 #endif /* defined( UNICODE_SUPPORT) && defined( ICONV_MAPPING) */
-                case 'l':      /* longer form of "ls -l" type listing */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 5;
-                    break;
-                case (o_LI):    /* show license */
-                    showhelp = -1;
-                    break;
-                case 'm':      /* medium form of "ls -l" type listing */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 4;
-                    break;
-                case (o_mc):   /* show separate dir/file/link member counts */
-                    if (negative)
-                        uO.member_counts = -1;
-                    else
-                        uO.member_counts = 1;
-                    break;
+            case 'l':      /* longer form of "ls -l" type listing */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 5;
+                break;
+            case (o_LI):    /* show license */
+                showhelp = -1;
+                break;
+            case 'm':      /* medium form of "ls -l" type listing */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 4;
+                break;
+            case (o_mc):   /* show separate dir/file/link member counts */
+                if (negative)
+                    uO.member_counts = -1;
+                else
+                    uO.member_counts = 1;
+                break;
 #ifdef MORE
-                case 'M':      /* send output through built-in "more" */
-                    if (negative)
-                        G.M_flag = FALSE;
-                    else
-                        G.M_flag = TRUE;
-                    break;
+            case 'M':      /* send output through built-in "more" */
+                if (negative)
+                    G.M_flag = FALSE;
+                else
+                    G.M_flag = TRUE;
+                break;
 #endif
 # if defined( UNICODE_SUPPORT) && defined( ICONV_MAPPING)
 # ifdef UNIX
-                case ('O'):    /* -O:  map OEM name to internal */
-                    strncpy( G.oem_cp, value, sizeof( G.oem_cp));
-                    break;
+            case ('O'):    /* -O:  map OEM name to internal */
+                strncpy( G.oem_cp, value, sizeof( G.oem_cp));
+                break;
 # endif /* def UNIX */
 #endif /* defined( UNICODE_SUPPORT) && defined( ICONV_MAPPING) */
-                case 's':      /* default:  shorter "ls -l" type listing */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 3;
-                    break;
+            case 's':      /* default:  shorter "ls -l" type listing */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 3;
+                break;
 #ifndef SFX
-                case (o_sc):   /* show processed command line and exit */
-                    *pargc = -1;
-                    showhelp = -3;
-                    break;
+            case (o_sc):   /* show processed command line and exit */
+                *pargc = -1;
+                showhelp = -3;
+                break;
 
-                case (o_so):   /* show processed command line and exit */
-                    *pargc = -1;
-                    showhelp = -2;
-                    break;
+            case (o_so):   /* show processed command line and exit */
+                *pargc = -1;
+                showhelp = -2;
+                break;
 #endif /* ndef SFX */
-                case 't':      /* totals line */
-                    if (negative)
-                        tflag_2v = tflag_slm = FALSE;
-                    else {
-                        tflag_2v = tflag_slm = explicit_t = TRUE;
-                        if (uO.lflag == -1)
-                            uO.lflag = 0;
-                    }
-                    break;
-                case ('T'):    /* use (sortable) decimal time format */
-                    if (negative)
-                        uO.T_flag = FALSE;
-                    else
-                        uO.T_flag = TRUE;
-                    break;
+            case 't':      /* totals line */
+                if (negative)
+                    tflag_2v = tflag_slm = FALSE;
+                else {
+                    tflag_2v = tflag_slm = explicit_t = TRUE;
+                    if (uO.lflag == -1)
+                        uO.lflag = 0;
+                }
+                break;
+            case ('T'):    /* use (sortable) decimal time format */
+                if (negative)
+                    uO.T_flag = FALSE;
+                else
+                    uO.T_flag = TRUE;
+                break;
 #ifdef UNICODE_SUPPORT
-                case ('U'):    /* escape UTF-8, or disable UTF-8 support */
-                    if (negative)
-                        uO.U_flag = IZ_MAX(uO.U_flag - 1, 0);
-                    else
-                        uO.U_flag++;
-                    break;
+            case ('U'):    /* escape UTF-8, or disable UTF-8 support */
+                if (negative)
+                    uO.U_flag = IZ_MAX(uO.U_flag - 1, 0);
+                else
+                    uO.U_flag++;
+                break;
 #endif /* UNICODE_SUPPORT */
-                case 'v':      /* turbo-verbose listing */
-                    if (negative)
-                        uO.lflag = -2;
-                    else
-                        uO.lflag = 10;
-                    break;
+            case 'v':      /* turbo-verbose listing */
+                if (negative)
+                    uO.lflag = -2;
+                else
+                    uO.lflag = 10;
+                break;
 #ifndef SFX
             case (o_ve):   /* version */
                 if (negative)
@@ -751,69 +754,81 @@ int zi_opts(__G__ pargc, pargv)
 #endif /* ndef SFX */
 
 #ifdef WILD_STOP_AT_DIR
-                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
-                    if (negative)
-                        uO.W_flag = FALSE;
-                    else
-                        uO.W_flag = TRUE;
-                    break;
+            case ('W'):    /* Wildcard interpretation (stop at '/'?) */
+                if (negative)
+                    uO.W_flag = FALSE;
+                else
+                    uO.W_flag = TRUE;
+                break;
 #endif /* WILD_STOP_AT_DIR */
-                case ('x'):     /* Exclude.  Add -x file to linked list. */
-                    if (in_xfiles_count == 0) {
-                        /* first entry */
-                        if ((in_xfiles = (struct file_list *) izu_malloc(
-                         sizeof(struct file_list))) == NULL) {
-                            Info(slide, 0x401, ((char *)slide,
-                             LoadFarString(NoMemArguments)));
-                            /* Leaving early.  Free it. */
-                            FREE_NON_NULL( value);
-                            UPDATE_PARGV;       /* See note 2013-01-17 SMS. */
-                            return PK_MEM;
-                        }
-                        in_xfiles->name = value;
-                        in_xfiles->next = NULL;
-                        next_in_xfiles = in_xfiles;
-                    } else {
-                        /* add next entry */
-                        if ((next_file = (struct file_list *) izu_malloc(
-                         sizeof(struct file_list))) == NULL) {
-                            Info(slide, 0x401, ((char *)slide,
-                             LoadFarString(NoMemArguments)));
-                            /* Leaving early.  Free it. */
-                            FREE_NON_NULL( value);
-                            UPDATE_PARGV;       /* See note 2013-01-17 SMS. */
-                            return PK_MEM;
-                        }
-                        next_in_xfiles->next = next_file;
-                        next_file->name = value;
-                        next_file->next = NULL;
-                        next_in_xfiles = next_file;
+            case ('x'):     /* Exclude.  Add -x file to linked list. */
+                if (in_xfiles_count == 0) {
+                    /* first entry */
+                    if ((in_xfiles = (struct file_list *) izu_malloc(
+                     sizeof(struct file_list))) == NULL) {
+                        Info(slide, 0x401, ((char *)slide,
+                         LoadFarString(NoMemArguments)));
+                        /* Leaving early.  Free it. */
+                        FREE_NON_NULL( value);
+                        UPDATE_PARGV;       /* See note 2013-01-17 SMS. */
+                        return PK_MEM;
                     }
-                    in_xfiles_count++;
-                    value = NULL;       /* In use.  Don't free it. */
-                case 'z':      /* print zipfile comment */
-                    if (negative)
-                        uO.zflag = 0;
-                    else
-                        uO.zflag = 1;
-                    break;
-                case 'Z':      /* ZipInfo mode:  ignore */
-                    break;
-                case o_NON_OPTION_ARG:
-                    /* not an option */
-                    /* no more options as permuting */
-
+                    in_xfiles->name = value;
+                    in_xfiles->next = NULL;
+                    next_in_xfiles = in_xfiles;
+                } else {
+                    /* add next entry */
+                    if ((next_file = (struct file_list *) izu_malloc(
+                     sizeof(struct file_list))) == NULL) {
+                        Info(slide, 0x401, ((char *)slide,
+                         LoadFarString(NoMemArguments)));
+                        /* Leaving early.  Free it. */
+                        FREE_NON_NULL( value);
+                        UPDATE_PARGV;       /* See note 2013-01-17 SMS. */
+                        return PK_MEM;
+                    }
+                    next_in_xfiles->next = next_file;
+                    next_file->name = value;
+                    next_file->next = NULL;
+                    next_in_xfiles = next_file;
+                }
+                in_xfiles_count++;
+                value = NULL;       /* In use.  Don't free it. */
+            case 'z':      /* print zipfile comment */
+                if (negative)
+                    uO.zflag = 0;
+                else
+                    uO.zflag = 1;
+                break;
+            case 'Z':      /* ZipInfo mode:  ignore */
+                break;
+            case o_NON_OPTION_ARG:
+                /* Not an option.  (Because of permutation, no more
+                 * "-" options are expected henceforth.)
+                 * "--" also appears here.
+                 */
 
+                /* First "--" is ignored (and stops arg processing for
+                 * remaining args).
+                 */
+                if ((strcmp( value, "--") == 0) && (dashdash == 0))
+                {
+                  dashdash = 1;
+                }
+                else
+                {
                     if (G.wildzipfn == NULL) {
                         /* first non-option argument is zip file */
                         G.wildzipfn = value;
-
-                    } else {
+                    }
+                    else
+                    {
                         /* add include file to list */
                         if (in_files_count == 0) {
                             /* first entry */
-                            if ((next_file = (struct file_list *) izu_malloc(
-                             sizeof(struct file_list))) == NULL) {
+                            if ((next_file = (struct file_list *)
+                             izu_malloc( sizeof(struct file_list))) == NULL)
+                            {
                                 Info(slide, 0x401, ((char *)slide,
                                  LoadFarString(NoMemArguments)));
                                 /* Leaving early.  Free it. */
@@ -825,10 +840,13 @@ int zi_opts(__G__ pargc, pargv)
                             next_file->next = NULL;
                             in_files = next_file;
                             next_in_files = next_file;
-                        } else {
+                        }
+                        else
+                        {
                             /* add next entry */
-                            if ((next_file = (struct file_list *) izu_malloc(
-                             sizeof(struct file_list))) == NULL) {
+                            if ((next_file = (struct file_list *)
+                             izu_malloc( sizeof(struct file_list))) == NULL)
+                            {
                                 Info(slide, 0x401, ((char *)slide,
                                  LoadFarString(NoMemArguments)));
                                 /* Leaving early.  Free it. */
@@ -843,16 +861,17 @@ int zi_opts(__G__ pargc, pargv)
                         }
                         in_files_count++;
                     }
-                    value = NULL;       /* In use.  Don't free it. */
-                    break;
-                default:
-                    error = TRUE;
-                    break;
-        } /* switch */
+                }
+                value = NULL;       /* In use.  Don't free it. */
+                break;
+            default:
+                error = TRUE;
+                break;
+        } /* switch (option) */
 
         FREE_NON_NULL( value);          /* Free it now, if it's not in use. */
 
-    } /* get_option() */
+    } /* while (get_option()) */
 
 
     if (showhelp == -1)
@@ -1066,7 +1085,9 @@ void zi_end_central(__G)
 int zipinform(__G)   /* return PK-type error code */
     __GDEF
 {
-    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+    int do_this_file = FALSE;
+    int error;
+    int error_in_archive = PK_COOL;
     int *fn_matched=NULL, *xn_matched=NULL;
     ulg j;
     ulg members = 0L;
@@ -1079,6 +1100,7 @@ int zipinform(__G)   /* return PK-type error code */
     zusz_t tot_csize=0L, tot_ucsize=0L;
     zusz_t endprev;   /* buffers end of previous entry for zi_long()'s check
                        *  of extra bytes */
+    long enddigsig_len;
 
 
 /*---------------------------------------------------------------------------
@@ -1115,12 +1137,27 @@ int zipinform(__G)   /* return PK-type error code */
     /* reset endprev for new zipfile; account for multi-part archives (?) */
     endprev = (G.crec.relative_offset_local_header == 4L)? 4L : 0L;
 
+    enddigsig_len = -1;
 
-    for (j = 1L;; j++) {
+    for (j = 1L; ; j++)
+    {
         if (readbuf(__G__ G.sig, 4) == 0) {
             error_in_archive = PK_EOF;
             break;
         }
+
+        if (memcmp(G.sig, central_digsig_sig, 4) == 0)
+        { /* Central directory digital signature.  Record its
+           * existence.  Read (and, for now, ignore) the data.
+           */
+          error = process_cdir_digsig( __G__ &enddigsig_len);
+          if (error != PK_OK)
+          {
+            error_in_archive = error;   /* Record the error code. */
+            break;
+          }
+        } /* process_cdir_digsig() should have read the next sig. */
+
         if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
             /* no new central directory entry
              * -> is the number of processed entries compatible with the
@@ -1349,12 +1386,11 @@ int zipinform(__G)   /* return PK-type error code */
 
 
     /* Skip the following checks in case of a premature listing break. */
-    if (error_in_archive <= PK_WARN) {
-
+    if (error_in_archive <= PK_WARN)
+    {
 /*---------------------------------------------------------------------------
     Double check that we're back at the end-of-central-directory record.
   ---------------------------------------------------------------------------*/
-
         if ( (memcmp(G.sig,
                      (G.ecrec.have_ecr64 ?
                       end_central64_sig : end_central_sig),
@@ -1363,7 +1399,17 @@ int zipinform(__G)   /* return PK-type error code */
             && (memcmp(G.sig, end_central_sig, 4) != 0)
            ) {          /* just to make sure again */
             Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
-            error_in_archive = PK_WARN;   /* didn't find sig */
+            error_in_archive = PK_WARN;   /* Didn't find EOCD sig. */
+        }
+
+        if (enddigsig_len >= 0)
+        {
+          Info( slide, 0x401, ((char *)slide, LoadFarString( DigSigMsg),
+           enddigsig_len));
+# if 0   /* Enable to make this a warning. */
+          if (error_in_archive < PK_WARN)       /* Keep more severe error. */
+            error_in_archive = PK_WARN;                
+# endif /* 0 */
         }
 
         /* Set specific return code when no files have been found. */
@@ -2546,7 +2592,18 @@ static int zi_short(__G)   /* return PK-type error code */
         ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
         methbuf[3] = dtype[dnum];
     } else if (methnum >= NUM_METHODS) {   /* unknown */
-        sprintf(&methbuf[1], "%03u", G.crec.compression_method);
+        /* 2016-12-05 SMS.
+         * https://launchpad.net/bugs/1643750  CVE-2016-9844.
+         * Unexpectedly large compression methods overflow
+         * &methbuf[].  Use the old, three-digit decimal format
+         * for values which fit.  Otherwise, sacrifice the "u",
+         * and use four-digit hexadecimal.
+         */
+        if (G.crec.compression_method <= 999) {
+            sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
+        } else {
+            sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
+        }
     }
 
     memset( attribs, ' ', (sizeof( attribs)- 1));
index 99bc53d..8fba2e4 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2015 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index 6dc3908..ded952c 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2007-Mar-04 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
index fb2f3d9..78c147f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2016 Info-ZIP.  All rights reserved.
 
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
   If, for some reason, all these files are missing, the Info-ZIP license
   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html