Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: unzip/Makefile
===================================================================
--- unzip/Makefile	(nonexistent)
+++ unzip/Makefile	(revision 5)
@@ -0,0 +1,57 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/infozip/unzip60
+
+versions    = 60
+pkgname     = unzip
+suffix      = tar.gz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname), $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+patches     = $(CURDIR)/patches/unzip-6.0-slackware.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-6.0-slackware-patch     ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: unzip/create-6.0-slackware-patch/create.patch.sh
===================================================================
--- unzip/create-6.0-slackware-patch/create.patch.sh	(nonexistent)
+++ unzip/create-6.0-slackware-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=6.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../unzip${version}.tar.gz
+mv unzip${version} unzip${version}-orig
+
+cp -rf ./unzip${version}-new ./unzip${version}
+
+diff --unified -Nr  unzip${version}-orig  unzip${version} > unzip-${VERSION}-slackware.patch
+
+mv unzip-${VERSION}-slackware.patch ../patches
+
+rm -rf ./unzip${version}
+rm -rf ./unzip${version}-orig

Property changes on: unzip/create-6.0-slackware-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: unzip/create-6.0-slackware-patch/file.list
===================================================================
--- unzip/create-6.0-slackware-patch/file.list	(nonexistent)
+++ unzip/create-6.0-slackware-patch/file.list	(revision 5)
@@ -0,0 +1,14 @@
+unzip60/crc_i386.S
+unzip60/crypt.c
+unzip60/extract.c
+unzip60/fileio.c
+unzip60/list.c
+unzip60/man/unzip.1
+unzip60/match.c
+unzip60/process.c
+unzip60/unix/configure
+unzip60/unix/unix.c
+unzip60/unix/unxcfg.h
+unzip60/unzip.c
+unzip60/unzpriv.h
+unzip60/zipinfo.c
Index: unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S	(revision 5)
@@ -0,0 +1,307 @@
+/*
+  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 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
+*/
+/*
+ * crc_i386.S, optimized CRC calculation function for Zip and UnZip,
+ * created by Paul Kienitz and Christian Spieler.  Last revised 07 Jan 2007.
+ *
+ * GRR 961110:  incorporated Scott Field optimizations from win32/crc_i386.asm
+ *              => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
+ *
+ * SPC 970402:  revised for Rodney Brown's optimizations (32-bit-wide
+ *              aligned reads for most of the data from buffer), can be
+ *              disabled by defining the macro NO_32_BIT_LOADS
+ *
+ * SPC 971012:  added Rodney Brown's additional tweaks for 32-bit-optimized
+ *              CPUs (like the Pentium Pro, Pentium II, and probably some
+ *              Pentium clones). This optimization is controlled by the
+ *              preprocessor switch "__686" and is disabled by default.
+ *              (This default is based on the assumption that most users
+ *              do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * COS 050116:  Enabled the 686 build by default, because there are hardly any
+ *              pre-686 CPUs in serious use nowadays. (See SPC 970402 above.)
+ *
+ * SPC 060103:  Updated code to incorporate newer optimizations found in zlib.
+ *
+ * SPC 070107:  Added conditional switch to deactivate crc32() compilation.
+ *
+ * FLAT memory model assumed.  Calling interface:
+ *   - args are pushed onto the stack from right to left,
+ *   - return value is given in the EAX register,
+ *   - all other registers (with exception of EFLAGS) are preserved. (With
+ *     GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
+ *     them nevertheless adds only 4 single byte instructions.)
+ *
+ * This source generates the function
+ * ulg crc32(ulg crc, ZCONST uch *buf, extent len).
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ */
+
+/* This file is NOT used in conjunction with zlib, or when only creation of
+ * the basic CRC_32_Table (for other purpose) is requested.
+ */
+#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+#  define _crc32            crc32
+#  define _get_crc_table    get_crc_table
+#endif
+/* Use 16-byte alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+#  define ALIGNMENT .align 4,0x90
+#endif
+
+#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
+
+/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to use the C version,
+ * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
+ */
+
+                .file   "crc_i386.S"
+
+#if !defined(PRE_686) && !defined(__686)
+   /* Optimize for Pentium Pro and compatible CPUs by default. */
+#  define __686
+#endif
+
+#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
+#  undef USE_STACKFRAME
+#else
+   /* The default is to use standard stack frame entry, because it
+    * results in smaller code!
+    */
+#  ifndef USE_STD_STACKFRAME
+#    define USE_STD_STACKFRAME
+#  endif
+#endif
+
+#ifdef USE_STD_STACKFRAME
+#  define _STD_ENTRY    pushl   %ebp ; movl   %esp,%ebp
+#  define arg1  8(%ebp)
+#  define arg2  12(%ebp)
+#  define arg3  16(%ebp)
+#  define _STD_LEAVE    popl    %ebp
+#else /* !USE_STD_STACKFRAME */
+#  define _STD_ENTRY
+#  define arg1  24(%esp)
+#  define arg2  28(%esp)
+#  define arg3  32(%esp)
+#  define _STD_LEAVE
+#endif /* ?USE_STD_STACKFRAME */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ *   eax  : crc value "c"
+ *   esi  : pointer to next data byte (or lword) "buf++"
+ * registers read:
+ *   edi  : pointer to base of crc_table array
+ * scratch registers:
+ *   ebx  : index into crc_table array
+ *          (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686   /* optimize for 386, 486, Pentium */
+#define Do_CRC          /* c = (c >> 8) ^ table[c & 0xFF] */\
+                movb    %al, %bl                ;/* tmp = c & 0xFF  */\
+                shrl    $8, %eax                ;/* c = (c >> 8)    */\
+                xorl    (%edi, %ebx, 4), %eax   ;/* c ^= table[tmp] */
+#else   /* __686 : optimize for Pentium Pro and compatible CPUs */
+#define Do_CRC          /* c = (c >> 8) ^ table[c & 0xFF] */\
+                movzbl  %al, %ebx               ;/* tmp = c & 0xFF  */\
+                shrl    $8, %eax                ;/* c = (c >> 8)    */\
+                xorl    (%edi, %ebx, 4), %eax   ;/* c ^=table[tmp]  */
+#endif  /* ?__686 */
+
+#define Do_CRC_byte             /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+                xorb    (%esi), %al     ;/* c ^= *buf  */\
+                incl    %esi            ;/* buf++      */\
+                Do_CRC
+
+#define Do_CRC_byteof(ofs)      /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+                xorb    ofs(%esi), %al  ;/* c ^= *buf  */\
+                incl    %esi            ;/* buf++      */\
+                Do_CRC
+
+#ifndef  NO_32_BIT_LOADS
+# ifdef IZ_CRCOPTIM_UNFOLDTBL
+   /* the edx register is needed in crc calculation */
+#  define SavLen arg3
+#  define UpdCRC_lword \
+                movzbl  %al, %ebx               ; \
+                movl    3072(%edi,%ebx,4), %edx ; \
+                movzbl  %ah, %ebx               ; \
+                shrl    $16, %eax               ; \
+                xor     2048(%edi,%ebx,4), %edx ; \
+                movzbl  %al, %ebx               ; \
+                shrl    $8,%eax                 ; \
+                xorl    1024(%edi,%ebx,4), %edx ; \
+                movl    (%edi,%eax,4), %eax     ; \
+                xorl    %edx,%eax               ;
+#  define UpdCRC_lword_sh(dwPtrIncr) \
+                movzbl  %al, %ebx               ; \
+                movl    3072(%edi,%ebx,4), %edx ; \
+                movzbl  %ah, %ebx               ; \
+                shrl    $16, %eax               ; \
+                xor     2048(%edi,%ebx,4), %edx ; \
+                movzbl  %al, %ebx               ; \
+                addl    $4*(dwPtrIncr), %esi    ;/* ((ulg *)buf)+=dwPtrIncr */\
+                shrl    $8,%eax                 ; \
+                xorl    1024(%edi,%ebx,4), %edx ; \
+                movl    (%edi,%eax,4),%eax      ; \
+                xorl    %edx,%eax               ;
+# else /* !IZ_CRCOPTIM_UNFOLDTBL */
+   /* the edx register is not needed anywhere else */
+#  define SavLen %edx
+#  define UpdCRC_lword \
+                Do_CRC \
+                Do_CRC \
+                Do_CRC \
+                Do_CRC
+#  define UpdCRC_lword_sh(dwPtrIncr) \
+                Do_CRC \
+                Do_CRC \
+                addl    $4*(dwPtrIncr), %esi    ;/* ((ulg *)buf)++   */\
+                Do_CRC \
+                Do_CRC
+# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+#define Do_CRC_lword \
+                xorl    (%esi), %eax           ;/* c ^= *(ulg *)buf */\
+                UpdCRC_lword_sh(1)              /* ... ((ulg *)buf)++ */
+#define Do_CRC_4lword \
+                xorl    (%esi), %eax           ;/* c ^= *(ulg *)buf */\
+                UpdCRC_lword \
+                xorl    4(%esi), %eax          ;/* c ^= *((ulg *)buf+1) */\
+                UpdCRC_lword \
+                xorl    8(%esi), %eax          ;/* c ^= *((ulg *)buf+2) */\
+                UpdCRC_lword \
+                xorl    12(%esi), %eax         ;/* c ^= *((ulg *)buf]+3 */\
+                UpdCRC_lword_sh(4)              /* ... ((ulg *)buf)+=4 */
+#endif  /* !NO_32_BIT_LOADS */
+
+
+                .text
+
+                .globl  _crc32
+
+_crc32:                         /* ulg crc32(ulg crc, uch *buf, extent len) */
+                _STD_ENTRY
+                pushl   %edi
+                pushl   %esi
+                pushl   %ebx
+                pushl   %edx
+                pushl   %ecx
+
+                movl    arg2, %esi           /* 2nd arg: uch *buf            */
+                subl    %eax, %eax           /* > if (!buf)                  */
+                testl   %esi, %esi           /* >   return 0;                */
+                jz      .L_fine              /* > else {                     */
+                call    _get_crc_table
+                movl    %eax, %edi
+                movl    arg1, %eax           /* 1st arg: ulg crc             */
+#ifndef __686
+                subl    %ebx, %ebx           /* ebx=0; bl usable as dword    */
+#endif
+                movl    arg3, %ecx           /* 3rd arg: extent len          */
+                notl    %eax                 /* >   c = ~crc;                */
+
+                testl   %ecx, %ecx
+#ifndef  NO_UNROLLED_LOOPS
+                jz      .L_bail
+#  ifndef  NO_32_BIT_LOADS
+                /* Assert now have positive length */
+.L_align_loop:
+                testl   $3, %esi        /* Align buf on lword boundary */
+                jz      .L_aligned_now
+                Do_CRC_byte
+                decl    %ecx
+                jnz     .L_align_loop
+.L_aligned_now:
+#  endif  /* !NO_32_BIT_LOADS */
+                movl    %ecx, SavLen         /* save current value of len */
+                shrl    $4, %ecx             /* ecx = len / 16   */
+                jz      .L_No_Sixteens
+/*  align loop head at start of 486 internal cache line !! */
+                ALIGNMENT
+.L_Next_Sixteen:
+#  ifndef NO_32_BIT_LOADS
+                 Do_CRC_4lword
+#  else   /* NO_32_BIT_LOADS */
+                 Do_CRC_byteof(0)
+                 Do_CRC_byteof(1)
+                 Do_CRC_byteof(2)
+                 Do_CRC_byteof(3)
+                 Do_CRC_byteof(4)
+                 Do_CRC_byteof(5)
+                 Do_CRC_byteof(6)
+                 Do_CRC_byteof(7)
+                 Do_CRC_byteof(8)
+                 Do_CRC_byteof(9)
+                 Do_CRC_byteof(10)
+                 Do_CRC_byteof(11)
+                 Do_CRC_byteof(12)
+                 Do_CRC_byteof(13)
+                 Do_CRC_byteof(14)
+                 Do_CRC_byteof(15)
+                 addl    $16,%esi        ;/* buf += 16 */
+#  endif  /* ?NO_32_BIT_LOADS */
+                decl    %ecx
+                jnz     .L_Next_Sixteen
+
+.L_No_Sixteens:
+                movl    SavLen, %ecx
+                andl    $15, %ecx         /* ecx = len % 16   */
+# ifndef NO_32_BIT_LOADS
+                shrl    $2,%ecx           /* ecx = len / 4    */
+                jz      .L_No_Fours
+.L_Next_Four:
+                Do_CRC_lword
+                decl    %ecx
+                jnz     .L_Next_Four
+.L_No_Fours:
+                movl    SavLen,%ecx
+                andl    $3,%ecx          /* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
+#endif /* !NO_UNROLLED_LOOPS */
+                jz      .L_bail          /* > if (len)                       */
+/* align loop head at start of 486 internal cache line !! */
+                ALIGNMENT
+.L_loupe:                                /* >   do {                         */
+                 Do_CRC_byte             /*       c = CRC32(c,*buf++,crctab);*/
+                decl    %ecx             /* >   } while (--len);             */
+                jnz     .L_loupe
+
+.L_bail:                                 /* > }                              */
+                notl    %eax             /* > return ~c;                     */
+.L_fine:
+                popl    %ecx
+                popl    %edx
+                popl    %ebx
+                popl    %esi
+                popl    %edi
+                _STD_LEAVE
+                ret
+
+#else
+ error: this asm version is for 386 only
+#endif /* i386 || _i386 || _I386 || __i386 */
+
+#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: unzip/create-6.0-slackware-patch/unzip60-new/crypt.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/crypt.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/crypt.c	(revision 5)
@@ -0,0 +1,663 @@
+/*
+  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2005-Feb-10 or later
+  (the contents of which are also included in (un)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
+*/
+/*
+  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
+
+  The main encryption/decryption source code for Info-Zip software was
+  originally written in Europe.  To the best of our knowledge, it can
+  be freely distributed in both source and object forms from any country,
+  including the USA under License Exception TSU of the U.S. Export
+  Administration Regulations (section 740.13(e)) of 6 June 2002.
+
+  NOTE on copyright history:
+  Previous versions of this source package (up to version 2.8) were
+  not copyrighted and put in the public domain.  If you cannot comply
+  with the Info-Zip LICENSE, you may want to look for one of those
+  public domain versions.
+ */
+
+/*
+  This encryption code is a direct transcription of the algorithm from
+  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+  file (appnote.txt) is distributed with the PKZIP program (even in the
+  version without encryption capabilities).
+ */
+
+#define ZCRYPT_INTERNAL
+#include "zip.h"
+#include "crypt.h"
+#include "ttyio.h"
+
+#if CRYPT
+
+#ifndef FALSE
+#  define FALSE 0
+#endif
+
+#ifdef ZIP
+   /* For the encoding task used in Zip (and ZipCloak), we want to initialize
+      the crypt algorithm with some reasonably unpredictable bytes, see
+      the crypthead() function. The standard rand() library function is
+      used to supply these `random' bytes, which in turn is initialized by
+      a srand() call. The srand() function takes an "unsigned" (at least 16bit)
+      seed value as argument to determine the starting point of the rand()
+      pseudo-random number generator.
+      This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
+      Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
+      as some (hopefully) nondeterministic bitmask. On many (most) systems,
+      we use some "process specific" number, as the PID or something similar,
+      but when nothing unpredictable is available, a fixed number may be
+      sufficient.
+      NOTE:
+      1.) This implementation requires the availability of the following
+          standard UNIX C runtime library functions: time(), rand(), srand().
+          On systems where some of them are missing, the environment that
+          incorporates the crypt routines must supply suitable replacement
+          functions.
+      2.) It is a very bad idea to use a second call to time() to set the
+          "Seed2" number! In this case, both "Seed1" and "Seed2" would be
+          (almost) identical, resulting in a (mostly) "zero" constant seed
+          number passed to srand().
+
+      The implementation environment defined in the "zip.h" header should
+      supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
+      most implementations of rand() and srand(), only the lower 16 bits are
+      significant!). An example that works on many systems would be
+           "#define ZCR_SEED2  (unsigned)getpid()".
+      The default definition for ZCR_SEED2 supplied below should be regarded
+      as a fallback to allow successful compilation in "beta state"
+      environments.
+    */
+#  include <time.h>     /* time() function supplies first part of crypt seed */
+   /* "last resort" source for second part of crypt seed pattern */
+#  ifndef ZCR_SEED2
+#    define ZCR_SEED2 (unsigned)3141592654L     /* use PI as default pattern */
+#  endif
+#  ifdef GLOBAL         /* used in Amiga system headers, maybe others too */
+#    undef GLOBAL
+#  endif
+#  define GLOBAL(g) g
+#else /* !ZIP */
+#  define GLOBAL(g) G.g
+#endif /* ?ZIP */
+
+
+#ifdef UNZIP
+   /* char *key = (char *)NULL; moved to globals.h */
+#  ifndef FUNZIP
+     local int testp OF((__GPRO__ ZCONST uch *h));
+     local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
+#  endif
+#endif /* UNZIP */
+
+#ifndef UNZIP             /* moved to globals.h for UnZip */
+#  ifndef Z_UINT4_DEFINED
+#   if !defined(NO_LIMITS_H)
+#    if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
+       typedef unsigned int     z_uint4;
+#      define Z_UINT4_DEFINED
+#    else
+#    if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
+       typedef unsigned long    z_uint4;
+#      define Z_UINT4_DEFINED
+#    else
+#    if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
+       typedef unsigned short   z_uint4;
+#      define Z_UINT4_DEFINED
+#    endif
+#    endif
+#    endif
+#   endif /* !NO_LIMITS_H */
+#  endif /* !Z_UINT4_DEFINED */
+#  ifndef Z_UINT4_DEFINED
+     typedef ulg                z_uint4;
+#    define Z_UINT4_DEFINED
+#  endif
+   local z_uint4 keys[3];       /* keys defining the pseudo-random sequence */
+#endif /* !UNZIP */
+
+#ifndef Trace
+#  ifdef CRYPT_DEBUG
+#    define Trace(x) fprintf x
+#  else
+#    define Trace(x)
+#  endif
+#endif
+
+#include "crc32.h"
+
+#ifdef IZ_CRC_BE_OPTIMIZ
+   local z_uint4 near crycrctab[256];
+   local z_uint4 near *cry_crctb_p = NULL;
+   local z_uint4 near *crytab_init OF((__GPRO));
+#  define CRY_CRC_TAB  cry_crctb_p
+#  undef CRC32
+#  define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+#else
+#  define CRY_CRC_TAB  CRC_32_TAB
+#endif /* ?IZ_CRC_BE_OPTIMIZ */
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+int decrypt_byte(__G)
+    __GDEF
+{
+    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
+                     * unpredictable manner on 16-bit systems; not a problem
+                     * with any known compiler so far, though */
+
+    temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
+    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+int update_keys(__G__ c)
+    __GDEF
+    int c;                      /* byte of plain text */
+{
+    GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB);
+    GLOBAL(keys[1]) = (GLOBAL(keys[1])
+                       + (GLOBAL(keys[0]) & 0xff))
+                      * 134775813L + 1;
+    {
+      register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
+      GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
+    }
+    return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+void init_keys(__G__ passwd)
+    __GDEF
+    ZCONST char *passwd;        /* password string with which to modify keys */
+{
+#ifdef IZ_CRC_BE_OPTIMIZ
+    if (cry_crctb_p == NULL) {
+        cry_crctb_p = crytab_init(__G);
+    }
+#endif
+    GLOBAL(keys[0]) = 305419896L;
+    GLOBAL(keys[1]) = 591751049L;
+    GLOBAL(keys[2]) = 878082192L;
+    while (*passwd != '\0') {
+        update_keys(__G__ (int)*passwd);
+        passwd++;
+    }
+}
+
+
+/***********************************************************************
+ * Initialize the local copy of the table of precomputed crc32 values.
+ * Whereas the public crc32-table is optimized for crc32 calculations
+ * on arrays of bytes, the crypt code needs the crc32 values in an
+ * byte-order-independent form as 32-bit unsigned numbers. On systems
+ * with Big-Endian byte order using the optimized crc32 code, this
+ * requires inverting the byte-order of the values in the
+ * crypt-crc32-table.
+ */
+#ifdef IZ_CRC_BE_OPTIMIZ
+local z_uint4 near *crytab_init(__G)
+    __GDEF
+{
+    int i;
+
+    for (i = 0; i < 256; i++) {
+        crycrctab[i] = REV_BE(CRC_32_TAB[i]);
+    }
+    return crycrctab;
+}
+#endif
+
+
+#ifdef ZIP
+
+/***********************************************************************
+ * Write encryption header to file zfile using the password passwd
+ * and the cyclic redundancy check crc.
+ */
+void crypthead(passwd, crc, zfile)
+    ZCONST char *passwd;         /* password string */
+    ulg crc;                     /* crc of file being encrypted */
+    FILE *zfile;                 /* where to write header */
+{
+    int n;                       /* index in random header */
+    int t;                       /* temporary */
+    int c;                       /* random byte */
+    uch header[RAND_HEAD_LEN];   /* random header */
+    static unsigned calls = 0;   /* ensure different random header each time */
+
+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+     * output of rand() to get less predictability, since rand() is
+     * often poorly implemented.
+     */
+    if (++calls == 1) {
+        srand((unsigned)time(NULL) ^ ZCR_SEED2);
+    }
+    init_keys(passwd);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+        c = (rand() >> 7) & 0xff;
+        header[n] = (uch)zencode(c, t);
+    }
+    /* Encrypt random header (last two bytes is high word of crc) */
+    init_keys(passwd);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+        header[n] = (uch)zencode(header[n], t);
+    }
+    header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t);
+    header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t);
+    fwrite(header, 1, RAND_HEAD_LEN, f);
+}
+
+
+#ifdef UTIL
+
+/***********************************************************************
+ * Encrypt the zip entry described by z from file source to file dest
+ * using the password passwd.  Return an error code in the ZE_ class.
+ */
+int zipcloak(z, source, dest, passwd)
+    struct zlist far *z;    /* zip entry to encrypt */
+    FILE *source, *dest;    /* source and destination files */
+    ZCONST char *passwd;    /* password string */
+{
+    int c;                  /* input byte */
+    int res;                /* result code */
+    ulg n;                  /* holds offset and counts size */
+    ush flag;               /* previous flags */
+    int t;                  /* temporary */
+    int ztemp;              /* temporary storage for zencode value */
+
+    /* Set encrypted bit, clear extended local header bit and write local
+       header to output file */
+    if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+    z->off = n;
+    flag = z->flg;
+    z->flg |= 1,  z->flg &= ~8;
+    z->lflg |= 1, z->lflg &= ~8;
+    z->siz += RAND_HEAD_LEN;
+    if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+    /* Initialize keys with password and write random header */
+    crypthead(passwd, z->crc, dest);
+
+    /* Skip local header in input file */
+    if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
+              SEEK_CUR)) {
+        return ferror(source) ? ZE_READ : ZE_EOF;
+    }
+
+    /* Encrypt data */
+    for (n = z->siz - RAND_HEAD_LEN; n; n--) {
+        if ((c = getc(source)) == EOF) {
+            return ferror(source) ? ZE_READ : ZE_EOF;
+        }
+        ztemp = zencode(c, t);
+        putc(ztemp, dest);
+    }
+    /* Skip extended local header in input file if there is one */
+    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+        return ferror(source) ? ZE_READ : ZE_EOF;
+    }
+    if (fflush(dest) == EOF) return ZE_TEMP;
+
+    /* Update number of bytes written to output file */
+    tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
+
+    return ZE_OK;
+}
+
+/***********************************************************************
+ * Decrypt the zip entry described by z from file source to file dest
+ * using the password passwd.  Return an error code in the ZE_ class.
+ */
+int zipbare(z, source, dest, passwd)
+    struct zlist far *z;  /* zip entry to encrypt */
+    FILE *source, *dest;  /* source and destination files */
+    ZCONST char *passwd;  /* password string */
+{
+#ifdef ZIP10
+    int c0                /* byte preceding the last input byte */
+#endif
+    int c1;               /* last input byte */
+    ulg offset;           /* used for file offsets */
+    ulg size;             /* size of input data */
+    int r;                /* size of encryption header */
+    int res;              /* return code */
+    ush flag;             /* previous flags */
+
+    /* Save position and skip local header in input file */
+    if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
+        fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
+              SEEK_CUR)) {
+        return ferror(source) ? ZE_READ : ZE_EOF;
+    }
+    /* Initialize keys with password */
+    init_keys(passwd);
+
+    /* Decrypt encryption header, save last two bytes */
+    c1 = 0;
+    for (r = RAND_HEAD_LEN; r; r--) {
+#ifdef ZIP10
+        c0 = c1;
+#endif
+        if ((c1 = getc(source)) == EOF) {
+            return ferror(source) ? ZE_READ : ZE_EOF;
+        }
+        Trace((stdout, " (%02x)", c1));
+        zdecode(c1);
+        Trace((stdout, " %02x", c1));
+    }
+    Trace((stdout, "\n"));
+
+    /* If last two bytes of header don't match crc (or file time in the
+     * case of an extended local header), back up and just copy. For
+     * pkzip 2.0, the check has been reduced to one byte only.
+     */
+#ifdef ZIP10
+    if ((ush)(c0 | (c1<<8)) !=
+        (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
+#else
+    if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
+#endif
+        if (fseek(source, offset, SEEK_SET)) {
+            return ferror(source) ? ZE_READ : ZE_EOF;
+        }
+        if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
+        return ZE_MISS;
+    }
+
+    /* Clear encrypted bit and local header bit, and write local header to
+       output file */
+    if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+    z->off = offset;
+    flag = z->flg;
+    z->flg &= ~9;
+    z->lflg &= ~9;
+    z->siz -= RAND_HEAD_LEN;
+    if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+    /* Decrypt data */
+    for (size = z->siz; size; size--) {
+        if ((c1 = getc(source)) == EOF) {
+            return ferror(source) ? ZE_READ : ZE_EOF;
+        }
+        zdecode(c1);
+        putc(c1, dest);
+    }
+    /* Skip extended local header in input file if there is one */
+    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+        return ferror(source) ? ZE_READ : ZE_EOF;
+    }
+    if (fflush(dest) == EOF) return ZE_TEMP;
+
+    /* Update number of bytes written to output file */
+    tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
+
+    return ZE_OK;
+}
+
+
+#else /* !UTIL */
+
+/***********************************************************************
+ * If requested, encrypt the data in buf, and in any case call fwrite()
+ * with the arguments to zfwrite().  Return what fwrite() returns.
+ *
+ * A bug has been found when encrypting large files.  See trees.c
+ * for details and the fix.
+ */
+unsigned zfwrite(buf, item_size, nb, f)
+    zvoid *buf;                 /* data buffer */
+    extent item_size;           /* size of each item in bytes */
+    extent nb;                  /* number of items */
+    FILE *f;                    /* file to write to */
+{
+    int t;                      /* temporary */
+
+    if (key != (char *)NULL) {  /* key is the global password pointer */
+        ulg size;               /* buffer size */
+        char *p = (char*)buf;   /* steps through buffer */
+
+        /* Encrypt data in buffer */
+        for (size = item_size*(ulg)nb; size != 0; p++, size--) {
+            *p = (char)zencode(*p, t);
+        }
+    }
+    /* Write the buffer out */
+    return fwrite(buf, item_size, nb, f);
+}
+
+#endif /* ?UTIL */
+#endif /* ZIP */
+
+
+#if (defined(UNZIP) && !defined(FUNZIP))
+
+/***********************************************************************
+ * Get the password and set up keys for current zipfile member.
+ * Return PK_ class error.
+ */
+int decrypt(__G__ passwrd)
+    __GDEF
+    ZCONST char *passwrd;
+{
+    ush b;
+    int n, r;
+    uch h[RAND_HEAD_LEN];
+
+    Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
+
+    /* get header once (turn off "encrypted" flag temporarily so we don't
+     * try to decrypt the same data twice) */
+    GLOBAL(pInfo->encrypted) = FALSE;
+    defer_leftover_input(__G);
+    for (n = 0; n < RAND_HEAD_LEN; n++) {
+        /* 2012-11-23 SMS.  (OUSPG report.)
+         * Quit early if compressed size < HEAD_LEN.  The resulting
+         * error message ("unable to get password") could be improved,
+         * but it's better than trying to read nonexistent data, and
+         * then continuing with a negative G.csize.  (See
+         * fileio.c:readbyte()).
+         */
+        if ((b = NEXTBYTE) == (ush)EOF)
+        {
+            return PK_ERR;
+        }
+        h[n] = (uch)b;
+        Trace((stdout, " (%02x)", h[n]));
+    }
+    undefer_input(__G);
+    GLOBAL(pInfo->encrypted) = TRUE;
+
+    if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
+        GLOBAL(newzip) = FALSE;
+        if (passwrd != (char *)NULL) { /* user gave password on command line */
+            if (!GLOBAL(key)) {
+                if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
+                    (char *)NULL)
+                    return PK_MEM2;
+                strcpy(GLOBAL(key), passwrd);
+                GLOBAL(nopwd) = TRUE;  /* inhibit password prompting! */
+            }
+        } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
+            free(GLOBAL(key));
+            GLOBAL(key) = (char *)NULL;
+        }
+    }
+
+    /* if have key already, test it; else allocate memory for it */
+    if (GLOBAL(key)) {
+        if (!testp(__G__ h))
+            return PK_COOL;   /* existing password OK (else prompt for new) */
+        else if (GLOBAL(nopwd))
+            return PK_WARN;   /* user indicated no more prompting */
+    } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
+        return PK_MEM2;
+
+    /* try a few keys */
+    n = 0;
+    do {
+        r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
+                             GLOBAL(zipfn), GLOBAL(filename));
+        if (r == IZ_PW_ERROR) {         /* internal error in fetch of PW */
+            free (GLOBAL(key));
+            GLOBAL(key) = NULL;
+            return PK_MEM2;
+        }
+        if (r != IZ_PW_ENTERED) {       /* user replied "skip" or "skip all" */
+            *GLOBAL(key) = '\0';        /*   We try the NIL password, ... */
+            n = 0;                      /*   and cancel fetch for this item. */
+        }
+        if (!testp(__G__ h))
+            return PK_COOL;
+        if (r == IZ_PW_CANCELALL)       /* User replied "Skip all" */
+            GLOBAL(nopwd) = TRUE;       /*   inhibit any further PW prompt! */
+    } while (n > 0);
+
+    return PK_WARN;
+
+} /* end function decrypt() */
+
+
+
+/***********************************************************************
+ * Test the password.  Return -1 if bad, 0 if OK.
+ */
+local int testp(__G__ h)
+    __GDEF
+    ZCONST uch *h;
+{
+    int r;
+    char *key_translated;
+
+    /* On systems with "obscure" native character coding (e.g., EBCDIC),
+     * the first test translates the password to the "main standard"
+     * character coding. */
+
+#ifdef STR_TO_CP1
+    /* allocate buffer for translated password */
+    if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+        return -1;
+    /* first try, test password translated "standard" charset */
+    r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
+#else /* !STR_TO_CP1 */
+    /* first try, test password as supplied on the extractor's host */
+    r = testkey(__G__ h, GLOBAL(key));
+#endif /* ?STR_TO_CP1 */
+
+#ifdef STR_TO_CP2
+    if (r != 0) {
+#ifndef STR_TO_CP1
+        /* now prepare for second (and maybe third) test with translated pwd */
+        if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+            return -1;
+#endif
+        /* second try, password translated to alternate ("standard") charset */
+        r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
+#ifdef STR_TO_CP3
+        if (r != 0)
+            /* third try, password translated to another "standard" charset */
+            r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
+#endif
+#ifndef STR_TO_CP1
+        free(key_translated);
+#endif
+    }
+#endif /* STR_TO_CP2 */
+
+#ifdef STR_TO_CP1
+    free(key_translated);
+    if (r != 0) {
+        /* last resort, test password as supplied on the extractor's host */
+        r = testkey(__G__ h, GLOBAL(key));
+    }
+#endif /* STR_TO_CP1 */
+
+    return r;
+
+} /* end function testp() */
+
+
+local int testkey(__G__ h, key)
+    __GDEF
+    ZCONST uch *h;      /* decrypted header */
+    ZCONST char *key;   /* decryption password to test */
+{
+    ush b;
+#ifdef ZIP10
+    ush c;
+#endif
+    int n;
+    uch *p;
+    uch hh[RAND_HEAD_LEN]; /* decrypted header */
+
+    /* set keys and save the encrypted header */
+    init_keys(__G__ key);
+    memcpy(hh, h, RAND_HEAD_LEN);
+
+    /* check password */
+    for (n = 0; n < RAND_HEAD_LEN; n++) {
+        zdecode(hh[n]);
+        Trace((stdout, " %02x", hh[n]));
+    }
+
+    Trace((stdout,
+      "\n  lrec.crc= %08lx  crec.crc= %08lx  pInfo->ExtLocHdr= %s\n",
+      GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
+      GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
+    Trace((stdout, "  incnt = %d  unzip offset into zipfile = %ld\n",
+      GLOBAL(incnt),
+      GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
+
+    /* same test as in zipbare(): */
+
+#ifdef ZIP10 /* check two bytes */
+    c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
+    Trace((stdout,
+      "  (c | (b<<8)) = %04x  (crc >> 16) = %04x  lrec.time = %04x\n",
+      (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
+      ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
+    if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
+                           ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
+                           (ush)(GLOBAL(lrec.crc32) >> 16)))
+        return -1;  /* bad */
+#else
+    b = hh[RAND_HEAD_LEN-1];
+    Trace((stdout, "  b = %02x  (crc >> 24) = %02x  (lrec.time >> 8) = %02x\n",
+      b, (ush)(GLOBAL(lrec.crc32) >> 24),
+      ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
+    if (b != (GLOBAL(pInfo->ExtLocHdr) ?
+        ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
+        (ush)(GLOBAL(lrec.crc32) >> 24)))
+        return -1;  /* bad */
+#endif
+    /* password OK:  decrypt current buffer contents before leaving */
+    for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
+             (int)GLOBAL(csize) : GLOBAL(incnt),
+         p = GLOBAL(inptr); n--; p++)
+        zdecode(*p);
+    return 0;       /* OK */
+
+} /* end function testkey() */
+
+#endif /* UNZIP && !FUNZIP */
+
+#else /* !CRYPT */
+
+/* something "externally visible" to shut up compiler/linker warnings */
+int zcr_dummy;
+
+#endif /* ?CRYPT */
Index: unzip/create-6.0-slackware-patch/unzip60-new/extract.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/extract.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/extract.c	(revision 5)
@@ -0,0 +1,3031 @@
+/*
+  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
+*/
+/*---------------------------------------------------------------------------
+
+  extract.c
+
+  This file contains the high-level routines ("driver routines") for extrac-
+  ting and testing zipfile members.  It calls the low-level routines in files
+  explode.c, inflate.c, unreduce.c and unshrink.c.
+
+  Contains:  extract_or_test_files()
+             store_info()
+             find_compr_idx()
+             extract_or_test_entrylist()
+             extract_or_test_member()
+             TestExtraField()
+             test_compr_eb()
+             memextract()
+             memflush()
+             extract_izvms_block()    (VMS or VMS_TEXT_CONV)
+             set_deferred_symlink()   (SYMLINKS only)
+             fnfilter()
+             dircomp()                (SET_DIR_ATTRIB only)
+             UZbunzip2()              (USE_BZIP2 only)
+
+  ---------------------------------------------------------------------------*/
+
+
+#define __EXTRACT_C     /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+#  ifdef POCKET_UNZIP
+#    include "wince/intrface.h"
+#  else
+#    include "windll/windll.h"
+#  endif
+#endif
+#include "crc32.h"
+#include "crypt.h"
+#include <wctype.h>
+
+#define GRRDUMP(buf,len) { \
+    int i, j; \
+ \
+    for (j = 0;  j < (len)/16;  ++j) { \
+        printf("        "); \
+        for (i = 0;  i < 16;  ++i) \
+            printf("%02x ", (uch)(buf)[i+(j<<4)]); \
+        printf("\n        "); \
+        for (i = 0;  i < 16;  ++i) { \
+            char c = (char)(buf)[i+(j<<4)]; \
+ \
+            if (c == '\n') \
+                printf("\\n "); \
+            else if (c == '\r') \
+                printf("\\r "); \
+            else \
+                printf(" %c ", c); \
+        } \
+        printf("\n"); \
+    } \
+    if ((len) % 16) { \
+        printf("        "); \
+        for (i = j<<4;  i < (len);  ++i) \
+            printf("%02x ", (uch)(buf)[i]); \
+        printf("\n        "); \
+        for (i = j<<4;  i < (len);  ++i) { \
+            char c = (char)(buf)[i]; \
+ \
+            if (c == '\n') \
+                printf("\\n "); \
+            else if (c == '\r') \
+                printf("\\r "); \
+            else \
+                printf(" %c ", c); \
+        } \
+        printf("\n"); \
+    } \
+}
+
+static int store_info OF((__GPRO));
+#ifdef SET_DIR_ATTRIB
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
+                unsigned *pnum_dirs, direntry **pdirlist,
+                int error_in_archive));
+#else
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
+                int error_in_archive));
+#endif
+static int extract_or_test_member OF((__GPRO));
+#ifndef SFX
+   static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
+   static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
+        unsigned compr_offset,
+        int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+                              uch *eb_ucptr, ulg eb_ucsize)));
+#endif
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+   static void decompress_bits OF((uch *outptr, unsigned needlen,
+                                   ZCONST uch *bitptr));
+#endif
+#ifdef SYMLINKS
+   static void set_deferred_symlink OF((__GPRO__ slinkentry *slnk_entry));
+#endif
+#ifdef SET_DIR_ATTRIB
+   static int Cdecl dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
+#endif
+
+
+
+/*******************************/
+/*  Strings used in extract.c  */
+/*******************************/
+
+static ZCONST char Far VersionMsg[] =
+  "   skipping: %-22s  need %s compat. v%u.%u (can do v%u.%u)\n";
+static ZCONST char Far ComprMsgNum[] =
+  "   skipping: %-22s  unsupported compression method %u\n";
+#ifndef SFX
+   static ZCONST char Far ComprMsgName[] =
+     "   skipping: %-22s  `%s' method not supported\n";
+   static ZCONST char Far CmprNone[]       = "store";
+   static ZCONST char Far CmprShrink[]     = "shrink";
+   static ZCONST char Far CmprReduce[]     = "reduce";
+   static ZCONST char Far CmprImplode[]    = "implode";
+   static ZCONST char Far CmprTokenize[]   = "tokenize";
+   static ZCONST char Far CmprDeflate[]    = "deflate";
+   static ZCONST char Far CmprDeflat64[]   = "deflate64";
+   static ZCONST char Far CmprDCLImplode[] = "DCL implode";
+   static ZCONST char Far CmprBzip[]       = "bzip2";
+   static ZCONST char Far CmprLZMA[]       = "LZMA";
+   static ZCONST char Far CmprIBMTerse[]   = "IBM/Terse";
+   static ZCONST char Far CmprIBMLZ77[]    = "IBM LZ77";
+   static ZCONST char Far CmprWavPack[]    = "WavPack";
+   static ZCONST char Far CmprPPMd[]       = "PPMd";
+   static ZCONST char Far *ComprNames[NUM_METHODS] = {
+     CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
+     CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode,
+     CmprBzip, CmprLZMA, CmprIBMTerse, CmprIBMLZ77, CmprWavPack, CmprPPMd
+   };
+   static ZCONST unsigned ComprIDs[NUM_METHODS] = {
+     STORED, SHRUNK, REDUCED1, REDUCED2, REDUCED3, REDUCED4,
+     IMPLODED, TOKENIZED, DEFLATED, ENHDEFLATED, DCLIMPLODED,
+     BZIPPED, LZMAED, IBMTERSED, IBMLZ77ED, WAVPACKED, PPMDED
+   };
+#endif /* !SFX */
+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\
+         continuing with \"central\" filename version\n";
+#endif /* !SFX */
+#if (!defined(SFX) && defined(UNICODE_SUPPORT))
+   static ZCONST char Far GP11FlagsDiffer[] =
+     "file #%lu (%s):\n\
+         mismatch between local and central GPF bit 11 (\"UTF-8\"),\n\
+         continuing with central flag (IsUTF8 = %d)\n";
+#endif /* !SFX && UNICODE_SUPPORT */
+static ZCONST char Far WrnStorUCSizCSizDiff[] =
+  "%s:  ucsize %s <> csize %s for STORED entry\n\
+         continuing with \"compressed\" size value\n";
+static ZCONST char Far ExtFieldMsg[] =
+  "%s:  bad extra field length (%s)\n";
+static ZCONST char Far OffsetMsg[] =
+  "file #%lu:  bad zipfile offset (%s):  %ld\n";
+static ZCONST char Far ExtractMsg[] =
+  "%8sing: %-22s  %s%s";
+#ifndef SFX
+   static ZCONST char Far LengthMsg[] =
+     "%s  %s:  %s bytes required to uncompress to %s bytes;\n    %s\
+      supposed to require %s bytes%s%s%s\n";
+#endif
+
+static ZCONST char Far BadFileCommLength[] = "%s:  bad file comment length\n";
+static ZCONST char Far LocalHdrSig[] = "local header sig";
+static ZCONST char Far BadLocalHdr[] = "file #%lu:  bad local header\n";
+static ZCONST char Far AttemptRecompensate[] =
+  "  (attempting to re-compensate)\n";
+#ifndef SFX
+   static ZCONST char Far BackslashPathSep[] =
+     "warning:  %s appears to use backslashes as path separators\n";
+#endif
+static ZCONST char Far AbsolutePathWarning[] =
+  "warning:  stripped absolute path spec from %s\n";
+static ZCONST char Far SkipVolumeLabel[] =
+  "   skipping: %-22s  %svolume label\n";
+
+#ifdef SET_DIR_ATTRIB   /* messages of code for setting directory attributes */
+   static ZCONST char Far DirlistEntryNoMem[] =
+     "warning:  cannot alloc memory for dir times/permissions/UID/GID\n";
+   static ZCONST char Far DirlistSortNoMem[] =
+     "warning:  cannot alloc memory to sort dir times/perms/etc.\n";
+   static ZCONST char Far DirlistSetAttrFailed[] =
+     "warning:  set times/attribs failed for %s\n";
+   static ZCONST char Far DirlistFailAttrSum[] =
+     "     failed setting times/attribs for %lu dir entries";
+#endif
+
+#ifdef SYMLINKS         /* messages of the deferred symlinks handler */
+   static ZCONST char Far SymLnkWarnNoMem[] =
+     "warning:  deferred symlink (%s) failed:\n\
+          out of memory\n";
+   static ZCONST char Far SymLnkWarnInvalid[] =
+     "warning:  deferred symlink (%s) failed:\n\
+          invalid placeholder file\n";
+   static ZCONST char Far SymLnkDeferred[] =
+     "finishing deferred symbolic links:\n";
+   static ZCONST char Far SymLnkFinish[] =
+     "  %-22s -> %s\n";
+#endif
+
+#ifndef WINDLL
+   static ZCONST char Far ReplaceQuery[] =
+# ifdef VMS
+     "new version of %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
+# else
+     "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
+# endif
+   static ZCONST char Far AssumeNone[] =
+     " NULL\n(EOF or read error, treating as \"[N]one\" ...)\n";
+   static ZCONST char Far NewNameQuery[] = "new name: ";
+   static ZCONST char Far InvalidResponse[] =
+     "error:  invalid response [%s]\n";
+#endif /* !WINDLL */
+
+static ZCONST char Far ErrorInArchive[] =
+  "At least one %serror was detected in %s.\n";
+static ZCONST char Far ZeroFilesTested[] =
+  "Caution:  zero files tested in %s.\n";
+
+#ifndef VMS
+   static ZCONST char Far VMSFormatQuery[] =
+     "\n%s:  stored in VMS format.  Extract anyway? (y/n) ";
+#endif
+
+#if CRYPT
+   static ZCONST char Far SkipCannotGetPasswd[] =
+     "   skipping: %-22s  unable to get password\n";
+   static ZCONST char Far SkipIncorrectPasswd[] =
+     "   skipping: %-22s  incorrect password\n";
+   static ZCONST char Far FilesSkipBadPasswd[] =
+     "%lu file%s skipped because of incorrect password.\n";
+   static ZCONST char Far MaybeBadPasswd[] =
+     "    (may instead be incorrect password)\n";
+#else
+   static ZCONST char Far SkipEncrypted[] =
+     "   skipping: %-22s  encrypted (not supported)\n";
+#endif
+
+static ZCONST char Far NoErrInCompData[] =
+  "No errors detected in compressed data of %s.\n";
+static ZCONST char Far NoErrInTestedFiles[] =
+  "No errors detected in %s for the %lu file%s tested.\n";
+static ZCONST char Far FilesSkipped[] =
+  "%lu file%s skipped because of unsupported compression or encoding.\n";
+
+static ZCONST char Far ErrUnzipFile[] = "  error:  %s%s %s\n";
+static ZCONST char Far ErrUnzipNoFile[] = "\n  error:  %s%s\n";
+static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
+static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
+static ZCONST char Far Inflate[] = "inflate";
+#ifdef USE_BZIP2
+  static ZCONST char Far BUnzip[] = "bunzip";
+#endif
+
+#ifndef SFX
+   static ZCONST char Far Explode[] = "explode";
+#ifndef LZW_CLEAN
+   static ZCONST char Far Unshrink[] = "unshrink";
+#endif
+#endif
+
+#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
+   static ZCONST char Far FileTruncated[] =
+     "warning:  %s is probably truncated\n";
+#endif
+
+static ZCONST char Far FileUnknownCompMethod[] =
+  "%s:  unknown compression method\n";
+static ZCONST char Far BadCRC[] = " bad CRC %08lx  (should be %08lx)\n";
+
+      /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
+char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
+char ZCONST Far TruncNTSD[] =
+  " compressed WinNT security data missing (%d bytes)%s";
+
+#ifndef SFX
+   static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
+     EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
+   static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
+     EF block length (%u bytes) invalid (< %d)\n";
+   static ZCONST char Far InvalidComprDataEAs[] =
+     " invalid compressed data for EAs\n";
+#  if (defined(WIN32) && defined(NTSD_EAS))
+     static ZCONST char Far InvalidSecurityEAs[] =
+       " EAs fail security check\n";
+#  endif
+   static ZCONST char Far UnsuppNTSDVersEAs[] =
+     " unsupported NTSD EAs version %d\n";
+   static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
+   static ZCONST char Far UnknComprMethodEAs[] =
+     " unknown compression method for EAs (%u)\n";
+   static ZCONST char Far NotEnoughMemEAs[] =
+     " out of memory while inflating EAs\n";
+   static ZCONST char Far UnknErrorEAs[] =
+     " unknown error on extended attributes\n";
+#endif /* !SFX */
+
+static ZCONST char Far UnsupportedExtraField[] =
+  "\nerror:  unsupported extra-field compression type (%u)--skipping\n";
+static ZCONST char Far BadExtraFieldCRC[] =
+  "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";
+
+
+
+
+
+/**************************************/
+/*  Function extract_or_test_files()  */
+/**************************************/
+
+int extract_or_test_files(__G)    /* return PK-type error code */
+     __GDEF
+{
+    unsigned i, j;
+    zoff_t cd_bufstart;
+    uch *cd_inptr;
+    int cd_incnt;
+    ulg filnum=0L, blknum=0L;
+    int reached_end;
+#ifndef SFX
+    int no_endsig_found;
+#endif
+    int error, error_in_archive=PK_COOL;
+    int *fn_matched=NULL, *xn_matched=NULL;
+    zucn_t members_processed;
+    ulg num_skipped=0L, num_bad_pwd=0L;
+    zoff_t old_extra_bytes = 0L;
+#ifdef SET_DIR_ATTRIB
+    unsigned num_dirs=0;
+    direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
+#endif
+
+    /*
+     * First, two general initializations are applied. These have been moved
+     * here from process_zipfiles() because they are only needed for accessing
+     * and/or extracting the data content of the zip archive.
+     */
+
+    /* a) initialize the CRC table pointer (once) */
+    if (CRC_32_TAB == NULL) {
+        if ((CRC_32_TAB = get_crc_table()) == NULL) {
+            return PK_MEM;
+        }
+    }
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+    /* b) check out if specified extraction root directory exists */
+    if (uO.exdir != (char *)NULL && G.extract_flag) {
+        G.create_dirs = !uO.fflag;
+        if ((error = checkdir(__G__ uO.exdir, ROOT)) > MPN_INF_SKIP) {
+            /* out of memory, or file in way */
+            return (error == MPN_NOMEM ? PK_MEM : PK_ERR);
+        }
+    }
+#endif /* !SFX || SFX_EXDIR */
+
+/*---------------------------------------------------------------------------
+    The basic idea of this function is as follows.  Since the central di-
+    rectory lies at the end of the zipfile and the member files lie at the
+    beginning or middle or wherever, it is not very desirable to simply
+    read a central directory entry, jump to the member and extract it, and
+    then jump back to the central directory.  In the case of a large zipfile
+    this would lead to a whole lot of disk-grinding, especially if each mem-
+    ber file is small.  Instead, we read from the central directory the per-
+    tinent information for a block of files, then go extract/test the whole
+    block.  Thus this routine contains two small(er) loops within a very
+    large outer loop:  the first of the small ones reads a block of files
+    from the central directory; the second extracts or tests each file; and
+    the outer one loops over blocks.  There's some file-pointer positioning
+    stuff in between, but that's about it.  Btw, it's because of this jump-
+    ing around that we can afford to be lenient if an error occurs in one of
+    the member files:  we should still be able to go find the other members,
+    since we know the offset of each from the beginning of the zipfile.
+  ---------------------------------------------------------------------------*/
+
+    G.pInfo = G.info;
+
+#if CRYPT
+    G.newzip = TRUE;
+#endif
+#ifndef SFX
+    G.reported_backslash = FALSE;
+#endif
+
+    /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
+    if (G.filespecs > 0  &&
+        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
+        for (i = 0;  i < G.filespecs;  ++i)
+            fn_matched[i] = FALSE;
+    if (G.xfilespecs > 0  &&
+        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
+        for (i = 0;  i < G.xfilespecs;  ++i)
+            xn_matched[i] = FALSE;
+
+/*---------------------------------------------------------------------------
+    Begin main loop over blocks of member files.  We know the entire central
+    directory is on this disk:  we would not have any of this information un-
+    less the end-of-central-directory record was on this disk, and we would
+    not have gotten to this routine unless this is also the disk on which
+    the central directory starts.  In practice, this had better be the ONLY
+    disk in the archive, but we'll add multi-disk support soon.
+  ---------------------------------------------------------------------------*/
+
+    members_processed = 0;
+#ifndef SFX
+    no_endsig_found = FALSE;
+#endif
+    reached_end = FALSE;
+    while (!reached_end) {
+        j = 0;
+#ifdef AMIGA
+        memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
+#endif
+
+        /*
+         * Loop through files in central directory, storing offsets, file
+         * attributes, case-conversion and text-conversion flags until block
+         * size is reached.
+         */
+
+        while ((j < DIR_BLKSIZ)) {
+            G.pInfo = &G.info[j];
+
+            if (readbuf(__G__ G.sig, 4) == 0) {
+                error_in_archive = PK_EOF;
+                reached_end = TRUE;     /* ...so no more left to do */
+                break;
+            }
+            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
+                 *    number of entries as stored in the end_central record?
+                 */
+                if ((members_processed
+                     & (G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+                    == G.ecrec.total_entries_central_dir) {
+#ifndef SFX
+                    /* 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)
+                      );
+#endif /* !SFX */
+                } else {
+                    /* no; we have found an error in the central directory
+                     * -> report it and stop searching for more Zip entries
+                     */
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
+                    Info(slide, 0x401,
+                         ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                    error_in_archive = PK_BADERR;
+                }
+                reached_end = TRUE;     /* ...so no more left to do */
+                break;
+            }
+            /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
+            if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
+                error_in_archive = error;   /* only PK_EOF defined */
+                reached_end = TRUE;     /* ...so no more left to do */
+                break;
+            }
+            if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+                 PK_COOL)
+            {
+                if (error > error_in_archive)
+                    error_in_archive = error;
+                if (error > PK_WARN) {  /* fatal:  no more left to do */
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(FilNamMsg),
+                      FnFilter1(G.filename), "central"));
+                    reached_end = TRUE;
+                    break;
+                }
+            }
+            if ((error = do_string(__G__ G.crec.extra_field_length,
+                EXTRA_FIELD)) != 0)
+            {
+                if (error > error_in_archive)
+                    error_in_archive = error;
+                if (error > PK_WARN) {  /* fatal */
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(ExtFieldMsg),
+                      FnFilter1(G.filename), "central"));
+                    reached_end = TRUE;
+                    break;
+                }
+            }
+#ifdef AMIGA
+            G.filenote_slot = j;
+            if ((error = do_string(__G__ G.crec.file_comment_length,
+                                   uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
+#else
+            if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
+                != PK_COOL)
+#endif
+            {
+                if (error > error_in_archive)
+                    error_in_archive = error;
+                if (error > PK_WARN) {  /* fatal */
+                    Info(slide, 0x421, ((char *)slide,
+                      LoadFarString(BadFileCommLength),
+                      FnFilter1(G.filename)));
+                    reached_end = TRUE;
+                    break;
+                }
+            }
+            if (G.process_all_files) {
+                if (store_info(__G))
+                    ++j;  /* file is OK; info[] stored; continue with next */
+                else
+                    ++num_skipped;
+            } else {
+                int   do_this_file;
+
+                if (G.filespecs == 0)
+                    do_this_file = TRUE;
+                else {  /* check if this entry matches an `include' argument */
+                    do_this_file = FALSE;
+                    for (i = 0; i < G.filespecs; i++)
+                        if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+                            do_this_file = TRUE;  /* ^-- ignore case or not? */
+                            if (fn_matched)
+                                fn_matched[i] = TRUE;
+                            break;       /* found match, so stop looping */
+                        }
+                }
+                if (do_this_file) {  /* check if this is an excluded file */
+                    for (i = 0; i < G.xfilespecs; i++)
+                        if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+                            do_this_file = FALSE; /* ^-- ignore case or not? */
+                            if (xn_matched)
+                                xn_matched[i] = TRUE;
+                            break;
+                        }
+                }
+                if (do_this_file) {
+                    if (store_info(__G))
+                        ++j;            /* file is OK */
+                    else
+                        ++num_skipped;  /* unsupp. compression or encryption */
+                }
+            } /* end if (process_all_files) */
+
+            members_processed++;
+
+        } /* end while-loop (adding files to current block) */
+
+        /* save position in central directory so can come back later */
+        cd_bufstart = G.cur_zipfile_bufstart;
+        cd_inptr = G.inptr;
+        cd_incnt = G.incnt;
+
+    /*-----------------------------------------------------------------------
+        Second loop:  process files in current block, extracting or testing
+        each one.
+      -----------------------------------------------------------------------*/
+
+        error = extract_or_test_entrylist(__G__ j,
+                        &filnum, &num_bad_pwd, &old_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+                        &num_dirs, &dirlist,
+#endif
+                        error_in_archive);
+        if (error != PK_COOL) {
+            if (error > error_in_archive)
+                error_in_archive = error;
+            /* ...and keep going (unless disk full or user break) */
+            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+                /* clear reached_end to signal premature stop ... */
+                reached_end = FALSE;
+                /* ... and cancel scanning the central directory */
+                break;
+            }
+        }
+
+
+        /*
+         * Jump back to where we were in the central directory, then go and do
+         * the next batch of files.
+         */
+
+#ifdef USE_STRM_INPUT
+        zfseeko(G.zipfd, cd_bufstart, SEEK_SET);
+        G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+        G.cur_zipfile_bufstart =
+          zlseek(G.zipfd, cd_bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+        read(G.zipfd, (char *)G.inbuf, INBUFSIZ);  /* been here before... */
+        G.inptr = cd_inptr;
+        G.incnt = cd_incnt;
+        ++blknum;
+
+#ifdef TEST
+        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
+        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
+          cur_zipfile_bufstart);
+        printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
+        printf("incnt = %d\n\n", G.incnt);
+#endif
+
+    } /* end while-loop (blocks of files in central directory) */
+
+/*---------------------------------------------------------------------------
+    Process the list of deferred symlink extractions and finish up
+    the symbolic links.
+  ---------------------------------------------------------------------------*/
+
+#ifdef SYMLINKS
+    if (G.slink_last != NULL) {
+        if (QCOND2)
+            Info(slide, 0, ((char *)slide, LoadFarString(SymLnkDeferred)));
+        while (G.slink_head != NULL) {
+           set_deferred_symlink(__G__ G.slink_head);
+           /* remove the processed entry from the chain and free its memory */
+           G.slink_last = G.slink_head;
+           G.slink_head = G.slink_last->next;
+           free(G.slink_last);
+       }
+       G.slink_last = NULL;
+    }
+#endif /* SYMLINKS */
+
+/*---------------------------------------------------------------------------
+    Go back through saved list of directories, sort and set times/perms/UIDs
+    and GIDs from the deepest level on up.
+  ---------------------------------------------------------------------------*/
+
+#ifdef SET_DIR_ATTRIB
+    if (num_dirs > 0) {
+        sorted_dirlist = (direntry **)malloc(num_dirs*sizeof(direntry *));
+        if (sorted_dirlist == (direntry **)NULL) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(DirlistSortNoMem)));
+            while (dirlist != (direntry *)NULL) {
+                direntry *d = dirlist;
+
+                dirlist = dirlist->next;
+                free(d);
+            }
+        } else {
+            ulg ndirs_fail = 0;
+
+            if (num_dirs == 1)
+                sorted_dirlist[0] = dirlist;
+            else {
+                for (i = 0;  i < num_dirs;  ++i) {
+                    sorted_dirlist[i] = dirlist;
+                    dirlist = dirlist->next;
+                }
+                qsort((char *)sorted_dirlist, num_dirs, sizeof(direntry *),
+                  dircomp);
+            }
+
+            Trace((stderr, "setting directory times/perms/attributes\n"));
+            for (i = 0;  i < num_dirs;  ++i) {
+                direntry *d = sorted_dirlist[i];
+
+                Trace((stderr, "dir = %s\n", d->fn));
+                if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
+                    ndirs_fail++;
+                    Info(slide, 0x201, ((char *)slide,
+                      LoadFarString(DirlistSetAttrFailed), d->fn));
+                    if (!error_in_archive)
+                        error_in_archive = error;
+                }
+                free(d);
+            }
+            free(sorted_dirlist);
+            if (!uO.tflag && QCOND2) {
+                if (ndirs_fail > 0)
+                    Info(slide, 0, ((char *)slide,
+                      LoadFarString(DirlistFailAttrSum), ndirs_fail));
+            }
+        }
+    }
+#endif /* SET_DIR_ATTRIB */
+
+/*---------------------------------------------------------------------------
+    Check for unmatched filespecs on command line and print warning if any
+    found.  Free allocated memory.  (But suppress check when central dir
+    scan was interrupted prematurely.)
+  ---------------------------------------------------------------------------*/
+
+    if (fn_matched) {
+        if (reached_end) for (i = 0;  i < G.filespecs;  ++i)
+            if (!fn_matched[i]) {
+#ifdef DLL
+                if (!G.redirect_data && !G.redirect_text)
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(FilenameNotMatched), G.pfnames[i]));
+                else
+                    setFileNotFound(__G);
+#else
+                Info(slide, 1, ((char *)slide,
+                  LoadFarString(FilenameNotMatched), G.pfnames[i]));
+#endif
+                if (error_in_archive <= PK_WARN)
+                    error_in_archive = PK_FIND;   /* some files not found */
+            }
+        free((zvoid *)fn_matched);
+    }
+    if (xn_matched) {
+        if (reached_end) for (i = 0;  i < G.xfilespecs;  ++i)
+            if (!xn_matched[i])
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
+        free((zvoid *)xn_matched);
+    }
+
+/*---------------------------------------------------------------------------
+    Now, all locally allocated memory has been released.  When the central
+    directory processing has been interrupted prematurely, it is safe to
+    return immediately.  All completeness checks and summary messages are
+    skipped in this case.
+  ---------------------------------------------------------------------------*/
+    if (!reached_end)
+        return error_in_archive;
+
+/*---------------------------------------------------------------------------
+    Double-check that we're back at the end-of-central-directory record, and
+    print quick summary of results, if we were just testing the archive.  We
+    send the summary to stdout so that people doing the testing in the back-
+    ground and redirecting to a file can just do a "tail" on the output file.
+  ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+    if (no_endsig_found) {                      /* just to make sure */
+        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(ReportMsg)));
+        if (!error_in_archive)       /* don't overwrite stronger error */
+            error_in_archive = PK_WARN;
+    }
+#endif /* !SFX */
+    if (uO.tflag) {
+        ulg num = filnum - num_bad_pwd;
+
+        if (uO.qflag < 2) {        /* GRR 930710:  was (uO.qflag == 1) */
+            if (error_in_archive)
+                Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
+                  (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
+            else if (num == 0L)
+                Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
+                  G.zipfn));
+            else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
+                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
+                  G.zipfn));
+            else
+                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
+                  , G.zipfn, num, (num==1L)? "":"s"));
+            if (num_skipped > 0L)
+                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
+                  num_skipped, (num_skipped==1L)? "":"s"));
+#if CRYPT
+            if (num_bad_pwd > 0L)
+                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
+                  , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
+#endif /* CRYPT */
+        }
+    }
+
+    /* give warning if files not tested or extracted (first condition can still
+     * happen if zipfile is empty and no files specified on command line) */
+
+    if ((filnum == 0) && error_in_archive <= PK_WARN) {
+        if (num_skipped > 0L)
+            error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
+        else
+            error_in_archive = PK_FIND;  /* no files found at all */
+    }
+#if CRYPT
+    else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
+        error_in_archive = IZ_BADPWD;    /* bad passwd => all files skipped */
+#endif
+    else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
+        error_in_archive = IZ_UNSUP;     /* was PK_WARN; Jean-loup complained */
+#if CRYPT
+    else if ((num_bad_pwd > 0L) && !error_in_archive)
+        error_in_archive = PK_WARN;
+#endif
+
+    return error_in_archive;
+
+} /* end function extract_or_test_files() */
+
+
+
+
+
+/***************************/
+/*  Function store_info()  */
+/***************************/
+
+static int store_info(__G)   /* return 0 if skipping, 1 if OK */
+    __GDEF
+{
+#ifdef USE_BZIP2
+#  define UNKN_BZ2 (G.crec.compression_method!=BZIPPED)
+#else
+#  define UNKN_BZ2 TRUE       /* bzip2 unknown */
+#endif
+
+#ifdef USE_LZMA
+#  define UNKN_LZMA (G.crec.compression_method!=LZMAED)
+#else
+#  define UNKN_LZMA TRUE      /* LZMA unknown */
+#endif
+
+#ifdef USE_WAVP
+#  define UNKN_WAVP (G.crec.compression_method!=WAVPACKED)
+#else
+#  define UNKN_WAVP TRUE      /* WavPack unknown */
+#endif
+
+#ifdef USE_PPMD
+#  define UNKN_PPMD (G.crec.compression_method!=PPMDED)
+#else
+#  define UNKN_PPMD TRUE      /* PPMd unknown */
+#endif
+
+#ifdef SFX
+#  ifdef USE_DEFLATE64
+#    define UNKN_COMPR \
+     (G.crec.compression_method!=STORED && G.crec.compression_method<DEFLATED \
+      && G.crec.compression_method>ENHDEFLATED \
+      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
+#  else
+#    define UNKN_COMPR \
+     (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED\
+      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
+#  endif
+#else
+#  ifdef COPYRIGHT_CLEAN  /* no reduced files */
+#    define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
+                      G.crec.compression_method <= REDUCED4)
+#  else
+#    define UNKN_RED  FALSE  /* reducing not unknown */
+#  endif
+#  ifdef LZW_CLEAN  /* no shrunk files */
+#    define UNKN_SHR (G.crec.compression_method == SHRUNK)
+#  else
+#    define UNKN_SHR  FALSE  /* unshrinking not unknown */
+#  endif
+#  ifdef USE_DEFLATE64
+#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+     G.crec.compression_method==TOKENIZED || \
+     (G.crec.compression_method>ENHDEFLATED && UNKN_BZ2 && UNKN_LZMA \
+      && UNKN_WAVP && UNKN_PPMD))
+#  else
+#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+     G.crec.compression_method==TOKENIZED || \
+     (G.crec.compression_method>DEFLATED && UNKN_BZ2 && UNKN_LZMA \
+      && UNKN_WAVP && UNKN_PPMD))
+#  endif
+#endif
+
+#if (defined(USE_BZIP2) && (UNZIP_VERSION < UNZIP_BZ2VERS))
+    int unzvers_support = (UNKN_BZ2 ? UNZIP_VERSION : UNZIP_BZ2VERS);
+#   define UNZVERS_SUPPORT  unzvers_support
+#else
+#   define UNZVERS_SUPPORT  UNZIP_VERSION
+#endif
+
+/*---------------------------------------------------------------------------
+    Check central directory info for version/compatibility requirements.
+  ---------------------------------------------------------------------------*/
+
+    G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1;   /* bit field */
+    G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8;  /* bit */
+    G.pInfo->textfile = G.crec.internal_file_attributes & 1;    /* bit field */
+    G.pInfo->crc = G.crec.crc32;
+    G.pInfo->compr_size = G.crec.csize;
+    G.pInfo->uncompr_size = G.crec.ucsize;
+
+    switch (uO.aflag) {
+        case 0:
+            G.pInfo->textmode = FALSE;   /* bit field */
+            break;
+        case 1:
+            G.pInfo->textmode = G.pInfo->textfile;   /* auto-convert mode */
+            break;
+        default:  /* case 2: */
+            G.pInfo->textmode = TRUE;
+            break;
+    }
+
+    if (G.crec.version_needed_to_extract[1] == VMS_) {
+        if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
+            if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+                Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+                  FnFilter1(G.filename), "VMS",
+                  G.crec.version_needed_to_extract[0] / 10,
+                  G.crec.version_needed_to_extract[0] % 10,
+                  VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
+            return 0;
+        }
+#ifndef VMS   /* won't be able to use extra field, but still have data */
+        else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
+            Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
+              FnFilter1(G.filename)));
+            fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
+            if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
+                return 0;
+        }
+#endif /* !VMS */
+    /* usual file type:  don't need VMS to extract */
+    } else if (G.crec.version_needed_to_extract[0] > UNZVERS_SUPPORT) {
+        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+            Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+              FnFilter1(G.filename), "PK",
+              G.crec.version_needed_to_extract[0] / 10,
+              G.crec.version_needed_to_extract[0] % 10,
+              UNZVERS_SUPPORT / 10, UNZVERS_SUPPORT % 10));
+        return 0;
+    }
+
+    if (UNKN_COMPR) {
+        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
+#ifndef SFX
+            unsigned cmpridx;
+
+            if ((cmpridx = find_compr_idx(G.crec.compression_method))
+                < NUM_METHODS)
+                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
+                  FnFilter1(G.filename),
+                  LoadFarStringSmall(ComprNames[cmpridx])));
+            else
+#endif
+                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
+                  FnFilter1(G.filename),
+                  G.crec.compression_method));
+        }
+        return 0;
+    }
+#if (!CRYPT)
+    if (G.pInfo->encrypted) {
+        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+            Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
+              FnFilter1(G.filename)));
+        return 0;
+    }
+#endif /* !CRYPT */
+
+#ifndef SFX
+    /* store a copy of the central header filename for later comparison */
+    if ((G.pInfo->cfilname = zfmalloc(strlen(G.filename) + 1)) == NULL) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(WarnNoMemCFName),
+          FnFilter1(G.filename)));
+    } else
+        zfstrcpy(G.pInfo->cfilname, G.filename);
+#endif /* !SFX */
+
+    /* map whatever file attributes we have into the local format */
+    mapattr(__G);   /* GRR:  worry about return value later */
+
+    G.pInfo->diskstart = G.crec.disk_number_start;
+    G.pInfo->offset = (zoff_t)G.crec.relative_offset_local_header;
+    return 1;
+
+} /* end function store_info() */
+
+
+
+
+
+#ifndef SFX
+/*******************************/
+/*  Function find_compr_idx()  */
+/*******************************/
+
+unsigned find_compr_idx(compr_methodnum)
+    unsigned compr_methodnum;
+{
+    unsigned i;
+
+    for (i = 0; i < NUM_METHODS; i++) {
+        if (ComprIDs[i] == compr_methodnum) break;
+    }
+    return i;
+}
+#endif /* !SFX */
+
+
+
+
+
+/******************************************/
+/*  Function extract_or_test_entrylist()  */
+/******************************************/
+
+static int extract_or_test_entrylist(__G__ numchunk,
+                pfilnum, pnum_bad_pwd, pold_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+                pnum_dirs, pdirlist,
+#endif
+                error_in_archive)    /* return PK-type error code */
+    __GDEF
+    unsigned numchunk;
+    ulg *pfilnum;
+    ulg *pnum_bad_pwd;
+    zoff_t *pold_extra_bytes;
+#ifdef SET_DIR_ATTRIB
+    unsigned *pnum_dirs;
+    direntry **pdirlist;
+#endif
+    int error_in_archive;
+{
+    unsigned i;
+    int renamed, query;
+    int skip_entry;
+    zoff_t bufstart, inbuf_offset, request;
+    int error, errcode;
+
+/* possible values for local skip_entry flag: */
+#define SKIP_NO         0       /* do not skip this entry */
+#define SKIP_Y_EXISTING 1       /* skip this entry, do not overwrite file */
+#define SKIP_Y_NONEXIST 2       /* skip this entry, do not create new file */
+
+    /*-----------------------------------------------------------------------
+        Second loop:  process files in current block, extracting or testing
+        each one.
+      -----------------------------------------------------------------------*/
+
+    for (i = 0; i < numchunk; ++i) {
+        (*pfilnum)++;   /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
+        G.pInfo = &G.info[i];
+#ifdef NOVELL_BUG_FAILSAFE
+        G.dne = FALSE;  /* assume file exists until stat() says otherwise */
+#endif
+
+        /* if the target position is not within the current input buffer
+         * (either haven't yet read far enough, or (maybe) skipping back-
+         * ward), skip to the target position and reset readbuf(). */
+
+        /* seek_zipf(__G__ pInfo->offset);  */
+        request = G.pInfo->offset + G.extra_bytes;
+        inbuf_offset = request % INBUFSIZ;
+        bufstart = request - inbuf_offset;
+
+        Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
+          (long)request, (long)inbuf_offset));
+        Trace((stderr,
+          "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+          (long)bufstart, (long)G.cur_zipfile_bufstart));
+        if (request < 0) {
+            Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
+              G.zipfn, LoadFarString(ReportMsg)));
+            error_in_archive = PK_ERR;
+            if (*pfilnum == 1 && G.extra_bytes != 0L) {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(AttemptRecompensate)));
+                *pold_extra_bytes = G.extra_bytes;
+                G.extra_bytes = 0L;
+                request = G.pInfo->offset;  /* could also check if != 0 */
+                inbuf_offset = request % INBUFSIZ;
+                bufstart = request - inbuf_offset;
+                Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
+                  (long)request, (long)inbuf_offset));
+                Trace((stderr,
+                  "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+                  (long)bufstart, (long)G.cur_zipfile_bufstart));
+                /* try again */
+                if (request < 0) {
+                    Trace((stderr,
+                      "debug: recompensated request still < 0\n"));
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarStringSmall(SeekMsg),
+                      G.zipfn, LoadFarString(ReportMsg)));
+                    error_in_archive = PK_BADERR;
+                    continue;
+                }
+            } else {
+                error_in_archive = PK_BADERR;
+                continue;  /* this one hosed; try next */
+            }
+        }
+
+        if (bufstart != G.cur_zipfile_bufstart) {
+            Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
+#ifdef USE_STRM_INPUT
+            zfseeko(G.zipfd, bufstart, SEEK_SET);
+            G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+            G.cur_zipfile_bufstart =
+              zlseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+            if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+            {
+                Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+                  *pfilnum, "lseek", (long)bufstart));
+                error_in_archive = PK_BADERR;
+                continue;   /* can still do next file */
+            }
+            G.inptr = G.inbuf + (int)inbuf_offset;
+            G.incnt -= (int)inbuf_offset;
+        } else {
+            G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
+            G.inptr = G.inbuf + (int)inbuf_offset;
+        }
+
+        /* should be in proper position now, so check for sig */
+        if (readbuf(__G__ G.sig, 4) == 0) {  /* bad offset */
+            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+              *pfilnum, "EOF", (long)request));
+            error_in_archive = PK_BADERR;
+            continue;   /* but can still try next one */
+        }
+        if (memcmp(G.sig, local_hdr_sig, 4)) {
+            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+              *pfilnum, LoadFarStringSmall(LocalHdrSig), (long)request));
+            /*
+                GRRDUMP(G.sig, 4)
+                GRRDUMP(local_hdr_sig, 4)
+             */
+            error_in_archive = PK_ERR;
+            if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
+                (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(AttemptRecompensate)));
+                if (G.extra_bytes) {
+                    *pold_extra_bytes = G.extra_bytes;
+                    G.extra_bytes = 0L;
+                } else
+                    G.extra_bytes = *pold_extra_bytes; /* third attempt */
+                if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
+                    (readbuf(__G__ G.sig, 4) == 0)) {  /* bad offset */
+                    if (error != PK_BADERR)
+                      Info(slide, 0x401, ((char *)slide,
+                        LoadFarString(OffsetMsg), *pfilnum, "EOF",
+                        (long)request));
+                    error_in_archive = PK_BADERR;
+                    continue;   /* but can still try next one */
+                }
+                if (memcmp(G.sig, local_hdr_sig, 4)) {
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(OffsetMsg), *pfilnum,
+                      LoadFarStringSmall(LocalHdrSig), (long)request));
+                    error_in_archive = PK_BADERR;
+                    continue;
+                }
+            } else
+                continue;  /* this one hosed; try next */
+        }
+        if ((error = process_local_file_hdr(__G)) != PK_COOL) {
+            Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
+              *pfilnum));
+            error_in_archive = error;   /* only PK_EOF defined */
+            continue;   /* can still try next one */
+        }
+#if (!defined(SFX) && defined(UNICODE_SUPPORT))
+        if (((G.lrec.general_purpose_bit_flag & (1 << 11)) == (1 << 11))
+            != (G.pInfo->GPFIsUTF8 != 0)) {
+            if (QCOND2) {
+#  ifdef SMALL_MEM
+                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
+
+                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
+#    define  cFile_PrintBuf  temp_cfilnam
+#  else
+#    define  cFile_PrintBuf  G.pInfo->cfilname
+#  endif
+                Info(slide, 0x421, ((char *)slide,
+                  LoadFarStringSmall2(GP11FlagsDiffer),
+                  *pfilnum, FnFilter1(cFile_PrintBuf), G.pInfo->GPFIsUTF8));
+#  undef    cFile_PrintBuf
+            }
+            if (error_in_archive < PK_WARN)
+                error_in_archive = PK_WARN;
+        }
+#endif /* !SFX && UNICODE_SUPPORT */
+        if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
+             PK_COOL)
+        {
+            if (error > error_in_archive)
+                error_in_archive = error;
+            if (error > PK_WARN) {
+                Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
+                  FnFilter1(G.filename), "local"));
+                continue;   /* go on to next one */
+            }
+        }
+        if (G.extra_field != (uch *)NULL) {
+            free(G.extra_field);
+            G.extra_field = (uch *)NULL;
+        }
+        if ((error =
+             do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
+        {
+            if (error > error_in_archive)
+                error_in_archive = error;
+            if (error > PK_WARN) {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(ExtFieldMsg),
+                  FnFilter1(G.filename), "local"));
+                continue;   /* go on */
+            }
+        }
+#ifndef SFX
+        /* Filename consistency checks must come after reading in the local
+         * extra field, so that a UTF-8 entry name e.f. block has already
+         * been processed.
+         */
+        if (G.pInfo->cfilname != (char Far *)NULL) {
+            if (zfstrcmp(G.pInfo->cfilname, G.filename) != 0) {
+#  ifdef SMALL_MEM
+                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
+
+                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
+#    define  cFile_PrintBuf  temp_cfilnam
+#  else
+#    define  cFile_PrintBuf  G.pInfo->cfilname
+#  endif
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarStringSmall2(LvsCFNamMsg),
+                  FnFilter2(cFile_PrintBuf), FnFilter1(G.filename)));
+#  undef    cFile_PrintBuf
+                zfstrcpy(G.filename, G.pInfo->cfilname);
+                if (error_in_archive < PK_WARN)
+                    error_in_archive = PK_WARN;
+            }
+            zffree(G.pInfo->cfilname);
+            G.pInfo->cfilname = (char Far *)NULL;
+        }
+#endif /* !SFX */
+        /* Size consistency checks must come after reading in the local extra
+         * field, so that any Zip64 extension local e.f. block has already
+         * been processed.
+         */
+        if (G.lrec.compression_method == STORED) {
+            zusz_t csiz_decrypted = G.lrec.csize;
+
+            if (G.pInfo->encrypted) {
+                if (csiz_decrypted < 12) {
+                    /* handle the error now to prevent unsigned overflow */
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarStringSmall(ErrUnzipNoFile),
+                      LoadFarString(InvalidComprData),
+                      LoadFarStringSmall2(Inflate)));
+                    return PK_ERR;
+                }
+                csiz_decrypted -= 12;
+            }
+            if (G.lrec.ucsize != csiz_decrypted) {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarStringSmall2(WrnStorUCSizCSizDiff),
+                  FnFilter1(G.filename),
+                  FmZofft(G.lrec.ucsize, NULL, "u"),
+                  FmZofft(csiz_decrypted, NULL, "u")));
+                G.lrec.ucsize = csiz_decrypted;
+                if (error_in_archive < PK_WARN)
+                    error_in_archive = PK_WARN;
+            }
+        }
+
+#if CRYPT
+        if (G.pInfo->encrypted &&
+            (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
+            if (error == PK_WARN) {
+                if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(SkipIncorrectPasswd),
+                      FnFilter1(G.filename)));
+                ++(*pnum_bad_pwd);
+            } else {  /* (error > PK_WARN) */
+                if (error > error_in_archive)
+                    error_in_archive = error;
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(SkipCannotGetPasswd),
+                  FnFilter1(G.filename)));
+            }
+            continue;   /* go on to next file */
+        }
+#endif /* CRYPT */
+
+        /*
+         * 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) {
+               /* remove absolute path specs */
+               if (G.filename[0] == '/') {
+                   Info(slide, 0x401, ((char *)slide,
+                        LoadFarString(AbsolutePathWarning),
+                        FnFilter1(G.filename)));
+                   if (!error_in_archive)
+                       error_in_archive = PK_WARN;
+                   do {
+                       char *p = G.filename + 1;
+                       do {
+                           *(p-1) = *p;
+                       } while (*p++ != '\0');
+                   } while (G.filename[0] == '/');
+               }
+            }
+
+            /* mapname can create dirs if not freshening or if renamed */
+            error = mapname(__G__ renamed);
+            if ((errcode = error & ~MPN_MASK) != PK_OK &&
+                error_in_archive < errcode)
+                error_in_archive = errcode;
+            if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
+                if (errcode == MPN_CREATED_DIR) {
+#ifdef SET_DIR_ATTRIB
+                    direntry *d_entry;
+
+                    error = defer_dir_attribs(__G__ &d_entry);
+                    if (d_entry == (direntry *)NULL) {
+                        /* There may be no dir_attribs info available, or
+                         * we have encountered a mem allocation error.
+                         * In case of an error, report it and set program
+                         * error state to warning level.
+                         */
+                        if (error) {
+                            Info(slide, 0x401, ((char *)slide,
+                                 LoadFarString(DirlistEntryNoMem)));
+                            if (!error_in_archive)
+                                error_in_archive = PK_WARN;
+                        }
+                    } else {
+                        d_entry->next = (*pdirlist);
+                        (*pdirlist) = d_entry;
+                        ++(*pnum_dirs);
+                    }
+#endif /* SET_DIR_ATTRIB */
+                } else if (errcode == MPN_VOL_LABEL) {
+#ifdef DOS_OS2_W32
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(SkipVolumeLabel),
+                      FnFilter1(G.filename),
+                      uO.volflag? "hard disk " : ""));
+#else
+                    Info(slide, 1, ((char *)slide,
+                      LoadFarString(SkipVolumeLabel),
+                      FnFilter1(G.filename), ""));
+#endif
+                } else if (errcode > MPN_INF_SKIP &&
+                           error_in_archive < PK_ERR)
+                    error_in_archive = PK_ERR;
+                Trace((stderr, "mapname(%s) returns error code = %d\n",
+                  FnFilter1(G.filename), error));
+                continue;   /* go on to next file */
+            }
+
+#ifdef QDOS
+            QFilename(__G__ G.filename);
+#endif
+            switch (check_for_newer(__G__ G.filename)) {
+                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) {
+                /* 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(G.answerbuf, sizeof(G.answerbuf), stdin)
+                    == (char *)NULL) {
+                    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)));
+                            fgets(G.filename, FILNAMSIZ, stdin);
+                            /* usually get \n here:  better 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.  Skipping %s\n" :
+                       "Target file newer.  Skipping %s\n"),
+                      FnFilter1(G.filename)));
+                }
+#endif /* WINDLL */
+                continue;
+            }
+        } /* end if (extracting to disk) */
+
+#ifdef DLL
+        if ((G.statreportcb != NULL) &&
+            (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
+                              G.filename, NULL)) {
+            return IZ_CTRLC;        /* cancel operation by user request */
+        }
+#endif
+#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
+        UserStop();
+#endif
+#ifdef AMIGA
+        G.filenote_slot = i;
+#endif
+        G.disk_full = 0;
+        if ((error = extract_or_test_member(__G)) != PK_COOL) {
+            if (error > error_in_archive)
+                error_in_archive = error;       /* ...and keep going */
+#ifdef DLL
+            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+#else
+            if (G.disk_full > 1) {
+#endif
+                return error_in_archive;        /* (unless disk full) */
+            }
+        }
+#ifdef DLL
+        if ((G.statreportcb != NULL) &&
+            (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
+                              G.filename, (zvoid *)&G.lrec.ucsize)) {
+            return IZ_CTRLC;        /* cancel operation by user request */
+        }
+#endif
+#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
+        UserStop();
+#endif
+    } /* end for-loop (i:  files in current block) */
+
+    return error_in_archive;
+
+} /* end function extract_or_test_entrylist() */
+
+
+
+
+
+/* wsize is used in extract_or_test_member() and UZbunzip2() */
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+#  define wsize G._wsize    /* wsize is a variable */
+#else
+#  define wsize WSIZE       /* wsize is a constant */
+#endif
+
+/***************************************/
+/*  Function extract_or_test_member()  */
+/***************************************/
+
+static int extract_or_test_member(__G)    /* return PK-type error code */
+     __GDEF
+{
+    char *nul="[empty] ", *txt="[text]  ", *bin="[binary]";
+#ifdef CMS_MVS
+    char *ebc="[ebcdic]";
+#endif
+    register int b;
+    int r, error=PK_COOL;
+
+
+/*---------------------------------------------------------------------------
+    Initialize variables, buffers, etc.
+  ---------------------------------------------------------------------------*/
+
+    G.bits_left = 0;
+    G.bitbuf = 0L;       /* unreduce and unshrink only */
+    G.zipeof = 0;
+    G.newfile = TRUE;
+    G.crc32val = CRCVAL_INITIAL;
+
+#ifdef SYMLINKS
+    /* If file is a (POSIX-compatible) symbolic link and we are extracting
+     * to disk, prepare to restore the link. */
+    G.symlnk = (G.pInfo->symlink &&
+                !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0));
+#endif /* SYMLINKS */
+
+    if (uO.tflag) {
+        if (!uO.qflag)
+            Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
+              FnFilter1(G.filename), "", ""));
+    } else {
+#ifdef DLL
+        if (uO.cflag && !G.redirect_data)
+#else
+        if (uO.cflag)
+#endif
+        {
+#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
+            G.outfile = freopen("", "wb", stdout);   /* VAC++ ignores setmode */
+#else
+            G.outfile = stdout;
+#endif
+#ifdef DOS_FLX_NLM_OS2_W32
+#if (defined(__HIGHC__) && !defined(FLEXOS))
+            setmode(G.outfile, _BINARY);
+#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
+            setmode(fileno(G.outfile), O_BINARY);
+#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
+#           define NEWLINE "\r\n"
+#else /* !DOS_FLX_NLM_OS2_W32 */
+#           define NEWLINE "\n"
+#endif /* ?DOS_FLX_NLM_OS2_W32 */
+#ifdef VMS
+            /* VMS:  required even for stdout! */
+            if ((r = open_outfile(__G)) != 0)
+                switch (r) {
+                  case OPENOUT_SKIPOK:
+                    return PK_OK;
+                  case OPENOUT_SKIPWARN:
+                    return PK_WARN;
+                  default:
+                    return PK_DISK;
+                }
+        } else if ((r = open_outfile(__G)) != 0)
+            switch (r) {
+              case OPENOUT_SKIPOK:
+                return PK_OK;
+              case OPENOUT_SKIPWARN:
+                return PK_WARN;
+              default:
+                return PK_DISK;
+            }
+#else /* !VMS */
+        } else if (open_outfile(__G))
+            return PK_DISK;
+#endif /* ?VMS */
+    }
+
+/*---------------------------------------------------------------------------
+    Unpack the file.
+  ---------------------------------------------------------------------------*/
+
+    defer_leftover_input(__G);    /* so NEXTBYTE bounds check will work */
+    switch (G.lrec.compression_method) {
+        case STORED:
+            if (!uO.tflag && QCOND2) {
+#ifdef SYMLINKS
+                if (G.symlnk)   /* can also be deflated, but rarer... */
+                    Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                      "link", FnFilter1(G.filename), "", ""));
+                else
+#endif /* SYMLINKS */
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  "extract", FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
+                  bin)), uO.cflag? NEWLINE : ""));
+            }
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+            if (G.redirect_slide) {
+                wsize = G.redirect_size; redirSlide = G.redirect_buffer;
+            } else {
+                wsize = WSIZE; redirSlide = slide;
+            }
+#endif
+            G.outptr = redirSlide;
+            G.outcnt = 0L;
+            while ((b = NEXTBYTE) != EOF) {
+                *G.outptr++ = (uch)b;
+                if (++G.outcnt == wsize) {
+                    error = flush(__G__ redirSlide, G.outcnt, 0);
+                    G.outptr = redirSlide;
+                    G.outcnt = 0L;
+                    if (error != PK_COOL || G.disk_full) break;
+                }
+            }
+            if (G.outcnt) {        /* flush final (partial) buffer */
+                r = flush(__G__ redirSlide, G.outcnt, 0);
+                if (error < r) error = r;
+            }
+            break;
+
+#ifndef SFX
+#ifndef LZW_CLEAN
+        case SHRUNK:
+            if (!uO.tflag && QCOND2) {
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+            }
+            if ((r = unshrink(__G)) != PK_COOL) {
+                if (r < PK_DISK) {
+                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipFile), r == PK_MEM3 ?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Unshrink),
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipNoFile), r == PK_MEM3 ?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Unshrink)));
+                }
+                error = r;
+            }
+            break;
+#endif /* !LZW_CLEAN */
+
+#ifndef COPYRIGHT_CLEAN
+        case REDUCED1:
+        case REDUCED2:
+        case REDUCED3:
+        case REDUCED4:
+            if (!uO.tflag && QCOND2) {
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  "unreduc", FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+            }
+            if ((r = unreduce(__G)) != PK_COOL) {
+                /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
+                error = r;
+            }
+            break;
+#endif /* !COPYRIGHT_CLEAN */
+
+        case IMPLODED:
+            if (!uO.tflag && QCOND2) {
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  "explod", FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+            }
+            if ((r = explode(__G)) != 0) {
+                if (r == 5) { /* treat 5 specially */
+                    int warning = ((zusz_t)G.used_csize <= G.lrec.csize);
+
+                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(LengthMsg),
+                          "", warning ? "warning" : "error",
+                          FmZofft(G.used_csize, NULL, NULL),
+                          FmZofft(G.lrec.ucsize, NULL, "u"),
+                          warning ? "  " : "",
+                          FmZofft(G.lrec.csize, NULL, "u"),
+                          " [", FnFilter1(G.filename), "]"));
+                    else
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(LengthMsg),
+                          "\n", warning ? "warning" : "error",
+                          FmZofft(G.used_csize, NULL, NULL),
+                          FmZofft(G.lrec.ucsize, NULL, "u"),
+                          warning ? "  " : "",
+                          FmZofft(G.lrec.csize, NULL, "u"),
+                          "", "", "."));
+                    error = warning ? PK_WARN : PK_ERR;
+                } else if (r < PK_DISK) {
+                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Explode),
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Explode)));
+                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
+                } else {
+                    error = r;
+                }
+            }
+            break;
+#endif /* !SFX */
+
+        case DEFLATED:
+#ifdef USE_DEFLATE64
+        case ENHDEFLATED:
+#endif
+            if (!uO.tflag && QCOND2) {
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  "inflat", FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+            }
+#ifndef USE_ZLIB  /* zlib's function is called inflate(), too */
+#  define UZinflate inflate
+#endif
+            if ((r = UZinflate(__G__
+                               (G.lrec.compression_method == ENHDEFLATED)))
+                != 0) {
+                if (r < PK_DISK) {
+                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Inflate),
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(Inflate)));
+                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
+                } else {
+                    error = r;
+                }
+            }
+            break;
+
+#ifdef USE_BZIP2
+        case BZIPPED:
+            if (!uO.tflag && QCOND2) {
+                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+                  "bunzipp", FnFilter1(G.filename),
+                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+            }
+            if ((r = UZbunzip2(__G)) != 0) {
+                if (r < PK_DISK) {
+                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(BUnzip),
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+                          LoadFarString(NotEnoughMem) :
+                          LoadFarString(InvalidComprData),
+                          LoadFarStringSmall2(BUnzip)));
+                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
+                } else {
+                    error = r;
+                }
+            }
+            break;
+#endif /* USE_BZIP2 */
+
+        default:   /* should never get to this point */
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
+            /* close and delete file before return? */
+            undefer_input(__G);
+            return PK_WARN;
+
+    } /* end switch (compression method) */
+
+/*---------------------------------------------------------------------------
+    Close the file and set its date and time (not necessarily in that order),
+    and make sure the CRC checked out OK.  Logical-AND the CRC for 64-bit
+    machines (redundant on 32-bit machines).
+  ---------------------------------------------------------------------------*/
+
+#ifdef VMS                  /* VMS:  required even for stdout! (final flush) */
+    if (!uO.tflag)           /* don't close NULL file */
+        error = close_outfile(__G);
+#else
+#ifdef DLL
+    if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
+        if (G.redirect_data)
+            FINISH_REDIRECT();
+        else
+            error = close_outfile(__G);
+    }
+#else
+    if (!uO.tflag && !uO.cflag)   /* don't close NULL file or stdout */
+        error = close_outfile(__G);
+#endif
+#endif /* VMS */
+
+    if (G.disk_full) {            /* set by flush() */
+        if (G.disk_full > 1) {
+#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
+            /* delete the incomplete file if we can */
+            if (unlink(G.filename) != 0)
+                Trace((stderr, "extract.c:  could not delete %s\n",
+                  FnFilter1(G.filename)));
+#else
+            /* warn user about the incomplete file */
+            Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
+              FnFilter1(G.filename)));
+#endif
+            error = PK_DISK;
+        } else {
+            error = PK_WARN;
+        }
+    }
+
+    if (error > PK_WARN) {/* don't print redundant CRC error if error already */
+        undefer_input(__G);
+        return error;
+    }
+    if (G.crc32val != G.lrec.crc32) {
+        /* if quiet enough, we haven't output the filename yet:  do it */
+        if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+            Info(slide, 0x401, ((char *)slide, "%-22s ",
+              FnFilter1(G.filename)));
+        Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
+          G.lrec.crc32));
+#if CRYPT
+        if (G.pInfo->encrypted)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
+#endif
+        error = PK_ERR;
+    } else if (uO.tflag) {
+#ifndef SFX
+        if (G.extra_field) {
+            if ((r = TestExtraField(__G__ G.extra_field,
+                                    G.lrec.extra_field_length)) > error)
+                error = r;
+        } else
+#endif /* !SFX */
+        if (!uO.qflag)
+            Info(slide, 0, ((char *)slide, " OK\n"));
+    } else {
+        if (QCOND2 && !error)   /* GRR:  is stdout reset to text mode yet? */
+            Info(slide, 0, ((char *)slide, "\n"));
+    }
+
+    undefer_input(__G);
+    return error;
+
+} /* end function extract_or_test_member() */
+
+
+
+
+
+#ifndef SFX
+
+/*******************************/
+/*  Function TestExtraField()  */
+/*******************************/
+
+static int TestExtraField(__G__ ef, ef_len)
+    __GDEF
+    uch *ef;
+    unsigned ef_len;
+{
+    ush ebID;
+    unsigned ebLen;
+    unsigned eb_cmpr_offs = 0;
+    int r;
+
+    /* we know the regular compressed file data tested out OK, or else we
+     * wouldn't be here ==> print filename if any extra-field errors found
+     */
+    while (ef_len >= EB_HEADSIZE) {
+        ebID = makeword(ef);
+        ebLen = (unsigned)makeword(ef+EB_LEN);
+
+        if (ebLen > (ef_len - EB_HEADSIZE))
+        {
+           /* Discovered some extra field inconsistency! */
+            if (uO.qflag)
+                Info(slide, 1, ((char *)slide, "%-22s ",
+                  FnFilter1(G.filename)));
+            Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
+              ebLen, (ef_len - EB_HEADSIZE)));
+            return PK_ERR;
+        }
+
+        switch (ebID) {
+            case EF_OS2:
+            case EF_ACL:
+            case EF_MAC3:
+            case EF_BEOS:
+            case EF_ATHEOS:
+                switch (ebID) {
+                  case EF_OS2:
+                  case EF_ACL:
+                    eb_cmpr_offs = EB_OS2_HLEN;
+                    break;
+                  case EF_MAC3:
+                    if (ebLen >= EB_MAC3_HLEN &&
+                        (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
+                         & EB_M3_FL_UNCMPR) &&
+                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
+                        eb_cmpr_offs = 0;
+                    else
+                        eb_cmpr_offs = EB_MAC3_HLEN;
+                    break;
+                  case EF_BEOS:
+                  case EF_ATHEOS:
+                    if (ebLen >= EB_BEOS_HLEN &&
+                        (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
+                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
+                        eb_cmpr_offs = 0;
+                    else
+                        eb_cmpr_offs = EB_BEOS_HLEN;
+                    break;
+                }
+                if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
+                    != PK_OK) {
+                    if (uO.qflag)
+                        Info(slide, 1, ((char *)slide, "%-22s ",
+                          FnFilter1(G.filename)));
+                    switch (r) {
+                        case IZ_EF_TRUNC:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(TruncEAs),
+                              ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
+                            break;
+                        case PK_ERR:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(InvalidComprDataEAs)));
+                            break;
+                        case PK_MEM3:
+                        case PK_MEM4:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(NotEnoughMemEAs)));
+                            break;
+                        default:
+                            if ((r & 0xff) != PK_ERR)
+                                Info(slide, 1, ((char *)slide,
+                                  LoadFarString(UnknErrorEAs)));
+                            else {
+                                ush m = (ush)(r >> 8);
+                                if (m == DEFLATED)            /* GRR KLUDGE! */
+                                    Info(slide, 1, ((char *)slide,
+                                      LoadFarString(BadCRC_EAs)));
+                                else
+                                    Info(slide, 1, ((char *)slide,
+                                      LoadFarString(UnknComprMethodEAs), m));
+                            }
+                            break;
+                    }
+                    return r;
+                }
+                break;
+
+            case EF_NTSD:
+                Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
+                r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
+                    ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
+                     (PK_WARN | 0x4000) :
+                     test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
+                if (r != PK_OK) {
+                    if (uO.qflag)
+                        Info(slide, 1, ((char *)slide, "%-22s ",
+                          FnFilter1(G.filename)));
+                    switch (r) {
+                        case IZ_EF_TRUNC:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(TruncNTSD),
+                              ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
+                            break;
+#if (defined(WIN32) && defined(NTSD_EAS))
+                        case PK_WARN:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(InvalidSecurityEAs)));
+                            break;
+#endif
+                        case PK_ERR:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(InvalidComprDataEAs)));
+                            break;
+                        case PK_MEM3:
+                        case PK_MEM4:
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(NotEnoughMemEAs)));
+                            break;
+                        case (PK_WARN | 0x4000):
+                            Info(slide, 1, ((char *)slide,
+                              LoadFarString(UnsuppNTSDVersEAs),
+                              (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
+                            r = PK_WARN;
+                            break;
+                        default:
+                            if ((r & 0xff) != PK_ERR)
+                                Info(slide, 1, ((char *)slide,
+                                  LoadFarString(UnknErrorEAs)));
+                            else {
+                                ush m = (ush)(r >> 8);
+                                if (m == DEFLATED)            /* GRR KLUDGE! */
+                                    Info(slide, 1, ((char *)slide,
+                                      LoadFarString(BadCRC_EAs)));
+                                else
+                                    Info(slide, 1, ((char *)slide,
+                                      LoadFarString(UnknComprMethodEAs), m));
+                            }
+                            break;
+                    }
+                    return r;
+                }
+                break;
+            case EF_PKVMS:
+                /* 2015-01-30 SMS.  Added sufficient-bytes test/message
+                 * here.  (Removed defective ebLen test above.)
+                 *
+                 * If sufficient bytes (EB_PKVMS_MINLEN) are available,
+                 * then compare the stored CRC value with the calculated
+                 * CRC for the remainder of the data (and complain about
+                 * a mismatch).
+                 */
+                if (ebLen < EB_PKVMS_MINLEN)
+                {
+                    /* Insufficient bytes available. */
+                    Info( slide, 1,
+                     ((char *)slide, LoadFarString( TooSmallEBlength),
+                     ebLen, EB_PKVMS_MINLEN));
+                }
+                else if (makelong(ef+ EB_HEADSIZE) !=
+                 crc32(CRCVAL_INITIAL,
+                 (ef+ EB_HEADSIZE+ EB_PKVMS_MINLEN),
+                 (extent)(ebLen- EB_PKVMS_MINLEN)))
+                {
+                     Info(slide, 1, ((char *)slide,
+                       LoadFarString(BadCRC_EAs)));
+                }
+                break;
+            case EF_PKW32:
+            case EF_PKUNIX:
+            case EF_ASIUNIX:
+            case EF_IZVMS:
+            case EF_IZUNIX:
+            case EF_VMCMS:
+            case EF_MVS:
+            case EF_SPARK:
+            case EF_TANDEM:
+            case EF_THEOS:
+            case EF_AV:
+            default:
+                break;
+        }
+        ef_len -= (ebLen + EB_HEADSIZE);
+        ef += (ebLen + EB_HEADSIZE);
+    }
+
+    if (!uO.qflag)
+        Info(slide, 0, ((char *)slide, " OK\n"));
+
+    return PK_COOL;
+
+} /* end function TestExtraField() */
+
+
+
+
+
+/******************************/
+/*  Function test_compr_eb()  */
+/******************************/
+
+#ifdef PROTO
+static int test_compr_eb(
+    __GPRO__
+    uch *eb,
+    unsigned eb_size,
+    unsigned compr_offset,
+    int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+                          uch *eb_ucptr, ulg eb_ucsize))
+#else /* !PROTO */
+static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
+    __GDEF
+    uch *eb;
+    unsigned eb_size;
+    unsigned compr_offset;
+    int (*test_uc_ebdata)();
+#endif /* ?PROTO */
+{
+    ulg eb_ucsize;
+    uch *eb_ucptr;
+    int r;
+    ush method;
+
+    if (compr_offset < 4)                /* field is not compressed: */
+        return PK_OK;                    /* do nothing and signal OK */
+
+    /* Return no/bad-data error status if any problem is found:
+     *    1. eb_size is too small to hold the uncompressed size
+     *       (eb_ucsize).  (Else extract eb_ucsize.)
+     *    2. eb_ucsize is zero (invalid).  2014-12-04 SMS.
+     *    3. eb_ucsize is positive, but eb_size is too small to hold
+     *       the compressed data header.
+     */
+    if ((eb_size < (EB_UCSIZE_P + 4)) ||
+     ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
+     ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
+        return IZ_EF_TRUNC;             /* no/bad compressed data! */
+
+    method = makeword(eb + (EB_HEADSIZE + compr_offset));
+    if ((method == STORED) && (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
+        return PK_ERR;            /* compressed & uncompressed
+                                   * should match in STORED
+                                   * method */
+
+    if (
+#ifdef INT_16BIT
+        (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
+#endif
+        (eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
+        return PK_MEM4;
+
+    r = memextract(__G__ eb_ucptr, eb_ucsize,
+                   eb + (EB_HEADSIZE + compr_offset),
+                   (ulg)(eb_size - compr_offset));
+
+    if (r == PK_OK && test_uc_ebdata != NULL)
+        r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
+
+    free(eb_ucptr);
+    return r;
+
+} /* end function test_compr_eb() */
+
+#endif /* !SFX */
+
+
+
+
+
+/***************************/
+/*  Function memextract()  */
+/***************************/
+
+int memextract(__G__ tgt, tgtsize, src, srcsize)  /* extract compressed */
+    __GDEF                                        /*  extra field block; */
+    uch *tgt;                                     /*  return PK-type error */
+    ulg tgtsize;                                  /*  level */
+    ZCONST uch *src;
+    ulg srcsize;
+{
+    zoff_t old_csize=G.csize;
+    uch   *old_inptr=G.inptr;
+    int    old_incnt=G.incnt;
+    int    r, error=PK_OK;
+    ush    method;
+    ulg    extra_field_crc;
+
+
+    method = makeword(src);
+    extra_field_crc = makelong(src+2);
+
+    /* compressed extra field exists completely in memory at this location: */
+    G.inptr = (uch *)src + (2 + 4);     /* method and extra_field_crc */
+    G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
+    G.mem_mode = TRUE;
+    G.outbufptr = tgt;
+    G.outsize = tgtsize;
+
+    switch (method) {
+        case STORED:
+            memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
+            G.outcnt = (ulg)G.csize;    /* for CRC calculation */
+            break;
+        case DEFLATED:
+#ifdef USE_DEFLATE64
+        case ENHDEFLATED:
+#endif
+            G.outcnt = 0L;
+            if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
+                if (!uO.tflag)
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+                      LoadFarString(NotEnoughMem) :
+                      LoadFarString(InvalidComprData),
+                      LoadFarStringSmall2(Inflate)));
+                error = (r == 3)? PK_MEM3 : PK_ERR;
+            }
+            if (G.outcnt == 0L)   /* inflate's final FLUSH sets outcnt */
+                break;
+            break;
+        default:
+            if (uO.tflag)
+                error = PK_ERR | ((int)method << 8);
+            else {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(UnsupportedExtraField), method));
+                error = PK_ERR;  /* GRR:  should be passed on up via SetEAs() */
+            }
+            break;
+    }
+
+    G.inptr = old_inptr;
+    G.incnt = old_incnt;
+    G.csize = old_csize;
+    G.mem_mode = FALSE;
+
+    if (!error) {
+        register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
+
+        if (crcval != extra_field_crc) {
+            if (uO.tflag)
+                error = PK_ERR | (DEFLATED << 8);  /* kludge for now */
+            else {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
+                  extra_field_crc));
+                error = PK_ERR;
+            }
+        }
+    }
+    return error;
+
+} /* end function memextract() */
+
+
+
+
+
+/*************************/
+/*  Function memflush()  */
+/*************************/
+
+int memflush(__G__ rawbuf, size)
+    __GDEF
+    ZCONST uch *rawbuf;
+    ulg size;
+{
+    if (size > G.outsize)
+        /* Here, PK_DISK is a bit off-topic, but in the sense of marking
+           "overflow of output space", its use may be tolerated. */
+        return PK_DISK;   /* more data than output buffer can hold */
+
+
+
+    memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
+    G.outbufptr += (unsigned int)size;
+    G.outsize -= size;
+    G.outcnt += size;
+
+    return 0;
+
+} /* end function memflush() */
+
+
+
+
+
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+
+/************************************/
+/*  Function extract_izvms_block()  */
+/************************************/
+
+/*
+ * Extracts block from p. If resulting length is less than needed, fill
+ * extra space with corresponding bytes from 'init'.
+ * Currently understands 3 formats of block compression:
+ * - Simple storing
+ * - Compression of zero bytes to zero bits
+ * - Deflation (see memextract())
+ * The IZVMS block data is returned in malloc'd space.
+ */
+uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
+    __GDEF
+    ZCONST uch *ebdata;
+    unsigned size;
+    unsigned *retlen;
+    ZCONST uch *init;
+    unsigned needlen;
+{
+    uch *ucdata;       /* Pointer to block allocated */
+    int cmptype;
+    unsigned usiz, csiz;
+
+    cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
+    csiz = size - EB_IZVMS_HLEN;
+    usiz = (cmptype == EB_IZVMS_BCSTOR ?
+            csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
+
+    if (retlen)
+        *retlen = usiz;
+
+    if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
+        return NULL;
+
+    if (init && (usiz < needlen))
+        memcpy((char *)ucdata, (ZCONST char *)init, needlen);
+
+    switch (cmptype)
+    {
+        case EB_IZVMS_BCSTOR: /* The simplest case */
+            memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
+            break;
+        case EB_IZVMS_BC00:
+            decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
+            break;
+        case EB_IZVMS_BCDEFL:
+            memextract(__G__ ucdata, (ulg)usiz,
+                       ebdata+EB_IZVMS_HLEN, (ulg)csiz);
+            break;
+        default:
+            free(ucdata);
+            ucdata = NULL;
+    }
+    return ucdata;
+
+} /* end of extract_izvms_block */
+
+
+
+
+
+/********************************/
+/*  Function decompress_bits()  */
+/********************************/
+/*
+ *  Simple uncompression routine. The compression uses bit stream.
+ *  Compression scheme:
+ *
+ *  if (byte!=0)
+ *      putbit(1),putbyte(byte)
+ *  else
+ *      putbit(0)
+ */
+static void decompress_bits(outptr, needlen, bitptr)
+    uch *outptr;        /* Pointer into output block */
+    unsigned needlen;   /* Size of uncompressed block */
+    ZCONST uch *bitptr; /* Pointer into compressed data */
+{
+    ulg bitbuf = 0;
+    int bitcnt = 0;
+
+#define _FILL   {       bitbuf |= (*bitptr++) << bitcnt;\
+                        bitcnt += 8;                    \
+                }
+
+    while (needlen--)
+    {
+        if (bitcnt <= 0)
+            _FILL;
+
+        if (bitbuf & 1)
+        {
+            bitbuf >>= 1;
+            if ((bitcnt -= 1) < 8)
+                _FILL;
+            *outptr++ = (uch)bitbuf;
+            bitcnt -= 8;
+            bitbuf >>= 8;
+        }
+        else
+        {
+            *outptr++ = '\0';
+            bitcnt -= 1;
+            bitbuf >>= 1;
+        }
+    }
+} /* end function decompress_bits() */
+
+#endif /* VMS || VMS_TEXT_CONV */
+
+
+
+
+
+#ifdef SYMLINKS
+/***********************************/
+/* Function set_deferred_symlink() */
+/***********************************/
+
+static void set_deferred_symlink(__G__ slnk_entry)
+    __GDEF
+    slinkentry *slnk_entry;
+{
+    extent ucsize = slnk_entry->targetlen;
+    char *linkfname = slnk_entry->fname;
+    char *linktarget = (char *)malloc(ucsize+1);
+
+    if (!linktarget) {
+        Info(slide, 0x201, ((char *)slide,
+          LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
+        return;
+    }
+    linktarget[ucsize] = '\0';
+    G.outfile = zfopen(linkfname, FOPR); /* open link placeholder for reading */
+    /* Check that the following conditions are all fulfilled:
+     * a) the placeholder file exists,
+     * b) the placeholder file contains exactly "ucsize" bytes
+     *    (read the expected placeholder content length + 1 extra byte, this
+     *    should return the expected content length),
+     * c) the placeholder content matches the link target specification as
+     *    stored in the symlink control structure.
+     */
+    if (!G.outfile ||
+        fread(linktarget, 1, ucsize+1, G.outfile) != ucsize ||
+        strcmp(slnk_entry->target, linktarget))
+    {
+        Info(slide, 0x201, ((char *)slide,
+          LoadFarString(SymLnkWarnInvalid), FnFilter1(linkfname)));
+        free(linktarget);
+        if (G.outfile)
+            fclose(G.outfile);
+        return;
+    }
+    fclose(G.outfile);                  /* close "data" file for good... */
+    unlink(linkfname);                  /* ...and delete it */
+    if (QCOND2)
+        Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
+          FnFilter1(linkfname), FnFilter2(linktarget)));
+    if (symlink(linktarget, linkfname))  /* create the real link */
+        perror("symlink error");
+    free(linktarget);
+#ifdef SET_SYMLINK_ATTRIBS
+    set_symlnk_attribs(__G__ slnk_entry);
+#endif
+    return;                             /* can't set time on symlinks */
+
+} /* end function set_deferred_symlink() */
+#endif /* SYMLINKS */
+
+/*
+ * If Unicode is supported, assume we have what we need to do this
+ * check using wide characters, avoiding MBCS issues.
+ */
+
+#ifndef UZ_FNFILTER_REPLACECHAR
+        /* A convenient choice for the replacement of unprintable char codes is
+         * the "single char wildcard", as this character is quite unlikely to
+         * appear in filenames by itself.  The following default definition
+         * sets the replacement char to a question mark as the most common
+         * "single char wildcard"; this setting should be overridden in the
+         * appropiate system-specific configuration header when needed.
+         */
+# define UZ_FNFILTER_REPLACECHAR      '?'
+#endif
+
+/*************************/
+/*  Function fnfilter()  */        /* here instead of in list.c for SFX */
+/*************************/
+
+char *fnfilter(raw, space, size)   /* convert name to safely printable form */
+    ZCONST char *raw;
+    uch *space;
+    extent size;
+{
+#ifndef NATIVE   /* ASCII:  filter ANSI escape codes, etc. */
+    ZCONST uch *r; // =(ZCONST uch *)raw;
+    uch *s=space;
+    uch *slim=NULL;
+    uch *se=NULL;
+    int have_overflow = FALSE;
+
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+/* If Unicode support is enabled, and we have multi-byte characters,
+ * then do the isprint() checks by first converting to wide characters
+ * and checking those.  This avoids our having to parse multi-byte
+ * characters for ourselves.  After the wide-char replacements have been
+ * made, the wide string is converted back to the local character set.
+ */
+    wchar_t *wstring;    /* wchar_t version of raw */
+    size_t wslen;        /* length of wstring */
+    wchar_t *wostring;   /* wchar_t version of output string */
+    size_t woslen;       /* length of wostring */
+    char *newraw;        /* new raw */
+
+    /* 2012-11-06 SMS.
+     * Changed to check the value returned by mbstowcs(), and bypass the
+     * Unicode processing if it fails.  This seems to fix a problem
+     * reported in the SourceForge forum, but it's not clear that we
+     * should be doing any Unicode processing without some evidence that
+     * the name actually is Unicode.  (Check bit 11 in the flags before
+     * coming here?)
+     * http://sourceforge.net/p/infozip/bugs/40/
+     */
+
+    if (MB_CUR_MAX <= 1)
+    {
+        /* There's no point to converting multi-byte chars if there are
+         * no multi-byte chars.
+         */
+        wslen = (size_t)-1;
+    }
+    else
+    {
+        /* Get Unicode wide character count (for storage allocation). */
+        wslen = mbstowcs( NULL, raw, 0);
+    }
+
+    if (wslen != (size_t)-1)
+    {
+        /* Apparently valid Unicode.  Allocate wide-char storage. */
+        wstring = (wchar_t *)malloc((wslen + 1) * sizeof(wchar_t));
+        if (wstring == NULL) {
+            strcpy( (char *)space, raw);
+            return (char *)space;
+        }
+        wostring = (wchar_t *)malloc(2 * (wslen + 1) * sizeof(wchar_t));
+        if (wostring == NULL) {
+            free(wstring);
+            strcpy( (char *)space, raw);
+            return (char *)space;
+        }
+
+        /* Convert the multi-byte Unicode to wide chars. */
+        wslen = mbstowcs(wstring, raw, wslen + 1);
+
+        /* Filter the wide-character string. */
+        fnfilterw( wstring, wostring, (2 * (wslen + 1) * sizeof(wchar_t)));
+
+        /* Convert filtered wide chars back to multi-byte. */
+        woslen = wcstombs( NULL, wostring, 0);
+        if ((newraw = malloc(woslen + 1)) == NULL) {
+            free(wstring);
+            free(wostring);
+            strcpy( (char *)space, raw);
+            return (char *)space;
+        }
+        woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1);
+
+        if (size > 0) {
+            slim = space + size - 4;
+        }
+        r = (ZCONST uch *)newraw;
+        while (*r) {
+            if (size > 0 && s >= slim && se == NULL) {
+                se = s;
+            }
+#  ifdef QDOS
+            if (qlflag & 2) {
+                if (*r == '/' || *r == '.') {
+                    if (se != NULL && (s > (space + (size-3)))) {
+                        have_overflow = TRUE;
+                        break;
+                    }
+                    ++r;
+                    *s++ = '_';
+                    continue;
+                }
+            } else
+#  endif
+            {
+                if (se != NULL && (s > (space + (size-3)))) {
+                    have_overflow = TRUE;
+                    break;
+                }
+                *s++ = *r++;
+            }
+        }
+        if (have_overflow) {
+            strcpy((char *)se, "...");
+        } else {
+            *s = '\0';
+        }
+
+        free(wstring);
+        free(wostring);
+        free(newraw);
+    }
+    else
+# endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+    {
+        /* No Unicode support, or apparently invalid Unicode. */
+        r = (ZCONST uch *)raw;
+
+        if (size > 0) {
+            slim = space + size
+#ifdef _MBCS
+                         - (MB_CUR_MAX - 1)
+#endif
+                         - 4;
+        }
+        while (*r) {
+            if (size > 0 && s >= slim && se == NULL) {
+                se = s;
+            }
+#ifdef QDOS
+            if (qlflag & 2) {
+                if (*r == '/' || *r == '.') {
+                    if (se != NULL && (s > (space + (size-3)))) {
+                        have_overflow = TRUE;
+                        break;
+                    }
+                    ++r;
+                    *s++ = '_';
+                    continue;
+                }
+            } else
+#endif
+#ifdef HAVE_WORKING_ISPRINT
+            if (!isprint(*r)) {
+                if (*r < 32) {
+                    /* ASCII control codes are escaped as "^{letter}". */
+                    if (se != NULL && (s > (space + (size-4)))) {
+                        have_overflow = TRUE;
+                        break;
+                    }
+                    *s++ = '^', *s++ = (uch)(64 + *r++);
+                } else {
+                    /* Other unprintable codes are replaced by the
+                     * placeholder character. */
+                    if (se != NULL && (s > (space + (size-3)))) {
+                        have_overflow = TRUE;
+                        break;
+                    }
+                    *s++ = UZ_FNFILTER_REPLACECHAR;
+                    INCSTR(r);
+                }
+#else /* !HAVE_WORKING_ISPRINT */
+            if (*r < 32) {
+                /* ASCII control codes are escaped as "^{letter}". */
+                if (se != NULL && (s > (space + (size-4)))) {
+                    have_overflow = TRUE;
+                    break;
+                }
+                *s++ = '^', *s++ = (uch)(64 + *r++);
+#endif /* ?HAVE_WORKING_ISPRINT */
+            } else {
+#ifdef _MBCS
+                unsigned i = CLEN(r);
+                if (se != NULL && (s > (space + (size-i-2)))) {
+                    have_overflow = TRUE;
+                    break;
+                }
+                for (; i > 0; i--)
+                    *s++ = *r++;
+#else
+                if (se != NULL && (s > (space + (size-3)))) {
+                    have_overflow = TRUE;
+                    break;
+                }
+                *s++ = *r++;
+#endif
+             }
+        }
+        if (have_overflow) {
+            strcpy((char *)se, "...");
+        } else {
+            *s = '\0';
+        }
+    }
+
+#ifdef WINDLL
+    INTERN_TO_ISO((char *)space, (char *)space);  /* translate to ANSI */
+#else
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+    /* Win9x console always uses OEM character coding, and
+       WinNT console is set to OEM charset by default, too */
+    INTERN_TO_OEM((char *)space, (char *)space);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+
+    return (char *)space;
+
+#else /* NATIVE:  EBCDIC or whatever */
+    return (char *)raw;
+#endif
+
+} /* end function fnfilter() */
+
+
+#if defined( UNICODE_SUPPORT) && defined( _MBCS)
+
+/****************************/
+/*  Function fnfilter[w]()  */  /* (Here instead of in list.c for SFX.) */
+/****************************/
+
+/* fnfilterw() - Convert wide name to safely printable form. */
+
+/* fnfilterw() - Convert wide-character name to safely printable form. */
+
+wchar_t *fnfilterw( src, dst, siz)
+    ZCONST wchar_t *src;        /* Pointer to source char (string). */
+    wchar_t *dst;               /* Pointer to destination char (string). */
+    extent siz;                 /* Not used (!). */
+{
+    wchar_t *dsx = dst;
+
+    /* Filter the wide chars. */
+    while (*src)
+    {
+        if (iswprint( *src))
+        {
+            /* Printable code.  Copy it. */
+            *dst++ = *src;
+        }
+        else
+        {
+            /* Unprintable code.  Substitute something printable for it. */
+            if (*src < 32)
+            {
+                /* Replace ASCII control code with "^{letter}". */
+                *dst++ = (wchar_t)'^';
+                *dst++ = (wchar_t)(64 + *src);
+            }
+            else
+            {
+                /* Replace other unprintable code with the placeholder. */
+                *dst++ = (wchar_t)UZ_FNFILTER_REPLACECHAR;
+            }
+        }
+        src++;
+    }
+    *dst = (wchar_t)0;  /* NUL-terminate the destination string. */
+    return dsx;
+} /* fnfilterw(). */
+
+#endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+
+
+#ifdef SET_DIR_ATTRIB
+/* must sort saved directories so can set perms from bottom up */
+
+/************************/
+/*  Function dircomp()  */
+/************************/
+
+static int Cdecl dircomp(a, b)  /* used by qsort(); swiped from Zip */
+    ZCONST zvoid *a, *b;
+{
+    /* order is significant:  this sorts in reverse order (deepest first) */
+    return strcmp((*(direntry **)b)->fn, (*(direntry **)a)->fn);
+ /* return namecmp((*(direntry **)b)->fn, (*(direntry **)a)->fn); */
+}
+
+#endif /* SET_DIR_ATTRIB */
+
+
+#ifdef USE_BZIP2
+
+/**************************/
+/*  Function UZbunzip2()  */
+/**************************/
+
+int UZbunzip2(__G)
+__GDEF
+/* decompress a bzipped entry using the libbz2 routines */
+{
+    int retval = 0;     /* return code: 0 = "no error" */
+    int err=BZ_OK;
+    int repeated_buf_err;
+    bz_stream bstrm;
+
+    if (G.incnt <= 0 && G.csize <= 0L) {
+        /* avoid an infinite loop */
+        Trace((stderr, "UZbunzip2() got empty input\n"));
+        return 2;
+    }
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+    if (G.redirect_slide)
+        wsize = G.redirect_size, redirSlide = G.redirect_buffer;
+    else
+        wsize = WSIZE, redirSlide = slide;
+#endif
+
+    bstrm.next_out = (char *)redirSlide;
+    bstrm.avail_out = wsize;
+
+    bstrm.next_in = (char *)G.inptr;
+    bstrm.avail_in = G.incnt;
+
+    {
+        /* local buffer for efficiency */
+        /* $TODO Check for BZIP LIB version? */
+
+        bstrm.bzalloc = NULL;
+        bstrm.bzfree = NULL;
+        bstrm.opaque = NULL;
+
+        Trace((stderr, "initializing bzlib()\n"));
+        err = BZ2_bzDecompressInit(&bstrm, 0, 0);
+
+        if (err == BZ_MEM_ERROR)
+            return 3;
+        else if (err != BZ_OK)
+            Trace((stderr, "oops!  (BZ2_bzDecompressInit() err = %d)\n", err));
+    }
+
+#ifdef FUNZIP
+    while (err != BZ_STREAM_END) {
+#else /* !FUNZIP */
+    while (G.csize > 0) {
+        Trace((stderr, "first loop:  G.csize = %ld\n", G.csize));
+#endif /* ?FUNZIP */
+        while (bstrm.avail_out > 0) {
+            err = BZ2_bzDecompress(&bstrm);
+
+            if (err == BZ_DATA_ERROR) {
+                retval = 2; goto uzbunzip_cleanup_exit;
+            } else if (err == BZ_MEM_ERROR) {
+                retval = 3; goto uzbunzip_cleanup_exit;
+            } else if (err != BZ_OK && err != BZ_STREAM_END)
+                Trace((stderr, "oops!  (bzip(first loop) err = %d)\n", err));
+
+#ifdef FUNZIP
+            if (err == BZ_STREAM_END)    /* "END-of-entry-condition" ? */
+#else /* !FUNZIP */
+            if (G.csize <= 0L)          /* "END-of-entry-condition" ? */
+#endif /* ?FUNZIP */
+                break;
+
+            if (bstrm.avail_in == 0) {
+                if (fillinbuf(__G) == 0) {
+                    /* no "END-condition" yet, but no more data */
+                    retval = 2; goto uzbunzip_cleanup_exit;
+                }
+
+                bstrm.next_in = (char *)G.inptr;
+                bstrm.avail_in = G.incnt;
+            }
+            Trace((stderr, "     avail_in = %u\n", bstrm.avail_in));
+        }
+        /* flush slide[] */
+        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
+            goto uzbunzip_cleanup_exit;
+        Trace((stderr, "inside loop:  flushing %ld bytes (ptr diff = %ld)\n",
+          (long)(wsize - bstrm.avail_out),
+          (long)(bstrm.next_out-(char *)redirSlide)));
+        bstrm.next_out = (char *)redirSlide;
+        bstrm.avail_out = wsize;
+    }
+
+    /* no more input, so loop until we have all output */
+    Trace((stderr, "beginning final loop:  err = %d\n", err));
+    repeated_buf_err = FALSE;
+    while (err != BZ_STREAM_END) {
+        err = BZ2_bzDecompress(&bstrm);
+        if (err == BZ_DATA_ERROR) {
+            retval = 2; goto uzbunzip_cleanup_exit;
+        } else if (err == BZ_MEM_ERROR) {
+            retval = 3; goto uzbunzip_cleanup_exit;
+        } else if (err != BZ_OK && err != BZ_STREAM_END) {
+            Trace((stderr, "oops!  (bzip(final loop) err = %d)\n", err));
+            DESTROYGLOBALS();
+            EXIT(PK_MEM3);
+        }
+        /* final flush of slide[] */
+        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
+            goto uzbunzip_cleanup_exit;
+        Trace((stderr, "final loop:  flushing %ld bytes (ptr diff = %ld)\n",
+          (long)(wsize - bstrm.avail_out),
+          (long)(bstrm.next_out-(char *)redirSlide)));
+        bstrm.next_out = (char *)redirSlide;
+        bstrm.avail_out = wsize;
+    }
+#ifdef LARGE_FILE_SUPPORT
+    Trace((stderr, "total in = %llu, total out = %llu\n",
+      (zusz_t)(bstrm.total_in_lo32) + ((zusz_t)(bstrm.total_in_hi32))<<32,
+      (zusz_t)(bstrm.total_out_lo32) + ((zusz_t)(bstrm.total_out_hi32))<<32));
+#else
+    Trace((stderr, "total in = %lu, total out = %lu\n", bstrm.total_in_lo32,
+      bstrm.total_out_lo32));
+#endif
+
+    G.inptr = (uch *)bstrm.next_in;
+    G.incnt = (G.inbuf + INBUFSIZ) - G.inptr;  /* reset for other routines */
+
+uzbunzip_cleanup_exit:
+    err = BZ2_bzDecompressEnd(&bstrm);
+    if (err != BZ_OK)
+        Trace((stderr, "oops!  (BZ2_bzDecompressEnd() err = %d)\n", err));
+
+    return retval;
+} /* end function UZbunzip2() */
+#endif /* USE_BZIP2 */
Index: unzip/create-6.0-slackware-patch/unzip60-new/fileio.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/fileio.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/fileio.c	(revision 5)
@@ -0,0 +1,2889 @@
+/*
+  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.
+  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
+*/
+/*---------------------------------------------------------------------------
+
+  fileio.c
+
+  This file contains routines for doing direct but relatively generic input/
+  output, file-related sorts of things, plus some miscellaneous stuff.  Most
+  of the stuff has to do with opening, closing, reading and/or writing files.
+
+  Contains:  open_input_file()
+             open_outfile()           (not: VMS, AOS/VS, CMSMVS, MACOS, TANDEM)
+             undefer_input()
+             defer_leftover_input()
+             readbuf()
+             readbyte()
+             fillinbuf()
+             seek_zipf()
+             flush()                  (non-VMS)
+             is_vms_varlen_txt()      (non-VMS, VMS_TEXT_CONV only)
+             disk_error()             (non-VMS)
+             UzpMessagePrnt()
+             UzpMessageNull()         (DLL only)
+             UzpInput()
+             UzpMorePause()
+             UzpPassword()            (non-WINDLL)
+             handler()
+             dos_to_unix_time()       (non-VMS, non-VM/CMS, non-MVS)
+             check_for_newer()        (non-VMS, non-OS/2, non-VM/CMS, non-MVS)
+             do_string()
+             makeword()
+             makelong()
+             makeint64()
+             fzofft()
+             str2iso()                (CRYPT && NEED_STR2ISO, only)
+             str2oem()                (CRYPT && NEED_STR2OEM, only)
+             memset()                 (ZMEM only)
+             memcpy()                 (ZMEM only)
+             zstrnicmp()              (NO_STRNICMP only)
+             zstat()                  (REGULUS only)
+             plastchar()              (_MBCS only)
+             uzmbclen()               (_MBCS && NEED_UZMBCLEN, only)
+             uzmbschr()               (_MBCS && NEED_UZMBSCHR, only)
+             uzmbsrchr()              (_MBCS && NEED_UZMBSRCHR, only)
+             fLoadFarString()         (SMALL_MEM only)
+             fLoadFarStringSmall()    (SMALL_MEM only)
+             fLoadFarStringSmall2()   (SMALL_MEM only)
+             zfstrcpy()               (SMALL_MEM only)
+             zfstrcmp()               (SMALL_MEM && !(SFX || FUNZIP) only)
+
+  ---------------------------------------------------------------------------*/
+
+
+#define __FILEIO_C      /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+#  ifdef POCKET_UNZIP
+#    include "wince/intrface.h"
+#  else
+#    include "windll/windll.h"
+#  endif
+#  include <setjmp.h>
+#endif
+#include "crc32.h"
+#include "crypt.h"
+#include "ttyio.h"
+
+/* setup of codepage conversion for decryption passwords */
+#if CRYPT
+#  if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY))
+#    define IZ_ISO2OEM_ARRAY            /* pull in iso2oem[] table */
+#  endif
+#  if (defined(CRYP_USES_OEM2ISO) && !defined(IZ_OEM2ISO_ARRAY))
+#    define IZ_OEM2ISO_ARRAY            /* pull in oem2iso[] table */
+#  endif
+#endif
+#include "ebcdic.h"   /* definition/initialization of ebcdic[] */
+
+
+/*
+   Note: Under Windows, the maximum size of the buffer that can be used
+   with any of the *printf calls is 16,384, so win_fprintf was used to
+   feed the fprintf clone no more than 16K chunks at a time. This should
+   be valid for anything up to 64K (and probably beyond, assuming your
+   buffers are that big).
+*/
+#ifdef WINDLL
+#  define WriteError(buf,len,strm) \
+   (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len))
+#else /* !WINDLL */
+#  ifdef USE_FWRITE
+#    define WriteError(buf,len,strm) \
+     ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
+#  else
+#    define WriteError(buf,len,strm) \
+     ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
+#  endif
+#endif /* ?WINDLL */
+
+/*
+   2005-09-16 SMS.
+   On VMS, when output is redirected to a file, as in a command like
+   "PIPE UNZIP -v > X.OUT", the output file is created with VFC record
+   format, and multiple calls to write() or fwrite() will produce multiple
+   records, even when there's no newline terminator in the buffer.
+   The result is unsightly output with spurious newlines.  Using fprintf()
+   instead of write() here, and disabling a fflush(stdout) in UzpMessagePrnt()
+   below, together seem to solve the problem.
+
+   According to the C RTL manual, "The write and decc$record_write
+   functions always generate at least one record."  Also, "[T]he fwrite
+   function always generates at least <number_items> records."  So,
+   "fwrite(buf, len, 1, strm)" is much better ("1" record) than
+   "fwrite(buf, 1, len, strm)" ("len" (1-character) records, _really_
+   ugly), but neither is better than write().  Similarly, "The fflush
+   function always generates a record if there is unwritten data in the
+   buffer."  Apparently fprintf() buffers the stuff somewhere, and puts
+   out a record (only) when it sees a newline.
+*/
+#ifdef VMS
+#  define WriteTxtErr(buf,len,strm) \
+   ((extent)fprintf(strm, "%.*s", len, buf) != (extent)(len))
+#else
+#  define WriteTxtErr(buf,len,strm)  WriteError(buf,len,strm)
+#endif
+
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+static int partflush OF((__GPRO__ uch *rawbuf, ulg size, int unshrink));
+#endif
+#ifdef VMS_TEXT_CONV
+static int is_vms_varlen_txt OF((__GPRO__ uch *ef_buf, unsigned ef_len));
+#endif
+static int disk_error OF((__GPRO));
+
+
+/****************************/
+/* Strings used in fileio.c */
+/****************************/
+
+static ZCONST char Far CannotOpenZipfile[] =
+  "error:  cannot open zipfile [ %s ]\n        %s\n";
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+#if (defined(ATH_BEO_THS_UNX) || defined(DOS_FLX_NLM_OS2_W32))
+   static ZCONST char Far CannotDeleteOldFile[] =
+     "error:  cannot delete old %s\n        %s\n";
+#ifdef UNIXBACKUP
+   static ZCONST char Far CannotRenameOldFile[] =
+     "error:  cannot rename old %s\n        %s\n";
+   static ZCONST char Far BackupSuffix[] = "~";
+#endif
+#endif /* ATH_BEO_THS_UNX || DOS_FLX_NLM_OS2_W32 */
+#ifdef NOVELL_BUG_FAILSAFE
+   static ZCONST char Far NovellBug[] =
+     "error:  %s: stat() says does not exist, but fopen() found anyway\n";
+#endif
+   static ZCONST char Far CannotCreateFile[] =
+     "error:  cannot create %s\n        %s\n";
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+static ZCONST char Far ReadError[] = "error:  zipfile read error\n";
+static ZCONST char Far FilenameTooLongTrunc[] =
+  "warning:  filename too long--truncating.\n";
+#ifdef UNICODE_SUPPORT
+   static ZCONST char Far UFilenameCorrupt[] =
+     "error: Unicode filename corrupt.\n";
+   static ZCONST char Far UFilenameTooLongTrunc[] =
+     "warning:  Converted unicode filename too long--truncating.\n";
+#endif
+static ZCONST char Far ExtraFieldTooLong[] =
+  "warning:  extra field too long (%d).  Ignoring...\n";
+static ZCONST char Far ExtraFieldCorrupt[] =
+  "warning:  extra field (type: 0x%04x) corrupt.  Continuing...\n";
+
+#ifdef WINDLL
+   static ZCONST char Far DiskFullQuery[] =
+     "%s:  write error (disk full?).\n";
+#else
+   static ZCONST char Far DiskFullQuery[] =
+     "%s:  write error (disk full?).  Continue? (y/n/^C) ";
+   static ZCONST char Far ZipfileCorrupt[] =
+     "error:  zipfile probably corrupt (%s)\n";
+#  ifdef SYMLINKS
+     static ZCONST char Far FileIsSymLink[] =
+       "%s exists and is a symbolic link%s.\n";
+#  endif
+#  ifdef MORE
+     static ZCONST char Far MorePrompt[] = "--More--(%lu)";
+#  endif
+   static ZCONST char Far QuitPrompt[] =
+     "--- Press `Q' to quit, or any other key to continue ---";
+   static ZCONST char Far HidePrompt[] = /* "\r                       \r"; */
+     "\r                                                         \r";
+#  if CRYPT
+#    ifdef MACOS
+       /* SPC: are names on MacOS REALLY so much longer than elsewhere ??? */
+       static ZCONST char Far PasswPrompt[] = "[%s]\n %s password: ";
+#    else
+       static ZCONST char Far PasswPrompt[] = "[%s] %s password: ";
+#    endif
+     static ZCONST char Far PasswPrompt2[] = "Enter password: ";
+     static ZCONST char Far PasswRetry[] = "password incorrect--reenter: ";
+#  endif /* CRYPT */
+#endif /* !WINDLL */
+
+
+
+
+
+/******************************/
+/* Function open_input_file() */
+/******************************/
+
+int open_input_file(__G)    /* return 1 if open failed */
+    __GDEF
+{
+    /*
+     *  open the zipfile for reading and in BINARY mode to prevent cr/lf
+     *  translation, which would corrupt the bitstreams
+     */
+
+#ifdef VMS
+    G.zipfd = open(G.zipfn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
+#else /* !VMS */
+#ifdef MACOS
+    G.zipfd = open(G.zipfn, 0);
+#else /* !MACOS */
+#ifdef CMS_MVS
+    G.zipfd = vmmvs_open_infile(__G);
+#else /* !CMS_MVS */
+#ifdef USE_STRM_INPUT
+    G.zipfd = fopen(G.zipfn, FOPR);
+#else /* !USE_STRM_INPUT */
+    G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);
+#endif /* ?USE_STRM_INPUT */
+#endif /* ?CMS_MVS */
+#endif /* ?MACOS */
+#endif /* ?VMS */
+
+#ifdef USE_STRM_INPUT
+    if (G.zipfd == NULL)
+#else
+    /* if (G.zipfd < 0) */  /* no good for Windows CE port */
+    if (G.zipfd == -1)
+#endif
+    {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile),
+          G.zipfn, strerror(errno)));
+        return 1;
+    }
+    return 0;
+
+} /* end function open_input_file() */
+
+
+
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+
+/***************************/
+/* Function open_outfile() */
+/***************************/
+
+int open_outfile(__G)           /* return 1 if fail */
+    __GDEF
+{
+#ifdef DLL
+    if (G.redirect_data)
+        return (redirect_outfile(__G) == FALSE);
+#endif
+#ifdef QDOS
+    QFilename(__G__ G.filename);
+#endif
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_THS_UNX))
+#ifdef BORLAND_STAT_BUG
+    /* Borland 5.0's stat() barfs if the filename has no extension and the
+     * file doesn't exist. */
+    if (access(G.filename, 0) == -1) {
+        FILE *tmp = fopen(G.filename, "wb+");
+
+        /* file doesn't exist, so create a dummy file to keep stat() from
+         * failing (will be over-written anyway) */
+        fputc('0', tmp);  /* just to have something in the file */
+        fclose(tmp);
+    }
+#endif /* BORLAND_STAT_BUG */
+#ifdef SYMLINKS
+    if (SSTAT(G.filename, &G.statbuf) == 0 ||
+        lstat(G.filename, &G.statbuf) == 0)
+#else
+    if (SSTAT(G.filename, &G.statbuf) == 0)
+#endif /* ?SYMLINKS */
+    {
+        Trace((stderr, "open_outfile:  stat(%s) returns 0:  file exists\n",
+          FnFilter1(G.filename)));
+#ifdef UNIXBACKUP
+        if (uO.B_flag) {    /* do backup */
+            char *tname;
+            z_stat tmpstat;
+            int blen, flen, tlen;
+
+            blen = strlen(BackupSuffix);
+            flen = strlen(G.filename);
+            tlen = flen + blen + 6;    /* includes space for 5 digits */
+            if (tlen >= FILNAMSIZ) {   /* in case name is too long, truncate */
+                tname = (char *)malloc(FILNAMSIZ);
+                if (tname == NULL)
+                    return 1;                 /* in case we run out of space */
+                tlen = FILNAMSIZ - 1 - blen;
+                strcpy(tname, G.filename);    /* make backup name */
+                tname[tlen] = '\0';
+                if (flen > tlen) flen = tlen;
+                tlen = FILNAMSIZ;
+            } else {
+                tname = (char *)malloc(tlen);
+                if (tname == NULL)
+                    return 1;                 /* in case we run out of space */
+                strcpy(tname, G.filename);    /* make backup name */
+            }
+            strcpy(tname+flen, BackupSuffix);
+
+            if (IS_OVERWRT_ALL) {
+                /* If there is a previous backup file, delete it,
+                 * otherwise the following rename operation may fail.
+                 */
+                if (SSTAT(tname, &tmpstat) == 0)
+                    unlink(tname);
+            } else {
+                /* Check if backupname exists, and, if it's true, try
+                 * appending numbers of up to 5 digits (or the maximum
+                 * "unsigned int" number on 16-bit systems) to the
+                 * BackupSuffix, until an unused name is found.
+                 */
+                unsigned maxtail, i;
+                char *numtail = tname + flen + blen;
+
+                /* take account of the "unsigned" limit on 16-bit systems: */
+                maxtail = ( ((~0) >= 99999L) ? 99999 : (~0) );
+                switch (tlen - flen - blen - 1) {
+                    case 4: maxtail = 9999; break;
+                    case 3: maxtail = 999; break;
+                    case 2: maxtail = 99; break;
+                    case 1: maxtail = 9; break;
+                    case 0: maxtail = 0; break;
+                }
+                /* while filename exists */
+                for (i = 0; (i < maxtail) && (SSTAT(tname, &tmpstat) == 0);)
+                    sprintf(numtail,"%u", ++i);
+            }
+
+            if (rename(G.filename, tname) != 0) {   /* move file */
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(CannotRenameOldFile),
+                  FnFilter1(G.filename), strerror(errno)));
+                free(tname);
+                return 1;
+            }
+            Trace((stderr, "open_outfile:  %s now renamed into %s\n",
+              FnFilter1(G.filename), FnFilter2(tname)));
+            free(tname);
+        } else
+#endif /* UNIXBACKUP */
+        {
+#ifdef DOS_FLX_OS2_W32
+            if (!(G.statbuf.st_mode & S_IWRITE)) {
+                Trace((stderr,
+                  "open_outfile:  existing file %s is read-only\n",
+                  FnFilter1(G.filename)));
+                chmod(G.filename, S_IREAD | S_IWRITE);
+                Trace((stderr, "open_outfile:  %s now writable\n",
+                  FnFilter1(G.filename)));
+            }
+#endif /* DOS_FLX_OS2_W32 */
+#ifdef NLM
+            /* Give the file read/write permission (non-POSIX shortcut) */
+            chmod(G.filename, 0);
+#endif /* NLM */
+            if (unlink(G.filename) != 0) {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(CannotDeleteOldFile),
+                  FnFilter1(G.filename), strerror(errno)));
+                return 1;
+            }
+            Trace((stderr, "open_outfile:  %s now deleted\n",
+              FnFilter1(G.filename)));
+        }
+    }
+#endif /* DOS_FLX_NLM_OS2_W32 || ATH_BEO_THS_UNX */
+#ifdef RISCOS
+    if (SWI_OS_File_7(G.filename,0xDEADDEAD,0xDEADDEAD,G.lrec.ucsize)!=NULL) {
+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+          FnFilter1(G.filename), strerror(errno)));
+        return 1;
+    }
+#endif /* RISCOS */
+#ifdef TOPS20
+    char *tfilnam;
+
+    if ((tfilnam = (char *)malloc(2*strlen(G.filename)+1)) == (char *)NULL)
+        return 1;
+    strcpy(tfilnam, G.filename);
+    upper(tfilnam);
+    enquote(tfilnam);
+    if ((G.outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+          tfilnam, strerror(errno)));
+        free(tfilnam);
+        return 1;
+    }
+    free(tfilnam);
+#else /* !TOPS20 */
+#ifdef MTS
+    if (uO.aflag)
+        G.outfile = zfopen(G.filename, FOPWT);
+    else
+        G.outfile = zfopen(G.filename, FOPW);
+    if (G.outfile == (FILE *)NULL) {
+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+          FnFilter1(G.filename), strerror(errno)));
+        return 1;
+    }
+#else /* !MTS */
+#ifdef DEBUG
+    Info(slide, 1, ((char *)slide,
+      "open_outfile:  doing fopen(%s) for reading\n", FnFilter1(G.filename)));
+    if ((G.outfile = zfopen(G.filename, FOPR)) == (FILE *)NULL)
+        Info(slide, 1, ((char *)slide,
+          "open_outfile:  fopen(%s) for reading failed:  does not exist\n",
+          FnFilter1(G.filename)));
+    else {
+        Info(slide, 1, ((char *)slide,
+          "open_outfile:  fopen(%s) for reading succeeded:  file exists\n",
+          FnFilter1(G.filename)));
+        fclose(G.outfile);
+    }
+#endif /* DEBUG */
+#ifdef NOVELL_BUG_FAILSAFE
+    if (G.dne && ((G.outfile = zfopen(G.filename, FOPR)) != (FILE *)NULL)) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(NovellBug),
+          FnFilter1(G.filename)));
+        fclose(G.outfile);
+        return 1;   /* with "./" fix in checkdir(), should never reach here */
+    }
+#endif /* NOVELL_BUG_FAILSAFE */
+    Trace((stderr, "open_outfile:  doing fopen(%s) for writing\n",
+      FnFilter1(G.filename)));
+    {
+#if defined(ATH_BE_UNX) || defined(AOS_VS) || defined(QDOS) || defined(TANDEM)
+        mode_t umask_sav = umask(0077);
+#endif
+#if defined(SYMLINKS) || defined(QLZIP)
+        /* These features require the ability to re-read extracted data from
+           the output files. Output files are created with Read&Write access.
+         */
+        G.outfile = zfopen(G.filename, FOPWR);
+#else
+        G.outfile = zfopen(G.filename, FOPW);
+#endif
+#if defined(ATH_BE_UNX) || defined(AOS_VS) || defined(QDOS) || defined(TANDEM)
+        umask(umask_sav);
+#endif
+    }
+    if (G.outfile == (FILE *)NULL) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
+          FnFilter1(G.filename), strerror(errno)));
+        return 1;
+    }
+    Trace((stderr, "open_outfile:  fopen(%s) for writing succeeded\n",
+      FnFilter1(G.filename)));
+#endif /* !MTS */
+#endif /* !TOPS20 */
+
+#ifdef USE_FWRITE
+#ifdef DOS_NLM_OS2_W32
+    /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE):  bogus */
+    setbuf(G.outfile, (char *)NULL);   /* make output unbuffered */
+#else /* !DOS_NLM_OS2_W32 */
+#ifndef RISCOS
+#ifdef _IOFBF  /* make output fully buffered (works just about like write()) */
+    setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);
+#else
+    setbuf(G.outfile, (char *)slide);
+#endif
+#endif /* !RISCOS */
+#endif /* ?DOS_NLM_OS2_W32 */
+#endif /* USE_FWRITE */
+#ifdef OS2_W32
+    /* preallocate the final file size to prevent file fragmentation */
+    SetFileSize(G.outfile, G.lrec.ucsize);
+#endif
+    return 0;
+
+} /* end function open_outfile() */
+
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+
+
+
+
+/*
+ * These functions allow NEXTBYTE to function without needing two bounds
+ * checks.  Call defer_leftover_input() if you ever have filled G.inbuf
+ * by some means other than readbyte(), and you then want to start using
+ * NEXTBYTE.  When going back to processing bytes without NEXTBYTE, call
+ * undefer_input().  For example, extract_or_test_member brackets its
+ * central section that does the decompression with these two functions.
+ * If you need to check the number of bytes remaining in the current
+ * file while using NEXTBYTE, check (G.csize + G.incnt), not G.csize.
+ */
+
+/****************************/
+/* function undefer_input() */
+/****************************/
+
+void undefer_input(__G)
+    __GDEF
+{
+    if (G.incnt > 0)
+        G.csize += G.incnt;
+    if (G.incnt_leftover > 0) {
+        /* We know that "(G.csize < MAXINT)" so we can cast G.csize to int:
+         * This condition was checked when G.incnt_leftover was set > 0 in
+         * defer_leftover_input(), and it is NOT allowed to touch G.csize
+         * before calling undefer_input() when (G.incnt_leftover > 0)
+         * (single exception: see read_byte()'s  "G.csize <= 0" handling) !!
+         */
+        G.incnt = G.incnt_leftover + (int)G.csize;
+        G.inptr = G.inptr_leftover - (int)G.csize;
+        G.incnt_leftover = 0;
+    } else if (G.incnt < 0)
+        G.incnt = 0;
+} /* end function undefer_input() */
+
+
+
+
+
+/***********************************/
+/* function defer_leftover_input() */
+/***********************************/
+
+void defer_leftover_input(__G)
+    __GDEF
+{
+    if ((zoff_t)G.incnt > G.csize) {
+        /* (G.csize < MAXINT), we can safely cast it to int !! */
+        if (G.csize < 0L)
+            G.csize = 0L;
+        G.inptr_leftover = G.inptr + (int)G.csize;
+        G.incnt_leftover = G.incnt - (int)G.csize;
+        G.incnt = (int)G.csize;
+    } else
+        G.incnt_leftover = 0;
+    G.csize -= G.incnt;
+} /* end function defer_leftover_input() */
+
+
+
+
+
+/**********************/
+/* Function readbuf() */
+/**********************/
+
+unsigned readbuf(__G__ buf, size)   /* return number of bytes read into buf */
+    __GDEF
+    char *buf;
+    register unsigned size;
+{
+    register unsigned count;
+    unsigned n;
+
+    n = size;
+    while (size) {
+        if (G.incnt <= 0) {
+            if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
+                return (n-size);
+            else if (G.incnt < 0) {
+                /* another hack, but no real harm copying same thing twice */
+                (*G.message)((zvoid *)&G,
+                  (uch *)LoadFarString(ReadError),  /* CANNOT use slide */
+                  (ulg)strlen(LoadFarString(ReadError)), 0x401);
+                return 0;  /* discarding some data; better than lock-up */
+            }
+            /* buffer ALWAYS starts on a block boundary:  */
+            G.cur_zipfile_bufstart += INBUFSIZ;
+            G.inptr = G.inbuf;
+        }
+        count = MIN(size, (unsigned)G.incnt);
+        memcpy(buf, G.inptr, count);
+        buf += count;
+        G.inptr += count;
+        G.incnt -= count;
+        size -= count;
+    }
+    return n;
+
+} /* end function readbuf() */
+
+
+
+
+
+/***********************/
+/* Function readbyte() */
+/***********************/
+
+int readbyte(__G)   /* refill inbuf and return a byte if available, else EOF */
+    __GDEF
+{
+    if (G.mem_mode)
+        return EOF;
+    if (G.csize <= 0) {
+        G.csize--;             /* for tests done after exploding */
+        G.incnt = 0;
+        return EOF;
+    }
+    if (G.incnt <= 0) {
+        if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) {
+            return EOF;
+        } else if (G.incnt < 0) {  /* "fail" (abort, retry, ...) returns this */
+            /* another hack, but no real harm copying same thing twice */
+            (*G.message)((zvoid *)&G,
+              (uch *)LoadFarString(ReadError),
+              (ulg)strlen(LoadFarString(ReadError)), 0x401);
+            echon();
+#ifdef WINDLL
+            longjmp(dll_error_return, 1);
+#else
+            DESTROYGLOBALS();
+            EXIT(PK_BADERR);    /* totally bailing; better than lock-up */
+#endif
+        }
+        G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on block bndry */
+        G.inptr = G.inbuf;
+        defer_leftover_input(__G);           /* decrements G.csize */
+    }
+
+#if CRYPT
+    if (G.pInfo->encrypted) {
+        uch *p;
+        int n;
+
+        /* This was previously set to decrypt one byte beyond G.csize, when
+         * incnt reached that far.  GRR said, "but it's required:  why?"  This
+         * was a bug in fillinbuf() -- was it also a bug here?
+         */
+        for (n = G.incnt, p = G.inptr;  n--;  p++)
+            zdecode(*p);
+    }
+#endif /* CRYPT */
+
+    --G.incnt;
+    return *G.inptr++;
+
+} /* end function readbyte() */
+
+
+
+
+
+#if defined(USE_ZLIB) || defined(USE_BZIP2)
+
+/************************/
+/* Function fillinbuf() */
+/************************/
+
+int fillinbuf(__G) /* like readbyte() except returns number of bytes in inbuf */
+    __GDEF
+{
+    if (G.mem_mode ||
+                  (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+        return 0;
+    G.cur_zipfile_bufstart += INBUFSIZ;  /* always starts on a block boundary */
+    G.inptr = G.inbuf;
+    defer_leftover_input(__G);           /* decrements G.csize */
+
+#if CRYPT
+    if (G.pInfo->encrypted) {
+        uch *p;
+        int n;
+
+        for (n = G.incnt, p = G.inptr;  n--;  p++)
+            zdecode(*p);
+    }
+#endif /* CRYPT */
+
+    return G.incnt;
+
+} /* end function fillinbuf() */
+
+#endif /* USE_ZLIB || USE_BZIP2 */
+
+
+
+
+
+/************************/
+/* Function seek_zipf() */
+/************************/
+
+int seek_zipf(__G__ abs_offset)
+    __GDEF
+    zoff_t abs_offset;
+{
+/*
+ *  Seek to the block boundary of the block which includes abs_offset,
+ *  then read block into input buffer and set pointers appropriately.
+ *  If block is already in the buffer, just set the pointers.  This function
+ *  is used by do_seekable (process.c), extract_or_test_entrylist (extract.c)
+ *  and do_string (fileio.c).  Also, a slightly modified version is embedded
+ *  within extract_or_test_entrylist (extract.c).  readbyte() and readbuf()
+ *  (fileio.c) are compatible.  NOTE THAT abs_offset is intended to be the
+ *  "proper offset" (i.e., if there were no extra bytes prepended);
+ *  cur_zipfile_bufstart contains the corrected offset.
+ *
+ *  Since seek_zipf() is never used during decompression, it is safe to
+ *  use the slide[] buffer for the error message.
+ *
+ * returns PK error codes:
+ *  PK_BADERR if effective offset in zipfile is negative
+ *  PK_EOF if seeking past end of zipfile
+ *  PK_OK when seek was successful
+ */
+    zoff_t request = abs_offset + G.extra_bytes;
+    zoff_t inbuf_offset = request % INBUFSIZ;
+    zoff_t bufstart = request - inbuf_offset;
+
+    if (request < 0) {
+        Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
+             G.zipfn, LoadFarString(ReportMsg)));
+        return(PK_BADERR);
+    } else if (bufstart != G.cur_zipfile_bufstart) {
+        Trace((stderr,
+          "fpos_zip: abs_offset = %s, G.extra_bytes = %s\n",
+          FmZofft(abs_offset, NULL, NULL),
+          FmZofft(G.extra_bytes, NULL, NULL)));
+#ifdef USE_STRM_INPUT
+        zfseeko(G.zipfd, bufstart, SEEK_SET);
+        G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+        G.cur_zipfile_bufstart = zlseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+        Trace((stderr,
+          "       request = %s, (abs+extra) = %s, inbuf_offset = %s\n",
+          FmZofft(request, NULL, NULL),
+          FmZofft((abs_offset+G.extra_bytes), NULL, NULL),
+          FmZofft(inbuf_offset, NULL, NULL)));
+        Trace((stderr, "       bufstart = %s, cur_zipfile_bufstart = %s\n",
+          FmZofft(bufstart, NULL, NULL),
+          FmZofft(G.cur_zipfile_bufstart, NULL, NULL)));
+        if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+            return(PK_EOF);
+        G.incnt -= (int)inbuf_offset;
+        G.inptr = G.inbuf + (int)inbuf_offset;
+    } else {
+        G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset;
+        G.inptr = G.inbuf + (int)inbuf_offset;
+    }
+    return(PK_OK);
+} /* end function seek_zipf() */
+
+
+
+
+
+#ifndef VMS  /* for VMS use code in vms.c */
+
+/********************/
+/* Function flush() */   /* returns PK error codes: */
+/********************/   /* if tflag => always 0; PK_DISK if write error */
+
+int flush(__G__ rawbuf, size, unshrink)
+    __GDEF
+    uch *rawbuf;
+    ulg size;
+    int unshrink;
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+{
+    int ret;
+
+    /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions
+     * cannot handle writes of 64k blocks at once.  For these systems, the
+     * blocks to flush are split into pieces of 32k or less.
+     */
+    while (size > 0x8000L) {
+        ret = partflush(__G__ rawbuf, 0x8000L, unshrink);
+        if (ret != PK_OK)
+            return ret;
+        size -= 0x8000L;
+        rawbuf += (extent)0x8000;
+    }
+    return partflush(__G__ rawbuf, size, unshrink);
+} /* end function flush() */
+
+
+/************************/
+/* Function partflush() */  /* returns PK error codes: */
+/************************/  /* if tflag => always 0; PK_DISK if write error */
+
+static int partflush(__G__ rawbuf, size, unshrink)
+    __GDEF
+    uch *rawbuf;        /* cannot be ZCONST, gets passed to (*G.message)() */
+    ulg size;
+    int unshrink;
+#endif /* USE_DEFLATE64 && __16BIT__ */
+{
+    register uch *p;
+    register uch *q;
+    uch *transbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+    ulg transbufsiz;
+#endif
+    /* static int didCRlast = FALSE;    moved to globals.h */
+
+
+/*---------------------------------------------------------------------------
+    Compute the CRC first; if testing or if disk is full, that's it.
+  ---------------------------------------------------------------------------*/
+
+    G.crc32val = crc32(G.crc32val, rawbuf, (extent)size);
+
+#ifdef DLL
+    if ((G.statreportcb != NULL) &&
+        (*G.statreportcb)(__G__ UZ_ST_IN_PROGRESS, G.zipfn, G.filename, NULL))
+        return IZ_CTRLC;        /* cancel operation by user request */
+#endif
+
+    if (uO.tflag || size == 0L)  /* testing or nothing to write:  all done */
+        return PK_OK;
+
+    if (G.disk_full)
+        return PK_DISK;         /* disk already full:  ignore rest of file */
+
+/*---------------------------------------------------------------------------
+    Write the bytes rawbuf[0..size-1] to the output device, first converting
+    end-of-lines and ASCII/EBCDIC as needed.  If SMALL_MEM or MED_MEM are NOT
+    defined, outbuf is assumed to be at least as large as rawbuf and is not
+    necessarily checked for overflow.
+  ---------------------------------------------------------------------------*/
+
+    if (!G.pInfo->textmode) {   /* write raw binary data */
+        /* GRR:  note that for standard MS-DOS compilers, size argument to
+         * fwrite() can never be more than 65534, so WriteError macro will
+         * have to be rewritten if size can ever be that large.  For now,
+         * never more than 32K.  Also note that write() returns an int, which
+         * doesn't necessarily limit size to 32767 bytes if write() is used
+         * on 16-bit systems but does make it more of a pain; however, because
+         * at least MSC 5.1 has a lousy implementation of fwrite() (as does
+         * DEC Ultrix cc), write() is used anyway.
+         */
+#ifdef DLL
+        if (G.redirect_data) {
+#ifdef NO_SLIDE_REDIR
+            if (writeToMemory(__G__ rawbuf, (extent)size)) return PK_ERR;
+#else
+            writeToMemory(__G__ rawbuf, (extent)size);
+#endif
+        } else
+#endif
+        if (!uO.cflag && WriteError(rawbuf, size, G.outfile))
+            return disk_error(__G);
+        else if (uO.cflag && (*G.message)((zvoid *)&G, rawbuf, size, 0))
+            return PK_OK;
+    } else {   /* textmode:  aflag is true */
+        if (unshrink) {
+            /* rawbuf = outbuf */
+            transbuf = G.outbuf2;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+            transbufsiz = TRANSBUFSIZ;
+#endif
+        } else {
+            /* rawbuf = slide */
+            transbuf = G.outbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+            transbufsiz = OUTBUFSIZ;
+            Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n",
+                   (unsigned)OUTBUFSIZ));
+#endif
+        }
+        if (G.newfile) {
+#ifdef VMS_TEXT_CONV
+            if (G.pInfo->hostnum == VMS_ && G.extra_field &&
+                is_vms_varlen_txt(__G__ G.extra_field,
+                                  G.lrec.extra_field_length))
+                G.VMS_line_state = 0;    /* 0: ready to read line length */
+            else
+                G.VMS_line_state = -1;   /* -1: don't treat as VMS text */
+#endif
+            G.didCRlast = FALSE;         /* no previous buffers written */
+            G.newfile = FALSE;
+        }
+
+#ifdef VMS_TEXT_CONV
+        if (G.VMS_line_state >= 0)
+        {
+            p = rawbuf;
+            q = transbuf;
+            while ((extent)(p-rawbuf) < (extent)size) {
+                switch (G.VMS_line_state) {
+
+                    /* 0: ready to read line length */
+                    case 0:
+                        G.VMS_line_length = 0;
+                        if ((extent)(p-rawbuf) == (extent)size-1) {
+                            /* last char */
+                            G.VMS_line_length = (unsigned)(*p++);
+                            G.VMS_line_state = 1;
+                        } else {
+                            G.VMS_line_length = makeword(p);
+                            p += 2;
+                            G.VMS_line_state = 2;
+                        }
+                        G.VMS_line_pad =
+                               ((G.VMS_line_length & 1) != 0); /* odd */
+                        break;
+
+                    /* 1: read one byte of length, need second */
+                    case 1:
+                        G.VMS_line_length += ((unsigned)(*p++) << 8);
+                        G.VMS_line_state = 2;
+                        break;
+
+                    /* 2: ready to read VMS_line_length chars */
+                    case 2:
+                        {
+                            extent remaining = (extent)size+(rawbuf-p);
+                            extent outroom;
+
+                            if (G.VMS_line_length < remaining) {
+                                remaining = G.VMS_line_length;
+                                G.VMS_line_state = 3;
+                            }
+
+                            outroom = transbuf+(extent)transbufsiz-q;
+                            if (remaining >= outroom) {
+                                remaining -= outroom;
+                                for (;outroom > 0; p++, outroom--)
+                                    *q++ = native(*p);
+#ifdef DLL
+                                if (G.redirect_data) {
+                                    if (writeToMemory(__G__ transbuf,
+                                          (extent)(q-transbuf))) return PK_ERR;
+                                } else
+#endif
+                                if (!uO.cflag && WriteError(transbuf,
+                                    (extent)(q-transbuf), G.outfile))
+                                    return disk_error(__G);
+                                else if (uO.cflag && (*G.message)((zvoid *)&G,
+                                         transbuf, (ulg)(q-transbuf), 0))
+                                    return PK_OK;
+                                q = transbuf;
+                                /* fall through to normal case */
+                            }
+                            G.VMS_line_length -= remaining;
+                            for (;remaining > 0; p++, remaining--)
+                                *q++ = native(*p);
+                        }
+                        break;
+
+                    /* 3: ready to PutNativeEOL */
+                    case 3:
+                        if (q > transbuf+(extent)transbufsiz-lenEOL) {
+#ifdef DLL
+                            if (G.redirect_data) {
+                                if (writeToMemory(__G__ transbuf,
+                                      (extent)(q-transbuf))) return PK_ERR;
+                            } else
+#endif
+                            if (!uO.cflag &&
+                                WriteError(transbuf, (extent)(q-transbuf),
+                                  G.outfile))
+                                return disk_error(__G);
+                            else if (uO.cflag && (*G.message)((zvoid *)&G,
+                                     transbuf, (ulg)(q-transbuf), 0))
+                                return PK_OK;
+                            q = transbuf;
+                        }
+                        PutNativeEOL
+                        G.VMS_line_state = G.VMS_line_pad ? 4 : 0;
+                        break;
+
+                    /* 4: ready to read pad byte */
+                    case 4:
+                        ++p;
+                        G.VMS_line_state = 0;
+                        break;
+                }
+            } /* end while */
+
+        } else
+#endif /* VMS_TEXT_CONV */
+
+    /*-----------------------------------------------------------------------
+        Algorithm:  CR/LF => native; lone CR => native; lone LF => native.
+        This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
+        stream-oriented files, not record-oriented).
+      -----------------------------------------------------------------------*/
+
+        /* else not VMS text */ {
+            p = rawbuf;
+            if (*p == LF && G.didCRlast)
+                ++p;
+            G.didCRlast = FALSE;
+            for (q = transbuf;  (extent)(p-rawbuf) < (extent)size;  ++p) {
+                if (*p == CR) {           /* lone CR or CR/LF: treat as EOL  */
+                    PutNativeEOL
+                    if ((extent)(p-rawbuf) == (extent)size-1)
+                        /* last char in buffer */
+                        G.didCRlast = TRUE;
+                    else if (p[1] == LF)  /* get rid of accompanying LF */
+                        ++p;
+                } else if (*p == LF)      /* lone LF */
+                    PutNativeEOL
+                else
+#ifndef DOS_FLX_OS2_W32
+                if (*p != CTRLZ)          /* lose all ^Z's */
+#endif
+                    *q++ = native(*p);
+
+#if (defined(SMALL_MEM) || defined(MED_MEM))
+# if (lenEOL == 1)   /* don't check unshrink:  both buffers small but equal */
+                if (!unshrink)
+# endif
+                    /* check for danger of buffer overflow and flush */
+                    if (q > transbuf+(extent)transbufsiz-lenEOL) {
+                        Trace((stderr,
+                          "p - rawbuf = %u   q-transbuf = %u   size = %lu\n",
+                          (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+                        if (!uO.cflag && WriteError(transbuf,
+                            (extent)(q-transbuf), G.outfile))
+                            return disk_error(__G);
+                        else if (uO.cflag && (*G.message)((zvoid *)&G,
+                                 transbuf, (ulg)(q-transbuf), 0))
+                            return PK_OK;
+                        q = transbuf;
+                        continue;
+                    }
+#endif /* SMALL_MEM || MED_MEM */
+            }
+        }
+
+    /*-----------------------------------------------------------------------
+        Done translating:  write whatever we've got to file (or screen).
+      -----------------------------------------------------------------------*/
+
+        Trace((stderr, "p - rawbuf = %u   q-transbuf = %u   size = %lu\n",
+          (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+        if (q > transbuf) {
+#ifdef DLL
+            if (G.redirect_data) {
+                if (writeToMemory(__G__ transbuf, (extent)(q-transbuf)))
+                    return PK_ERR;
+            } else
+#endif
+            if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf),
+                G.outfile))
+                return disk_error(__G);
+            else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf,
+                (ulg)(q-transbuf), 0))
+                return PK_OK;
+        }
+    }
+
+    return PK_OK;
+
+} /* end function flush() [resp. partflush() for 16-bit Deflate64 support] */
+
+
+
+
+
+#ifdef VMS_TEXT_CONV
+
+/********************************/
+/* Function is_vms_varlen_txt() */
+/********************************/
+
+static int is_vms_varlen_txt(__G__ ef_buf, ef_len)
+    __GDEF
+    uch *ef_buf;        /* buffer containing extra field */
+    unsigned ef_len;    /* total length of extra field */
+{
+    unsigned eb_id;
+    unsigned eb_len;
+    uch *eb_data;
+    unsigned eb_datlen;
+#define VMSREC_C_UNDEF  0
+#define VMSREC_C_VAR    2
+    uch vms_rectype = VMSREC_C_UNDEF;
+ /* uch vms_fileorg = 0; */ /* currently, fileorg is not used... */
+
+#define VMSPK_ITEMID            0
+#define VMSPK_ITEMLEN           2
+#define VMSPK_ITEMHEADSZ        4
+
+#define VMSATR_C_RECATTR        4
+#define VMS_FABSIG              0x42414656      /* "VFAB" */
+/* offsets of interesting fields in VMS fabdef structure */
+#define VMSFAB_B_RFM            31      /* record format byte */
+#define VMSFAB_B_ORG            29      /* file organization byte */
+
+    if (ef_len == 0 || ef_buf == NULL)
+        return FALSE;
+
+    while (ef_len >= EB_HEADSIZE) {
+        eb_id = makeword(EB_ID + ef_buf);
+        eb_len = makeword(EB_LEN + ef_buf);
+
+        if (eb_len > (ef_len - EB_HEADSIZE)) {
+            /* discovered some extra field inconsistency! */
+            Trace((stderr,
+              "is_vms_varlen_txt: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+
+        switch (eb_id) {
+          case EF_PKVMS:
+            /* The PKVMS e.f. raw data part consists of:
+             * a) 4 bytes CRC checksum
+             * b) list of uncompressed variable-length data items
+             * Each data item is introduced by a fixed header
+             *  - 2 bytes data type ID
+             *  - 2 bytes <size> of data
+             *  - <size> bytes of actual attribute data
+             */
+
+            /* get pointer to start of data and its total length */
+            eb_data = ef_buf+(EB_HEADSIZE+4);
+            eb_datlen = eb_len-4;
+
+            /* test the CRC checksum */
+            if (makelong(ef_buf+EB_HEADSIZE) !=
+                crc32(CRCVAL_INITIAL, eb_data, (extent)eb_datlen))
+            {
+                Info(slide, 1, ((char *)slide,
+                  "[Warning: CRC error, discarding PKWARE extra field]\n"));
+                /* skip over the data analysis code */
+                break;
+            }
+
+            /* scan through the attribute data items */
+            while (eb_datlen > 4)
+            {
+                unsigned fldsize = makeword(&eb_data[VMSPK_ITEMLEN]);
+
+                /* check the item type word */
+                switch (makeword(&eb_data[VMSPK_ITEMID])) {
+                  case VMSATR_C_RECATTR:
+                    /* we have found the (currently only) interesting
+                     * data item */
+                    if (fldsize >= 1) {
+                        vms_rectype = eb_data[VMSPK_ITEMHEADSZ] & 15;
+                     /* vms_fileorg = eb_data[VMSPK_ITEMHEADSZ] >> 4; */
+                    }
+                    break;
+                  default:
+                    break;
+                }
+                /* skip to next data item */
+                eb_datlen -= fldsize + VMSPK_ITEMHEADSZ;
+                eb_data += fldsize + VMSPK_ITEMHEADSZ;
+            }
+            break;
+
+          case EF_IZVMS:
+            if (makelong(ef_buf+EB_HEADSIZE) == VMS_FABSIG) {
+                if ((eb_data = extract_izvms_block(__G__
+                                                   ef_buf+EB_HEADSIZE, eb_len,
+                                                   &eb_datlen, NULL, 0))
+                    != NULL)
+                {
+                    if (eb_datlen >= VMSFAB_B_RFM+1) {
+                        vms_rectype = eb_data[VMSFAB_B_RFM] & 15;
+                     /* vms_fileorg = eb_data[VMSFAB_B_ORG] >> 4; */
+                    }
+                    free(eb_data);
+                }
+            }
+            break;
+
+          default:
+            break;
+        }
+
+        /* Skip this extra field block */
+        ef_buf += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+
+    return (vms_rectype == VMSREC_C_VAR);
+
+} /* end function is_vms_varlen_txtfile() */
+
+#endif /* VMS_TEXT_CONV */
+
+
+
+
+/*************************/
+/* Function disk_error() */
+/*************************/
+
+static int disk_error(__G)
+    __GDEF
+{
+    /* OK to use slide[] here because this file is finished regardless */
+    Info(slide, 0x4a1, ((char *)slide, LoadFarString(DiskFullQuery),
+      FnFilter1(G.filename)));
+
+#ifndef WINDLL
+    fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
+    if (*G.answerbuf == 'y')   /* stop writing to this file */
+        G.disk_full = 1;       /*  (outfile bad?), but new OK */
+    else
+#endif
+        G.disk_full = 2;       /* no:  exit program */
+
+    return PK_DISK;
+
+} /* end function disk_error() */
+
+#endif /* !VMS */
+
+
+
+
+
+/*****************************/
+/* Function UzpMessagePrnt() */
+/*****************************/
+
+int UZ_EXP UzpMessagePrnt(pG, buf, size, flag)
+    zvoid *pG;   /* globals struct:  always passed */
+    uch *buf;    /* preformatted string to be printed */
+    ulg size;    /* length of string (may include nulls) */
+    int flag;    /* flag bits */
+{
+    /* IMPORTANT NOTE:
+     *    The name of the first parameter of UzpMessagePrnt(), which passes
+     *    the "Uz_Globs" address, >>> MUST <<< be identical to the string
+     *    expansion of the __G__ macro in the REENTRANT case (see globals.h).
+     *    This name identity is mandatory for the LoadFarString() macro
+     *    (in the SMALL_MEM case) !!!
+     */
+    int error;
+    uch *q=buf, *endbuf=buf+(unsigned)size;
+#ifdef MORE
+    uch *p=buf;
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+    int islinefeed = FALSE;
+#endif
+#endif
+    FILE *outfp;
+
+
+/*---------------------------------------------------------------------------
+    These tests are here to allow fine-tuning of UnZip's output messages,
+    but none of them will do anything without setting the appropriate bit
+    in the flag argument of every Info() statement which is to be turned
+    *off*.  That is, all messages are currently turned on for all ports.
+    To turn off *all* messages, use the UzpMessageNull() function instead
+    of this one.
+  ---------------------------------------------------------------------------*/
+
+#if (defined(OS2) && defined(DLL))
+    if (MSG_NO_DLL2(flag))  /* if OS/2 DLL bit is set, do NOT print this msg */
+        return 0;
+#endif
+#ifdef WINDLL
+    if (MSG_NO_WDLL(flag))
+        return 0;
+#endif
+#ifdef WINDLL
+    if (MSG_NO_WGUI(flag))
+        return 0;
+#endif
+/*
+#ifdef ACORN_GUI
+    if (MSG_NO_AGUI(flag))
+        return 0;
+#endif
+ */
+#ifdef DLL                 /* don't display message if data is redirected */
+    if (((Uz_Globs *)pG)->redirect_data &&
+        !((Uz_Globs *)pG)->redirect_text)
+        return 0;
+#endif
+
+    if (MSG_STDERR(flag) && !((Uz_Globs *)pG)->UzO.tflag)
+        outfp = (FILE *)stderr;
+    else
+        outfp = (FILE *)stdout;
+
+#ifdef QUERY_TRNEWLN
+    /* some systems require termination of query prompts with '\n' to force
+     * immediate display */
+    if (MSG_MNEWLN(flag)) {   /* assumes writable buffer (e.g., slide[]) */
+        *endbuf++ = '\n';     /*  with room for one more char at end of buf */
+        ++size;               /*  (safe assumption:  only used for four */
+    }                         /*  short queries in extract.c and fileio.c) */
+#endif
+
+    if (MSG_TNEWLN(flag)) {   /* again assumes writable buffer:  fragile... */
+        if ((!size && !((Uz_Globs *)pG)->sol) ||
+            (size && (endbuf[-1] != '\n')))
+        {
+            *endbuf++ = '\n';
+            ++size;
+        }
+    }
+
+#ifdef MORE
+# ifdef SCREENSIZE
+    /* room for --More-- and one line of overlap: */
+#  if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+    SCREENSIZE(&((Uz_Globs *)pG)->height, &((Uz_Globs *)pG)->width);
+#  else
+    SCREENSIZE(&((Uz_Globs *)pG)->height, (int *)NULL);
+#  endif
+    ((Uz_Globs *)pG)->height -= 2;
+# else
+    /* room for --More-- and one line of overlap: */
+    ((Uz_Globs *)pG)->height = SCREENLINES - 2;
+#  if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+    ((Uz_Globs *)pG)->width = SCREENWIDTH;
+#  endif
+# endif
+#endif /* MORE */
+
+    if (MSG_LNEWLN(flag) && !((Uz_Globs *)pG)->sol) {
+        /* not at start of line:  want newline */
+#ifdef OS2DLL
+        if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+            putc('\n', outfp);
+            fflush(outfp);
+#ifdef MORE
+            if (((Uz_Globs *)pG)->M_flag)
+            {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+                ((Uz_Globs *)pG)->chars = 0;
+#endif
+                ++((Uz_Globs *)pG)->numlines;
+                ++((Uz_Globs *)pG)->lines;
+                if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+                    (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+                      LoadFarString(MorePrompt), 1);
+            }
+#endif /* MORE */
+            if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+                !isatty(1) && isatty(2))
+            {
+                /* error output from testing redirected:  also send to stderr */
+                putc('\n', stderr);
+                fflush(stderr);
+            }
+#ifdef OS2DLL
+        } else
+           REDIRECTC('\n');
+#endif
+        ((Uz_Globs *)pG)->sol = TRUE;
+    }
+
+    /* put zipfile name, filename and/or error/warning keywords here */
+
+#ifdef MORE
+    if (((Uz_Globs *)pG)->M_flag
+#ifdef OS2DLL
+         && !((Uz_Globs *)pG)->redirect_text
+#endif
+                                                 )
+    {
+        while (p < endbuf) {
+            if (*p == '\n') {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+                islinefeed = TRUE;
+            } else if (SCREENLWRAP) {
+                if (*p == '\r') {
+                    ((Uz_Globs *)pG)->chars = 0;
+                } else {
+#  ifdef TABSIZE
+                    if (*p == '\t')
+                        ((Uz_Globs *)pG)->chars +=
+                            (TABSIZE - (((Uz_Globs *)pG)->chars % TABSIZE));
+                    else
+#  endif
+                        ++((Uz_Globs *)pG)->chars;
+
+                    if (((Uz_Globs *)pG)->chars >= ((Uz_Globs *)pG)->width)
+                        islinefeed = TRUE;
+                }
+            }
+            if (islinefeed) {
+                islinefeed = FALSE;
+                ((Uz_Globs *)pG)->chars = 0;
+#endif /* (SCREENWIDTH && SCREEN_LWRAP) */
+                ++((Uz_Globs *)pG)->numlines;
+                ++((Uz_Globs *)pG)->lines;
+                if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+                {
+                    if ((error = WriteTxtErr(q, p-q+1, outfp)) != 0)
+                        return error;
+                    fflush(outfp);
+                    ((Uz_Globs *)pG)->sol = TRUE;
+                    q = p + 1;
+                    (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+                      LoadFarString(MorePrompt), 1);
+                }
+            }
+            INCSTR(p);
+        } /* end while */
+        size = (ulg)(p - q);   /* remaining text */
+    }
+#endif /* MORE */
+
+    if (size) {
+#ifdef OS2DLL
+        if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+            if ((error = WriteTxtErr(q, size, outfp)) != 0)
+                return error;
+#ifndef VMS     /* 2005-09-16 SMS.  See note at "WriteTxtErr()", above. */
+            fflush(outfp);
+#endif
+            if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+                !isatty(1) && isatty(2))
+            {
+                /* error output from testing redirected:  also send to stderr */
+                if ((error = WriteTxtErr(q, size, stderr)) != 0)
+                    return error;
+                fflush(stderr);
+            }
+#ifdef OS2DLL
+        } else {                /* GRR:  this is ugly:  hide with macro */
+            if ((error = REDIRECTPRINT(q, size)) != 0)
+                return error;
+        }
+#endif /* OS2DLL */
+        ((Uz_Globs *)pG)->sol = (endbuf[-1] == '\n');
+    }
+    return 0;
+
+} /* end function UzpMessagePrnt() */
+
+
+
+
+
+#ifdef DLL
+
+/*****************************/
+/* Function UzpMessageNull() */  /* convenience routine for no output at all */
+/*****************************/
+
+int UZ_EXP UzpMessageNull(pG, buf, size, flag)
+    zvoid *pG;    /* globals struct:  always passed */
+    uch *buf;     /* preformatted string to be printed */
+    ulg size;     /* length of string (may include nulls) */
+    int flag;     /* flag bits */
+{
+    return 0;
+
+} /* end function UzpMessageNull() */
+
+#endif /* DLL */
+
+
+
+
+
+/***********************/
+/* Function UzpInput() */   /* GRR:  this is a placeholder for now */
+/***********************/
+
+int UZ_EXP UzpInput(pG, buf, size, flag)
+    zvoid *pG;    /* globals struct:  always passed */
+    uch *buf;     /* preformatted string to be printed */
+    int *size;    /* (address of) size of buf and of returned string */
+    int flag;     /* flag bits (bit 0: no echo) */
+{
+    /* tell picky compilers to shut up about "unused variable" warnings */
+    pG = pG; buf = buf; flag = flag;
+
+    *size = 0;
+    return 0;
+
+} /* end function UzpInput() */
+
+
+
+
+
+#if (!defined(WINDLL) && !defined(MACOS))
+
+/***************************/
+/* Function UzpMorePause() */
+/***************************/
+
+void UZ_EXP UzpMorePause(pG, prompt, flag)
+    zvoid *pG;            /* globals struct:  always passed */
+    ZCONST char *prompt;  /* "--More--" prompt */
+    int flag;             /* 0 = any char OK; 1 = accept only '\n', ' ', q */
+{
+    uch c;
+
+/*---------------------------------------------------------------------------
+    Print a prompt and wait for the user to press a key, then erase prompt
+    if possible.
+  ---------------------------------------------------------------------------*/
+
+    if (!((Uz_Globs *)pG)->sol)
+        fprintf(stderr, "\n");
+    /* numlines may or may not be used: */
+    fprintf(stderr, prompt, ((Uz_Globs *)pG)->numlines);
+    fflush(stderr);
+    if (flag & 1) {
+        do {
+            c = (uch)FGETCH(0);
+        } while (
+#ifdef THEOS
+                 c != 17 &&     /* standard QUIT key */
+#endif
+                 c != '\r' && c != '\n' && c != ' ' && c != 'q' && c != 'Q');
+    } else
+        c = (uch)FGETCH(0);
+
+    /* newline was not echoed, so cover up prompt line */
+    fprintf(stderr, LoadFarString(HidePrompt));
+    fflush(stderr);
+
+    if (
+#ifdef THEOS
+        (c == 17) ||            /* standard QUIT key */
+#endif
+        (ToLower(c) == 'q')) {
+        DESTROYGLOBALS();
+        EXIT(PK_COOL);
+    }
+
+    ((Uz_Globs *)pG)->sol = TRUE;
+
+#ifdef MORE
+    /* space for another screen, enter for another line. */
+    if ((flag & 1) && c == ' ')
+        ((Uz_Globs *)pG)->lines = 0;
+#endif /* MORE */
+
+} /* end function UzpMorePause() */
+
+#endif /* !WINDLL && !MACOS */
+
+
+
+
+#ifndef WINDLL
+
+/**************************/
+/* Function UzpPassword() */
+/**************************/
+
+int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, efn)
+    zvoid *pG;         /* pointer to UnZip's internal global vars */
+    int *rcnt;         /* retry counter */
+    char *pwbuf;       /* buffer for password */
+    int size;          /* size of password buffer */
+    ZCONST char *zfn;  /* name of zip archive */
+    ZCONST char *efn;  /* name of archive entry being processed */
+{
+#if CRYPT
+    int r = IZ_PW_ENTERED;
+    char *m;
+    char *prompt;
+    char *ep;
+    char *zp;
+
+#ifndef REENTRANT
+    /* tell picky compilers to shut up about "unused variable" warnings */
+    pG = pG;
+#endif
+
+    if (*rcnt == 0) {           /* First call for current entry */
+        *rcnt = 2;
+        zp = FnFilter1( zfn);
+        ep = FnFilter2( efn);
+        prompt = (char *)malloc(        /* Slightly too long (2* "%s"). */
+         sizeof( PasswPrompt)+ strlen( zp)+ strlen( ep));
+        if (prompt != (char *)NULL) {
+            sprintf(prompt, LoadFarString(PasswPrompt), zp, ep);
+            m = prompt;
+        } else
+            m = (char *)LoadFarString(PasswPrompt2);
+    } else {                    /* Retry call, previous password was wrong */
+        (*rcnt)--;
+        prompt = NULL;
+        m = (char *)LoadFarString(PasswRetry);
+    }
+
+    m = getp(__G__ m, pwbuf, size);
+    if (prompt != (char *)NULL) {
+        free(prompt);
+    }
+    if (m == (char *)NULL) {
+        r = IZ_PW_ERROR;
+    }
+    else if (*pwbuf == '\0') {
+        r = IZ_PW_CANCELALL;
+    }
+    return r;
+
+#else /* !CRYPT */
+    /* tell picky compilers to shut up about "unused variable" warnings */
+    pG = pG; rcnt = rcnt; pwbuf = pwbuf; size = size; zfn = zfn; efn = efn;
+
+    return IZ_PW_ERROR;  /* internal error; function should never get called */
+#endif /* ?CRYPT */
+
+} /* end function UzpPassword() */
+
+
+
+
+
+/**********************/
+/* Function handler() */
+/**********************/
+
+void handler(signal)   /* upon interrupt, turn on echo and exit cleanly */
+    int signal;
+{
+    GETGLOBALS();
+
+#if !(defined(SIGBUS) || defined(SIGSEGV))      /* add a newline if not at */
+    (*G.message)((zvoid *)&G, slide, 0L, 0x41); /*  start of line (to stderr; */
+#endif                                          /*  slide[] should be safe) */
+
+    echon();
+
+#ifdef SIGBUS
+    if (signal == SIGBUS) {
+        Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+          "bus error"));
+        DESTROYGLOBALS();
+        EXIT(PK_BADERR);
+    }
+#endif /* SIGBUS */
+
+#ifdef SIGILL
+    if (signal == SIGILL) {
+        Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+          "illegal instruction"));
+        DESTROYGLOBALS();
+        EXIT(PK_BADERR);
+    }
+#endif /* SIGILL */
+
+#ifdef SIGSEGV
+    if (signal == SIGSEGV) {
+        Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+          "segmentation violation"));
+        DESTROYGLOBALS();
+        EXIT(PK_BADERR);
+    }
+#endif /* SIGSEGV */
+
+    /* probably ctrl-C */
+    DESTROYGLOBALS();
+#if defined(AMIGA) && defined(__SASC)
+    _abort();
+#endif
+    EXIT(IZ_CTRLC);       /* was EXIT(0), then EXIT(PK_ERR) */
+}
+
+#endif /* !WINDLL */
+
+
+
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+#if (!defined(OS2) || defined(TIMESTAMP))
+
+#if (!defined(HAVE_MKTIME) || defined(WIN32))
+/* also used in amiga/filedate.c and win32/win32.c */
+ZCONST ush ydays[] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+#endif
+
+/*******************************/
+/* Function dos_to_unix_time() */ /* used for freshening/updating/timestamps */
+/*******************************/
+
+time_t dos_to_unix_time(dosdatetime)
+    ulg dosdatetime;
+{
+    time_t m_time;
+
+#ifdef HAVE_MKTIME
+
+    ZCONST time_t now = time(NULL);
+    struct tm *tm;
+#   define YRBASE  1900
+
+    tm = localtime(&now);
+    tm->tm_isdst = -1;          /* let mktime determine if DST is in effect */
+
+    /* dissect date */
+    tm->tm_year = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+    tm->tm_mon  = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+    tm->tm_mday = ((int)(dosdatetime >> 16) & 0x1f);
+
+    /* dissect time */
+    tm->tm_hour = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+    tm->tm_min  = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+    tm->tm_sec  = (int)((unsigned)dosdatetime << 1) & 0x3e;
+
+    m_time = mktime(tm);
+    NATIVE_TO_TIMET(m_time)     /* NOP unless MSC 7.0 or Macintosh */
+    TTrace((stderr, "  final m_time  =       %lu\n", (ulg)m_time));
+
+#else /* !HAVE_MKTIME */
+
+    int yr, mo, dy, hh, mm, ss;
+#ifdef TOPS20
+#   define YRBASE  1900
+    struct tmx *tmx;
+    char temp[20];
+#else /* !TOPS20 */
+#   define YRBASE  1970
+    int leap;
+    unsigned days;
+    struct tm *tm;
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+    TIME_ZONE_INFORMATION tzinfo;
+    DWORD res;
+#else /* ! WIN32 */
+#ifndef BSD4_4   /* GRR:  change to !defined(MODERN) ? */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+    struct timeb tbp;
+#else /* !(BSD || MTS || __GO32__) */
+#ifdef DECLARE_TIMEZONE
+    extern time_t timezone;
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* !BSD4_4 */
+#endif /* ?WIN32 */
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+
+    /* dissect date */
+    yr = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+    mo = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+    dy = ((int)(dosdatetime >> 16) & 0x1f) - 1;
+
+    /* dissect time */
+    hh = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+    mm = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+    ss = (int)((unsigned)dosdatetime & 0x1f) * 2;
+
+#ifdef TOPS20
+    tmx = (struct tmx *)malloc(sizeof(struct tmx));
+    sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
+    time_parse(temp, tmx, (char *)0);
+    m_time = time_make(tmx);
+    free(tmx);
+
+#else /* !TOPS20 */
+
+/*---------------------------------------------------------------------------
+    Calculate the number of seconds since the epoch, usually 1 January 1970.
+  ---------------------------------------------------------------------------*/
+
+    /* leap = # of leap yrs from YRBASE up to but not including current year */
+    leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
+
+    /* calculate days from BASE to this year and add expired days this year */
+    days = (yr * 365) + (leap - 492) + ydays[mo];
+
+    /* if year is a leap year and month is after February, add another day */
+    if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
+        ++days;                 /* OK through 2199 */
+
+    /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
+    m_time = (time_t)((unsigned long)(days + dy) * 86400L +
+                      (unsigned long)hh * 3600L +
+                      (unsigned long)(mm * 60 + ss));
+      /* - 1;   MS-DOS times always rounded up to nearest even second */
+    TTrace((stderr, "dos_to_unix_time:\n"));
+    TTrace((stderr, "  m_time before timezone = %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+    Adjust for local standard timezone offset.
+  ---------------------------------------------------------------------------*/
+
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+    /* account for timezone differences */
+    res = GetTimeZoneInformation(&tzinfo);
+    if (res != TIME_ZONE_ID_INVALID)
+    {
+    m_time += 60*(tzinfo.Bias);
+#else /* !WIN32 */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+#ifdef BSD4_4
+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+         (m_time < (time_t)0x70000000L) )
+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
+    if ((tm = localtime(&m_time)) != (struct tm *)NULL)
+        m_time -= tm->tm_gmtoff;                /* sec. EAST of GMT: subtr. */
+#else /* !(BSD4_4 */
+    ftime(&tbp);                                /* get `timezone' */
+    m_time += tbp.timezone * 60L;               /* seconds WEST of GMT:  add */
+#endif /* ?(BSD4_4 || __EMX__) */
+#else /* !(BSD || MTS || __GO32__) */
+    /* tzset was already called at start of process_zipfiles() */
+    /* tzset(); */              /* set `timezone' variable */
+#ifndef __BEOS__                /* BeOS DR8 has no timezones... */
+    m_time += timezone;         /* seconds WEST of GMT:  add */
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* ?WIN32 */
+    TTrace((stderr, "  m_time after timezone =  %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+    Adjust for local daylight savings (summer) time.
+  ---------------------------------------------------------------------------*/
+
+#ifndef BSD4_4  /* (DST already added to tm_gmtoff, so skip tm_isdst) */
+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+         (m_time < (time_t)0x70000000L) )
+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
+    TIMET_TO_NATIVE(m_time)     /* NOP unless MSC 7.0 or Macintosh */
+    if (((tm = localtime((time_t *)&m_time)) != NULL) && tm->tm_isdst)
+#ifdef WIN32
+        m_time += 60L * tzinfo.DaylightBias;    /* adjust with DST bias */
+    else
+        m_time += 60L * tzinfo.StandardBias;    /* add StdBias (normally 0) */
+#else
+        m_time -= 60L * 60L;    /* adjust for daylight savings time */
+#endif
+    NATIVE_TO_TIMET(m_time)     /* NOP unless MSC 7.0 or Macintosh */
+    TTrace((stderr, "  m_time after DST =       %lu\n", (ulg)m_time));
+#endif /* !BSD4_4 */
+#ifdef WIN32
+    }
+#endif
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+#endif /* ?HAVE_MKTIME */
+
+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+         (m_time < (time_t)0x70000000L) )
+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
+
+    return m_time;
+
+} /* end function dos_to_unix_time() */
+
+#endif /* !OS2 || TIMESTAMP */
+#endif /* !VMS && !CMS_MVS */
+
+
+
+#if (!defined(VMS) && !defined(OS2) && !defined(CMS_MVS))
+
+/******************************/
+/* Function check_for_newer() */  /* used for overwriting/freshening/updating */
+/******************************/
+
+int check_for_newer(__G__ filename)  /* return 1 if existing file is newer */
+    __GDEF                           /*  or equal; 0 if older; -1 if doesn't */
+    char *filename;                  /*  exist yet */
+{
+    time_t existing, archive;
+#ifdef USE_EF_UT_TIME
+    iztimes z_utime;
+#endif
+#ifdef AOS_VS
+    long    dyy, dmm, ddd, dhh, dmin, dss;
+
+
+    dyy = (lrec.last_mod_dos_datetime >> 25) + 1980;
+    dmm = (lrec.last_mod_dos_datetime >> 21) & 0x0f;
+    ddd = (lrec.last_mod_dos_datetime >> 16) & 0x1f;
+    dhh = (lrec.last_mod_dos_datetime >> 11) & 0x1f;
+    dmin = (lrec.last_mod_dos_datetime >> 5) & 0x3f;
+    dss = (lrec.last_mod_dos_datetime & 0x1f) * 2;
+
+    /* under AOS/VS, file times can only be set at creation time,
+     * with the info in a special DG format.  Make sure we can create
+     * it here - we delete it later & re-create it, whether or not
+     * it exists now.
+     */
+    if (!zvs_create(filename, (((ulg)dgdate(dmm, ddd, dyy)) << 16) |
+        (dhh*1800L + dmin*30L + dss/2L), -1L, -1L, (char *) -1, -1, -1, -1))
+        return DOES_NOT_EXIST;
+#endif /* AOS_VS */
+
+    Trace((stderr, "check_for_newer:  doing stat(%s)\n", FnFilter1(filename)));
+    if (SSTAT(filename, &G.statbuf)) {
+        Trace((stderr,
+          "check_for_newer:  stat(%s) returns %d:  file does not exist\n",
+          FnFilter1(filename), SSTAT(filename, &G.statbuf)));
+#ifdef SYMLINKS
+        Trace((stderr, "check_for_newer:  doing lstat(%s)\n",
+          FnFilter1(filename)));
+        /* GRR OPTION:  could instead do this test ONLY if G.symlnk is true */
+        if (lstat(filename, &G.statbuf) == 0) {
+            Trace((stderr,
+              "check_for_newer:  lstat(%s) returns 0:  symlink does exist\n",
+              FnFilter1(filename)));
+            if (QCOND2 && !IS_OVERWRT_ALL)
+                Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+                  FnFilter1(filename), " with no real file"));
+            return EXISTS_AND_OLDER;   /* symlink dates are meaningless */
+        }
+#endif /* SYMLINKS */
+        return DOES_NOT_EXIST;
+    }
+    Trace((stderr, "check_for_newer:  stat(%s) returns 0:  file exists\n",
+      FnFilter1(filename)));
+
+#ifdef SYMLINKS
+    /* GRR OPTION:  could instead do this test ONLY if G.symlnk is true */
+    if (lstat(filename, &G.statbuf) == 0 && S_ISLNK(G.statbuf.st_mode)) {
+        Trace((stderr, "check_for_newer:  %s is a symbolic link\n",
+          FnFilter1(filename)));
+        if (QCOND2 && !IS_OVERWRT_ALL)
+            Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+              FnFilter1(filename), ""));
+        return EXISTS_AND_OLDER;   /* symlink dates are meaningless */
+    }
+#endif /* SYMLINKS */
+
+    NATIVE_TO_TIMET(G.statbuf.st_mtime)   /* NOP unless MSC 7.0 or Macintosh */
+
+#ifdef USE_EF_UT_TIME
+    /* The `Unix extra field mtime' should be used for comparison with the
+     * time stamp of the existing file >>>ONLY<<< when the EF info is also
+     * used to set the modification time of the extracted file.
+     */
+    if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+        G.tz_is_valid &&
+#endif
+        (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, "check_for_newer:  using Unix extra field mtime\n"));
+        existing = G.statbuf.st_mtime;
+        archive  = z_utime.mtime;
+    } else {
+        /* round up existing filetime to nearest 2 seconds for comparison,
+         * but saturate in case of arithmetic overflow
+         */
+        existing = ((G.statbuf.st_mtime & 1) &&
+                    (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+                   G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+        archive  = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+    }
+#else /* !USE_EF_UT_TIME */
+    /* round up existing filetime to nearest 2 seconds for comparison,
+     * but saturate in case of arithmetic overflow
+     */
+    existing = ((G.statbuf.st_mtime & 1) &&
+                (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+               G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+    archive  = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+#endif /* ?USE_EF_UT_TIME */
+
+    TTrace((stderr, "check_for_newer:  existing %lu, archive %lu, e-a %ld\n",
+      (ulg)existing, (ulg)archive, (long)(existing-archive)));
+
+    return (existing >= archive);
+
+} /* end function check_for_newer() */
+
+#endif /* !VMS && !OS2 && !CMS_MVS */
+
+
+
+
+
+/************************/
+/* Function do_string() */
+/************************/
+
+int do_string(__G__ length, option)   /* return PK-type error code */
+    __GDEF
+    unsigned int length;        /* without prototype, ush converted to this */
+    int option;
+{
+    unsigned comment_bytes_left;
+    unsigned int block_len;
+    int error=PK_OK;
+    unsigned int length2;
+#ifdef AMIGA
+    char tmp_fnote[2 * AMIGA_FILENOTELEN];   /* extra room for squozen chars */
+#endif
+
+
+/*---------------------------------------------------------------------------
+    This function processes arbitrary-length (well, usually) strings.  Four
+    major options are allowed:  SKIP, wherein the string is skipped (pretty
+    logical, eh?); DISPLAY, wherein the string is printed to standard output
+    after undergoing any necessary or unnecessary character conversions;
+    DS_FN, wherein the string is put into the filename[] array after under-
+    going appropriate conversions (including case-conversion, if that is
+    indicated: see the global variable pInfo->lcflag); and EXTRA_FIELD,
+    wherein the `string' is assumed to be an extra field and is copied to
+    the (freshly malloced) buffer G.extra_field.  The third option should
+    be OK since filename is dimensioned at 1025, but we check anyway.
+
+    The string, by the way, is assumed to start at the current file-pointer
+    position; its length is given by 'length'.  So start off by checking the
+    length of the string:  if zero, we're already done.
+  ---------------------------------------------------------------------------*/
+
+    if (!length)
+        return PK_COOL;
+
+    switch (option) {
+
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+    /*
+     * Special case: See if the comment begins with an autorun command line.
+     * Save that and display (or skip) the remainder.
+     */
+
+    case CHECK_AUTORUN:
+    case CHECK_AUTORUN_Q:
+        comment_bytes_left = length;
+        if (length >= 10)
+        {
+            block_len = readbuf(__G__ (char *)G.outbuf, 10);
+            if (block_len == 0)
+                return PK_EOF;
+            comment_bytes_left -= block_len;
+            G.outbuf[block_len] = '\0';
+            if (!strcmp((char *)G.outbuf, "$AUTORUN$>")) {
+                char *eol;
+                length -= 10;
+                block_len = readbuf(__G__ G.autorun_command,
+                                    MIN(length, sizeof(G.autorun_command)-1));
+                if (block_len == 0)
+                    return PK_EOF;
+                comment_bytes_left -= block_len;
+                G.autorun_command[block_len] = '\0';
+                A_TO_N(G.autorun_command);
+                eol = strchr(G.autorun_command, '\n');
+                if (!eol)
+                    eol = G.autorun_command + strlen(G.autorun_command) - 1;
+                length -= eol + 1 - G.autorun_command;
+                while (eol >= G.autorun_command && isspace(*eol))
+                    *eol-- = '\0';
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+                /* Win9x console always uses OEM character coding, and
+                   WinNT console is set to OEM charset by default, too */
+                INTERN_TO_OEM(G.autorun_command, G.autorun_command);
+#endif /* (WIN32 && !_WIN32_WCE) */
+            }
+        }
+        if (option == CHECK_AUTORUN_Q)  /* don't display the remainder */
+            length = 0;
+        /* seek to beginning of remaining part of comment -- rewind if */
+        /* displaying entire comment, or skip to end if discarding it  */
+        seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+                  (G.inptr - G.inbuf) + comment_bytes_left - length);
+        if (!length)
+            break;
+        /*  FALL THROUGH...  */
+#endif /* SFX && CHEAP_SFX_AUTORUN */
+
+    /*
+     * First normal case:  print string on standard output.  First set loop
+     * variables, then loop through the comment in chunks of OUTBUFSIZ bytes,
+     * converting formats and printing as we go.  The second half of the
+     * loop conditional was added because the file might be truncated, in
+     * which case comment_bytes_left will remain at some non-zero value for
+     * all time.  outbuf and slide are used as scratch buffers because they
+     * are available (we should be either before or in between any file pro-
+     * cessing).
+     */
+
+    case DISPLAY:
+    case DISPL_8:
+        comment_bytes_left = length;
+        block_len = OUTBUFSIZ;       /* for the while statement, first time */
+        while (comment_bytes_left > 0 && block_len > 0) {
+            register uch *p = G.outbuf;
+            register uch *q = G.outbuf;
+
+            if ((block_len = readbuf(__G__ (char *)G.outbuf,
+                   MIN((unsigned)OUTBUFSIZ, comment_bytes_left))) == 0)
+                return PK_EOF;
+            comment_bytes_left -= block_len;
+
+            /* this is why we allocated an extra byte for outbuf:  terminate
+             *  with zero (ASCIIZ) */
+            G.outbuf[block_len] = '\0';
+
+            /* remove all ASCII carriage returns from comment before printing
+             * (since used before A_TO_N(), check for CR instead of '\r')
+             */
+            while (*p) {
+                while (*p == CR)
+                    ++p;
+                *q++ = *p++;
+            }
+            /* could check whether (p - outbuf) == block_len here */
+            *q = '\0';
+
+            if (option == DISPL_8) {
+                /* translate the text coded in the entry's host-dependent
+                   "extended ASCII" charset into the compiler's (system's)
+                   internal text code page */
+                Ext_ASCII_TO_Native((char *)G.outbuf, G.pInfo->hostnum,
+                                    G.pInfo->hostver, G.pInfo->HasUxAtt,
+                                    FALSE);
+#ifdef WINDLL
+                /* translate to ANSI (RTL internal codepage may be OEM) */
+                INTERN_TO_ISO((char *)G.outbuf, (char *)G.outbuf);
+#else /* !WINDLL */
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+                /* Win9x console always uses OEM character coding, and
+                   WinNT console is set to OEM charset by default, too */
+                INTERN_TO_OEM((char *)G.outbuf, (char *)G.outbuf);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+            } else {
+                A_TO_N(G.outbuf);   /* translate string to native */
+            }
+
+#ifdef WINDLL
+            /* ran out of local mem -- had to cheat */
+            win_fprintf((zvoid *)&G, stdout, (extent)(q-G.outbuf),
+                        (char *)G.outbuf);
+            win_fprintf((zvoid *)&G, stdout, 2, (char *)"\n\n");
+#else /* !WINDLL */
+#ifdef NOANSIFILT       /* GRR:  can ANSI be used with EBCDIC? */
+            (*G.message)((zvoid *)&G, G.outbuf, (ulg)(q-G.outbuf), 0);
+#else /* ASCII, filter out ANSI escape sequences and handle ^S (pause) */
+            p = G.outbuf - 1;
+            q = slide;
+            while (*++p) {
+                int pause = FALSE;
+
+                if (*p == 0x1B) {          /* ASCII escape char */
+                    *q++ = '^';
+                    *q++ = '[';
+                } else if (*p == 0x13) {   /* ASCII ^S (pause) */
+                    pause = TRUE;
+                    if (p[1] == LF)        /* ASCII LF */
+                        *q++ = *++p;
+                    else if (p[1] == CR && p[2] == LF) {  /* ASCII CR LF */
+                        *q++ = *++p;
+                        *q++ = *++p;
+                    }
+                } else
+                    *q++ = *p;
+                if ((unsigned)(q-slide) > WSIZE-3 || pause) {   /* flush */
+                    (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+                    q = slide;
+                    if (pause && G.extract_flag) /* don't pause for list/test */
+                        (*G.mpause)((zvoid *)&G, LoadFarString(QuitPrompt), 0);
+                }
+            }
+            (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+#endif /* ?NOANSIFILT */
+#endif /* ?WINDLL */
+        }
+        /* add '\n' if not at start of line */
+        (*G.message)((zvoid *)&G, slide, 0L, 0x40);
+        break;
+
+    /*
+     * Second case:  read string into filename[] array.  The filename should
+     * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
+     * just to be sure.
+     */
+
+    case DS_FN:
+    case DS_FN_L:
+#ifdef UNICODE_SUPPORT
+        /* get the whole filename as need it for Unicode checksum */
+        if (G.fnfull_bufsize <= length) {
+            extent fnbufsiz = FILNAMSIZ;
+
+            if (fnbufsiz <= length)
+                fnbufsiz = length + 1;
+            if (G.filename_full)
+                free(G.filename_full);
+            G.filename_full = malloc(fnbufsiz);
+            if (G.filename_full == NULL)
+                return PK_MEM;
+            G.fnfull_bufsize = fnbufsiz;
+        }
+        if (readbuf(__G__ G.filename_full, length) == 0)
+            return PK_EOF;
+        G.filename_full[length] = '\0';      /* terminate w/zero:  ASCIIZ */
+
+        /* if needed, chop off end so standard filename is a valid length */
+        if (length >= FILNAMSIZ) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(FilenameTooLongTrunc)));
+            error = PK_WARN;
+            length = FILNAMSIZ - 1;
+        }
+        /* no excess size */
+        block_len = 0;
+        strncpy(G.filename, G.filename_full, length);
+        G.filename[length] = '\0';      /* terminate w/zero:  ASCIIZ */
+#else /* !UNICODE_SUPPORT */
+        if (length >= FILNAMSIZ) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(FilenameTooLongTrunc)));
+            error = PK_WARN;
+            /* remember excess length in block_len */
+            block_len = length - (FILNAMSIZ - 1);
+            length = FILNAMSIZ - 1;
+        } else
+            /* no excess size */
+            block_len = 0;
+        if (readbuf(__G__ G.filename, length) == 0)
+            return PK_EOF;
+        G.filename[length] = '\0';      /* terminate w/zero:  ASCIIZ */
+#endif /* ?UNICODE_SUPPORT */
+
+        /* translate the Zip entry filename coded in host-dependent "extended
+           ASCII" into the compiler's (system's) internal text code page */
+        Ext_ASCII_TO_Native(G.filename, G.pInfo->hostnum, G.pInfo->hostver,
+                            G.pInfo->HasUxAtt, (option == DS_FN_L));
+
+        if (G.pInfo->lcflag)      /* replace with lowercase filename */
+            STRLOWER(G.filename, G.filename);
+
+        if (G.pInfo->vollabel && length > 8 && G.filename[8] == '.') {
+            char *p = G.filename+8;
+            while (*p++)
+                p[-1] = *p;  /* disk label, and 8th char is dot:  remove dot */
+        }
+
+        if (!block_len)         /* no overflow, we're done here */
+            break;
+
+        /*
+         * We truncated the filename, so print what's left and then fall
+         * through to the SKIP routine.
+         */
+        Info(slide, 0x401, ((char *)slide, "[ %s ]\n", FnFilter1(G.filename)));
+        length = block_len;     /* SKIP the excess bytes... */
+        /*  FALL THROUGH...  */
+
+    /*
+     * Third case:  skip string, adjusting readbuf's internal variables
+     * as necessary (and possibly skipping to and reading a new block of
+     * data).
+     */
+
+    case SKIP:
+        /* cur_zipfile_bufstart already takes account of extra_bytes, so don't
+         * correct for it twice: */
+        seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+                  (G.inptr-G.inbuf) + length);
+        break;
+
+    /*
+     * Fourth case:  assume we're at the start of an "extra field"; malloc
+     * storage for it and read data into the allocated space.
+     */
+
+    case EXTRA_FIELD:
+        if (G.extra_field != (uch *)NULL)
+            free(G.extra_field);
+        if ((G.extra_field = (uch *)malloc(length)) == (uch *)NULL) {
+            Info(slide, 0x401, ((char *)slide, LoadFarString(ExtraFieldTooLong),
+              length));
+            /* cur_zipfile_bufstart already takes account of extra_bytes,
+             * so don't correct for it twice: */
+            seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+                      (G.inptr-G.inbuf) + length);
+        } else {
+            if ((length2 = readbuf(__G__ (char *)G.extra_field, length)) == 0)
+                return PK_EOF;
+            if(length2 < length) {
+              memset (__G__ (char *)G.extra_field+length2, 0 , length-length2);
+              length = length2;
+            }
+            /* Looks like here is where extra fields are read */
+            if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
+            {
+                Info(slide, 0x401, ((char *)slide,
+                 LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
+                error = PK_WARN;
+            }
+
+#ifdef UNICODE_SUPPORT
+            G.unipath_filename = NULL;
+            if (G.UzO.U_flag < 2) {
+              /* check if GPB11 (General Purpuse Bit 11) is set indicating
+                 the standard path and comment are UTF-8 */
+              if (G.pInfo->GPFIsUTF8) {
+                /* if GPB11 set then filename_full is untruncated UTF-8 */
+                G.unipath_filename = G.filename_full;
+              } else {
+                /* Get the Unicode fields if exist */
+                getUnicodeData(__G__ G.extra_field, length);
+                if (G.unipath_filename && strlen(G.unipath_filename) == 0) {
+                  /* the standard filename field is UTF-8 */
+                  free(G.unipath_filename);
+                  G.unipath_filename = G.filename_full;
+                }
+              }
+              if (G.unipath_filename) {
+# ifdef UTF8_MAYBE_NATIVE
+                if (G.native_is_utf8
+#  ifdef UNICODE_WCHAR
+                    && (!G.unicode_escape_all)
+#  endif
+                   ) {
+                  strncpy(G.filename, G.unipath_filename, FILNAMSIZ - 1);
+                  /* make sure filename is short enough */
+                  if (strlen(G.unipath_filename) >= FILNAMSIZ) {
+                    G.filename[FILNAMSIZ - 1] = '\0';
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(UFilenameTooLongTrunc)));
+                    error = PK_WARN;
+                  }
+                }
+#  ifdef UNICODE_WCHAR
+                else
+#  endif
+# endif /* UTF8_MAYBE_NATIVE */
+# ifdef UNICODE_WCHAR
+                {
+                  char *fn;
+
+                  /* convert UTF-8 to local character set */
+                  fn = utf8_to_local_string(G.unipath_filename,
+                                            G.unicode_escape_all);
+
+                  /* 2022-07-22 SMS, et al.  CVE-2022-0530
+                   * Detect conversion failure, emit message.
+                   * Continue with unconverted name.
+                   */
+                  if (fn == NULL)
+                  {
+                    Info(slide, 0x401, ((char *)slide,
+                     LoadFarString(UFilenameCorrupt)));
+                    error = PK_ERR;
+                  }
+                  else
+                  {
+                    /* make sure filename is short enough */
+                    if (strlen(fn) >= FILNAMSIZ) {
+                      fn[FILNAMSIZ - 1] = '\0';
+                      Info(slide, 0x401, ((char *)slide,
+                        LoadFarString(UFilenameTooLongTrunc)));
+                      error = PK_WARN;
+                    }
+                    /* replace filename with converted UTF-8 */
+                    strcpy(G.filename, fn);
+                    free(fn);
+                  }
+                }
+# endif /* UNICODE_WCHAR */
+                if (G.unipath_filename != G.filename_full)
+                  free(G.unipath_filename);
+                G.unipath_filename = NULL;
+              }
+            }
+#endif /* UNICODE_SUPPORT */
+        }
+        break;
+
+#ifdef AMIGA
+    /*
+     * Fifth case, for the Amiga only:  take the comment that would ordinarily
+     * be skipped over, and turn it into a 79 character string that will be
+     * attached to the file as a "filenote" after it is extracted.
+     */
+
+    case FILENOTE:
+        if ((block_len = readbuf(__G__ tmp_fnote, (unsigned)
+                                 MIN(length, 2 * AMIGA_FILENOTELEN - 1))) == 0)
+            return PK_EOF;
+        if ((length -= block_len) > 0)  /* treat remainder as in case SKIP: */
+            seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes
+                      + (G.inptr - G.inbuf) + length);
+        /* convert multi-line text into single line with no ctl-chars: */
+        tmp_fnote[block_len] = '\0';
+        while ((short int) --block_len >= 0)
+            if ((unsigned) tmp_fnote[block_len] < ' ')
+                if (tmp_fnote[block_len+1] == ' ')     /* no excess */
+                    strcpy(tmp_fnote+block_len, tmp_fnote+block_len+1);
+                else
+                    tmp_fnote[block_len] = ' ';
+        tmp_fnote[AMIGA_FILENOTELEN - 1] = '\0';
+        if (G.filenotes[G.filenote_slot])
+            free(G.filenotes[G.filenote_slot]);     /* should not happen */
+        G.filenotes[G.filenote_slot] = NULL;
+        if (tmp_fnote[0]) {
+            if (!(G.filenotes[G.filenote_slot] = malloc(strlen(tmp_fnote)+1)))
+                return PK_MEM;
+            strcpy(G.filenotes[G.filenote_slot], tmp_fnote);
+        }
+        break;
+#endif /* AMIGA */
+
+    } /* end switch (option) */
+
+    return error;
+
+} /* end function do_string() */
+
+
+
+
+
+/***********************/
+/* Function makeword() */
+/***********************/
+
+ush makeword(b)
+    ZCONST uch *b;
+{
+    /*
+     * Convert Intel style 'short' integer to non-Intel non-16-bit
+     * host format.  This routine also takes care of byte-ordering.
+     */
+    return (ush)((b[1] << 8) | b[0]);
+}
+
+
+
+
+
+/***********************/
+/* Function makelong() */
+/***********************/
+
+ulg makelong(sig)
+    ZCONST uch *sig;
+{
+    /*
+     * Convert intel style 'long' variable to non-Intel non-16-bit
+     * host format.  This routine also takes care of byte-ordering.
+     */
+    return (((ulg)sig[3]) << 24)
+         + (((ulg)sig[2]) << 16)
+         + (ulg)((((unsigned)sig[1]) << 8)
+               + ((unsigned)sig[0]));
+}
+
+
+
+
+
+/************************/
+/* Function makeint64() */
+/************************/
+
+zusz_t makeint64(sig)
+    ZCONST uch *sig;
+{
+#ifdef LARGE_FILE_SUPPORT
+    /*
+     * Convert intel style 'int64' variable to non-Intel non-16-bit
+     * host format.  This routine also takes care of byte-ordering.
+     */
+    return (((zusz_t)sig[7]) << 56)
+        + (((zusz_t)sig[6]) << 48)
+        + (((zusz_t)sig[4]) << 32)
+        + (zusz_t)((((ulg)sig[3]) << 24)
+                 + (((ulg)sig[2]) << 16)
+                 + (((unsigned)sig[1]) << 8)
+                 + (sig[0]));
+
+#else /* !LARGE_FILE_SUPPORT */
+
+    if ((sig[7] | sig[6] | sig[5] | sig[4]) != 0)
+        return (zusz_t)0xffffffffL;
+    else
+        return (zusz_t)((((ulg)sig[3]) << 24)
+                      + (((ulg)sig[2]) << 16)
+                      + (((unsigned)sig[1]) << 8)
+                      + (sig[0]));
+
+#endif /* ?LARGE_FILE_SUPPORT */
+}
+
+
+
+
+
+/*********************/
+/* Function fzofft() */
+/*********************/
+
+/* Format a zoff_t value in a cylindrical buffer set. */
+char *fzofft(__G__ val, pre, post)
+    __GDEF
+    zoff_t val;
+    ZCONST char *pre;
+    ZCONST char *post;
+{
+    /* Storage cylinder. (now in globals.h) */
+    /*static char fzofft_buf[FZOFFT_NUM][FZOFFT_LEN];*/
+    /*static int fzofft_index = 0;*/
+
+    /* Temporary format string storage. */
+    char fmt[16];
+
+    /* Assemble the format string. */
+    fmt[0] = '%';
+    fmt[1] = '\0';             /* Start after initial "%". */
+    if (pre == FZOFFT_HEX_WID)  /* Special hex width. */
+    {
+        strcat(fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+    {
+        strcat(fmt, ".");
+        strcat(fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre != NULL)       /* Caller's prefix (width). */
+    {
+        strcat(fmt, pre);
+    }
+
+    strcat(fmt, FZOFFT_FMT);   /* Long or long-long or whatever. */
+
+    if (post == NULL)
+        strcat(fmt, "d");      /* Default radix = decimal. */
+    else
+        strcat(fmt, post);     /* Caller's radix. */
+
+    /* Advance the cylinder. */
+    G.fzofft_index = (G.fzofft_index + 1) % FZOFFT_NUM;
+
+    /* Write into the current chamber. */
+    sprintf(G.fzofft_buf[G.fzofft_index], fmt, val);
+
+    /* Return a pointer to this chamber. */
+    return G.fzofft_buf[G.fzofft_index];
+}
+
+
+
+
+#if CRYPT
+
+#ifdef NEED_STR2ISO
+/**********************/
+/* Function str2iso() */
+/**********************/
+
+char *str2iso(dst, src)
+    char *dst;                          /* destination buffer */
+    register ZCONST char *src;          /* source string */
+{
+#ifdef INTERN_TO_ISO
+    INTERN_TO_ISO(src, dst);
+#else
+    register uch c;
+    register char *dstp = dst;
+
+    do {
+        c = (uch)foreign(*src++);
+        *dstp++ = (char)ASCII2ISO(c);
+    } while (c != '\0');
+#endif
+
+    return dst;
+}
+#endif /* NEED_STR2ISO */
+
+
+#ifdef NEED_STR2OEM
+/**********************/
+/* Function str2oem() */
+/**********************/
+
+char *str2oem(dst, src)
+    char *dst;                          /* destination buffer */
+    register ZCONST char *src;          /* source string */
+{
+#ifdef INTERN_TO_OEM
+    INTERN_TO_OEM(src, dst);
+#else
+    register uch c;
+    register char *dstp = dst;
+
+    do {
+        c = (uch)foreign(*src++);
+        *dstp++ = (char)ASCII2OEM(c);
+    } while (c != '\0');
+#endif
+
+    return dst;
+}
+#endif /* NEED_STR2OEM */
+
+#endif /* CRYPT */
+
+
+#ifdef ZMEM  /* memset/memcmp/memcpy for systems without either them or */
+             /* bzero/bcmp/bcopy */
+             /* (no known systems as of 960211) */
+
+/*********************/
+/* Function memset() */
+/*********************/
+
+zvoid *memset(buf, init, len)
+    register zvoid *buf;        /* buffer location */
+    register int init;          /* initializer character */
+    register unsigned int len;  /* length of the buffer */
+{
+    zvoid *start;
+
+    start = buf;
+    while (len--)
+        *((char *)buf++) = (char)init;
+    return start;
+}
+
+
+
+/*********************/
+/* Function memcmp() */
+/*********************/
+
+int memcmp(b1, b2, len)
+    register ZCONST zvoid *b1;
+    register ZCONST zvoid *b2;
+    register unsigned int len;
+{
+    register int c;
+
+    if (len > 0) do {
+        if ((c = (int)(*((ZCONST unsigned char *)b1)++) -
+                 (int)(*((ZCONST unsigned char *)b2)++)) != 0)
+           return c;
+    } while (--len > 0)
+    return 0;
+}
+
+
+
+/*********************/
+/* Function memcpy() */
+/*********************/
+
+zvoid *memcpy(dst, src, len)
+    register zvoid *dst;
+    register ZCONST zvoid *src;
+    register unsigned int len;
+{
+    zvoid *start;
+
+    start = dst;
+    while (len-- > 0)
+        *((char *)dst)++ = *((ZCONST char *)src)++;
+    return start;
+}
+
+#endif /* ZMEM */
+
+
+
+
+#ifdef NO_STRNICMP
+
+/************************/
+/* Function zstrnicmp() */
+/************************/
+
+int zstrnicmp(s1, s2, n)
+    register ZCONST char *s1, *s2;
+    register unsigned n;
+{
+    for (; n > 0;  --n, ++s1, ++s2) {
+
+        if (ToLower(*s1) != ToLower(*s2))
+            /* test includes early termination of one string */
+            return ((uch)ToLower(*s1) < (uch)ToLower(*s2))? -1 : 1;
+
+        if (*s1 == '\0')   /* both strings terminate early */
+            return 0;
+    }
+    return 0;
+}
+
+#endif /* NO_STRNICMP */
+
+
+
+
+#ifdef REGULUS  /* returns the inode number on success(!)...argh argh argh */
+#  undef stat
+
+/********************/
+/* Function zstat() */
+/********************/
+
+int zstat(p, s)
+    ZCONST char *p;
+    struct stat *s;
+{
+    return (stat((char *)p,s) >= 0? 0 : (-1));
+}
+
+#endif /* REGULUS */
+
+
+
+
+#ifdef _MBCS
+
+/* DBCS support for Info-ZIP's zip  (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ * This code is public domain!   Date: 1998/12/20
+ */
+
+/************************/
+/* Function plastchar() */
+/************************/
+
+char *plastchar(ptr, len)
+    ZCONST char *ptr;
+    extent len;
+{
+    unsigned clen;
+    ZCONST char *oldptr = ptr;
+    while(*ptr != '\0' && len > 0){
+        oldptr = ptr;
+        clen = CLEN(ptr);
+        ptr += clen;
+        len -= clen;
+    }
+    return (char *)oldptr;
+}
+
+
+#ifdef NEED_UZMBCLEN
+/***********************/
+/* Function uzmbclen() */
+/***********************/
+
+extent uzmbclen(ptr)
+    ZCONST unsigned char *ptr;
+{
+    int mbl;
+
+    mbl = mblen((ZCONST char *)ptr, MB_CUR_MAX);
+    /* For use in code scanning through MBCS strings, we need a strictly
+       positive "MB char bytes count".  For our scanning purpose, it is not
+       not relevant whether the MB character is valid or not. And, the NUL
+       char '\0' has a byte count of 1, but mblen() returns 0. So, we make
+       sure that the uzmbclen() return value is not less than 1.
+     */
+    return (extent)(mbl > 0 ? mbl : 1);
+}
+#endif /* NEED_UZMBCLEN */
+
+
+#ifdef NEED_UZMBSCHR
+/***********************/
+/* Function uzmbschr() */
+/***********************/
+
+unsigned char *uzmbschr(str, c)
+    ZCONST unsigned char *str;
+    unsigned int c;
+{
+    while(*str != '\0'){
+        if (*str == c) {return (unsigned char *)str;}
+        INCSTR(str);
+    }
+    return NULL;
+}
+#endif /* NEED_UZMBSCHR */
+
+
+#ifdef NEED_UZMBSRCHR
+/************************/
+/* Function uzmbsrchr() */
+/************************/
+
+unsigned char *uzmbsrchr(str, c)
+    ZCONST unsigned char *str;
+    unsigned int c;
+{
+    unsigned char *match = NULL;
+    while(*str != '\0'){
+        if (*str == c) {match = (unsigned char *)str;}
+        INCSTR(str);
+    }
+    return match;
+}
+#endif /* NEED_UZMBSRCHR */
+#endif /* _MBCS */
+
+
+
+
+
+#ifdef SMALL_MEM
+
+/*******************************/
+/*  Function fLoadFarString()  */   /* (and friends...) */
+/*******************************/
+
+char *fLoadFarString(__GPRO__ const char Far *sz)
+{
+    (void)zfstrcpy(G.rgchBigBuffer, sz);
+    return G.rgchBigBuffer;
+}
+
+char *fLoadFarStringSmall(__GPRO__ const char Far *sz)
+{
+    (void)zfstrcpy(G.rgchSmallBuffer, sz);
+    return G.rgchSmallBuffer;
+}
+
+char *fLoadFarStringSmall2(__GPRO__ const char Far *sz)
+{
+    (void)zfstrcpy(G.rgchSmallBuffer2, sz);
+    return G.rgchSmallBuffer2;
+}
+
+
+
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+/*************************/
+/*  Function zfstrcpy()  */   /* portable clone of _fstrcpy() */
+/*************************/
+
+char Far * Far zfstrcpy(char Far *s1, const char Far *s2)
+{
+    char Far *p = s1;
+
+    while ((*s1++ = *s2++) != '\0');
+    return p;
+}
+
+#if (!(defined(SFX) || defined(FUNZIP)))
+/*************************/
+/*  Function zfstrcmp()  */   /* portable clone of _fstrcmp() */
+/*************************/
+
+int Far zfstrcmp(const char Far *s1, const char Far *s2)
+{
+    int ret;
+
+    while ((ret = (int)(uch)*s1 - (int)(uch)*s2) == 0
+           && *s2 != '\0') {
+        ++s2; ++s1;
+    }
+    return ret;
+}
+#endif /* !(SFX || FUNZIP) */
+#endif /* !_MSC_VER || (_MSC_VER < 600) */
+
+#endif /* SMALL_MEM */
Index: unzip/create-6.0-slackware-patch/unzip60-new/list.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/list.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/list.c	(revision 5)
@@ -0,0 +1,746 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+
+  list.c
+
+  This file contains the non-ZipInfo-specific listing routines for UnZip.
+
+  Contains:  list_files()
+             get_time_stamp()   [optional feature]
+             ratio()
+             fnprint()
+
+  ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+#  ifdef POCKET_UNZIP
+#    include "wince/intrface.h"
+#  else
+#    include "windll/windll.h"
+#  endif
+#endif
+
+
+#ifdef TIMESTAMP
+   static int  fn_is_dir   OF((__GPRO));
+#endif
+
+#ifndef WINDLL
+   static ZCONST char Far CompFactorStr[] = "%c%d%%";
+   static ZCONST char Far CompFactor100[] = "100%%";
+
+#ifdef OS2_EAS
+   static ZCONST char Far HeadersS[]  =
+     "  Length     EAs   ACLs     Date    Time    Name";
+   static ZCONST char Far HeadersS1[] =
+     "---------    ---   ----  ---------- -----   ----";
+#else
+   static ZCONST char Far HeadersS[]  =
+     "  Length      Date    Time    Name";
+   static ZCONST char Far HeadersS1[] =
+     "---------  ---------- -----   ----";
+#endif
+
+   static ZCONST char Far HeadersL[]  =
+     " Length   Method    Size  Cmpr    Date    Time   CRC-32   Name";
+   static ZCONST char Far HeadersL1[] =
+     "--------  ------  ------- ---- ---------- ----- --------  ----";
+   static ZCONST char Far *Headers[][2] =
+     { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
+
+   static ZCONST char Far CaseConversion[] =
+     "%s (\"^\" ==> case\n%s   conversion)\n";
+   static ZCONST char Far LongHdrStats[] =
+     "%s  %-7s%s %4s %02u%c%02u%c%02u %02u:%02u %08lx %c";
+   static ZCONST char Far LongFileTrailer[] =
+     "--------          -------  ---                       \
+     -------\n%s         %s %4s                            %lu file%s\n";
+#ifdef OS2_EAS
+   static ZCONST char Far ShortHdrStats[] =
+     "%s %6lu %6lu  %02u%c%02u%c%02u %02u:%02u  %c";
+   static ZCONST char Far ShortFileTrailer[] =
+     "---------  -----  -----                \
+     -------\n%s %6lu %6lu                     %lu file%s\n";
+   static ZCONST char Far OS2ExtAttrTrailer[] =
+     "%lu file%s %lu bytes of OS/2 extended attributes attached.\n";
+   static ZCONST char Far OS2ACLTrailer[] =
+     "%lu file%s %lu bytes of access control lists attached.\n";
+#else
+   static ZCONST char Far ShortHdrStats[] =
+     "%s  %02u%c%02u%c%02u %02u:%02u  %c";
+   static ZCONST char Far ShortFileTrailer[] =
+     "---------                     -------\n%s\
+                     %lu file%s\n";
+#endif /* ?OS2_EAS */
+#endif /* !WINDLL */
+
+
+
+
+
+/*************************/
+/* Function list_files() */
+/*************************/
+
+int list_files(__G)    /* return PK-type error code */
+    __GDEF
+{
+    int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
+#ifndef WINDLL
+    char sgn, cfactorstr[1+10+1+1];	/* <sgn><int>%NUL */
+    int longhdr=(uO.vflag>1);
+#endif
+    int date_format;
+    char dt_sepchar;
+    ulg members=0L;
+    zusz_t j;
+    unsigned methnum;
+#ifdef USE_EF_UT_TIME
+    iztimes z_utime;
+    struct tm *t;
+#endif
+    unsigned yr, mo, dy, hh, mm;
+    zusz_t csiz, tot_csize=0L, tot_ucsize=0L;
+#ifdef OS2_EAS
+    ulg ea_size, tot_easize=0L, tot_eafiles=0L;
+    ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
+#endif
+    min_info info;
+    char methbuf[8];
+    static ZCONST char dtype[]="NXFS";  /* see zi_short() */
+    static ZCONST char Far method[NUM_METHODS+1][8] =
+        {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
+         "Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "BZip2",
+         "LZMA", "Terse", "IBMLZ77", "WavPack", "PPMd", "Unk:###"};
+
+
+
+/*---------------------------------------------------------------------------
+    Unlike extract_or_test_files(), this routine confines itself to the cen-
+    tral directory.  Thus its structure is somewhat simpler, since we can do
+    just a single loop through the entire directory, listing files as we go.
+
+    So to start off, print the heading line and then begin main loop through
+    the central directory.  The results will look vaguely like the following:
+
+ Length   Method    Size  Ratio   Date   Time   CRC-32    Name ("^" ==> case
+--------  ------  ------- -----   ----   ----   ------    ----   conversion)
+   44004  Implode   13041  71%  11-02-89 19:34  8b4207f7  Makefile.UNIX
+    3438  Shrunk     2209  36%  09-15-90 14:07  a2394fd8 ^dos-file.ext
+   16717  Defl:X     5252  69%  11-03-97 06:40  1ce0f189  WHERE
+--------          -------  ---                            -------
+   64159            20502  68%                            3 files
+  ---------------------------------------------------------------------------*/
+
+    G.pInfo = &info;
+    date_format = DATE_FORMAT;
+    dt_sepchar = DATE_SEPCHAR;
+
+#ifndef WINDLL
+    if (uO.qflag < 2) {
+        if (uO.L_flag)
+            Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
+              LoadFarStringSmall(Headers[longhdr][0]),
+              LoadFarStringSmall2(Headers[longhdr][1])));
+        else
+            Info(slide, 0, ((char *)slide, "%s\n%s\n",
+               LoadFarString(Headers[longhdr][0]),
+               LoadFarStringSmall(Headers[longhdr][1])));
+    }
+#endif /* !WINDLL */
+
+    for (j = 1L;;j++) {
+
+        if (readbuf(__G__ G.sig, 4) == 0)
+            return PK_EOF;
+        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
+             *    number of entries as stored in the end_central record?
+             */
+            if (((j - 1) &
+                 (ulg)(G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+                == (ulg)G.ecrec.total_entries_central_dir)
+            {
+                /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
+                 * number of directory entries -> probably, the regular
+                 * end of the central directory has been reached
+                 */
+                break;
+            } else {
+                Info(slide, 0x401,
+                     ((char *)slide, LoadFarString(CentSigMsg), j));
+                Info(slide, 0x401,
+                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                return PK_BADERR;   /* sig not found */
+            }
+        }
+        /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
+        if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
+            return error;       /* only PK_EOF defined */
+
+        /*
+         * We could DISPLAY the filename instead of storing (and possibly trun-
+         * cating, in the case of a very long name) and printing it, but that
+         * has the disadvantage of not allowing case conversion--and it's nice
+         * to be able to see in the listing precisely how you have to type each
+         * filename in order for unzip to consider it a match.  Speaking of
+         * which, if member names were specified on the command line, check in
+         * with match() to see if the current file is one of them, and make a
+         * note of it if it is.
+         */
+
+        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+             PK_COOL)   /*  ^--(uses pInfo->lcflag) */
+        {
+            error_in_archive = error;
+            if (error > PK_WARN)   /* fatal:  can't continue */
+                return error;
+        }
+        if (G.extra_field != (uch *)NULL) {
+            free(G.extra_field);
+            G.extra_field = (uch *)NULL;
+        }
+        if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
+            != 0)
+        {
+            error_in_archive = error;
+            if (error > PK_WARN)      /* fatal */
+                return error;
+        }
+        if (!G.process_all_files) {   /* check if specified on command line */
+            unsigned i;
+
+            if (G.filespecs == 0)
+                do_this_file = TRUE;
+            else {  /* check if this entry matches an `include' argument */
+                do_this_file = FALSE;
+                for (i = 0; i < G.filespecs; i++)
+                    if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+                        do_this_file = TRUE;
+                        break;       /* found match, so stop looping */
+                    }
+            }
+            if (do_this_file) {  /* check if this is an excluded file */
+                for (i = 0; i < G.xfilespecs; i++)
+                    if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+                        do_this_file = FALSE;  /* ^-- ignore case in match */
+                        break;
+                    }
+            }
+        }
+        /*
+         * If current file was specified on command line, or if no names were
+         * specified, do the listing for this file.  Otherwise, get rid of the
+         * file comment and go back for the next file.
+         */
+
+        if (G.process_all_files || do_this_file) {
+
+#ifdef OS2DLL
+            /* this is used by UzpFileTree() to allow easy processing of lists
+             * of zip directory contents */
+            if (G.processExternally) {
+                if ((G.processExternally)(G.filename, &G.crec))
+                    break;
+                ++members;
+            } else {
+#endif
+#ifdef OS2_EAS
+            {
+                uch *ef_ptr = G.extra_field;
+                int ef_size, ef_len = G.crec.extra_field_length;
+                ea_size = acl_size = 0;
+
+                while (ef_len >= EB_HEADSIZE) {
+                    ef_size = makeword(&ef_ptr[EB_LEN]);
+                    switch (makeword(&ef_ptr[EB_ID])) {
+                        case EF_OS2:
+                            ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
+                            break;
+                        case EF_ACL:
+                            acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
+                            break;
+                    }
+                    ef_ptr += (ef_size + EB_HEADSIZE);
+                    ef_len -= (ef_size + EB_HEADSIZE);
+                }
+            }
+#endif
+#ifdef USE_EF_UT_TIME
+            if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+                G.tz_is_valid &&
+#endif
+                (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+                                  G.crec.last_mod_dos_datetime, &z_utime, NULL)
+                 & EB_UT_FL_MTIME))
+            {
+                TIMET_TO_NATIVE(z_utime.mtime)   /* NOP unless MSC 7.0, Mac */
+                t = localtime(&(z_utime.mtime));
+            } else
+                t = (struct tm *)NULL;
+            if (t != (struct tm *)NULL) {
+                mo = (unsigned)(t->tm_mon + 1);
+                dy = (unsigned)(t->tm_mday);
+                yr = (unsigned)(t->tm_year + 1900);
+                hh = (unsigned)(t->tm_hour);
+                mm = (unsigned)(t->tm_min);
+            } else
+#endif /* USE_EF_UT_TIME */
+            {
+                yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
+                       + 1980));
+                mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
+                dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
+                hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
+                mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
+            }
+            /* permute date so it displays according to nat'l convention
+             * ('methnum' is not yet set, it is used as temporary buffer) */
+            switch (date_format) {
+                case DF_YMD:
+                    methnum = mo;
+                    mo = yr; yr = dy; dy = methnum;
+                    break;
+                case DF_DMY:
+                    methnum = mo;
+                    mo = dy; dy = methnum;
+            }
+
+            csiz = G.crec.csize;
+            if (G.crec.general_purpose_bit_flag & 1)
+                csiz -= 12;   /* if encrypted, don't count encryption header */
+            if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
+#ifndef WINDLL
+                sgn = '-';
+#endif
+                cfactor = (-cfactor + 5) / 10;
+            } else {
+#ifndef WINDLL
+                sgn = ' ';
+#endif
+                cfactor = (cfactor + 5) / 10;
+            }
+
+            methnum = find_compr_idx(G.crec.compression_method);
+            zfstrcpy(methbuf, method[methnum]);
+            if (G.crec.compression_method == DEFLATED ||
+                G.crec.compression_method == ENHDEFLATED) {
+                methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
+            } else if (methnum >= NUM_METHODS) {
+                /* 2013-02-26 SMS.
+                 * http://sourceforge.net/tracker/?func=detail
+                 *  &aid=2861648&group_id=118012&atid=679786
+                 * Unexpectedly large compression methods overflow
+                 * &methbuf[].  Use the old, three-digit decimal format
+                 * for values which fit.  Otherwise, sacrifice the
+                 * colon, and use four-digit hexadecimal.
+                 */
+                if (G.crec.compression_method <= 999) {
+                    sprintf( &methbuf[ 4], "%03u", G.crec.compression_method);
+                } else {
+                    sprintf( &methbuf[ 3], "%04X", G.crec.compression_method);
+                }
+            }
+
+#if 0       /* GRR/Euro:  add this? */
+#if defined(DOS_FLX_NLM_OS2_W32) || defined(THEOS) || defined(UNIX)
+            for (p = G.filename;  *p;  ++p)
+                if (!isprint(*p))
+                    *p = '?';  /* change non-printable chars to '?' */
+#endif /* DOS_FLX_NLM_OS2_W32 || THEOS || UNIX */
+#endif /* 0 */
+
+#ifdef WINDLL
+            /* send data to application for formatting and printing */
+            if (G.lpUserFunctions->SendApplicationMessage != NULL)
+                (*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize,
+                  csiz, (unsigned)cfactor, mo, dy, yr, hh, mm,
+                  (char)(G.pInfo->lcflag ? '^' : ' '),
+                  (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
+                  (LPCSTR)methbuf, G.crec.crc32,
+                  (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
+            else if (G.lpUserFunctions->SendApplicationMessage_i32 != NULL) {
+                unsigned long ucsize_lo, csiz_lo;
+                unsigned long ucsize_hi=0L, csiz_hi=0L;
+                ucsize_lo = (unsigned long)(G.crec.ucsize);
+                csiz_lo = (unsigned long)(csiz);
+#ifdef ZIP64_SUPPORT
+                ucsize_hi = (unsigned long)(G.crec.ucsize >> 32);
+                csiz_hi = (unsigned long)(csiz >> 32);
+#endif /* ZIP64_SUPPORT */
+                (*G.lpUserFunctions->SendApplicationMessage_i32)(ucsize_lo,
+                    ucsize_hi, csiz_lo, csiz_hi, (unsigned)cfactor,
+                    mo, dy, yr, hh, mm,
+                    (char)(G.pInfo->lcflag ? '^' : ' '),
+                    (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
+                    (LPCSTR)methbuf, G.crec.crc32,
+                    (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
+            }
+#else /* !WINDLL */
+            if (cfactor == 100)
+                snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+            else
+                snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+            if (longhdr)
+                Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
+                  FmZofft(G.crec.ucsize, "8", "u"), methbuf,
+                  FmZofft(csiz, "8", "u"), cfactorstr,
+                  mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+                  G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
+            else
+#ifdef OS2_EAS
+                Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+                  FmZofft(G.crec.ucsize, "9", "u"), ea_size, acl_size,
+                  mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+                  (G.pInfo->lcflag? '^':' ')));
+#else
+                Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+                  FmZofft(G.crec.ucsize, "9", "u"),
+                  mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+                  (G.pInfo->lcflag? '^':' ')));
+#endif
+            fnprint(__G);
+#endif /* ?WINDLL */
+
+            if ((error = do_string(__G__ G.crec.file_comment_length,
+                                   QCOND? DISPL_8 : SKIP)) != 0)
+            {
+                error_in_archive = error;  /* might be just warning */
+                if (error > PK_WARN)       /* fatal */
+                    return error;
+            }
+            tot_ucsize += G.crec.ucsize;
+            tot_csize += csiz;
+            ++members;
+#ifdef OS2_EAS
+            if (ea_size) {
+                tot_easize += ea_size;
+                ++tot_eafiles;
+            }
+            if (acl_size) {
+                tot_aclsize += acl_size;
+                ++tot_aclfiles;
+            }
+#endif
+#ifdef OS2DLL
+            } /* end of "if (G.processExternally) {...} else {..." */
+#endif
+        } else {        /* not listing this file */
+            SKIP_(G.crec.file_comment_length)
+        }
+    } /* end for-loop (j: files in central directory) */
+
+/*---------------------------------------------------------------------------
+    Print footer line and totals (compressed size, uncompressed size, number
+    of members in zipfile).
+  ---------------------------------------------------------------------------*/
+
+    if (uO.qflag < 2
+#ifdef OS2DLL
+                     && !G.processExternally
+#endif
+                                            ) {
+        if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
+#ifndef WINDLL
+            sgn = '-';
+#endif
+            cfactor = (-cfactor + 5) / 10;
+        } else {
+#ifndef WINDLL
+            sgn = ' ';
+#endif
+            cfactor = (cfactor + 5) / 10;
+        }
+#ifdef WINDLL
+        /* pass the totals back to the calling application */
+        G.lpUserFunctions->TotalSizeComp = tot_csize;
+        G.lpUserFunctions->TotalSize = tot_ucsize;
+        G.lpUserFunctions->CompFactor = (ulg)cfactor;
+        G.lpUserFunctions->NumMembers = members;
+
+#else /* !WINDLL */
+        if (cfactor == 100)
+            snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+        else
+            snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+        if (longhdr) {
+            Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
+              FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"),
+              cfactorstr, members, members==1? "":"s"));
+#ifdef OS2_EAS
+            if (tot_easize || tot_aclsize)
+                Info(slide, 0, ((char *)slide, "\n"));
+            if (tot_eafiles && tot_easize)
+                Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
+                  tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
+                  tot_easize));
+            if (tot_aclfiles && tot_aclsize)
+                Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
+                  tot_aclfiles,
+                  tot_aclfiles == 1 ? " has" : "s have a total of",
+                  tot_aclsize));
+#endif /* OS2_EAS */
+        } else
+#ifdef OS2_EAS
+            Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
+              FmZofft(tot_ucsize, "9", "u"), tot_easize, tot_aclsize,
+              members, members == 1 ? "" : "s"));
+#else
+            Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
+              FmZofft(tot_ucsize, "9", "u"),
+              members, members == 1 ? "" : "s"));
+#endif /* OS2_EAS */
+#endif /* ?WINDLL */
+    }
+
+    /* Skip the following checks in case of a premature listing break. */
+    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 */
+            Info(slide, 0x401, 
+                 ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+            error_in_archive = PK_WARN;   /* didn't find sig */
+        }
+
+        /* 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;
+
+} /* end function list_files() */
+
+
+
+
+
+#ifdef TIMESTAMP
+
+/************************/
+/* Function fn_is_dir() */
+/************************/
+
+static int fn_is_dir(__G)    /* returns TRUE if G.filename is directory */
+    __GDEF
+{
+    extent fn_len = strlen(G.filename);
+    register char   endc;
+
+    return  fn_len > 0 &&
+            ((endc = lastchar(G.filename, fn_len)) == '/' ||
+             (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
+              endc == '\\'));
+}
+
+
+
+
+
+/*****************************/
+/* Function get_time_stamp() */
+/*****************************/
+
+int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
+    __GDEF
+    time_t *last_modtime;
+    ulg *nmember;
+{
+    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+    ulg j;
+#ifdef USE_EF_UT_TIME
+    iztimes z_utime;
+#endif
+    min_info info;
+
+
+/*---------------------------------------------------------------------------
+    Unlike extract_or_test_files() but like list_files(), this function works
+    on information in the central directory alone.  Thus we have a single,
+    large loop through the entire directory, searching for the latest time
+    stamp.
+  ---------------------------------------------------------------------------*/
+
+    *last_modtime = 0L;         /* assuming no zipfile data older than 1970 */
+    *nmember = 0L;
+    G.pInfo = &info;
+
+    for (j = 1L;; j++) {
+
+        if (readbuf(__G__ G.sig, 4) == 0)
+            return PK_EOF;
+        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) {
+                /* "j modulus 64k" matches the reported 16-bit-unsigned
+                 * number of directory entries -> probably, the regular
+                 * end of the central directory has been reached
+                 */
+                break;
+            } else {
+                Info(slide, 0x401,
+                     ((char *)slide, LoadFarString(CentSigMsg), j));
+                Info(slide, 0x401,
+                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                return PK_BADERR;   /* sig not found */
+            }
+        }
+        /* process_cdir_file_hdr() sets pInfo->lcflag: */
+        if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
+            return error;       /* only PK_EOF defined */
+        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
+        {        /*  ^-- (uses pInfo->lcflag) */
+            error_in_archive = error;
+            if (error > PK_WARN)   /* fatal:  can't continue */
+                return error;
+        }
+        if (G.extra_field != (uch *)NULL) {
+            free(G.extra_field);
+            G.extra_field = (uch *)NULL;
+        }
+        if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
+            != 0)
+        {
+            error_in_archive = error;
+            if (error > PK_WARN)      /* fatal */
+                return error;
+        }
+        if (!G.process_all_files) {   /* check if specified on command line */
+            unsigned i;
+
+            if (G.filespecs == 0)
+                do_this_file = TRUE;
+            else {  /* check if this entry matches an `include' argument */
+                do_this_file = FALSE;
+                for (i = 0; i < G.filespecs; i++)
+                    if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+                        do_this_file = TRUE;
+                        break;       /* found match, so stop looping */
+                    }
+            }
+            if (do_this_file) {  /* check if this is an excluded file */
+                for (i = 0; i < G.xfilespecs; i++)
+                    if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+                        do_this_file = FALSE;  /* ^-- ignore case in match */
+                        break;
+                    }
+            }
+        }
+
+        /* If current file was specified on command line, or if no names were
+         * specified, check the time for this file.  Either way, get rid of the
+         * file comment and go back for the next file.
+         * Directory entries are always ignored, to stay compatible with both
+         * Zip and PKZIP.
+         */
+        if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
+#ifdef USE_EF_UT_TIME
+            if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+                G.tz_is_valid &&
+#endif
+                (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+                                  G.crec.last_mod_dos_datetime, &z_utime, NULL)
+                 & EB_UT_FL_MTIME))
+            {
+                if (*last_modtime < z_utime.mtime)
+                    *last_modtime = z_utime.mtime;
+            } else
+#endif /* USE_EF_UT_TIME */
+            {
+                time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
+
+                if (*last_modtime < modtime)
+                    *last_modtime = modtime;
+            }
+            ++*nmember;
+        }
+        SKIP_(G.crec.file_comment_length)
+
+    } /* end for-loop (j: files in central directory) */
+
+/*---------------------------------------------------------------------------
+    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 */
+        Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+        error_in_archive = PK_WARN;
+    }
+    if (*nmember == 0L && error_in_archive <= PK_WARN)
+        error_in_archive = PK_FIND;
+
+    return error_in_archive;
+
+} /* end function get_time_stamp() */
+
+#endif /* TIMESTAMP */
+
+
+
+
+
+/********************/
+/* Function ratio() */    /* also used by ZipInfo routines */
+/********************/
+
+int ratio(uc, c)
+    zusz_t uc, c;
+{
+    zusz_t denom;
+
+    if (uc == 0)
+        return 0;
+    if (uc > 2000000L) {    /* risk signed overflow if multiply numerator */
+        denom = uc / 1000L;
+        return ((uc >= c) ?
+            (int) ((uc-c + (denom>>1)) / denom) :
+          -((int) ((c-uc + (denom>>1)) / denom)));
+    } else {             /* ^^^^^^^^ rounding */
+        denom = uc;
+        return ((uc >= c) ?
+            (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
+          -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
+    }                            /* ^^^^^^^^ rounding */
+}
+
+
+
+
+
+/************************/
+/*  Function fnprint()  */    /* also used by ZipInfo routines */
+/************************/
+
+void fnprint(__G)    /* print filename (after filtering) and newline */
+    __GDEF
+{
+    char *name = fnfilter(G.filename, slide, (extent)(WSIZE>>1));
+
+    (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
+    (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+} /* end function fnprint() */
Index: unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1	(revision 5)
@@ -0,0 +1,1040 @@
+.\"  Copyright (c) 1990-2009 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
+.\"
+.\" unzip.1 by Greg Roelofs, Fulvio Marino, Jim van Zandt and others.
+.\"
+.\" =========================================================================
+.\" define .EX/.EE (for multiline user-command examples; normal Courier font)
+.de EX
+.in +4n
+.nf
+.ft CW
+..
+.de EE
+.ft R
+.fi
+.in -4n
+..
+.\" =========================================================================
+.TH UNZIP 1L "20 April 2009 (v6.0)" "Info-ZIP"
+.SH NAME
+unzip \- list, test and extract compressed files in a ZIP archive
+.PD
+.SH SYNOPSIS
+\fBunzip\fP [\fB\-Z\fP] [\fB\-cflptTuvz\fP[\fBabjnoqsCDKLMUVWX$/:^\fP]]
+\fIfile\fP[\fI.zip\fP] [\fIfile(s)\fP\ .\|.\|.]
+[\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.] [\fB\-d\fP\ \fIexdir\fP]
+.PD
+.\" =========================================================================
+.SH DESCRIPTION
+\fIunzip\fP will list, test, or extract files from a ZIP archive, commonly
+found on MS-DOS 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, \fIzip\fP(1L), creates ZIP
+archives; both programs are compatible with archives created by PKWARE's
+\fIPKZIP\fP and \fIPKUNZIP\fP for MS-DOS, but in many cases the program
+options or default behaviors differ.
+.PD
+.\" =========================================================================
+.SH ARGUMENTS
+.TP
+.IR file [ .zip ]
+Path of the ZIP archive(s).  If the file specification is a wildcard,
+each matching file is processed in an order determined by the operating
+system (or file system).  Only the filename can be a wildcard; the path
+itself cannot.  Wildcard expressions are similar to those supported in
+commonly used Unix shells (\fIsh\fP, \fIksh\fP, \fIcsh\fP) and may contain:
+.RS
+.IP *
+matches a sequence of 0 or more characters
+.IP ?
+matches exactly 1 character
+.IP [.\|.\|.]
+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 (`!' or `^') follows the left bracket, then the range of
+characters within the brackets is complemented (that is, anything \fIexcept\fP
+the characters inside the brackets is considered a match).  To specify a
+verbatim left bracket, the three-character sequence ``[[]'' has to be used.
+.RE
+.IP
+(Be sure to quote any character that might otherwise be interpreted or
+modified by the operating system, particularly under Unix and VMS.)  If no
+matches are found, the specification is assumed to be a literal filename;
+and if that also fails, the suffix \fC.zip\fR is appended.  Note that
+self-extracting ZIP files are supported, as with any other ZIP archive;
+just specify the \fC.exe\fR suffix (if any) explicitly.
+.IP [\fIfile(s)\fP]
+An optional list of archive members to be processed, separated by spaces.
+(VMS versions compiled with VMSCLI defined must delimit files with commas
+instead.  See \fB\-v\fP in \fBOPTIONS\fP below.)
+Regular expressions (wildcards) may be used to match multiple members; see
+above.  Again, be sure to quote expressions that would otherwise be expanded
+or modified by the operating system.
+.IP [\fB\-x\fP\ \fIxfile(s)\fP]
+An optional list of archive members to be excluded from processing.
+Since wildcard characters normally match (`/') directory separators
+(for exceptions see the option \fB\-W\fP), this option may be used
+to exclude any files that are in subdirectories.  For
+example, ``\fCunzip foo *.[ch] -x */*\fR'' would extract all C source files
+in the main directory, but none in any subdirectories.  Without the \fB\-x\fP
+option, all C source files in all directories within the zipfile would be
+extracted.
+.IP [\fB\-d\fP\ \fIexdir\fP]
+An optional directory to which to extract files.  By default, all files
+and subdirectories are recreated in the current directory; the \fB\-d\fP
+option allows extraction in an arbitrary directory (always assuming one
+has permission to write to the directory).  This option need not appear
+at the end of the command line; it is also accepted before the zipfile
+specification (with the normal options), immediately after the zipfile
+specification, or between the \fIfile(s)\fP and the \fB\-x\fP option.
+The option and directory may be concatenated without any white space
+between them, but note that this may cause normal shell behavior to be
+suppressed.  In particular, ``\fC\-d\ ~\fR'' (tilde) is expanded by Unix
+C shells into the name of the user's home directory, but ``\fC\-d~\fR''
+is treated as a literal subdirectory ``\fB~\fP'' of the current directory.
+.\" =========================================================================
+.SH OPTIONS
+Note that, in order to support obsolescent hardware, \fIunzip\fP's usage
+screen is limited to 22 or 23 lines and should therefore be considered
+only a reminder of the basic \fIunzip\fP syntax rather than an exhaustive
+list of all possible flags.  The exhaustive list follows:
+.TP
+.B \-Z
+\fIzipinfo\fP(1L) mode.  If the first option on the command line is \fB\-Z\fP,
+the remaining options are taken to be \fIzipinfo\fP(1L) options.  See the
+appropriate manual page for a description of these options.
+.TP
+.B \-A
+[OS/2, Unix DLL] print extended help for the DLL's programming interface (API).
+.TP
+.B \-c
+extract files to stdout/screen (``CRT'').  This option is similar to the
+\fB\-p\fP option except that the name of each file is printed as it is
+extracted, the \fB\-a\fP option is allowed, and ASCII-EBCDIC conversion
+is automatically performed if appropriate.  This option is not listed in
+the \fIunzip\fP usage screen.
+.TP
+.B \-f
+freshen existing files, i.e., 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 under many operating systems,
+the TZ (timezone) environment variable must be set correctly in order for
+\fB\-f\fP and \fB\-u\fP to work properly (under 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 in GMT/UTC) and the necessity to compare
+the two.  A typical TZ value is ``PST8PDT'' (US Pacific time with automatic
+adjustment for Daylight Savings Time or ``summer time'').
+.TP
+.B \-l
+list archive files (short format).  The names, uncompressed file sizes and
+modification dates and times of the specified files are printed, along
+with totals for all files specified.  If UnZip was compiled with OS2_EAS
+defined, the \fB\-l\fP option also lists columns for the sizes of stored
+OS/2 extended attributes (EAs) and OS/2 access control lists (ACLs).  In
+addition, the zipfile comment and individual file 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 \fB\-L\fP option was given,
+the filename is converted to lowercase and is prefixed with a caret (^).
+.TP
+.B \-p
+extract files to pipe (stdout).  Nothing but the file data is sent to
+stdout, and the files are always extracted in binary format, just as they
+are stored (no conversions).
+.TP
+.B \-t
+test archive files.  This option extracts each specified file in memory
+and compares the CRC (cyclic redundancy check, an enhanced checksum) of
+the expanded file with the original file's stored CRC value.
+.TP
+.B \-T
+[most OSes] 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 zipfiles (e.g., ``\fCunzip \-T \e*.zip\fR'') and
+is much faster.
+.TP
+.B \-u
+update existing files and create new ones if needed.  This option performs
+the same function as the \fB\-f\fP option, extracting (with query) files
+that are newer than those with the same name on disk, and in addition it
+extracts those files that do not already exist on disk.  See \fB\-f\fP
+above for information on setting the timezone properly.
+.TP
+.B \-v
+list archive files (verbose format) or show diagnostic version info.
+This option has evolved and now behaves as both an option and a modifier.
+As an option it has two purposes:  when a zipfile is specified with no
+other options, \fB\-v\fP lists archive files verbosely, adding to the
+basic \fB\-l\fP info the compression method, compressed size,
+compression ratio and 32-bit CRC.  In contrast to most of the competing
+utilities, \fIunzip\fP removes the 12 additional header bytes of
+encrypted entries from the compressed size numbers.  Therefore,
+compressed size and compression ratio figures are independent of the entry's
+encryption status and show the correct compression performance.  (The complete
+size of the encrypted compressed data stream for zipfile entries is reported
+by the more verbose \fIzipinfo\fP(1L) reports, see the separate manual.)
+When no zipfile is specified (that is, the complete command is simply
+``\fCunzip \-v\fR''), a diagnostic screen is printed.  In addition to
+the normal header with release date and version, \fIunzip\fP lists the
+home Info-ZIP ftp site and where to find a list of other ftp and non-ftp
+sites; the target operating system for which it was compiled, as well
+as (possibly) the hardware on which it was compiled, the compiler and
+version used, and the compilation date; any special compilation options
+that might affect the program's operation (see also \fBDECRYPTION\fP below);
+and any options stored in environment variables that might do the same
+(see \fBENVIRONMENT OPTIONS\fP below).  As a modifier it works in
+conjunction with other options (e.g., \fB\-t\fP) to produce more
+verbose or debugging output; this is not yet fully implemented
+but will be in future releases.
+.TP
+.B \-z
+display only the archive comment.
+.PD
+.\" =========================================================================
+.SH MODIFIERS
+.TP
+.B \-a
+convert text files.  Ordinarily all files are extracted exactly as they
+are stored (as ``binary'' files).  The \fB\-a\fP option causes files identified
+by \fIzip\fP as text files (those with the `t' label in \fIzipinfo\fP
+listings, rather than `b') to be automatically extracted as such, converting
+line endings, end-of-file characters and the character set itself as necessary.
+(For example, Unix files use line feeds (LFs) for end-of-line (EOL) and
+have no end-of-file (EOF) marker; Macintoshes use carriage returns (CRs)
+for EOLs; and most PC operating systems use CR+LF for EOLs and control-Z for
+EOF.  In addition, IBM mainframes and the Michigan Terminal System use EBCDIC
+rather than the more common ASCII character set, and NT supports Unicode.)
+Note that \fIzip\fP's identification of text files is by no means perfect; some
+``text'' files may actually be binary and vice versa.  \fIunzip\fP therefore
+prints ``\fC[text]\fR'' or ``\fC[binary]\fR'' as a visual check for each file
+it extracts when using the \fB\-a\fP option.  The \fB\-aa\fP option forces
+all files to be extracted as text, regardless of the supposed file type.
+On VMS, see also \fB\-S\fP.
+.TP
+.B \-b
+[general] treat all files as binary (no text conversions).  This is a shortcut
+for \fB\-\-\-a\fP.
+.TP
+.B \-b
+[Tandem] force the creation files with filecode type 180 ('C') when
+extracting Zip entries marked as "text". (On Tandem, \fB\-a\fP is enabled
+by default, see above).
+.TP
+.B \-b
+[VMS] auto-convert binary files (see \fB\-a\fP above) to fixed-length,
+512-byte record format.  Doubling the option (\fB\-bb\fP) forces all files
+to be extracted in this format. When extracting to standard output
+(\fB\-c\fP or \fB\-p\fP option in effect), the default conversion of text
+record delimiters is disabled for binary (\fB\-b\fP) resp. all (\fB\-bb\fP)
+files.
+.TP
+.B \-B
+[when compiled with UNIXBACKUP defined] save a backup copy of each
+overwritten file. The backup file is 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 applied whenever another file with the original name
+plus tilde already exists.  When used together with the "overwrite all"
+option \fB\-o\fP, numbered backup files are never created. In this case,
+all backup files are named as the original file with an appended tilde,
+existing backup files are deleted without notice.
+This feature works similarly to the default behavior of \fIemacs\fP(1)
+in many locations.
+.IP
+Example: the old copy of ``\fCfoo\fR'' is renamed to ``\fCfoo~\fR''.
+.IP
+Warning: Users should be aware that the \fB-B\fP option does not prevent
+loss of existing data under all circumstances.  For example, when
+\fIunzip\fP is run in overwrite-all mode, an existing ``\fCfoo~\fR'' file
+is deleted before \fIunzip\fP attempts to rename ``\fCfoo\fR'' to
+``\fCfoo~\fR''.  When this rename attempt fails (because of a file locks,
+insufficient privileges, or ...), the extraction of ``\fCfoo~\fR'' 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.
+.TP
+.B \-C
+use case-insensitive matching for the selection of archive entries
+from the command-line list of extract selection patterns.
+\fIunzip\fP's philosophy is ``you get what you ask for'' (this is
+also responsible for the \fB\-L\fP/\fB\-U\fP change; see the relevant
+options below).  Because some file systems are fully case-sensitive
+(notably those under the Unix operating system) and because
+both ZIP archives and \fIunzip\fP itself are portable across platforms,
+\fIunzip\fP's default behavior is to match both wildcard and literal
+filenames case-sensitively.  That is, specifying ``\fCmakefile\fR''
+on the command line will \fIonly\fP match ``makefile'' in the archive,
+not ``Makefile'' or ``MAKEFILE'' (and similarly for wildcard specifications).
+Since this does not correspond to the behavior of many other
+operating/file systems (for example, OS/2 HPFS, which preserves
+mixed case but is not sensitive to it), the \fB\-C\fP option may be
+used to force all filename matches to be case-insensitive.  In the
+example above, all three files would then match ``\fCmakefile\fR''
+(or ``\fCmake*\fR'', or similar).  The \fB\-C\fP option affects
+file specs in both the normal file list and the excluded-file list (xlist).
+.IP
+Please note that the \fB\-C\fP option does neither affect the search for
+the zipfile(s) nor the matching of archive entries to existing files on
+the extraction path.  On a case-sensitive file system, \fIunzip\fP will
+never try to overwrite a file ``FOO'' when extracting an entry ``foo''!
+.TP
+.B \-D
+skip restoration of timestamps for extracted items.  Normally, \fIunzip\fP
+tries to restore all meta-information for extracted items that are supplied
+in the Zip archive (and do not require privileges or impose a security risk).
+By specifying \fB\-D\fP, \fIunzip\fP is told to suppress restoration of
+timestamps for directories explicitly created from Zip archive entries.
+This option only applies to ports that support setting timestamps for
+directories (currently ATheOS, BeOS, MacOS, OS/2, Unix, VMS, Win32, for other
+\fIunzip\fP ports, \fB\-D\fP has no effect).
+The duplicated option \fB\-DD\fP forces suppression of timestamp restoration
+for all extracted entries (files and directories).  This option results in
+setting the timestamps for all extracted entries to the current time.
+.IP
+On VMS, the default setting for this option is \fB\-D\fP for consistency
+with the behaviour of BACKUP: file timestamps are restored, timestamps of
+extracted directories are left at the current time.  To enable restoration
+of directory timestamps, the negated option \fB\--D\fP should be specified.
+On VMS, the option \fB\-D\fP disables timestamp restoration for all extracted
+Zip archive items.  (Here, a single \fB\-D\fP on the command line combines
+with the default \fB\-D\fP to do what an explicit \fB\-DD\fP does on other
+systems.)
+.TP
+.B \-E
+[MacOS only] display contents of MacOS extra field during restore operation.
+.TP
+.B \-F
+[Acorn only] suppress removal of NFS filetype extension from stored filenames.
+.TP
+.B \-F
+[non-Acorn systems supporting long filenames with embedded commas,
+and only if compiled with ACORN_FTYPE_NFS defined] translate
+filetype information from ACORN RISC OS extra field blocks into a
+NFS filetype extension and append it to the names of the extracted files.
+(When the stored filename appears to already have an appended NFS filetype
+extension, it is replaced by the info from the extra field.)
+.TP
+.B \-i
+[MacOS only] ignore filenames stored in MacOS extra fields. Instead, the
+most compatible filename stored in the generic part of the entry's header
+is used.
+.TP
+.B \-j
+junk paths.  The archive's directory structure is not recreated; all files
+are deposited in the extraction directory (by default, the current one).
+.TP
+.B \-J
+[BeOS only] junk file attributes.  The file's BeOS file attributes are not
+restored, just the file's data.
+.TP
+.B \-J
+[MacOS only] ignore MacOS extra fields.  All Macintosh specific info
+is skipped. Data-fork and resource-fork are restored as separate files.
+.TP
+.B \-K
+[AtheOS, BeOS, Unix only] retain SUID/SGID/Tacky file attributes.  Without
+this flag, these attribute bits are cleared for security reasons.
+.TP
+.B \-L
+convert to lowercase any filename originating on an uppercase-only operating
+system or file system.  (This was \fIunzip\fP's default behavior in releases
+prior to 5.11; the new default behavior is identical to the old behavior with
+the \fB\-U\fP option, which is now obsolete and will be removed in a future
+release.)  Depending on the archiver, files archived under single-case
+file systems (VMS, old MS-DOS FAT, etc.) 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 under
+Unix.  By default \fIunzip\fP lists and extracts such filenames exactly as
+they're stored (excepting truncation, conversion of unsupported characters,
+etc.); this option causes the names of all files from certain systems to be
+converted to lowercase.  The \fB\-LL\fP option forces conversion of every
+filename to lowercase, regardless of the originating file system.
+.TP
+.B \-M
+pipe all output through an internal pager similar to the Unix \fImore\fP(1)
+command.  At the end of a screenful of output, \fIunzip\fP pauses with a
+``\-\-More\-\-'' prompt; the next screenful may be viewed by pressing the
+Enter (Return) key or the space bar.  \fIunzip\fP can be terminated by
+pressing the ``q'' key and, on some systems, the Enter/Return key.  Unlike
+Unix \fImore\fP(1), there is no forward-searching or editing capability.
+Also, \fIunzip\fP 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.
+On some systems the number of available lines on the screen is not detected,
+in which case \fIunzip\fP assumes the height is 24 lines.
+.TP
+.B \-n
+never overwrite existing files.  If a file already exists, skip the extraction
+of that file without prompting.  By default \fIunzip\fP queries 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.
+.TP
+.B \-N
+[Amiga] extract file comments as Amiga filenotes.  File comments are created
+with the \-c option of \fIzip\fP(1L), or with the \-N option of the Amiga port
+of \fIzip\fP(1L), which stores filenotes as comments.
+.TP
+.B \-o
+overwrite existing files without prompting.  This is a dangerous option, so
+use it with care.  (It is often used with \fB\-f\fP, however, and is the only
+way to overwrite directory EAs under OS/2.)
+.IP \fB\-P\fP\ \fIpassword\fP
+use \fIpassword\fP to decrypt encrypted zipfile entries (if any).  \fBTHIS IS
+INSECURE!\fP  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 is even worse.
+Whenever possible, use the non-echoing, interactive prompt to enter passwords.
+(And where security is truly important, use strong encryption such as Pretty
+Good Privacy instead of the relatively weak encryption provided by standard
+zipfile utilities.)
+.TP
+.B \-q
+perform operations quietly (\fB\-qq\fP = even quieter).  Ordinarily \fIunzip\fP
+prints the names of the files it's extracting or testing, the extraction
+methods, any file or zipfile comments that may be stored in the archive,
+and possibly a summary when finished with each archive.  The \fB\-q\fP[\fBq\fP]
+options suppress the printing of some or all of these messages.
+.TP
+.B \-s
+[OS/2, NT, MS-DOS] convert spaces in filenames to underscores.  Since all PC
+operating systems allow spaces in filenames, \fIunzip\fP by default extracts
+filenames with spaces intact (e.g., ``\fCEA\ DATA.\ SF\fR'').  This can be
+awkward, however, since MS-DOS in particular does not gracefully support
+spaces in filenames.  Conversion of spaces to underscores can eliminate the
+awkwardness in some cases.
+.TP
+.B \-S
+[VMS] convert text files (\fB\-a\fP, \fB\-aa\fP) into Stream_LF record format,
+instead of the text-file default, variable-length record format.
+(Stream_LF is the default record format of VMS \fIunzip\fP. It is applied
+unless conversion (\fB\-a\fP, \fB\-aa\fP and/or \fB\-b\fP, \fB\-bb\fP) is
+requested or a VMS-specific entry is processed.)
+.TP
+.B \-U
+[UNICODE_SUPPORT only] modify or disable UTF-8 handling.
+When UNICODE_SUPPORT is available, the option \fB\-U\fP forces \fIunzip\fP
+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.
+.IP
+The option \fB\-UU\fP allows to entirely disable the recognition of UTF-8
+encoded filenames.  The handling of filename codings within \fIunzip\fP falls
+back to the behaviour of previous versions.
+.IP
+[old, obsolete usage] leave filenames uppercase if
+created under MS-DOS, VMS, etc.  See \fB\-L\fP above.
+.TP
+.B \-V
+retain (VMS) file version numbers.  VMS files can be stored with a version
+number, in the format \fCfile.ext;##\fR.  By default the ``\fC;##\fR'' 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.)
+.TP
+.B \-W
+[only when WILD_STOP_AT_DIR compile-time option enabled]
+modifies the pattern matching routine so that both `?' (single-char wildcard)
+and `*' (multi-char wildcard) do not match the directory separator character
+`/'.  (The two-character sequence ``**'' acts as a multi-char wildcard that
+includes the directory separator in its matched characters.)  Examples:
+.PP
+.EX
+    "*.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"
+.EE
+.IP
+This modified behaviour 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
+zipfile specifications and zip entry selection patterns in most ports.
+For systems allowing `/' as regular filename character, the -W option
+would not work as expected on a wildcard zipfile specification.)
+.TP
+.B \-X
+[VMS, Unix, OS/2, NT, Tandem] restore owner/protection info (UICs and ACL
+entries) under VMS, or user and group info (UID/GID) under Unix, or access
+control lists (ACLs) under 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 under Windows NT.  In most cases this will
+require special system privileges, and doubling the option (\fB\-XX\fP)
+under NT instructs \fIunzip\fP to use privileges for extraction; but under
+Unix, for example, a user who belongs to several groups can restore files
+owned by any of those groups, as long as the user IDs match his or her 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 what conditions this would ever be
+useful anyway.]
+.TP
+.B \-Y
+[VMS] treat archived file 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.)  Example:
+.EX
+     "a.b.3" -> "a.b;3".
+.EE
+.TP
+.B \-$
+.\" Amiga support possible eventually, but not yet
+[MS-DOS, OS/2, NT] restore the volume label if the extraction medium is
+removable (e.g., a diskette).  Doubling the option (\fB\-$$\fP) allows fixed
+media (hard disks) to be labeled as well.  By default, volume labels are
+ignored.
+.IP \fB\-/\fP\ \fIextensions\fP
+[Acorn only] overrides the extension list supplied by 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.
+.TP
+.B \-:
+[all but Acorn, VM/CMS, MVS, Tandem] allows to extract archive members into
+locations outside of the current `` extraction root folder''. For security
+reasons, \fIunzip\fP normally removes ``parent dir'' path components
+(``../'') from the names of extracted file.  This safety feature (new for
+version 5.50) prevents \fIunzip\fP from accidentally writing files to
+``sensitive'' areas outside the active extraction folder tree head.  The
+\fB\-:\fP option lets \fIunzip\fP switch back to its previous, more liberal
+behaviour, to allow exact extraction of (older) archives that used ``../''
+components to create multiple directory trees at the level of the current
+extraction folder.  This option does not enable writing explicitly to the
+root directory (``/'').  To achieve this, it is necessary to set the
+extraction target folder to root (e.g. \fB\-d / \fP).  However, when the
+\fB\-:\fP option is specified, it is still possible to implicitly write to
+the root directory by specifying enough ``../'' path components within the
+zip archive.
+Use this option with extreme caution.
+.TP
+.B \-^
+[Unix only] allow control characters in names of extracted ZIP archive
+entries.  On Unix, a file name may contain any (8-bit) character code with
+the two exception '/' (directory delimiter) and NUL (0x00, the C string
+termination indicator), unless the specific file system has more
+restrictive conventions.  Generally, this allows to embed ASCII control
+characters (or even sophisticated control sequences) in file names, at least
+on 'native' Unix file systems.  However, it may be highly suspicious to
+make use of this Unix "feature".  Embedded control characters in file names
+might have nasty side effects when displayed on screen by some listing code
+without sufficient filtering.  And, for ordinary users, it may be difficult
+to handle such file names (e.g. when trying to specify it for open, copy,
+move, or delete operations).  Therefore, \fIunzip\fP applies a filter by
+default that removes potentially dangerous control characters from the
+extracted file names. The \fB-^\fP option allows to override this filter
+in the rare case that embedded filename control characters are to be
+intentionally restored.
+.TP
+.B \-2
+[VMS] force unconditionally conversion of file names to ODS2-compatible
+names.  The default is to exploit the destination file system, preserving
+case and extended file name characters on an ODS5 destination file system;
+and applying the ODS2-compatibility file name filtering on an ODS2 destination
+file system.
+.PD
+.\" =========================================================================
+.SH "ENVIRONMENT OPTIONS"
+\fIunzip\fP's default behavior may be modified via options placed in
+an environment variable.  This can be done with any option, but it
+is probably most useful with the \fB\-a\fP, \fB\-L\fP, \fB\-C\fP, \fB\-q\fP,
+\fB\-o\fP, or \fB\-n\fP modifiers:  make \fIunzip\fP auto-convert text
+files by default, make it convert filenames from uppercase systems to
+lowercase, make it match names case-insensitively, make it quieter,
+or make it always overwrite or never overwrite files as it extracts
+them.  For example, to make \fIunzip\fP act as quietly as possible, only
+reporting errors, one would use one of the following commands:
+.TP
+  Unix Bourne shell:
+UNZIP=\-qq; export UNZIP
+.TP
+  Unix C shell:
+setenv UNZIP \-qq
+.TP
+  OS/2 or MS-DOS:
+set UNZIP=\-qq
+.TP
+  VMS (quotes for \fIlowercase\fP):
+define UNZIP_OPTS "\-qq"
+.PP
+Environment options are, in effect, considered to be just like 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 the
+``minus operator'' to remove it.  For instance, to override one of the
+quiet-flags in the example above, use the command
+.PP
+.EX
+unzip \-\-q[\fIother options\fP] zipfile
+.EE
+.PP
+The first hyphen is the normal
+switch character, and the second is a minus sign, acting on the q option.
+Thus the effect here is to cancel one quantum of quietness.  To cancel
+both quiet flags, two (or more) minuses may be used:
+.PP
+.EX
+unzip \-t\-\-q zipfile
+unzip \-\-\-qt zipfile
+.EE
+.PP
+(the two are equivalent).  This may seem awkward
+or confusing, but it is reasonably intuitive:  just ignore the first
+hyphen and go from there.  It is also consistent with the behavior of
+Unix \fInice\fP(1).
+.PP
+As suggested by the examples above, the default variable names are UNZIP_OPTS
+for VMS (where the symbol used to install \fIunzip\fP as a foreign command
+would otherwise be confused with the environment variable), and UNZIP
+for all other operating systems.  For compatibility with \fIzip\fP(1L),
+UNZIPOPT is also accepted (don't ask).  If both UNZIP and UNZIPOPT
+are defined, however, UNZIP takes precedence.  \fIunzip\fP's diagnostic
+option (\fB\-v\fP with no zipfile name) can be used to check the values
+of all four possible \fIunzip\fP and \fIzipinfo\fP environment variables.
+.PP
+The timezone variable (TZ) should be set according to the local timezone
+in order for the \fB\-f\fP and \fB\-u\fP to operate correctly.  See the
+description of \fB\-f\fP above for details.  This variable may also be
+necessary to get timestamps of extracted files to be set correctly.
+The WIN32 (Win9x/ME/NT4/2K/XP/2K3) port of \fIunzip\fP gets the timezone
+configuration from the registry, assuming it is correctly set in the
+Control Panel.  The TZ variable is ignored for this port.
+.PD
+.\" =========================================================================
+.SH DECRYPTION
+Encrypted archives are fully supported by Info-ZIP software, but due to
+United States export restrictions, de-/encryption support might be disabled
+in your compiled binary.  However, since spring 2000, US export restrictions
+have been liberated, and our source archives do now include full crypt code.
+In case you need binary distributions with crypt support enabled, see the
+file ``WHERE'' in any Info-ZIP source or binary distribution for locations
+both inside and outside the US.
+.PP
+Some compiled versions of \fIunzip\fP may not support decryption.
+To check a version for crypt support, either attempt to test or extract
+an encrypted archive, or else check \fIunzip\fP's diagnostic
+screen (see the \fB\-v\fP option above) for ``\fC[decryption]\fR'' as one
+of the special compilation options.
+.PP
+As noted above, the \fB\-P\fP option may be used to supply a password on
+the command line, but at a cost in security.  The preferred decryption
+method is simply to extract normally; if a zipfile member is encrypted,
+\fIunzip\fP will prompt for the password without echoing what is typed.
+\fIunzip\fP continues to use the same password as long as it appears to be
+valid, by testing a 12-byte header on each file.  The correct password will
+always check out against the header, but there is a 1-in-256 chance that an
+incorrect password will as well.  (This is a security feature of the PKWARE
+zipfile 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 \fIunzip\fP
+will fail during the extraction because the ``decrypted'' bytes do not
+constitute a valid compressed data stream.
+.PP
+If the first password fails the header check on some file, \fIunzip\fP 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.  (In
+fact, that's not quite true; older versions of \fIzip\fP(1L) and
+\fIzipcloak\fP(1L) allowed null passwords, so \fIunzip\fP checks each encrypted
+file to see if the null password works.  This may result in ``false positives''
+and extraction errors, as noted above.)
+.PP
+Archives encrypted with 8-bit passwords (for example, passwords with accented
+European characters) may not be portable across systems and/or 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 \fIPKZIP\fP 2.04g uses the OEM code page; Windows \fIPKZIP\fP 2.50
+uses Latin-1 (and is therefore incompatible with DOS \fIPKZIP\fP); 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 \fIWinZip\fP 6.x does not
+allow 8-bit passwords at all.  \fIUnZip\fP 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 (partially) Unicode (resp.
+UTF-8) support in \fIUnZip\fP 6.0 has not yet been adapted to the encryption
+password handling in \fIunzip\fP.  On systems that use UTF-8 as native
+character encoding, \fIunzip\fP 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.
+.PD
+.\" =========================================================================
+.SH EXAMPLES
+To use \fIunzip\fP to extract all members of the archive \fIletters.zip\fP
+into the current directory and subdirectories below it, creating any
+subdirectories as necessary:
+.PP
+.EX
+unzip letters
+.EE
+.PP
+To extract all members of \fIletters.zip\fP into the current directory only:
+.PP
+.EX
+unzip -j letters
+.EE
+.PP
+To test \fIletters.zip\fP, printing only a summary message indicating
+whether the archive is OK or not:
+.PP
+.EX
+unzip -tq letters
+.EE
+.PP
+To test \fIall\fP zipfiles in the current directory, printing only the
+summaries:
+.PP
+.EX
+unzip -tq \e*.zip
+.EE
+.PP
+(The backslash before the asterisk is only required if the shell expands
+wildcards, as in Unix; double quotes could have been used instead, as in
+the source examples below.)\ \ To extract to standard output all members of
+\fIletters.zip\fP whose names end in \fI.tex\fP, auto-converting to the
+local end-of-line convention and piping the output into \fImore\fP(1):
+.PP
+.EX
+unzip \-ca letters \e*.tex | more
+.EE
+.PP
+To extract the binary file \fIpaper1.dvi\fP to standard output and pipe it
+to a printing program:
+.PP
+.EX
+unzip \-p articles paper1.dvi | dvips
+.EE
+.PP
+To extract all FORTRAN and C source files--*.f, *.c, *.h, and Makefile--into
+the /tmp directory:
+.PP
+.EX
+unzip source.zip "*.[fch]" Makefile -d /tmp
+.EE
+.PP
+(the double quotes are necessary only in Unix and only if globbing is turned
+on).  To extract all FORTRAN and C source files, regardless of case (e.g.,
+both *.c and *.C, and any makefile, Makefile, MAKEFILE or similar):
+.PP
+.EX
+unzip \-C source.zip "*.[fch]" makefile -d /tmp
+.EE
+.PP
+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 ``binary''):
+.PP
+.EX
+unzip \-aaCL source.zip "*.[fch]" makefile -d /tmp
+.EE
+.PP
+To extract only newer versions of the files already in the current
+directory, without querying (NOTE:  be careful of unzipping in one timezone a
+zipfile created in another--ZIP archives other than those created by Zip 2.1
+or later contain no timezone information, and a ``newer'' file from an eastern
+timezone may, in fact, be older):
+.PP
+.EX
+unzip \-fo sources
+.EE
+.PP
+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):
+.PP
+.EX
+unzip \-uo sources
+.EE
+.PP
+To display a diagnostic screen showing which \fIunzip\fP and \fIzipinfo\fP
+options are stored in environment variables, whether decryption support was
+compiled in, the compiler with which \fIunzip\fP was compiled, etc.:
+.PP
+.EX
+unzip \-v
+.EE
+.PP
+In the last five examples, assume that UNZIP or UNZIP_OPTS is set to -q.
+To do a singly quiet listing:
+.PP
+.EX
+unzip \-l file.zip
+.EE
+.PP
+To do a doubly quiet listing:
+.PP
+.EX
+unzip \-ql file.zip
+.EE
+.PP
+(Note that the ``\fC.zip\fR'' is generally not necessary.)  To do a standard
+listing:
+.PP
+.EX
+unzip \-\-ql file.zip
+.EE
+or
+.EX
+unzip \-l\-q file.zip
+.EE
+or
+.EX
+unzip \-l\-\-q file.zip
+.EE
+\fR(Extra minuses in options don't hurt.)
+.PD
+.\" =========================================================================
+.SH TIPS
+The current maintainer, being a lazy sort, finds it very useful to define
+a pair of aliases:  \fCtt\fR for ``\fCunzip \-tq\fR'' and \fCii\fR for
+``\fCunzip \-Z\fR'' (or ``\fCzipinfo\fR'').  One may then simply type
+``\fCtt zipfile\fR'' to test an archive, something that is worth making a
+habit of doing.  With luck \fIunzip\fP will report ``\fCNo errors detected
+in compressed data of zipfile.zip\fR,'' after which one may breathe a sigh
+of relief.
+.PP
+The maintainer also finds it useful to set the UNZIP environment variable
+to ``\fC\-aL\fR'' and is tempted to add ``\fC\-C\fR'' as well.  His ZIPINFO
+variable is set to ``\fC\-z\fR''.
+.PD
+.\" =========================================================================
+.SH DIAGNOSTICS
+The exit status (or error level) approximates the exit codes defined by PKWARE
+and takes on the following values, except under VMS:
+.RS
+.IP 0
+normal; no errors or warnings detected.
+.IP 1
+one or more warning errors were encountered, but processing completed
+successfully anyway.  This includes zipfiles where one or more files
+was skipped due to unsupported compression method or encryption with an
+unknown password.
+.IP 2
+a generic error in the zipfile format was detected.  Processing may have
+completed successfully anyway; some broken zipfiles created by other
+archivers have simple work-arounds.
+.IP 3
+a severe error in the zipfile format was detected.  Processing probably
+failed immediately.
+.IP 4
+\fIunzip\fP was unable to allocate memory for one or more buffers during
+program initialization.
+.IP 5
+\fIunzip\fP was unable to allocate memory or unable to obtain a tty to read
+the decryption password(s).
+.IP 6
+\fIunzip\fP was unable to allocate memory during decompression to disk.
+.IP 7
+\fIunzip\fP was unable to allocate memory during in-memory decompression.
+.IP 8
+[currently not used]
+.IP 9
+the specified zipfiles were not found.
+.IP 10
+invalid options were specified on the command line.
+.IP 11
+no matching files were found.
+.IP 50
+the disk is (or was) full during extraction.
+.IP 51
+the end of the ZIP archive was encountered prematurely.
+.IP 80
+the user aborted \fIunzip\fP prematurely with control-C (or similar)
+.IP 81
+testing or extraction of one or more files failed due to unsupported
+compression methods or unsupported decryption.
+.IP 82
+no files were found due to bad decryption password(s).  (If even one file is
+successfully processed, however, the exit status is 1.)
+.RE
+.PP
+VMS interprets standard Unix (or PC) return values as other, scarier-looking
+things, so \fIunzip\fP instead maps them into VMS-style status codes.  The
+current mapping is as follows:   1 (success) for normal exit, 0x7fff0001
+for warning errors, and (0x7fff000? + 16*normal_unzip_exit_status) for all
+other errors, where the `?' is 2 (error) for \fIunzip\fP values 2, 9-11 and
+80-82, and 4 (fatal error) for the remaining ones (3-8, 50, 51).  In addition,
+there is a compilation option to expand upon this behavior:  defining
+RETURN_CODES results in a human-readable explanation of what the error
+status means.
+.PD
+.\" =========================================================================
+.SH BUGS
+Multi-part archives are not yet supported, except in conjunction with
+\fIzip\fP.  (All parts must be concatenated together in order, and then
+``\fCzip \-F\fR'' (for \fIzip 2.x\fP) or ``\fCzip \-FF\fR'' (for
+\fIzip 3.x\fP) must be performed on the concatenated archive in order to
+``fix'' it.  Also, \fIzip 3.0\fP and later can combine multi-part (split)
+archives into a combined single-file archive using ``\fCzip \-s\- inarchive
+-O outarchive\fR''.  See the \fIzip 3\fP manual page for more information.)
+This will definitely be corrected in the next major release.
+.PP
+Archives read from standard input are not yet supported, except with
+\fIfunzip\fP (and then only the first member of the archive can be extracted).
+.PP
+Archives encrypted with 8-bit passwords (e.g., passwords with accented
+European characters) may not be portable across systems and/or other
+archivers.  See the discussion in \fBDECRYPTION\fP above.
+.PP
+\fIunzip\fP's \fB\-M\fP (``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 / OS port, \fIunzip\fP may not detect
+the true screen geometry but rather rely on "commonly used" default dimensions.
+The correct handling of tabs would require the implementation of a query for
+the actual tabulator setup on the output console.
+.PP
+Dates, times and permissions of stored directories are not restored except
+under Unix. (On Windows NT and successors, timestamps are now restored.)
+.PP
+[MS-DOS] When extracting or testing files from an archive on a defective
+floppy diskette, if the ``Fail'' option is chosen from DOS's ``Abort, Retry,
+Fail?'' message, older versions of \fIunzip\fP may hang the system, requiring
+a reboot.  This problem appears to be fixed, but control-C (or control-Break)
+can still be used to terminate \fIunzip\fP.
+.PP
+Under DEC Ultrix, \fIunzip\fP would sometimes fail on long zipfiles (bad CRC,
+not always reproducible).  This was apparently due either to a hardware bug
+(cache memory) or an operating system bug (improper handling of page faults?).
+Since Ultrix has been abandoned in favor of Digital Unix (OSF/1), this may not
+be an issue anymore.
+.PP
+[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 zipfile, nor are hard-linked files relinked.  Basically the only file
+types restored by \fIunzip\fP are regular files, directories and symbolic
+(soft) links.
+.PP
+[OS/2] Extended attributes for existing directories are only updated if the
+\fB\-o\fP (``overwrite all'') option is given.  This is a limitation of the
+operating system; because directories only have a creation time associated
+with them, \fIunzip\fP 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
+(e.g., ``\fCunzip -o foo */\fR'').
+.PP
+[VMS] When extracting to another directory, only the \fI[.foo]\fP syntax is
+accepted for the \fB\-d\fP option; the simple Unix \fIfoo\fP syntax is
+silently ignored (as is the less common VMS \fIfoo.dir\fP syntax).
+.PP
+[VMS] When the file being extracted already exists, \fIunzip\fP's query only
+allows skipping, overwriting or renaming; there should additionally be a
+choice for creating a new version of the file.  In fact, the ``overwrite''
+choice does create a new version; the old version is not overwritten or
+deleted.
+.PD
+.\" =========================================================================
+.SH "SEE ALSO"
+\fIfunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipgrep\fP(1L),
+\fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
+.PD
+.\" =========================================================================
+.SH URL
+The Info-ZIP home page is currently at
+.EX
+\fChttp://www.info-zip.org/pub/infozip/\fR
+.EE
+or
+.EX
+\fCftp://ftp.info-zip.org/pub/infozip/\fR .
+.EE
+.PD
+.\" =========================================================================
+.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 (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).
+.PP
+The following people were 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).
+.PP
+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 CONTRIBS
+file in the UnZip source distribution for a relatively complete version.
+.PD
+.\" =========================================================================
+.SH VERSIONS
+.ta \w'vx.xxnn'u +\w'fall 1989'u+3n
+.PD 0
+.IP "v1.2\t15 Mar 89" \w'\t\t'u
+Samuel H. Smith
+.IP "v2.0\t\ 9 Sep 89"
+Samuel H. Smith
+.IP "v2.x\tfall 1989"
+many Usenet contributors
+.IP "v3.0\t\ 1 May 90"
+Info-ZIP (DPK, consolidator)
+.IP "v3.1\t15 Aug 90"
+Info-ZIP (DPK, consolidator)
+.IP "v4.0\t\ 1 Dec 90"
+Info-ZIP (GRR, maintainer)
+.IP "v4.1\t12 May 91"
+Info-ZIP
+.IP "v4.2\t20 Mar 92"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.0\t21 Aug 92"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.01\t15 Jan 93"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.1\t\ 7 Feb 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.11\t\ 2 Aug 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.12\t28 Aug 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.2\t30 Apr 96"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.3\t22 Apr 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.31\t31 May 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.32\t\ 3 Nov 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.4\t28 Nov 98"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.41\t16 Apr 00"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.42\t14 Jan 01"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.5\t17 Feb 02"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.51\t22 May 04"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.52\t28 Feb 05"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v6.0\t20 Apr 09"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.PD
Index: unzip/create-6.0-slackware-patch/unzip60-new/man
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/man	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/man	(revision 5)

Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/man
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch/unzip60-new/match.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/match.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/match.c	(revision 5)
@@ -0,0 +1,512 @@
+/*
+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 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
+*/
+/*---------------------------------------------------------------------------
+
+  match.c
+
+  The match() routine recursively compares a string to a "pattern" (regular
+  expression), returning TRUE if a match is found or FALSE if not.  This
+  version is specifically for use with unzip.c:  as did the previous match()
+  routines from SEA and J. Kercheval, it leaves the case (upper, lower, or
+  mixed) of the string alone, but converts any uppercase characters in the
+  pattern to lowercase if indicated by the global var pInfo->lcflag (which
+  is to say, string is assumed to have been converted to lowercase already,
+  if such was necessary).
+
+  GRR:  reversed order of text, pattern in matche() (now same as match());
+        added ignore_case/ic flags, Case() macro.
+
+  PaulK:  replaced matche() with recmatch() from Zip, modified to have an
+          ignore_case argument; replaced test frame with simpler one.
+
+  ---------------------------------------------------------------------------
+
+  Copyright on recmatch() from Zip's util.c
+	 Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+
+	 See the accompanying file LICENSE, version 2004-May-22 or later
+	 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.info-zip.org/pub/infozip/license.html  
+
+
+  ---------------------------------------------------------------------------
+
+  Match the pattern (wildcard) against the string (fixed):
+
+     match(string, pattern, ignore_case, sepc);
+
+  returns TRUE if string matches pattern, FALSE otherwise.  In the pattern:
+
+     `*' matches any sequence of characters (zero or more)
+     `?' matches any single character
+     [SET] matches any character in the specified set,
+     [!SET] or [^SET] matches any character not in the specified set.
+
+  A set is composed of characters or ranges; a range looks like ``character
+  hyphen character'' (as in 0-9 or A-Z).  [0-9a-zA-Z_] is the minimal set of
+  characters ALlowed in the [..] pattern construct.  Other characters are
+  allowed (i.e., 8-bit characters) if your system will support them.
+
+  To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
+  side or outside a [..] construct, and match the character exactly, precede
+  it with a ``\'' (backslash).
+
+  Note that "*.*" and "*." are treated specially under MS-DOS if DOSWILD is
+  defined.  See the DOSWILD section below for an explanation.  Note also
+  that with VMSWILD defined, '%' is used instead of '?', and sets (ranges)
+  are delimited by () instead of [].
+
+  ---------------------------------------------------------------------------*/
+
+
+#define __MATCH_C       /* identifies this source module */
+
+/* define ToLower() in here (for Unix, define ToLower to be macro (using
+ * isupper()); otherwise just use tolower() */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#ifndef THEOS   /* the Theos port defines its own variant of match() */
+
+#if 0  /* this is not useful until it matches Amiga names insensitively */
+#ifdef AMIGA        /* some other platforms might also want to use this */
+#  define ANSI_CHARSET       /* MOVE INTO UNZIP.H EVENTUALLY */
+#endif
+#endif /* 0 */
+
+#ifdef ANSI_CHARSET
+#  ifdef ToLower
+#    undef ToLower
+#  endif
+   /* uppercase letters are values 41 thru 5A, C0 thru D6, and D8 thru DE */
+#  define IsUpper(c) (c>=0xC0 ? c<=0xDE && c!=0xD7 : c>=0x41 && c<=0x5A)
+#  define ToLower(c) (IsUpper((uch) c) ? (unsigned) c | 0x20 : (unsigned) c)
+#endif
+#define Case(x)  (ic? ToLower(x) : (x))
+
+#ifdef VMSWILD
+#  define WILDCHAR   '%'
+#  define BEG_RANGE  '('
+#  define END_RANGE  ')'
+#else
+#  define WILDCHAR   '?'
+#  define BEG_RANGE  '['
+#  define END_RANGE  ']'
+#  define WILDCHR_SINGLE '?'
+#  define DIRSEP_CHR '/'
+#  define WILDCHR_MULTI '*'
+#endif
+
+#ifdef WILD_STOP_AT_DIR
+   int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
+#else
+   int wild_stop_at_dir = 0; /* default wildcards do include / in matches */
+#endif
+
+
+
+/*
+ * case mapping functions. case_map is used to ignore case in comparisons,
+ * to_up is used to force upper case even on Unix (for dosify option).
+ */
+#ifdef USE_CASE_MAP
+#  define case_map(c) upper[(c) & 0xff]
+#  define to_up(c)    upper[(c) & 0xff]
+#else
+#  define case_map(c) (c)
+#  define to_up(c)    ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
+#endif /* USE_CASE_MAP */
+
+
+#if 0                /* GRR:  add this to unzip.h someday... */
+#if !(defined(MSDOS) && defined(DOSWILD))
+#ifdef WILD_STOP_AT_DIR
+#define match(s,p,ic,sc) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic,sc) == 1)
+#else
+#define match(s,p,ic)    (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic) == 1)
+#endif
+int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
+                 int ignore_case __WDLPRO));
+#endif
+#endif /* 0 */
+static int recmatch OF((ZCONST char *, ZCONST char *, 
+                        int));
+static char *isshexp OF((ZCONST char *p));
+static int namecmp OF((ZCONST char *s1, ZCONST char *s2));
+
+
+/* match() is a shell to recmatch() to return only Boolean values. */
+
+int match(string, pattern, ignore_case __WDL)
+    ZCONST char *string, *pattern;
+    int ignore_case;
+    __WDLDEF
+{
+#if (defined(MSDOS) && defined(DOSWILD))
+    char *dospattern;
+    int j = strlen(pattern);
+
+/*---------------------------------------------------------------------------
+    Optional MS-DOS preprocessing section:  compare last three chars of the
+    wildcard to "*.*" and translate to "*" if found; else compare the last
+    two characters to "*." and, if found, scan the non-wild string for dots.
+    If in the latter case a dot is found, return failure; else translate the
+    "*." to "*".  In either case, continue with the normal (Unix-like) match
+    procedure after translation.  (If not enough memory, default to normal
+    match.)  This causes "a*.*" and "a*." to behave as MS-DOS users expect.
+  ---------------------------------------------------------------------------*/
+
+    if ((dospattern = (char *)malloc(j+1)) != NULL) {
+        strcpy(dospattern, pattern);
+        if (!strcmp(dospattern+j-3, "*.*")) {
+            dospattern[j-2] = '\0';                    /* nuke the ".*" */
+        } else if (!strcmp(dospattern+j-2, "*.")) {
+            char *p = MBSCHR(string, '.');
+
+            if (p) {   /* found a dot:  match fails */
+                free(dospattern);
+                return 0;
+            }
+            dospattern[j-1] = '\0';                    /* nuke the end "." */
+        }
+        j = recmatch(dospattern, string, ignore_case);
+        free(dospattern);
+        return j == 1;
+    } else
+#endif /* MSDOS && DOSWILD */
+    return recmatch(pattern, string, ignore_case) == 1;
+}
+
+#ifdef _MBCS
+
+char *___tmp_ptr;
+
+#endif
+
+static int recmatch(p, s, ci)
+ZCONST char *p;         /* sh pattern to match */
+ZCONST char *s;         /* string to match it to */
+int ci;                 /* flag: force case-insensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+   they match, and 0 or 2 if they don't or if there is a syntax error in the
+   pattern.  This routine recurses on itself no deeper than the number of
+   characters in the pattern. */
+{
+  int c;                /* pattern char or start of range in [-] loop */
+  /* Get first character, the pattern for new recmatch calls follows */
+ /* borrowed from Zip's global.c */
+ int no_wild = 0; 
+ int allow_regex=1;
+  /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+     See 21 July 2006 mail.
+     It only applies when p is pointing to a doublebyte character and
+     things like / and wildcards are not doublebyte.  This probably
+     should not be needed. */
+
+#ifdef _MBCS
+  if (CLEN(p) == 2) {
+    if (CLEN(s) == 2) {
+      return (*p == *s && *(p+1) == *(s+1)) ?
+        recmatch(p + 2, s + 2, ci) : 0;
+    } else {
+      return 0;
+    }
+  }
+#endif /* ?_MBCS */
+
+  c = *POSTINCSTR(p);
+
+  /* If that was the end of the pattern, match if string empty too */
+  if (c == 0)
+    return *s == 0;
+
+  /* '?' (or '%' or '#') matches any character (but not an empty string) */
+  if (c == WILDCHR_SINGLE) {
+    if (wild_stop_at_dir)
+      return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), ci) : 0;
+    else
+      return *s ? recmatch(p, s + CLEN(s), ci) : 0;
+  }
+
+  /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+#ifdef AMIGA
+  if (!no_wild && c == '#' && *p == '?')            /* "#?" is Amiga-ese for "*" */
+    c = WILDCHR_MULTI, p++;
+#endif /* AMIGA */
+  if (!no_wild && c == WILDCHR_MULTI)
+  {
+    if (wild_stop_at_dir) {
+      /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+      if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+        c = WILDCHR_MULTI, p++;
+      if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+      if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+        /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+        for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+          if ((c = recmatch(p, s, ci)) != 0)
+            return c;
+        /* end of pattern: matched if at end of string, else continue */
+        if (*p == 0)
+          return (*s == 0);
+        /* continue to match if at DIRSEP_CHR in pattern, else give up */
+        return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+               ? recmatch(p, s, ci) : 2;
+      }
+      /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+      p++;        /* move p past the second WILDCHR_MULTI */
+      /* continue with the normal non-WILD_STOP_AT_DIR code */
+    } /* wild_stop_at_dir */
+
+    /* Not wild_stop_at_dir */
+    if (*p == 0)
+      return 1;
+    if (!isshexp((char *)p))
+    {
+      /* optimization for rest of pattern being a literal string */
+
+      /* optimization to handle patterns like *.txt */
+      /* if the first char in the pattern is '*' and there */
+      /* are no other shell expression chars, i.e. a literal string */
+      /* then just compare the literal string at the end */
+
+      ZCONST char *srest;
+
+      srest = s + (strlen(s) - strlen(p));
+      if (srest - s < 0)
+        /* remaining literal string from pattern is longer than rest of
+           test string, there can't be a match
+         */
+        return 0;
+      else
+        /* compare the remaining literal pattern string with the last bytes
+           of the test string to check for a match */
+#ifdef _MBCS
+      {
+        ZCONST char *q = s;
+
+        /* MBCS-aware code must not scan backwards into a string from
+         * the end.
+         * So, we have to move forward by character from our well-known
+         * character position s in the test string until we have advanced
+         * to the srest position.
+         */
+        while (q < srest)
+          INCSTR(q);
+        /* In case the byte *srest is a trailing byte of a multibyte
+         * character, we have actually advanced past the position (srest).
+         * For this case, the match has failed!
+         */
+        if (q != srest)
+          return 0;
+        return ((!ci ? strcmp(p, q) : namecmp(p, q)) == 0);
+      }
+#else /* !_MBCS */
+        return ((!ci ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+#endif /* ?_MBCS */
+    }
+    else
+    {
+      /* pattern contains more wildcards, continue with recursion... */
+      for (; *s; INCSTR(s))
+        if ((c = recmatch(p, s, ci)) != 0)
+          return c;
+      return 2;           /* 2 means give up--shmatch will return false */
+    }
+  }
+
+#ifndef VMS             /* No bracket matching in VMS */
+  /* Parse and process the list of characters and ranges in brackets */
+  if (!no_wild && allow_regex && c == '[')
+  {
+    int e;              /* flag true if next char to be taken literally */
+    ZCONST char *q;     /* pointer to end of [-] group */
+    int r;              /* flag true to match anything but the range */
+
+    if (*s == 0)                        /* need a character to match */
+      return 0;
+    p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+    for (q = p, e = 0; *q; q++)         /* find closing bracket */
+      if (e)
+        e = 0;
+      else
+        if (*q == '\\')
+          e = 1;
+        else if (*q == ']')
+          break;
+    if (*q != ']')                      /* nothing matches if bad syntax */
+      return 0;
+    for (c = 0, e = *p == '-'; p < q; p++)      /* go through the list */
+    {
+      if (e == 0 && *p == '\\')         /* set escape flag if \ */
+        e = 1;
+      else if (e == 0 && *p == '-')     /* set start of range if - */
+        c = *(p-1);
+      else
+      {
+        uch cc = (!ci ? (uch)*s : to_up((uch)*s));
+        uch uc = (uch) c;
+        if (*(p+1) != '-')
+          for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+            /* compare range */
+            if ((!ci ? uc : to_up(uc)) == cc)
+              return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), ci);
+        c = e = 0;                      /* clear range, escape flags */
+      }
+    }
+    return r ? recmatch(q + CLEN(q), s + CLEN(s), ci) : 0;
+                                        /* bracket match failed */
+  }
+#endif /* !VMS */
+
+  /* If escape ('\'), just compare next character */
+  if (!no_wild && c == '\\')
+    if ((c = *p++) == '\0')             /* if \ at end, then syntax error */
+      return 0;
+
+#ifdef VMS
+  /* 2005-11-06 SMS.
+     Handle "..." wildcard in p with "." or "]" in s.
+  */
+  if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+   ((*s == '.') || (*s == ']')))
+  {
+    /* Match "...]" with "]".  Continue after "]" in both. */
+    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+
+    /* Else, look for a reduced match in s, until "]" in or end of s. */
+    for (; *s && (*s != ']'); INCSTR(s))
+      if (*s == '.')
+        /* If reduced match, then continue after "..." in p, "." in s. */
+        if ((c = recmatch( (p+ CLEN( p)), s, ci)) != 0)
+          return (int)c;
+
+    /* Match "...]" with "]".  Continue after "]" in both. */
+    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+
+    /* No reduced match.  Quit. */
+    return 2;
+  }
+
+#endif /* def VMS */
+
+  /* Just a character--compare it */
+  return (!ci ? c == *s : to_up((uch)c) == to_up((uch)*s)) ?
+          recmatch(p, s + CLEN(s), ci) : 0;
+}
+
+
+
+
+/*************************************************************************************************/
+static char *isshexp(p)
+ZCONST char *p;
+/* If p is a sh expression, a pointer to the first special character is
+   returned.  Otherwise, NULL is returned. */
+{
+    for (; *p; INCSTR(p))
+        if (*p == '\\' && *(p+1))
+            p++;
+        else if (*p == WILDCHAR || *p == '*' || *p == BEG_RANGE)
+            return (char *)p;
+    return NULL;
+} /* end function isshexp() */
+
+
+
+static int namecmp(s1, s2)
+    ZCONST char *s1, *s2;
+{
+    int d;
+
+    for (;;) {
+        d = (int)ToLower((uch)*s1)
+          - (int)ToLower((uch)*s2);
+
+        if (d || *s1 == 0 || *s2 == 0)
+            return d;
+
+        s1++;
+        s2++;
+    }
+} /* end function namecmp() */
+
+#endif /* !THEOS */
+
+
+
+
+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))
+            ++p;
+#ifdef THEOS
+        else if (*p == '?' || *p == '*' || *p=='#'|| *p == '@')
+#else /* !THEOS */
+#ifdef VMS
+        else if (*p == '%' || *p == '*')
+#else /* !VMS */
+#ifdef AMIGA
+        else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
+#else /* !AMIGA */
+        else if (*p == '?' || *p == '*' || *p == '[')
+#endif /* ?AMIGA */
+#endif /* ?VMS */
+#endif /* ?THEOS */
+#ifdef QDOS
+            return (int)p;
+#else
+            return TRUE;
+#endif
+
+    return FALSE;
+
+} /* end function iswild() */
+
+
+
+
+
+#ifdef TEST_MATCH
+
+#define put(s) {fputs(s,stdout); fflush(stdout);}
+#ifdef main
+#  undef main
+#endif
+
+int main(int argc, char **argv)
+{
+    char pat[256], str[256];
+
+    for (;;) {
+        put("Pattern (return to exit): ");
+        gets(pat);
+        if (!pat[0])
+            break;
+        for (;;) {
+            put("String (return for new pattern): ");
+            gets(str);
+            if (!str[0])
+                break;
+            printf("Case sensitive: %s  insensitive: %s\n",
+              match(str, pat, 0) ? "YES" : "NO",
+              match(str, pat, 1) ? "YES" : "NO");
+        }
+    }
+    EXIT(0);
+}
+
+#endif /* TEST_MATCH */
Index: unzip/create-6.0-slackware-patch/unzip60-new/process.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/process.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/process.c	(revision 5)
@@ -0,0 +1,3170 @@
+/*
+  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
+*/
+/*---------------------------------------------------------------------------
+
+  process.c
+
+  This file contains the top-level routines for processing multiple zipfiles.
+
+  Contains:  process_zipfiles()
+             free_G_buffers()
+             do_seekable()
+             file_size()
+             rec_find()
+             find_ecrec64()
+             find_ecrec()
+             process_zip_cmmnt()
+             process_cdir_file_hdr()
+             get_cdir_ent()
+             process_local_file_hdr()
+             getZip64Data()
+             ef_scan_for_izux()
+             getRISCOSexfield()
+
+  ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+#  ifdef POCKET_UNZIP
+#    include "wince/intrface.h"
+#  else
+#    include "windll/windll.h"
+#  endif
+#endif
+#if defined(DYNALLOC_CRCTAB) || defined(UNICODE_SUPPORT)
+#  include "crc32.h"
+#endif
+
+static int    do_seekable        OF((__GPRO__ int lastchance));
+#ifdef DO_SAFECHECK_2GB
+# ifdef USE_STRM_INPUT
+static zoff_t file_size          OF((FILE *file));
+# else
+static zoff_t file_size          OF((int fh));
+# endif
+#endif /* DO_SAFECHECK_2GB */
+static int    rec_find           OF((__GPRO__ zoff_t, char *, int));
+static int    find_ecrec64       OF((__GPRO__ zoff_t searchlen));
+static int    find_ecrec         OF((__GPRO__ zoff_t searchlen));
+static int    process_zip_cmmnt  OF((__GPRO));
+static int    get_cdir_ent       OF((__GPRO));
+#ifdef IZ_HAVE_UXUIDGID
+static int    read_ux3_value     OF((ZCONST uch *dbuf, unsigned uidgid_sz,
+                                     ulg *p_uidgid));
+#endif /* IZ_HAVE_UXUIDGID */
+
+
+static ZCONST char Far CannotAllocateBuffers[] =
+  "error:  cannot allocate unzip buffers\n";
+
+#ifdef SFX
+   static ZCONST char Far CannotFindMyself[] =
+     "unzipsfx:  cannot find myself! [%s]\n";
+# ifdef CHEAP_SFX_AUTORUN
+   static ZCONST char Far AutorunPrompt[] =
+     "\nAuto-run command: %s\nExecute this command? [y/n] ";
+   static ZCONST char Far NotAutoRunning[] =
+     "Not executing auto-run command.";
+# endif
+
+#else /* !SFX */
+   /* process_zipfiles() strings */
+# if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+     static ZCONST char Far WarnInvalidTZ[] =
+       "Warning: TZ environment variable not found, cannot use UTC times!!\n";
+# endif
+# if !(defined(UNIX) || defined(AMIGA))
+   static ZCONST char Far CannotFindWildcardMatch[] =
+     "%s:  cannot find any matches for wildcard specification \"%s\".\n";
+# endif /* !(UNIX || AMIGA) */
+   static ZCONST char Far FilesProcessOK[] =
+     "%d archive%s successfully processed.\n";
+   static ZCONST char Far ArchiveWarning[] =
+     "%d archive%s had warnings but no fatal errors.\n";
+   static ZCONST char Far ArchiveFatalError[] =
+     "%d archive%s had fatal errors.\n";
+   static ZCONST char Far FileHadNoZipfileDir[] =
+     "%d file%s had no zipfile directory.\n";
+   static ZCONST char Far ZipfileWasDir[] = "1 \"zipfile\" was a directory.\n";
+   static ZCONST char Far ManyZipfilesWereDir[] =
+     "%d \"zipfiles\" were directories.\n";
+   static ZCONST char Far NoZipfileFound[] = "No zipfiles found.\n";
+
+   /* do_seekable() strings */
+# ifdef UNIX
+   static ZCONST char Far CannotFindZipfileDirMsg[] =
+     "%s:  cannot find zipfile directory in one of %s or\n\
+        %s%s.zip, and cannot find %s, period.\n";
+   static ZCONST char Far CannotFindEitherZipfile[] =
+     "%s:  cannot find or open %s, %s.zip or %s.\n";
+# else /* !UNIX */
+   static ZCONST char Far CannotFindZipfileDirMsg[] =
+     "%s:  cannot find zipfile directory in %s,\n\
+        %sand cannot find %s, period.\n";
+# ifdef VMS
+   static ZCONST char Far CannotFindEitherZipfile[] =
+     "%s:  cannot find %s (%s).\n";
+# else /* !VMS */
+   static ZCONST char Far CannotFindEitherZipfile[] =
+     "%s:  cannot find either %s or %s.\n";
+# endif /* ?VMS */
+# endif /* ?UNIX */
+   extern ZCONST char Far Zipnfo[];       /* in unzip.c */
+#ifndef WINDLL
+   static ZCONST char Far Unzip[] = "unzip";
+#else
+   static ZCONST char Far Unzip[] = "UnZip DLL";
+#endif
+#ifdef DO_SAFECHECK_2GB
+   static ZCONST char Far ZipfileTooBig[] =
+     "Trying to read large file (> 2 GiB) without large file support\n";
+#endif /* DO_SAFECHECK_2GB */
+   static ZCONST char Far MaybeExe[] =
+     "note:  %s may be a plain executable, not an archive\n";
+   static ZCONST char Far CentDirNotInZipMsg[] = "\n\
+   [%s]:\n\
+     Zipfile is disk %lu of a multi-disk archive, and this is not the disk on\n\
+     which the central zipfile directory begins (disk %lu).\n";
+   static ZCONST char Far EndCentDirBogus[] =
+     "\nwarning [%s]:  end-of-central-directory record claims this\n\
+  is disk %lu but that the central directory starts on disk %lu; this is a\n\
+  contradiction.  Attempting to process anyway.\n";
+# ifdef NO_MULTIPART
+   static ZCONST char Far NoMultiDiskArcSupport[] =
+     "\nerror [%s]:  zipfile is part of multi-disk archive\n\
+  (sorry, not yet supported).\n";
+   static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+  zipfile claims to be 2nd disk of a 2-part archive;\n\
+  attempting to process anyway.  If no further errors occur, this archive\n\
+  was probably created by PAK v2.51 or earlier.  This bug was reported to\n\
+  NoGate in March 1991 and was supposed to have been fixed by mid-1991; as\n\
+  of mid-1992 it still hadn't been.  (If further errors do occur, archive\n\
+  was probably created by PKZIP 2.04c or later; UnZip does not yet support\n\
+  multi-part archives.)\n";
+# else
+   static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+  zipfile claims to be last disk of a multi-part archive;\n\
+  attempting to process anyway, assuming all parts have been concatenated\n\
+  together in order.  Expect \"errors\" and warnings...true multi-part support\
+\n  doesn't exist yet (coming soon).\n";
+# endif
+   static ZCONST char Far ExtraBytesAtStart[] =
+     "warning [%s]:  %s extra byte%s at beginning or within zipfile\n\
+  (attempting to process anyway)\n";
+#endif /* ?SFX */
+
+#if ((!defined(WINDLL) && !defined(SFX)) || !defined(NO_ZIPINFO))
+   static ZCONST char Far LogInitline[] = "Archive:  %s\n";
+#endif
+
+static ZCONST char Far MissingBytes[] =
+  "error [%s]:  missing %s bytes in zipfile\n\
+  (attempting to process anyway)\n";
+static ZCONST char Far NullCentDirOffset[] =
+  "error [%s]:  NULL central directory offset\n\
+  (attempting to process anyway)\n";
+static ZCONST char Far ZipfileEmpty[] = "warning [%s]:  zipfile is empty\n";
+static ZCONST char Far CentDirStartNotFound[] =
+  "error [%s]:  start of central directory not found;\n\
+  zipfile corrupt.\n%s";
+static ZCONST char Far Cent64EndSigSearchErr[] =
+  "fatal error: read failure while seeking for End-of-centdir-64 signature.\n\
+  This zipfile is corrupt.\n";
+static ZCONST char Far Cent64EndSigSearchOff[] =
+  "error: End-of-centdir-64 signature not where expected (prepended bytes?)\n\
+  (attempting to process anyway)\n";
+#ifndef SFX
+   static ZCONST char Far CentDirTooLong[] =
+     "error [%s]:  reported length of central directory is\n\
+  %s bytes too long (Atari STZip zipfile?  J.H.Holm ZIPSPLIT 1.1\n\
+  zipfile?).  Compensating...\n";
+   static ZCONST char Far CentDirEndSigNotFound[] = "\
+  End-of-central-directory signature not found.  Either this file is not\n\
+  a zipfile, or it constitutes one disk of a multi-part archive.  In the\n\
+  latter case the central directory and zipfile comment will be found on\n\
+  the last disk(s) of this archive.\n";
+#else /* SFX */
+   static ZCONST char Far CentDirEndSigNotFound[] =
+     "  End-of-central-directory signature not found.\n";
+#endif /* ?SFX */
+#ifdef TIMESTAMP
+   static ZCONST char Far ZipTimeStampFailed[] =
+     "warning:  cannot set time for %s\n";
+   static ZCONST char Far ZipTimeStampSuccess[] =
+     "Updated time stamp for %s.\n";
+#endif
+static ZCONST char Far ZipfileCommTrunc1[] =
+  "\ncaution:  zipfile comment truncated\n";
+#ifndef NO_ZIPINFO
+   static ZCONST char Far NoZipfileComment[] =
+     "There is no zipfile comment.\n";
+   static ZCONST char Far ZipfileCommentDesc[] =
+     "The zipfile comment is %u bytes long and contains the following text:\n";
+   static ZCONST char Far ZipfileCommBegin[] =
+     "======================== zipfile comment begins\
+ ==========================\n";
+   static ZCONST char Far ZipfileCommEnd[] =
+     "========================= zipfile comment ends\
+ ===========================\n";
+   static ZCONST char Far ZipfileCommTrunc2[] =
+     "\n  The zipfile comment is truncated.\n";
+#endif /* !NO_ZIPINFO */
+#ifdef UNICODE_SUPPORT
+   static ZCONST char Far UnicodeVersionError[] =
+     "\nwarning:  Unicode Path version > 1\n";
+   static ZCONST char Far UnicodeMismatchError[] =
+     "\nwarning:  Unicode Path checksum invalid\n";
+   static ZCONST char Far UFilenameTooLongTrunc[] =
+     "warning:  filename too long (P1) -- truncating.\n";
+#endif
+
+
+
+
+/*******************************/
+/* Function process_zipfiles() */
+/*******************************/
+
+int process_zipfiles(__G)    /* return PK-type error code */
+    __GDEF
+{
+#ifndef SFX
+    char *lastzipfn = (char *)NULL;
+    int NumWinFiles, NumLoseFiles, NumWarnFiles;
+    int NumMissDirs, NumMissFiles;
+#endif
+    int error=0, error_in_archive=0;
+
+
+/*---------------------------------------------------------------------------
+    Start by allocating buffers and (re)constructing the various PK signature
+    strings.
+  ---------------------------------------------------------------------------*/
+
+    G.inbuf = (uch *)malloc(INBUFSIZ + 4);    /* 4 extra for hold[] (below) */
+    G.outbuf = (uch *)malloc(OUTBUFSIZ + 1);  /* 1 extra for string term. */
+
+    if ((G.inbuf == (uch *)NULL) || (G.outbuf == (uch *)NULL)) {
+        Info(slide, 0x401, ((char *)slide,
+          LoadFarString(CannotAllocateBuffers)));
+        return(PK_MEM);
+    }
+    G.hold = G.inbuf + INBUFSIZ;     /* to check for boundary-spanning sigs */
+#ifndef VMS     /* VMS uses its own buffer scheme for textmode flush(). */
+#ifdef SMALL_MEM
+    G.outbuf2 = G.outbuf+RAWBUFSIZ;  /* never changes */
+#endif
+#endif /* !VMS */
+
+#if 0 /* CRC_32_TAB has been NULLified by CONSTRUCTGLOBALS !!!! */
+    /* allocate the CRC table later when we know we can read zipfile data */
+    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;
+
+    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;
+
+/*---------------------------------------------------------------------------
+    Make sure timezone info is set correctly; localtime() returns GMT on some
+    OSes (e.g., Solaris 2.x) if this isn't done first.  The ifdefs around
+    tzset() were initially copied from dos_to_unix_time() in fileio.c.  They
+    may still be too strict; any listed OS that supplies tzset(), regardless
+    of whether the function does anything, should be removed from the ifdefs.
+  ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && defined(USE_EF_UT_TIME))
+    /* For the Win32 environment, we may have to "prepare" the environment
+       prior to the tzset() call, to work around tzset() implementation bugs.
+     */
+    iz_w32_prepareTZenv();
+#endif
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+#  ifndef VALID_TIMEZONE
+#     define VALID_TIMEZONE(tmp) \
+             (((tmp = getenv("TZ")) != NULL) && (*tmp != '\0'))
+#  endif
+    {
+        char *p;
+        G.tz_is_valid = VALID_TIMEZONE(p);
+#  ifndef SFX
+        if (!G.tz_is_valid) {
+            Info(slide, 0x401, ((char *)slide, LoadFarString(WarnInvalidTZ)));
+            error_in_archive = error = PK_WARN;
+        }
+#  endif /* !SFX */
+    }
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+/* For systems that do not have tzset() but supply this function using another
+   name (_tzset() or something similar), an appropiate "#define tzset ..."
+   should be added to the system specifc configuration section.  */
+#if (!defined(T20_VMS) && !defined(MACOS) && !defined(RISCOS) && !defined(QDOS))
+#if (!defined(BSD) && !defined(MTS) && !defined(CMS_MVS) && !defined(TANDEM))
+    tzset();
+#endif
+#endif
+
+/* Initialize UnZip's built-in pseudo hard-coded "ISO <--> OEM" translation,
+   depending on the detected codepage setup.  */
+#ifdef NEED_ISO_OEM_INIT
+    prepare_ISO_OEM_translat(__G);
+#endif
+
+/*---------------------------------------------------------------------------
+    Initialize the internal flag holding the mode of processing "overwrite
+    existing file" cases.  We do not use the calling interface flags directly
+    because the overwrite mode may be changed by user interaction while
+    processing archive files.  Such a change should not affect the option
+    settings as passed through the DLL calling interface.
+    In case of conflicting options, the 'safer' flag uO.overwrite_none takes
+    precedence.
+  ---------------------------------------------------------------------------*/
+    G.overwrite_mode = (uO.overwrite_none ? OVERWRT_NEVER :
+                        (uO.overwrite_all ? OVERWRT_ALWAYS : OVERWRT_QUERY));
+
+/*---------------------------------------------------------------------------
+    Match (possible) wildcard zipfile specification with existing files and
+    attempt to process each.  If no hits, try again after appending ".zip"
+    suffix.  If still no luck, give up.
+  ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+    if ((error = do_seekable(__G__ 0)) == PK_NOZIP) {
+#ifdef EXE_EXTENSION
+        int len=strlen(G.argv0);
+
+        /* append .exe if appropriate; also .sfx? */
+        if ( (G.zipfn = (char *)malloc(len+sizeof(EXE_EXTENSION))) !=
+             (char *)NULL ) {
+            strcpy(G.zipfn, G.argv0);
+            strcpy(G.zipfn+len, EXE_EXTENSION);
+            error = do_seekable(__G__ 0);
+            free(G.zipfn);
+            G.zipfn = G.argv0;  /* for "cannot find myself" message only */
+        }
+#endif /* EXE_EXTENSION */
+#ifdef WIN32
+        G.zipfn = G.argv0;  /* for "cannot find myself" message only */
+#endif
+    }
+    if (error) {
+        if (error == IZ_DIR)
+            error_in_archive = PK_NOZIP;
+        else
+            error_in_archive = error;
+        if (error == PK_NOZIP)
+            Info(slide, 1, ((char *)slide, LoadFarString(CannotFindMyself),
+              G.zipfn));
+    }
+#ifdef CHEAP_SFX_AUTORUN
+    if (G.autorun_command[0] && !uO.qflag) { /* NO autorun without prompt! */
+        Info(slide, 0x81, ((char *)slide, LoadFarString(AutorunPrompt),
+                      FnFilter1(G.autorun_command)));
+        if (fgets(G.answerbuf, 9, stdin) != (char *)NULL
+            && toupper(*G.answerbuf) == 'Y')
+            system(G.autorun_command);
+        else
+            Info(slide, 1, ((char *)slide, LoadFarString(NotAutoRunning)));
+    }
+#endif /* CHEAP_SFX_AUTORUN */
+
+#else /* !SFX */
+    NumWinFiles = NumLoseFiles = NumWarnFiles = 0;
+    NumMissDirs = NumMissFiles = 0;
+
+    while ((G.zipfn = do_wild(__G__ G.wildzipfn)) != (char *)NULL) {
+        Trace((stderr, "do_wild( %s ) returns %s\n", G.wildzipfn, G.zipfn));
+
+        lastzipfn = G.zipfn;
+
+        /* print a blank line between the output of different zipfiles */
+        if (!uO.qflag  &&  error != PK_NOZIP  &&  error != IZ_DIR
+#ifdef TIMESTAMP
+            && (!uO.T_flag || uO.zipinfo_mode)
+#endif
+            && (NumWinFiles+NumLoseFiles+NumWarnFiles+NumMissFiles) > 0)
+            (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+        if ((error = do_seekable(__G__ 0)) == PK_WARN)
+            ++NumWarnFiles;
+        else if (error == IZ_DIR)
+            ++NumMissDirs;
+        else if (error == PK_NOZIP)
+            ++NumMissFiles;
+        else if (error != PK_OK)
+            ++NumLoseFiles;
+        else
+            ++NumWinFiles;
+
+        Trace((stderr, "do_seekable(0) returns %d\n", error));
+        if (error != IZ_DIR && error > error_in_archive)
+            error_in_archive = error;
+#ifdef WINDLL
+        if (error == IZ_CTRLC) {
+            free_G_buffers(__G);
+            return error;
+        }
+#endif
+
+    } /* end while-loop (wildcard zipfiles) */
+
+    if ((NumWinFiles + NumWarnFiles + NumLoseFiles) == 0  &&
+        (NumMissDirs + NumMissFiles) == 1  &&  lastzipfn != (char *)NULL)
+    {
+#if (!defined(UNIX) && !defined(AMIGA)) /* filenames with wildcard characters */
+        if (iswild(G.wildzipfn)) {
+            if (iswild(lastzipfn)) {
+                NumMissDirs = NumMissFiles = 0;
+                error_in_archive = PK_COOL;
+                if (uO.qflag < 3)
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(CannotFindWildcardMatch),
+                      LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                      G.wildzipfn));
+            }
+        } else
+#endif
+        {
+#ifndef VMS
+            /* 2004-11-24 SMS.
+             * VMS has already tried a default file type of ".zip" in
+             * do_wild(), so adding ZSUFX here only causes confusion by
+             * corrupting some valid (though nonexistent) file names.
+             * Complaining below about "fred;4.zip" is unlikely to be
+             * helpful to the victim.
+             */
+            /* 2005-08-14 Chr. Spieler
+             * Although we already "know" the failure result, we call
+             * do_seekable() again with the same zipfile name (and the
+             * lastchance flag set), just to trigger the error report...
+             */
+#if defined(UNIX) || defined(QDOS)
+            char *p =
+#endif
+              strcpy(lastzipfn + strlen(lastzipfn), ZSUFX);
+#endif /* !VMS */
+
+            G.zipfn = lastzipfn;
+
+            NumMissDirs = NumMissFiles = 0;
+            error_in_archive = PK_COOL;
+
+#if defined(UNIX) || defined(QDOS)
+   /* only Unix has case-sensitive filesystems */
+   /* Well FlexOS (sometimes) also has them,  but support is per media */
+   /* and a pig to code for,  so treat as case insensitive for now */
+   /* we do this under QDOS to check for .zip as well as _zip */
+            if ((error = do_seekable(__G__ 0)) == PK_NOZIP || error == IZ_DIR) {
+                if (error == IZ_DIR)
+                    ++NumMissDirs;
+                strcpy(p, ALT_ZSUFX);
+                error = do_seekable(__G__ 1);
+            }
+#else
+            error = do_seekable(__G__ 1);
+#endif
+            Trace((stderr, "do_seekable(1) returns %d\n", error));
+            switch (error) {
+              case PK_WARN:
+                ++NumWarnFiles;
+                break;
+              case IZ_DIR:
+                ++NumMissDirs;
+                error = PK_NOZIP;
+                break;
+              case PK_NOZIP:
+                /* increment again => bug:
+                   "1 file had no zipfile directory." */
+                /* ++NumMissFiles */ ;
+                break;
+              default:
+                if (error)
+                    ++NumLoseFiles;
+                else
+                    ++NumWinFiles;
+                break;
+            }
+
+            if (error > error_in_archive)
+                error_in_archive = error;
+#ifdef WINDLL
+            if (error == IZ_CTRLC) {
+                free_G_buffers(__G);
+                return error;
+            }
+#endif
+        }
+    }
+#endif /* ?SFX */
+
+/*---------------------------------------------------------------------------
+    Print summary of all zipfiles, assuming zipfile spec was a wildcard (no
+    need for a summary if just one zipfile).
+  ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+    if (iswild(G.wildzipfn) && uO.qflag < 3
+#ifdef TIMESTAMP
+        && !(uO.T_flag && !uO.zipinfo_mode && uO.qflag > 1)
+#endif
+                                                    )
+    {
+        if ((NumMissFiles + NumLoseFiles + NumWarnFiles > 0 || NumWinFiles != 1)
+#ifdef TIMESTAMP
+            && !(uO.T_flag && !uO.zipinfo_mode && uO.qflag)
+#endif
+            && !(uO.tflag && uO.qflag > 1))
+            (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0x401);
+        if ((NumWinFiles > 1) ||
+            (NumWinFiles == 1 &&
+             NumMissDirs + NumMissFiles + NumLoseFiles + NumWarnFiles > 0))
+            Info(slide, 0x401, ((char *)slide, LoadFarString(FilesProcessOK),
+              NumWinFiles, (NumWinFiles == 1)? " was" : "s were"));
+        if (NumWarnFiles > 0)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveWarning),
+              NumWarnFiles, (NumWarnFiles == 1)? "" : "s"));
+        if (NumLoseFiles > 0)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveFatalError),
+              NumLoseFiles, (NumLoseFiles == 1)? "" : "s"));
+        if (NumMissFiles > 0)
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(FileHadNoZipfileDir), NumMissFiles,
+              (NumMissFiles == 1)? "" : "s"));
+        if (NumMissDirs == 1)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileWasDir)));
+        else if (NumMissDirs > 0)
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(ManyZipfilesWereDir), NumMissDirs));
+        if (NumWinFiles + NumLoseFiles + NumWarnFiles == 0)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(NoZipfileFound)));
+    }
+#endif /* !SFX */
+
+    /* free allocated memory */
+    free_G_buffers(__G);
+
+    return error_in_archive;
+
+} /* end function process_zipfiles() */
+
+
+
+
+
+/*****************************/
+/* Function free_G_buffers() */
+/*****************************/
+
+void free_G_buffers(__G)     /* releases all memory allocated in global vars */
+    __GDEF
+{
+#ifndef SFX
+    unsigned i;
+#endif
+
+#ifdef SYSTEM_SPECIFIC_DTOR
+    SYSTEM_SPECIFIC_DTOR(__G);
+#endif
+
+    inflate_free(__G);
+    checkdir(__G__ (char *)NULL, END);
+
+#ifdef DYNALLOC_CRCTAB
+    if (CRC_32_TAB) {
+        free_crc_table();
+        CRC_32_TAB = NULL;
+    }
+#endif
+
+   if (G.key != (char *)NULL) {
+        free(G.key);
+        G.key = (char *)NULL;
+   }
+
+   if (G.extra_field != (uch *)NULL) {
+        free(G.extra_field);
+        G.extra_field = (uch *)NULL;
+   }
+
+#if (!defined(VMS) && !defined(SMALL_MEM))
+    /* VMS uses its own buffer scheme for textmode flush() */
+    if (G.outbuf2) {
+        free(G.outbuf2);   /* malloc'd ONLY if unshrink and -a */
+        G.outbuf2 = (uch *)NULL;
+    }
+#endif
+
+    if (G.outbuf)
+        free(G.outbuf);
+    if (G.inbuf)
+        free(G.inbuf);
+    G.inbuf = G.outbuf = (uch *)NULL;
+
+#ifdef UNICODE_SUPPORT
+    if (G.filename_full) {
+        free(G.filename_full);
+        G.filename_full = (char *)NULL;
+        G.fnfull_bufsize = 0;
+    }
+#endif /* UNICODE_SUPPORT */
+
+#ifndef SFX
+    for (i = 0; i < DIR_BLKSIZ; i++) {
+        if (G.info[i].cfilname != (char Far *)NULL) {
+            zffree(G.info[i].cfilname);
+            G.info[i].cfilname = (char Far *)NULL;
+        }
+    }
+#endif
+
+#ifdef MALLOC_WORK
+    if (G.area.Slide) {
+        free(G.area.Slide);
+        G.area.Slide = (uch *)NULL;
+    }
+#endif
+
+} /* end function free_G_buffers() */
+
+
+
+
+
+/**************************/
+/* Function do_seekable() */
+/**************************/
+
+static int do_seekable(__G__ lastchance)        /* return PK-type error code */
+    __GDEF
+    int lastchance;
+{
+#ifndef SFX
+    /* static int no_ecrec = FALSE;  SKM: moved to globals.h */
+    int maybe_exe=FALSE;
+    int too_weird_to_continue=FALSE;
+#ifdef TIMESTAMP
+    time_t uxstamp;
+    ulg nmember = 0L;
+#endif
+#endif
+    int error=0, error_in_archive;
+
+
+/*---------------------------------------------------------------------------
+    Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
+    which would corrupt the bit streams.
+  ---------------------------------------------------------------------------*/
+
+    if (SSTAT(G.zipfn, &G.statbuf) ||
+#ifdef THEOS
+        (error = S_ISLIB(G.statbuf.st_mode)) != 0 ||
+#endif
+        (error = S_ISDIR(G.statbuf.st_mode)) != 0)
+    {
+#ifndef SFX
+        if (lastchance && (uO.qflag < 3)) {
+#if defined(UNIX) || defined(QDOS)
+            if (G.no_ecrec)
+                Info(slide, 1, ((char *)slide,
+                  LoadFarString(CannotFindZipfileDirMsg),
+                  LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                  G.wildzipfn, uO.zipinfo_mode? "  " : "", G.wildzipfn,
+                  G.zipfn));
+            else
+                Info(slide, 1, ((char *)slide,
+                  LoadFarString(CannotFindEitherZipfile),
+                  LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                  G.wildzipfn, G.wildzipfn, G.zipfn));
+#else /* !(UNIX || QDOS) */
+            if (G.no_ecrec)
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(CannotFindZipfileDirMsg),
+                  LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                  G.wildzipfn, uO.zipinfo_mode? "  " : "", G.zipfn));
+            else
+#ifdef VMS
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(CannotFindEitherZipfile),
+                  LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                  G.wildzipfn,
+                  (*G.zipfn ? G.zipfn : vms_msg_text())));
+#else /* !VMS */
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(CannotFindEitherZipfile),
+                  LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+                  G.wildzipfn, G.zipfn));
+#endif /* ?VMS */
+#endif /* ?(UNIX || QDOS) */
+        }
+#endif /* !SFX */
+        return error? IZ_DIR : PK_NOZIP;
+    }
+    G.ziplen = G.statbuf.st_size;
+
+#ifndef SFX
+#if defined(UNIX) || defined(DOS_OS2_W32) || defined(THEOS)
+    if (G.statbuf.st_mode & S_IEXEC)   /* no extension on Unix exes:  might */
+        maybe_exe = TRUE;               /*  find unzip, not unzip.zip; etc. */
+#endif
+#endif /* !SFX */
+
+#ifdef VMS
+    if (check_format(__G))              /* check for variable-length format */
+        return PK_ERR;
+#endif
+
+    if (open_input_file(__G))   /* this should never happen, given */
+        return PK_NOZIP;        /*  the stat() test above, but... */
+
+#ifdef DO_SAFECHECK_2GB
+    /* Need more care: Do not trust the size returned by stat() but
+       determine it by reading beyond the end of the file. */
+    G.ziplen = file_size(G.zipfd);
+
+    if (G.ziplen == EOF) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileTooBig)));
+        /*
+        printf(
+" We need a better error message for: 64-bit file, 32-bit program.\n");
+        */
+        CLOSE_INFILE();
+        return IZ_ERRBF;
+    }
+#endif /* DO_SAFECHECK_2GB */
+
+/*---------------------------------------------------------------------------
+    Find and process the end-of-central-directory header.  UnZip need only
+    check last 65557 bytes of zipfile:  comment may be up to 65535, end-of-
+    central-directory record is 18 bytes, and signature itself is 4 bytes;
+    add some to allow for appended garbage.  Since ZipInfo is often used as
+    a debugging tool, search the whole zipfile if zipinfo_mode is true.
+  ---------------------------------------------------------------------------*/
+
+    G.cur_zipfile_bufstart = 0;
+    G.inptr = G.inbuf;
+
+#if ((!defined(WINDLL) && !defined(SFX)) || !defined(NO_ZIPINFO))
+# if (!defined(WINDLL) && !defined(SFX))
+    if ( (!uO.zipinfo_mode && !uO.qflag
+#  ifdef TIMESTAMP
+          && !uO.T_flag
+#  endif
+         )
+#  ifndef NO_ZIPINFO
+         || (uO.zipinfo_mode && uO.hflag)
+#  endif
+       )
+# else /* not (!WINDLL && !SFX) ==> !NO_ZIPINFO !! */
+    if (uO.zipinfo_mode && uO.hflag)
+# endif /* if..else..: (!WINDLL && !SFX) */
+# ifdef WIN32   /* Win32 console may require codepage conversion for G.zipfn */
+        Info(slide, 0, ((char *)slide, LoadFarString(LogInitline),
+          FnFilter1(G.zipfn)));
+# else
+        Info(slide, 0, ((char *)slide, LoadFarString(LogInitline), G.zipfn));
+# endif
+#endif /* (!WINDLL && !SFX) || !NO_ZIPINFO */
+
+    if ( (error_in_archive = find_ecrec(__G__
+#ifndef NO_ZIPINFO
+                                        uO.zipinfo_mode ? G.ziplen :
+#endif
+                                        MIN(G.ziplen, 66000L)))
+         > PK_WARN )
+    {
+        CLOSE_INFILE();
+
+#ifdef SFX
+        ++lastchance;   /* avoid picky compiler warnings */
+        return error_in_archive;
+#else
+        if (maybe_exe)
+            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeExe),
+            G.zipfn));
+        if (lastchance)
+            return error_in_archive;
+        else {
+            G.no_ecrec = TRUE;    /* assume we found wrong file:  e.g., */
+            return PK_NOZIP;       /*  unzip instead of unzip.zip */
+        }
+#endif /* ?SFX */
+    }
+
+    if ((uO.zflag > 0) && !uO.zipinfo_mode) { /* unzip: zflag = comment ONLY */
+        CLOSE_INFILE();
+        return error_in_archive;
+    }
+
+/*---------------------------------------------------------------------------
+    Test the end-of-central-directory info for incompatibilities (multi-disk
+    archives) or inconsistencies (missing or extra bytes in zipfile).
+  ---------------------------------------------------------------------------*/
+
+#ifdef NO_MULTIPART
+    error = !uO.zipinfo_mode && (G.ecrec.number_this_disk == 1) &&
+            (G.ecrec.num_disk_start_cdir == 1);
+#else
+    error = !uO.zipinfo_mode && (G.ecrec.number_this_disk != 0);
+#endif
+
+#ifndef SFX
+    if (uO.zipinfo_mode &&
+        G.ecrec.number_this_disk != G.ecrec.num_disk_start_cdir)
+    {
+        if (G.ecrec.number_this_disk > G.ecrec.num_disk_start_cdir) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(CentDirNotInZipMsg), G.zipfn,
+              (ulg)G.ecrec.number_this_disk,
+              (ulg)G.ecrec.num_disk_start_cdir));
+            error_in_archive = PK_FIND;
+            too_weird_to_continue = TRUE;
+        } else {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(EndCentDirBogus), G.zipfn,
+              (ulg)G.ecrec.number_this_disk,
+              (ulg)G.ecrec.num_disk_start_cdir));
+            error_in_archive = PK_WARN;
+        }
+#ifdef NO_MULTIPART   /* concatenation of multiple parts works in some cases */
+    } else if (!uO.zipinfo_mode && !error && G.ecrec.number_this_disk != 0) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(NoMultiDiskArcSupport),
+          G.zipfn));
+        error_in_archive = PK_FIND;
+        too_weird_to_continue = TRUE;
+#endif
+    }
+
+    if (!too_weird_to_continue) {  /* (relatively) normal zipfile:  go for it */
+        if (error) {
+            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybePakBug),
+              G.zipfn));
+            error_in_archive = PK_WARN;
+        }
+#endif /* !SFX */
+        if ((G.extra_bytes = G.real_ecrec_offset-G.expect_ecrec_offset) <
+            (zoff_t)0)
+        {
+            Info(slide, 0x401, ((char *)slide, LoadFarString(MissingBytes),
+              G.zipfn, FmZofft((-G.extra_bytes), NULL, NULL)));
+            error_in_archive = PK_ERR;
+        } else if (G.extra_bytes > 0) {
+            if ((G.ecrec.offset_start_central_directory == 0) &&
+                (G.ecrec.size_central_directory != 0))   /* zip 1.5 -go bug */
+            {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(NullCentDirOffset), G.zipfn));
+                G.ecrec.offset_start_central_directory = G.extra_bytes;
+                G.extra_bytes = 0;
+                error_in_archive = PK_ERR;
+            }
+#ifndef SFX
+            else {
+                Info(slide, 0x401, ((char *)slide,
+                  LoadFarString(ExtraBytesAtStart), G.zipfn,
+                  FmZofft(G.extra_bytes, NULL, NULL),
+                  (G.extra_bytes == 1)? "":"s"));
+                error_in_archive = PK_WARN;
+            }
+#endif /* !SFX */
+        }
+
+    /*-----------------------------------------------------------------------
+        Check for empty zipfile and exit now if so.
+      -----------------------------------------------------------------------*/
+
+        if (G.expect_ecrec_offset==0L && G.ecrec.size_central_directory==0) {
+            if (uO.zipinfo_mode)
+                Info(slide, 0, ((char *)slide, "%sEmpty zipfile.\n",
+                  uO.lflag>9? "\n  " : ""));
+            else
+                Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileEmpty),
+                                    G.zipfn));
+            CLOSE_INFILE();
+            return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
+        }
+
+    /*-----------------------------------------------------------------------
+        Compensate for missing or extra bytes, and seek to where the start
+        of central directory should be.  If header not found, uncompensate
+        and try again (necessary for at least some Atari archives created
+        with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
+      -----------------------------------------------------------------------*/
+
+        error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+        if (error == PK_BADERR) {
+            CLOSE_INFILE();
+            return PK_BADERR;
+        }
+#ifdef OLD_SEEK_TEST
+        if (error != PK_OK || readbuf(__G__ G.sig, 4) == 0) {
+            CLOSE_INFILE();
+            return PK_ERR;  /* file may be locked, or possibly disk error(?) */
+        }
+        if (memcmp(G.sig, central_hdr_sig, 4))
+#else
+        if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+            memcmp(G.sig, central_hdr_sig, 4))
+#endif
+        {
+#ifndef SFX
+            zoff_t tmp = G.extra_bytes;
+#endif
+
+            G.extra_bytes = 0;
+            error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+            if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+                memcmp(G.sig, central_hdr_sig, 4))
+            {
+                if (error != PK_BADERR)
+                  Info(slide, 0x401, ((char *)slide,
+                    LoadFarString(CentDirStartNotFound), G.zipfn,
+                    LoadFarStringSmall(ReportMsg)));
+                CLOSE_INFILE();
+                return (error != PK_OK ? error : PK_BADERR);
+            }
+#ifndef SFX
+            Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirTooLong),
+              G.zipfn, FmZofft((-tmp), NULL, NULL)));
+#endif
+            error_in_archive = PK_ERR;
+        }
+
+    /*-----------------------------------------------------------------------
+        Seek to the start of the central directory one last time, since we
+        have just read the first entry's signature bytes; then list, extract
+        or test member files as instructed, and close the zipfile.
+      -----------------------------------------------------------------------*/
+
+        error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+        if (error != PK_OK) {
+            CLOSE_INFILE();
+            return error;
+        }
+
+        Trace((stderr, "about to extract/list files (error = %d)\n",
+          error_in_archive));
+
+#ifdef DLL
+        /* G.fValidate is used only to look at an archive to see if
+           it appears to be a valid archive.  There is no interest
+           in what the archive contains, nor in validating that the
+           entries in the archive are in good condition.  This is
+           currently used only in the Windows DLLs for purposes of
+           checking archives within an archive to determine whether
+           or not to display the inner archives.
+         */
+        if (!G.fValidate)
+#endif
+        {
+#ifndef NO_ZIPINFO
+            if (uO.zipinfo_mode)
+                error = zipinfo(__G);                 /* ZIPINFO 'EM */
+            else
+#endif
+#ifndef SFX
+#ifdef TIMESTAMP
+            if (uO.T_flag)
+                error = get_time_stamp(__G__ &uxstamp, &nmember);
+            else
+#endif
+            if (uO.vflag && !uO.tflag && !uO.cflag)
+                error = list_files(__G);              /* LIST 'EM */
+            else
+#endif /* !SFX */
+                error = extract_or_test_files(__G);   /* EXTRACT OR TEST 'EM */
+
+            Trace((stderr, "done with extract/list files (error = %d)\n",
+                   error));
+        }
+
+        if (error > error_in_archive)   /* don't overwrite stronger error */
+            error_in_archive = error;   /*  with (for example) a warning */
+#ifndef SFX
+    } /* end if (!too_weird_to_continue) */
+#endif
+
+    CLOSE_INFILE();
+
+#ifdef TIMESTAMP
+    if (uO.T_flag && !uO.zipinfo_mode && (nmember > 0L)) {
+# ifdef WIN32
+        if (stamp_file(__G__ G.zipfn, uxstamp)) {       /* TIME-STAMP 'EM */
+# else
+        if (stamp_file(G.zipfn, uxstamp)) {             /* TIME-STAMP 'EM */
+# endif
+            if (uO.qflag < 3)
+                Info(slide, 0x201, ((char *)slide,
+                  LoadFarString(ZipTimeStampFailed), G.zipfn));
+            if (error_in_archive < PK_WARN)
+                error_in_archive = PK_WARN;
+        } else {
+            if (!uO.qflag)
+                Info(slide, 0, ((char *)slide,
+                  LoadFarString(ZipTimeStampSuccess), G.zipfn));
+        }
+    }
+#endif
+    return error_in_archive;
+
+} /* end function do_seekable() */
+
+
+
+
+#ifdef DO_SAFECHECK_2GB
+/************************/
+/* Function file_size() */
+/************************/
+/* File size determination which does not mislead for large files in a
+   small-file program.  Probably should be somewhere else.
+   The file has to be opened previously
+*/
+#ifdef USE_STRM_INPUT
+static zoff_t file_size(file)
+    FILE *file;
+{
+    int sts;
+    size_t siz;
+#else /* !USE_STRM_INPUT */
+static zoff_t file_size(fh)
+    int fh;
+{
+    int siz;
+#endif /* ?USE_STRM_INPUT */
+    zoff_t ofs;
+    char waste[4];
+
+#ifdef USE_STRM_INPUT
+    /* Seek to actual EOF. */
+    sts = zfseeko(file, 0, SEEK_END);
+    if (sts != 0) {
+        /* fseeko() failed.  (Unlikely.) */
+        ofs = EOF;
+    } else {
+        /* Get apparent offset at EOF. */
+        ofs = zftello(file);
+        if (ofs < 0) {
+            /* Offset negative (overflow).  File too big. */
+            ofs = EOF;
+        } else {
+            /* Seek to apparent EOF offset.
+               Won't be at actual EOF if offset was truncated.
+            */
+            sts = zfseeko(file, ofs, SEEK_SET);
+            if (sts != 0) {
+                /* fseeko() failed.  (Unlikely.) */
+                ofs = EOF;
+            } else {
+                /* Read a byte at apparent EOF.  Should set EOF flag. */
+                siz = fread(waste, 1, 1, file);
+                if (feof(file) == 0) {
+                    /* Not at EOF, but should be.  File too big. */
+                    ofs = EOF;
+                }
+            }
+        }
+    }
+#else /* !USE_STRM_INPUT */
+    /* Seek to actual EOF. */
+    ofs = zlseek(fh, 0, SEEK_END);
+    if (ofs == (zoff_t) -1) {
+        /* zlseek() failed.  (Unlikely.) */
+        ofs = EOF;
+    } else if (ofs < 0) {
+        /* Offset negative (overflow).  File too big. */
+        ofs = EOF;
+    } else {
+        /* Seek to apparent EOF offset.
+           Won't be at actual EOF if offset was truncated.
+        */
+        ofs = zlseek(fh, ofs, SEEK_SET);
+        if (ofs == (zoff_t) -1) {
+            /* zlseek() failed.  (Unlikely.) */
+            ofs = EOF;
+        } else {
+            /* Read a byte at apparent EOF.  Should set EOF flag. */
+            siz = read(fh, waste, 1);
+            if (siz != 0) {
+                /* Not at EOF, but should be.  File too big. */
+                ofs = EOF;
+            }
+        }
+    }
+#endif /* ?USE_STRM_INPUT */
+    return ofs;
+} /* end function file_size() */
+#endif /* DO_SAFECHECK_2GB */
+
+
+
+
+/***********************/
+/* Function rec_find() */
+/***********************/
+
+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;
+    int rec_size;
+{
+    int i, numblks, found=FALSE;
+    zoff_t tail_len;
+
+/*---------------------------------------------------------------------------
+    Zipfile is longer than INBUFSIZ:  may need to loop.  Start with short
+    block at end of zipfile (if not TOO short).
+  ---------------------------------------------------------------------------*/
+
+    if ((tail_len = G.ziplen % INBUFSIZ) > rec_size) {
+#ifdef USE_STRM_INPUT
+        zfseeko(G.zipfd, G.ziplen-tail_len, SEEK_SET);
+        G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+        G.cur_zipfile_bufstart = zlseek(G.zipfd, G.ziplen-tail_len, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+        if ((G.incnt = read(G.zipfd, (char *)G.inbuf,
+            (unsigned int)tail_len)) != (int)tail_len)
+            return 2;      /* it's expedient... */
+
+        /* 'P' must be at least (rec_size+4) bytes from end of zipfile */
+        for (G.inptr = G.inbuf+(int)tail_len-(rec_size+4);
+             G.inptr >= G.inbuf;
+             --G.inptr) {
+            if ( (*G.inptr == (uch)0x50) &&         /* ASCII 'P' */
+                 !memcmp((char *)G.inptr, signature, 4) ) {
+                G.incnt -= (int)(G.inptr - G.inbuf);
+                found = TRUE;
+                break;
+            }
+        }
+        /* sig may span block boundary: */
+        memcpy((char *)G.hold, (char *)G.inbuf, 3);
+    } else
+        G.cur_zipfile_bufstart = G.ziplen - tail_len;
+
+/*-----------------------------------------------------------------------
+    Loop through blocks of zipfile data, starting at the end and going
+    toward the beginning.  In general, need not check whole zipfile for
+    signature, but may want to do so if testing.
+  -----------------------------------------------------------------------*/
+
+    numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
+    /*               ==amount=   ==done==   ==rounding==    =blksiz=  */
+
+    for (i = 1;  !found && (i <= numblks);  ++i) {
+        G.cur_zipfile_bufstart -= INBUFSIZ;
+#ifdef USE_STRM_INPUT
+        zfseeko(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET);
+#else /* !USE_STRM_INPUT */
+        zlseek(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+        if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ))
+            != INBUFSIZ)
+            return 2;          /* read error is fatal failure */
+
+        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) ) {
+                G.incnt -= (int)(G.inptr - G.inbuf);
+                found = TRUE;
+                break;
+            }
+        /* sig may span block boundary: */
+        memcpy((char *)G.hold, (char *)G.inbuf, 3);
+    }
+    return (found ? 0 : 1);
+} /* end function rec_find() */
+
+
+
+
+#if 0
+/********************************/
+/* Function check_ecrec_zip64() */
+/********************************/
+
+static int check_ecrec_zip64(__G)
+    __GDEF
+{
+    return G.ecrec.offset_start_central_directory  == 0xFFFFFFFFL
+        || G.ecrec.size_central_directory          == 0xFFFFFFFFL
+        || G.ecrec.total_entries_central_dir       == 0xFFFF
+        || G.ecrec.num_entries_centrl_dir_ths_disk == 0xFFFF
+        || G.ecrec.num_disk_start_cdir             == 0xFFFF
+        || G.ecrec.number_this_disk                == 0xFFFF;
+} /* end function check_ecrec_zip64() */
+#endif /* never */
+
+
+
+/***************************/
+/* Function find_ecrec64() */
+/***************************/
+
+static int find_ecrec64(__G__ searchlen)         /* return PK-class error */
+    __GDEF
+    zoff_t searchlen;
+{
+    ec_byte_rec64 byterec;          /* buf for ecrec64 */
+    ec_byte_loc64 byterecL;         /* buf for ecrec64 locator */
+    zoff_t ecloc64_start_offset;    /* start offset of ecrec64 locator */
+    zusz_t ecrec64_start_offset;    /* start offset of ecrec64 */
+    zuvl_t ecrec64_start_disk;      /* start disk of ecrec64 */
+    zuvl_t ecloc64_total_disks;     /* total disks */
+    zuvl_t ecrec64_disk_cdstart;    /* disk number of central dir start */
+    zucn_t ecrec64_this_entries;    /* entries on disk with ecrec64 */
+    zucn_t ecrec64_tot_entries;     /* total number of entries */
+    zusz_t ecrec64_cdirsize;        /* length of central dir */
+    zusz_t ecrec64_offs_cdstart;    /* offset of central dir start */
+
+    /* First, find the ecrec64 locator.  By definition, this must be before
+       ecrec with nothing in between.  We back up the size of the ecrec64
+       locator and check.  */
+
+    ecloc64_start_offset = G.real_ecrec_offset - (ECLOC64_SIZE+4);
+    if (ecloc64_start_offset < 0)
+      /* Seeking would go past beginning, so probably empty archive */
+      return PK_COOL;
+
+#ifdef USE_STRM_INPUT
+    zfseeko(G.zipfd, ecloc64_start_offset, SEEK_SET);
+    G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+    G.cur_zipfile_bufstart = zlseek(G.zipfd, ecloc64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+    if ((G.incnt = read(G.zipfd, (char *)byterecL, ECLOC64_SIZE+4))
+        != (ECLOC64_SIZE+4)) {
+      if (uO.qflag || uO.zipinfo_mode)
+          Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+      Info(slide, 0x401, ((char *)slide,
+        LoadFarString(Cent64EndSigSearchErr)));
+      return PK_ERR;
+    }
+
+    if (memcmp((char *)byterecL, end_centloc64_sig, 4) ) {
+      /* not found */
+      return PK_COOL;
+    }
+
+    /* Read the locator. */
+    ecrec64_start_disk = (zuvl_t)makelong(&byterecL[NUM_DISK_START_EOCDR64]);
+    ecrec64_start_offset = (zusz_t)makeint64(&byterecL[OFFSET_START_EOCDR64]);
+    ecloc64_total_disks = (zuvl_t)makelong(&byterecL[NUM_THIS_DISK_LOC64]);
+
+    /* Check for consistency */
+#ifdef TEST
+    fprintf(stdout,"\nnumber of disks (ECR) %u, (ECLOC64) %lu\n",
+            G.ecrec.number_this_disk, ecloc64_total_disks); fflush(stdout);
+#endif
+    if ((G.ecrec.number_this_disk != 0xFFFF) &&
+        (G.ecrec.number_this_disk != ecloc64_total_disks - 1)) {
+      /* Note: For some unknown reason, the developers at PKWARE decided to
+         store the "zip64 total disks" value as a counter starting from 1,
+         whereas all other "split/span volume" related fields use 0-based
+         volume numbers. Sigh... */
+      /* When the total number of disks as found in the traditional ecrec
+         is not 0xFFFF, the disk numbers in ecrec and ecloc64 must match.
+         When this is not the case, the found ecrec64 locator cannot be valid.
+         -> This is not a Zip64 archive.
+       */
+      Trace((stderr,
+             "\ninvalid ECLOC64, differing disk# (ECR %u, ECL64 %lu)\n",
+             G.ecrec.number_this_disk, ecloc64_total_disks - 1));
+      return PK_COOL;
+    }
+
+    /* If found locator, look for ecrec64 where the locator says it is. */
+
+    /* For now assume that ecrec64 is on the same disk as ecloc64 and ecrec,
+       which is usually the case and is how Zip writes it.  To do this right,
+       however, we should allow the ecrec64 to be on another disk since
+       the AppNote allows it and the ecrec64 can be large, especially if
+       Version 2 is used (AppNote uses 8 bytes for the size of this record). */
+
+    /* FIX BELOW IF ADD SUPPORT FOR MULTIPLE DISKS */
+
+    if (ecrec64_start_offset > (zusz_t)ecloc64_start_offset) {
+      /* ecrec64 has to be before ecrec64 locator */
+      if (uO.qflag || uO.zipinfo_mode)
+          Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+      Info(slide, 0x401, ((char *)slide,
+        LoadFarString(Cent64EndSigSearchErr)));
+      return PK_ERR;
+    }
+
+#ifdef USE_STRM_INPUT
+    zfseeko(G.zipfd, ecrec64_start_offset, SEEK_SET);
+    G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+    G.cur_zipfile_bufstart = zlseek(G.zipfd, ecrec64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+    if ((G.incnt = read(G.zipfd, (char *)byterec, ECREC64_SIZE+4))
+        != (ECREC64_SIZE+4)) {
+      if (uO.qflag || uO.zipinfo_mode)
+          Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+      Info(slide, 0x401, ((char *)slide,
+        LoadFarString(Cent64EndSigSearchErr)));
+      return PK_ERR;
+    }
+
+    if (memcmp((char *)byterec, end_central64_sig, 4) ) {
+      /* Zip64 EOCD Record not found */
+      /* Since we already have seen the Zip64 EOCD Locator, it's
+         possible we got here because there are bytes prepended
+         to the archive, like the sfx prefix. */
+
+      /* Make a guess as to where the Zip64 EOCD Record might be */
+      ecrec64_start_offset = ecloc64_start_offset - ECREC64_SIZE - 4;
+
+#ifdef USE_STRM_INPUT
+      zfseeko(G.zipfd, ecrec64_start_offset, SEEK_SET);
+      G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+      G.cur_zipfile_bufstart = zlseek(G.zipfd, ecrec64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+      if ((G.incnt = read(G.zipfd, (char *)byterec, ECREC64_SIZE+4))
+          != (ECREC64_SIZE+4)) {
+        if (uO.qflag || uO.zipinfo_mode)
+            Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+        Info(slide, 0x401, ((char *)slide,
+          LoadFarString(Cent64EndSigSearchErr)));
+        return PK_ERR;
+      }
+
+      if (memcmp((char *)byterec, end_central64_sig, 4) ) {
+        /* Zip64 EOCD Record not found */
+        /* Probably something not so easy to handle so exit */
+        if (uO.qflag || uO.zipinfo_mode)
+            Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+        Info(slide, 0x401, ((char *)slide,
+          LoadFarString(Cent64EndSigSearchErr)));
+        return PK_ERR;
+      }
+
+      if (uO.qflag || uO.zipinfo_mode)
+          Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+      Info(slide, 0x401, ((char *)slide,
+        LoadFarString(Cent64EndSigSearchOff)));
+    }
+
+    /* Check consistency of found ecrec64 with ecloc64 (and ecrec): */
+    if ( (zuvl_t)makelong(&byterec[NUMBER_THIS_DSK_REC64])
+         != ecrec64_start_disk )
+        /* found ecrec64 does not match ecloc64 info -> no Zip64 archive */
+        return PK_COOL;
+    /* Read all relevant ecrec64 fields and compare them to the corresponding
+       ecrec fields unless those are set to "all-ones".
+     */
+    ecrec64_disk_cdstart =
+      (zuvl_t)makelong(&byterec[NUM_DISK_START_CEN_DIR64]);
+    if ( (G.ecrec.num_disk_start_cdir != 0xFFFF) &&
+         (G.ecrec.num_disk_start_cdir != ecrec64_disk_cdstart) )
+        return PK_COOL;
+    ecrec64_this_entries
+      = makeint64(&byterec[NUM_ENTRIES_CEN_DIR_THS_DISK64]);
+    if ( (G.ecrec.num_entries_centrl_dir_ths_disk != 0xFFFF) &&
+         (G.ecrec.num_entries_centrl_dir_ths_disk != ecrec64_this_entries) )
+        return PK_COOL;
+    ecrec64_tot_entries
+      = makeint64(&byterec[TOTAL_ENTRIES_CENTRAL_DIR64]);
+    if ( (G.ecrec.total_entries_central_dir != 0xFFFF) &&
+         (G.ecrec.total_entries_central_dir != ecrec64_tot_entries) )
+        return PK_COOL;
+    ecrec64_cdirsize
+      = makeint64(&byterec[SIZE_CENTRAL_DIRECTORY64]);
+    if ( (G.ecrec.size_central_directory != 0xFFFFFFFFL) &&
+         (G.ecrec.size_central_directory != ecrec64_cdirsize) )
+        return PK_COOL;
+    ecrec64_offs_cdstart
+      = makeint64(&byterec[OFFSET_START_CENTRAL_DIRECT64]);
+    if ( (G.ecrec.offset_start_central_directory != 0xFFFFFFFFL) &&
+         (G.ecrec.offset_start_central_directory != ecrec64_offs_cdstart) )
+        return PK_COOL;
+
+    /* Now, we are (almost) sure that we have a Zip64 archive. */
+    G.ecrec.have_ecr64 = 1;
+
+    /* Update the "end-of-central-dir offset" for later checks. */
+    G.real_ecrec_offset = ecrec64_start_offset;
+
+    /* Update all ecdir_rec data that are flagged to be invalid
+       in Zip64 mode.  Set the ecrec64-mandatory flag when such a
+       case is found. */
+    if (G.ecrec.number_this_disk == 0xFFFF) {
+      G.ecrec.number_this_disk = ecrec64_start_disk;
+      if (ecrec64_start_disk != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+    if (G.ecrec.num_disk_start_cdir == 0xFFFF) {
+      G.ecrec.num_disk_start_cdir = ecrec64_disk_cdstart;
+      if (ecrec64_disk_cdstart != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+    if (G.ecrec.num_entries_centrl_dir_ths_disk == 0xFFFF) {
+      G.ecrec.num_entries_centrl_dir_ths_disk = ecrec64_this_entries;
+      if (ecrec64_this_entries != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+    if (G.ecrec.total_entries_central_dir == 0xFFFF) {
+      G.ecrec.total_entries_central_dir = ecrec64_tot_entries;
+      if (ecrec64_tot_entries != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+    if (G.ecrec.size_central_directory == 0xFFFFFFFFL) {
+      G.ecrec.size_central_directory = ecrec64_cdirsize;
+      if (ecrec64_cdirsize != 0xFFFFFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+    if (G.ecrec.offset_start_central_directory == 0xFFFFFFFFL) {
+      G.ecrec.offset_start_central_directory = ecrec64_offs_cdstart;
+      if (ecrec64_offs_cdstart != 0xFFFFFFFF) G.ecrec.is_zip64_archive = TRUE;
+    }
+
+    return PK_COOL;
+} /* end function find_ecrec64() */
+
+
+
+/*************************/
+/* Function find_ecrec() */
+/*************************/
+
+static int find_ecrec(__G__ searchlen)          /* return PK-class error */
+    __GDEF
+    zoff_t searchlen;
+{
+    int found = FALSE;
+    int error_in_archive;
+    int result;
+    ec_byte_rec byterec;
+
+/*---------------------------------------------------------------------------
+    Treat case of short zipfile separately.
+  ---------------------------------------------------------------------------*/
+
+    if (G.ziplen <= INBUFSIZ) {
+#ifdef USE_STRM_INPUT
+        zfseeko(G.zipfd, 0L, SEEK_SET);
+#else /* !USE_STRM_INPUT */
+        zlseek(G.zipfd, 0L, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+        if ((G.incnt = read(G.zipfd,(char *)G.inbuf,(unsigned int)G.ziplen))
+            == (int)G.ziplen)
+
+            /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */
+            for (G.inptr = G.inbuf+(int)G.ziplen-(ECREC_SIZE+4);
+                 G.inptr >= G.inbuf;
+                 --G.inptr) {
+                if ( (*G.inptr == (uch)0x50) &&         /* ASCII 'P' */
+                     !memcmp((char *)G.inptr, end_central_sig, 4)) {
+                    G.incnt -= (int)(G.inptr - G.inbuf);
+                    found = TRUE;
+                    break;
+                }
+            }
+
+/*---------------------------------------------------------------------------
+    Zipfile is longer than INBUFSIZ:
+
+    MB - this next block of code moved to rec_find so that same code can be
+    used to look for zip64 ec record.  No need to include code above since
+    a zip64 ec record will only be looked for if it is a BIG file.
+  ---------------------------------------------------------------------------*/
+
+    } else {
+        found =
+          (rec_find(__G__ searchlen, end_central_sig, ECREC_SIZE) == 0
+           ? TRUE : FALSE);
+    } /* end if (ziplen > INBUFSIZ) */
+
+/*---------------------------------------------------------------------------
+    Searched through whole region where signature should be without finding
+    it.  Print informational message and die a horrible death.
+  ---------------------------------------------------------------------------*/
+
+    if (!found) {
+        if (uO.qflag || uO.zipinfo_mode)
+            Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+        Info(slide, 0x401, ((char *)slide,
+          LoadFarString(CentDirEndSigNotFound)));
+        return PK_ERR;   /* failed */
+    }
+
+/*---------------------------------------------------------------------------
+    Found the signature, so get the end-central data before returning.  Do
+    any necessary machine-type conversions (byte ordering, structure padding
+    compensation) by reading data into character array and copying to struct.
+  ---------------------------------------------------------------------------*/
+
+    G.real_ecrec_offset = G.cur_zipfile_bufstart + (G.inptr-G.inbuf);
+#ifdef TEST
+    printf("\n  found end-of-central-dir signature at offset %s (%sh)\n",
+      FmZofft(G.real_ecrec_offset, NULL, NULL),
+      FmZofft(G.real_ecrec_offset, FZOFFT_HEX_DOT_WID, "X"));
+    printf("    from beginning of file; offset %d (%.4Xh) within block\n",
+      G.inptr-G.inbuf, G.inptr-G.inbuf);
+#endif
+
+    if (readbuf(__G__ (char *)byterec, ECREC_SIZE+4) == 0)
+        return PK_EOF;
+
+    G.ecrec.number_this_disk =
+      makeword(&byterec[NUMBER_THIS_DISK]);
+    G.ecrec.num_disk_start_cdir =
+      makeword(&byterec[NUM_DISK_WITH_START_CEN_DIR]);
+    G.ecrec.num_entries_centrl_dir_ths_disk =
+      makeword(&byterec[NUM_ENTRIES_CEN_DIR_THS_DISK]);
+    G.ecrec.total_entries_central_dir =
+      makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
+    G.ecrec.size_central_directory =
+      makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
+    G.ecrec.offset_start_central_directory =
+      makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
+    G.ecrec.zipfile_comment_length =
+      makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
+
+    /* Now, we have to read the archive comment, BEFORE the file pointer
+       is moved away backwards to seek for a Zip64 ECLOC64 structure.
+     */
+    if ( (error_in_archive = process_zip_cmmnt(__G)) > PK_WARN )
+        return error_in_archive;
+
+    /* Next: Check for existence of Zip64 end-of-cent-dir locator
+       ECLOC64. This structure must reside on the same volume as the
+       classic ECREC, at exactly (ECLOC64_SIZE+4) bytes in front
+       of the ECREC.
+       The ECLOC64 structure directs to the longer ECREC64 structure
+       A ECREC64 will ALWAYS exist for a proper Zip64 archive, as
+       the "Version Needed To Extract" field is required to be set
+       to 4.5 or higher whenever any Zip64 features are used anywhere
+       in the archive, so just check for that to see if this is a
+       Zip64 archive.
+     */
+    result = find_ecrec64(__G__ searchlen+76);
+        /* 76 bytes for zip64ec & zip64 locator */
+    if (result != PK_COOL) {
+        if (error_in_archive < result)
+            error_in_archive = result;
+        return error_in_archive;
+    }
+
+    G.expect_ecrec_offset = G.ecrec.offset_start_central_directory +
+                            G.ecrec.size_central_directory;
+
+#ifndef NO_ZIPINFO
+    if (uO.zipinfo_mode) {
+        /* In ZipInfo mode, additional info about the data found in the
+           end-of-central-directory areas is printed out.
+         */
+        zi_end_central(__G);
+    }
+#endif
+
+    return error_in_archive;
+
+} /* end function find_ecrec() */
+
+
+
+
+
+/********************************/
+/* Function process_zip_cmmnt() */
+/********************************/
+
+static int process_zip_cmmnt(__G)       /* return PK-type error code */
+    __GDEF
+{
+    int error = PK_COOL;
+
+
+/*---------------------------------------------------------------------------
+    Get the zipfile comment (up to 64KB long), if any, and print it out.
+  ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+    /* for comment button: */
+    if ((!G.fValidate) && (G.lpUserFunctions != NULL))
+       G.lpUserFunctions->cchComment = G.ecrec.zipfile_comment_length;
+#endif /* WINDLL */
+
+#ifndef NO_ZIPINFO
+    /* ZipInfo, verbose format */
+    if (uO.zipinfo_mode && uO.lflag > 9) {
+        /*-------------------------------------------------------------------
+            Get the zipfile comment, if any, and print it out.
+            (Comment may be up to 64KB long.  May the fleas of a thousand
+            camels infest the arm-pits of anyone who actually takes advantage
+            of this fact.)
+          -------------------------------------------------------------------*/
+
+        if (!G.ecrec.zipfile_comment_length)
+            Info(slide, 0, ((char *)slide, LoadFarString(NoZipfileComment)));
+        else {
+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommentDesc),
+              G.ecrec.zipfile_comment_length));
+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommBegin)));
+            if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY))
+                error = PK_WARN;
+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommEnd)));
+            if (error)
+                Info(slide, 0, ((char *)slide,
+                  LoadFarString(ZipfileCommTrunc2)));
+        } /* endif (comment exists) */
+
+    /* ZipInfo, non-verbose mode:  print zipfile comment only if requested */
+    } else if (G.ecrec.zipfile_comment_length &&
+               (uO.zflag > 0) && uO.zipinfo_mode) {
+        if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(ZipfileCommTrunc1)));
+            error = PK_WARN;
+        }
+    } else
+#endif /* !NO_ZIPINFO */
+    if ( G.ecrec.zipfile_comment_length &&
+         (uO.zflag > 0
+#ifndef WINDLL
+          || (uO.zflag == 0
+# ifndef NO_ZIPINFO
+              && !uO.zipinfo_mode
+# endif
+# ifdef TIMESTAMP
+              && !uO.T_flag
+# endif
+              && !uO.qflag)
+#endif /* !WINDLL */
+         ) )
+    {
+        if (do_string(__G__ G.ecrec.zipfile_comment_length,
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+# ifndef NO_ZIPINFO
+                      (oU.zipinfo_mode ? DISPLAY : CHECK_AUTORUN)
+# else
+                      CHECK_AUTORUN
+# endif
+#else
+                      DISPLAY
+#endif
+                     ))
+        {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(ZipfileCommTrunc1)));
+            error = PK_WARN;
+        }
+    }
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+    else if (G.ecrec.zipfile_comment_length) {
+        if (do_string(__G__ G.ecrec.zipfile_comment_length, CHECK_AUTORUN_Q))
+        {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(ZipfileCommTrunc1)));
+            error = PK_WARN;
+        }
+    }
+#endif
+    return error;
+
+} /* end function process_zip_cmmnt() */
+
+
+
+
+
+/************************************/
+/* Function process_cdir_file_hdr() */
+/************************************/
+
+int process_cdir_file_hdr(__G)    /* return PK-type error code */
+    __GDEF
+{
+    int error;
+
+
+/*---------------------------------------------------------------------------
+    Get central directory info, save host and method numbers, and set flag
+    for lowercase conversion of filename, depending on the OS from which the
+    file is coming.
+  ---------------------------------------------------------------------------*/
+
+    if ((error = get_cdir_ent(__G)) != 0)
+        return error;
+
+    G.pInfo->hostver = G.crec.version_made_by[0];
+    G.pInfo->hostnum = MIN(G.crec.version_made_by[1], NUM_HOSTS);
+/*  extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
+
+    G.pInfo->lcflag = 0;
+    if (uO.L_flag == 1)       /* name conversion for monocase systems */
+        switch (G.pInfo->hostnum) {
+            case FS_FAT_:     /* PKZIP and zip -k store in uppercase */
+            case CPM_:        /* like MS-DOS, right? */
+            case VM_CMS_:     /* all caps? */
+            case MVS_:        /* all caps? */
+            case TANDEM_:
+            case TOPS20_:
+            case VMS_:        /* our Zip uses lowercase, but ASi's doesn't */
+        /*  case Z_SYSTEM_:   ? */
+        /*  case QDOS_:       ? */
+                G.pInfo->lcflag = 1;   /* convert filename to lowercase */
+                break;
+
+            default:     /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, ATARI_, */
+                break;   /*  FS_VFAT_, ATHEOS_, BEOS_ (Z_SYSTEM_), THEOS_: */
+                         /*  no conversion */
+        }
+    else if (uO.L_flag > 1)   /* let -LL force lower case for all names */
+        G.pInfo->lcflag = 1;
+
+    /* do Amigas (AMIGA_) also have volume labels? */
+    if (IS_VOLID(G.crec.external_file_attributes) &&
+        (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
+         G.pInfo->hostnum == FS_NTFS_ || G.pInfo->hostnum == ATARI_))
+    {
+        G.pInfo->vollabel = TRUE;
+        G.pInfo->lcflag = 0;        /* preserve case of volume labels */
+    } else
+        G.pInfo->vollabel = FALSE;
+
+    /* this flag is needed to detect archives made by "PKZIP for Unix" when
+       deciding which kind of codepage conversion has to be applied to
+       strings (see do_string() function in fileio.c) */
+    G.pInfo->HasUxAtt = (G.crec.external_file_attributes & 0xffff0000L) != 0L;
+
+#ifdef UNICODE_SUPPORT
+    /* remember the state of GPB11 (General Purpuse Bit 11) which indicates
+       that the standard path and comment are UTF-8. */
+    G.pInfo->GPFIsUTF8
+        = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
+#endif
+
+#ifdef SYMLINKS
+    /* Initialize the symlink flag, may be set by the platform-specific
+       mapattr function.  */
+    G.pInfo->symlink = 0;
+#endif
+
+    return PK_COOL;
+
+} /* end function process_cdir_file_hdr() */
+
+
+
+
+
+/***************************/
+/* Function get_cdir_ent() */
+/***************************/
+
+static int get_cdir_ent(__G)    /* return PK-type error code */
+    __GDEF
+{
+    cdir_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+    Read the next central directory entry and do any necessary machine-type
+    conversions (byte ordering, structure padding compensation--do so by
+    copying the data from the array into which it was read (byterec) to the
+    usable struct (crec)).
+  ---------------------------------------------------------------------------*/
+
+    if (readbuf(__G__ (char *)byterec, CREC_SIZE) == 0)
+        return PK_EOF;
+
+    G.crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
+    G.crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
+    G.crec.version_needed_to_extract[0] =
+      byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
+    G.crec.version_needed_to_extract[1] =
+      byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
+
+    G.crec.general_purpose_bit_flag =
+      makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
+    G.crec.compression_method =
+      makeword(&byterec[C_COMPRESSION_METHOD]);
+    G.crec.last_mod_dos_datetime =
+      makelong(&byterec[C_LAST_MOD_DOS_DATETIME]);
+    G.crec.crc32 =
+      makelong(&byterec[C_CRC32]);
+    G.crec.csize =
+      makelong(&byterec[C_COMPRESSED_SIZE]);
+    G.crec.ucsize =
+      makelong(&byterec[C_UNCOMPRESSED_SIZE]);
+    G.crec.filename_length =
+      makeword(&byterec[C_FILENAME_LENGTH]);
+    G.crec.extra_field_length =
+      makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
+    G.crec.file_comment_length =
+      makeword(&byterec[C_FILE_COMMENT_LENGTH]);
+    G.crec.disk_number_start =
+      makeword(&byterec[C_DISK_NUMBER_START]);
+    G.crec.internal_file_attributes =
+      makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
+    G.crec.external_file_attributes =
+      makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]);  /* LONG, not word! */
+    G.crec.relative_offset_local_header =
+      makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
+
+    return PK_COOL;
+
+} /* end function get_cdir_ent() */
+
+
+
+
+
+/*************************************/
+/* Function process_local_file_hdr() */
+/*************************************/
+
+int process_local_file_hdr(__G)    /* return PK-type error code */
+    __GDEF
+{
+    local_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+    Read the next local file header and do any necessary machine-type con-
+    versions (byte ordering, structure padding compensation--do so by copy-
+    ing the data from the array into which it was read (byterec) to the
+    usable struct (lrec)).
+  ---------------------------------------------------------------------------*/
+
+    if (readbuf(__G__ (char *)byterec, LREC_SIZE) == 0)
+        return PK_EOF;
+
+    G.lrec.version_needed_to_extract[0] =
+      byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
+    G.lrec.version_needed_to_extract[1] =
+      byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
+
+    G.lrec.general_purpose_bit_flag =
+      makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
+    G.lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
+    G.lrec.last_mod_dos_datetime = makelong(&byterec[L_LAST_MOD_DOS_DATETIME]);
+    G.lrec.crc32 = makelong(&byterec[L_CRC32]);
+    G.lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]);
+    G.lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
+    G.lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
+    G.lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
+
+    if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
+        /* can't trust local header, use central directory: */
+        G.lrec.crc32 = G.pInfo->crc;
+        G.lrec.csize = G.pInfo->compr_size;
+        G.lrec.ucsize = G.pInfo->uncompr_size;
+    }
+
+    G.csize = G.lrec.csize;
+
+    return PK_COOL;
+
+} /* end function process_local_file_hdr() */
+
+
+/*******************************/
+/* Function getZip64Data() */
+/*******************************/
+
+int getZip64Data(__G__ ef_buf, ef_len)
+    __GDEF
+    ZCONST uch *ef_buf; /* buffer containing extra field */
+    unsigned ef_len;    /* total length of extra field */
+{
+    unsigned eb_id;
+    unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+    This function scans the extra field for zip64 information, ie 8-byte
+    versions of compressed file size, uncompressed file size, relative offset
+    and a 4-byte version of disk start number.
+    Sets both local header and central header fields.  Not terribly clever,
+    but it means that this procedure is only called in one place.
+
+    2014-12-05 SMS.  (oCERT.org report.)  CVE-2014-8141.
+    Added checks to ensure that enough data are available before calling
+    makeint64() or makelong().  Replaced various sizeof() values with
+    simple ("4" or "8") constants.  (The Zip64 structures do not depend
+    on our variable sizes.)  Error handling is crude, but we should now
+    stay within the buffer.
+  ---------------------------------------------------------------------------*/
+
+#define Z64FLGS 0xffff
+#define Z64FLGL 0xffffffff
+
+    if (ef_len == 0 || ef_buf == NULL)
+        return PK_COOL;
+
+    Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
+      ef_len));
+
+    while (ef_len >= EB_HEADSIZE)
+    {
+        eb_id = makeword(EB_ID + ef_buf);
+        eb_len = makeword(EB_LEN + ef_buf);
+
+        if (eb_len > (ef_len - EB_HEADSIZE))
+        {
+            /* Extra block length exceeds remaining extra field length. */
+            Trace((stderr,
+              "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+
+        if (eb_id == EF_PKSZ64)
+        {
+          unsigned offset = EB_HEADSIZE;
+
+          if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
+            offset += 8;
+          }
+
+          if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
+            offset += 8;
+          }
+
+          if (G.crec.relative_offset_local_header == Z64FLGL)
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
+            offset += 8;
+          }
+
+          if (G.crec.disk_number_start == Z64FLGS)
+          {
+            if (offset+ 4 > ef_len)
+              return PK_ERR;
+
+            G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
+            offset += 4;
+          }
+#if 0
+          break;                /* Expect only one EF_PKSZ64 block. */
+#endif /* 0 */
+        }
+
+        /* Skip this extra field block. */
+        ef_buf += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+
+    return PK_COOL;
+} /* end function getZip64Data() */
+
+
+#ifdef UNICODE_SUPPORT
+
+/*******************************/
+/* Function getUnicodeData() */
+/*******************************/
+
+int getUnicodeData(__G__ ef_buf, ef_len)
+    __GDEF
+    ZCONST uch *ef_buf; /* buffer containing extra field */
+    unsigned ef_len;    /* total length of extra field */
+{
+    unsigned eb_id;
+    unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+    This function scans the extra field for Unicode information, ie UTF-8
+    path extra fields.
+
+    On return, G.unipath_filename =
+        NULL, if no Unicode path extra field or error
+        "", if the standard path is UTF-8 (free when done)
+        null-terminated UTF-8 path (free when done)
+    Return PK_COOL if no error.
+  ---------------------------------------------------------------------------*/
+
+    G.unipath_filename = NULL;
+
+    if (ef_len == 0 || ef_buf == NULL)
+        return PK_COOL;
+
+    Trace((stderr,"\ngetUnicodeData: scanning extra field of length %u\n",
+      ef_len));
+
+    while (ef_len >= EB_HEADSIZE) {
+        eb_id = makeword(EB_ID + ef_buf);
+        eb_len = makeword(EB_LEN + ef_buf);
+
+        if (eb_len > (ef_len - EB_HEADSIZE)) {
+            /* discovered some extra field inconsistency! */
+            Trace((stderr,
+              "getUnicodeData: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+        if (eb_id == EF_UNIPATH) {
+
+          unsigned offset = EB_HEADSIZE;
+          ush ULen = eb_len - 5;
+          ulg chksum = CRCVAL_INITIAL;
+
+          /* version */
+          G.unipath_version = (uch) *(offset + ef_buf);
+          offset += 1;
+          if (G.unipath_version > 1) {
+            /* can do only version 1 */
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(UnicodeVersionError)));
+            return PK_ERR;
+          }
+
+          /* filename CRC */
+          G.unipath_checksum = makelong(offset + ef_buf);
+          offset += 4;
+
+          if (!G.filename_full) {
+            /* Check if we have a unicode extra section but no filename set */
+            return PK_ERR;
+          }
+
+          /*
+           * Compute 32-bit crc
+           */
+
+          chksum = crc32(chksum, (uch *)(G.filename_full),
+                         strlen(G.filename_full));
+
+          /* If the checksums's don't match then likely filename has been
+           * modified and the Unicode Path is no longer valid.
+           */
+          if (chksum != G.unipath_checksum) {
+            Info(slide, 0x401, ((char *)slide,
+              LoadFarString(UnicodeMismatchError)));
+            if (G.unicode_mismatch == 1) {
+              /* warn and continue */
+            } else if (G.unicode_mismatch == 2) {
+              /* ignore and continue */
+            } else if (G.unicode_mismatch == 0) {
+            }
+            return PK_ERR;
+          }
+
+          /* UTF-8 Path */
+          if ((G.unipath_filename = malloc(ULen + 1)) == NULL) {
+            return PK_ERR;
+          }
+          if (ULen == 0) {
+            /* standard path is UTF-8 so use that */
+            G.unipath_filename[0] = '\0';
+          } else {
+            /* UTF-8 path */
+            strncpy(G.unipath_filename,
+                    (ZCONST char *)(offset + ef_buf), ULen);
+            G.unipath_filename[ULen] = '\0';
+          }
+        }
+
+        /* Skip this extra field block */
+        ef_buf += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+
+    return PK_COOL;
+} /* end function getUnicodeData() */
+
+
+
+
+#ifdef UNICODE_WCHAR
+  /*---------------------------------------------
+ * Unicode conversion functions
+ *
+ * Based on functions provided by Paul Kienitz
+ *
+ *---------------------------------------------
+ */
+
+/*
+   NOTES APPLICABLE TO ALL STRING FUNCTIONS:
+
+   All of the x_to_y functions take parameters for an output buffer and
+   its available length, and return an int.  The value returned is the
+   length of the string that the input produces, which may be larger than
+   the provided buffer length.  If the returned value is less than the
+   buffer length, then the contents of the buffer will be null-terminated;
+   otherwise, it will not be terminated and may be invalid, possibly
+   stopping in the middle of a multibyte sequence.
+
+   In all cases you may pass NULL as the buffer and/or 0 as the length, if
+   you just want to learn how much space the string is going to require.
+
+   The functions will return -1 if the input is invalid UTF-8 or cannot be
+   encoded as UTF-8.
+*/
+
+static int utf8_char_bytes OF((ZCONST char *utf8));
+static ulg ucs4_char_from_utf8 OF((ZCONST char **utf8));
+static int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *ucs4buf,
+                                   int buflen));
+
+/* utility functions for managing UTF-8 and UCS-4 strings */
+
+
+/* utf8_char_bytes
+ *
+ * Returns the number of bytes used by the first character in a UTF-8
+ * string, or -1 if the UTF-8 is invalid or null.
+ */
+static int utf8_char_bytes(utf8)
+  ZCONST char *utf8;
+{
+  int      t, r;
+  unsigned lead;
+
+  if (!utf8)
+    return -1;          /* no input */
+  lead = (unsigned char) *utf8;
+  if (lead < 0x80)
+    r = 1;              /* an ascii-7 character */
+  else if (lead < 0xC0)
+    return -1;          /* error: trailing byte without lead byte */
+  else if (lead < 0xE0)
+    r = 2;              /* an 11 bit character */
+  else if (lead < 0xF0)
+    r = 3;              /* a 16 bit character */
+  else if (lead < 0xF8)
+    r = 4;              /* a 21 bit character (the most currently used) */
+  else if (lead < 0xFC)
+    r = 5;              /* a 26 bit character (shouldn't happen) */
+  else if (lead < 0xFE)
+    r = 6;              /* a 31 bit character (shouldn't happen) */
+  else
+    return -1;          /* error: invalid lead byte */
+  for (t = 1; t < r; t++)
+    if ((unsigned char) utf8[t] < 0x80 || (unsigned char) utf8[t] >= 0xC0)
+      return -1;        /* error: not enough valid trailing bytes */
+  return r;
+}
+
+
+/* ucs4_char_from_utf8
+ *
+ * Given a reference to a pointer into a UTF-8 string, returns the next
+ * UCS-4 character and advances the pointer to the next character sequence.
+ * Returns ~0 (= -1 in twos-complement notation) and does not advance the
+ * pointer when input is ill-formed.
+ */
+static ulg ucs4_char_from_utf8(utf8)
+  ZCONST char **utf8;
+{
+  ulg  ret;
+  int  t, bytes;
+
+  if (!utf8)
+    return ~0L;                         /* no input */
+  bytes = utf8_char_bytes(*utf8);
+  if (bytes <= 0)
+    return ~0L;                         /* invalid input */
+  if (bytes == 1)
+    ret = **utf8;                       /* ascii-7 */
+  else
+    ret = **utf8 & (0x7F >> bytes);     /* lead byte of a multibyte sequence */
+  (*utf8)++;
+  for (t = 1; t < bytes; t++)           /* consume trailing bytes */
+    ret = (ret << 6) | (*((*utf8)++) & 0x3F);
+  return (zwchar) ret;
+}
+
+
+#if 0 /* currently unused */
+/* utf8_from_ucs4_char - Convert UCS char to UTF-8
+ *
+ * Returns the number of bytes put into utf8buf to represent ch, from 1 to 6,
+ * or -1 if ch is too large to represent.  utf8buf must have room for 6 bytes.
+ */
+static int utf8_from_ucs4_char(utf8buf, ch)
+  char *utf8buf;
+  ulg ch;
+{
+  int trailing = 0;
+  int leadmask = 0x80;
+  int leadbits = 0x3F;
+  int tch = ch;
+  int ret;
+
+  if (ch > 0x7FFFFFFFL)
+    return -1;                /* UTF-8 can represent 31 bits */
+  if (ch < 0x7F)
+  {
+    *utf8buf++ = (char) ch;   /* ascii-7 */
+    return 1;
+  }
+  do {
+    trailing++;
+    leadmask = (leadmask >> 1) | 0x80;
+    leadbits >>= 1;
+    tch >>= 6;
+  } while (tch & ~leadbits);
+  ret = trailing + 1;
+  /* produce lead byte */
+  *utf8buf++ = (char) (leadmask | (ch >> (6 * trailing)));
+  while (--trailing >= 0)
+    /* produce trailing bytes */
+    *utf8buf++ = (char) (0x80 | ((ch >> (6 * trailing)) & 0x3F));
+  return ret;
+}
+#endif /* unused */
+
+
+/*===================================================================*/
+
+/* utf8_to_ucs4_string - convert UTF-8 string to UCS string
+ *
+ * Return UCS count.  Now returns int so can return -1.
+ */
+static int utf8_to_ucs4_string(utf8, ucs4buf, buflen)
+  ZCONST char *utf8;
+  ulg *ucs4buf;
+  int buflen;
+{
+  int count = 0;
+
+  for (;;)
+  {
+    ulg ch = ucs4_char_from_utf8(&utf8);
+    if (ch == ~0L)
+      return -1;
+    else
+    {
+      if (ucs4buf && count < buflen)
+        ucs4buf[count] = ch;
+      if (ch == 0)
+        return count;
+      count++;
+    }
+  }
+}
+
+
+#if 0 /* currently unused */
+/* ucs4_string_to_utf8
+ *
+ *
+ */
+static int ucs4_string_to_utf8(ucs4, utf8buf, buflen)
+  ZCONST ulg *ucs4;
+  char *utf8buf;
+  int buflen;
+{
+  char mb[6];
+  int  count = 0;
+
+  if (!ucs4)
+    return -1;
+  for (;;)
+  {
+    int mbl = utf8_from_ucs4_char(mb, *ucs4++);
+    int c;
+    if (mbl <= 0)
+      return -1;
+    /* We could optimize this a bit by passing utf8buf + count */
+    /* directly to utf8_from_ucs4_char when buflen >= count + 6... */
+    c = buflen - count;
+    if (mbl < c)
+      c = mbl;
+    if (utf8buf && count < buflen)
+      strncpy(utf8buf + count, mb, c);
+    if (mbl == 1 && !mb[0])
+      return count;           /* terminating nul */
+    count += mbl;
+  }
+}
+
+
+/* utf8_chars
+ *
+ * Wrapper: counts the actual unicode characters in a UTF-8 string.
+ */
+static int utf8_chars(utf8)
+  ZCONST char *utf8;
+{
+  return utf8_to_ucs4_string(utf8, NULL, 0);
+}
+#endif /* unused */
+
+/* --------------------------------------------------- */
+/* Unicode Support
+ *
+ * These functions common for all Unicode ports.
+ *
+ * These functions should allocate and return strings that can be
+ * freed with free().
+ *
+ * 8/27/05 EG
+ *
+ * Use zwchar for wide char which is unsigned long
+ * in zip.h and 32 bits.  This avoids problems with
+ * different sizes of wchar_t.
+ */
+
+#if 0 /* currently unused */
+/* is_ascii_string
+ * Checks if a string is all ascii
+ */
+int is_ascii_string(mbstring)
+  ZCONST char *mbstring;
+{
+  char *p;
+  uch c;
+
+  for (p = mbstring; c = (uch)*p; p++) {
+    if (c > 0x7F) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* local to UTF-8 */
+char *local_to_utf8_string(local_string)
+  ZCONST char *local_string;
+{
+  return wide_to_utf8_string(local_to_wide_string(local_string));
+}
+# endif /* unused */
+
+/* wide_to_escape_string
+   provides a string that represents a wide char not in local char set
+
+   An initial try at an algorithm.  Suggestions welcome.
+
+   According to the standard, Unicode character points are restricted to
+   the number range from 0 to 0x10FFFF, respective 21 bits.
+   For a hexadecimal notation, 2 octets are sufficient for the mostly
+   used characters from the "Basic Multilingual Plane", all other
+   Unicode characters can be represented by 3 octets (= 6 hex digits).
+   The Unicode standard suggests to write Unicode character points
+   as 4 resp. 6 hex digits, preprended by "U+".
+   (e.g.: U+10FFFF for the highest character point, or U+0030 for the ASCII
+   digit "0")
+
+   However, for the purpose of escaping non-ASCII chars in an ASCII character
+   stream, the "U" is not a very good escape initializer. Therefore, we
+   use the following convention within our Info-ZIP code:
+
+   If not an ASCII char probably need 2 bytes at least.  So if
+   a 2-byte wide encode it as 4 hex digits with a leading #U.  If
+   needs 3 bytes then prefix the string with #L.  So
+   #U1234
+   is a 2-byte wide character with bytes 0x12 and 0x34 while
+   #L123456
+   is a 3-byte wide character with bytes 0x12, 0x34, 0x56.
+   On Windows, wide that need two wide characters need to be converted
+   to a single number.
+  */
+
+ /* set this to the max bytes an escape can be */
+#define MAX_ESCAPE_BYTES 8
+
+char *wide_to_escape_string(wide_char)
+  zwchar wide_char;
+{
+  int i;
+  zwchar w = wide_char;
+  uch b[sizeof(zwchar)];
+  char d[3];
+  char e[11];
+  int len;
+  char *r;
+
+  /* fill byte array with zeros */
+  memzero(b, sizeof(zwchar));
+  /* get bytes in right to left order */
+  for (len = 0; w; len++) {
+    b[len] = (char)(w % 0x100);
+    w /= 0x100;
+  }
+  strcpy(e, "#");
+  /* either 2 bytes or 3 bytes */
+  if (len <= 2) {
+    len = 2;
+    strcat(e, "U");
+  } else {
+    strcat(e, "L");
+  }
+  for (i = len - 1; i >= 0; i--) {
+    sprintf(d, "%02x", b[i]);
+    strcat(e, d);
+  }
+  if ((r = malloc(strlen(e) + 1)) == NULL) {
+    return NULL;
+  }
+  strcpy(r, e);
+  return r;
+}
+
+#if 0 /* currently unused */
+/* returns the wide character represented by the escape string */
+zwchar escape_string_to_wide(escape_string)
+  ZCONST char *escape_string;
+{
+  int i;
+  zwchar w;
+  char c;
+  int len;
+  ZCONST char *e = escape_string;
+
+  if (e == NULL) {
+    return 0;
+  }
+  if (e[0] != '#') {
+    /* no leading # */
+    return 0;
+  }
+  len = strlen(e);
+  /* either #U1234 or #L123456 format */
+  if (len != 6 && len != 8) {
+    return 0;
+  }
+  w = 0;
+  if (e[1] == 'L') {
+    if (len != 8) {
+      return 0;
+    }
+    /* 3 bytes */
+    for (i = 2; i < 8; i++) {
+      c = e[i];
+      if (c < '0' || c > '9') {
+        return 0;
+      }
+      w = w * 0x10 + (zwchar)(c - '0');
+    }
+  } else if (e[1] == 'U') {
+    /* 2 bytes */
+    for (i = 2; i < 6; i++) {
+      c = e[i];
+      if (c < '0' || c > '9') {
+        return 0;
+      }
+      w = w * 0x10 + (zwchar)(c - '0');
+    }
+  }
+  return w;
+}
+#endif /* unused */
+
+#ifndef WIN32  /* WIN32 supplies a special variant of this function */
+/* 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 b;
+  int state_dependent;
+  int wsize = 0;
+  int max_bytes = MB_CUR_MAX;
+  char buf[ MB_CUR_MAX + 1];  /* ("+1" not really needed?) */
+  char *buffer = NULL;
+  char *local_string = NULL;
+  size_t buffer_size;         /* CVE-2022-0529 */
+
+  for (wsize = 0; wide_string[wsize]; wsize++) ;
+
+  if (max_bytes < MAX_ESCAPE_BYTES)
+    max_bytes = MAX_ESCAPE_BYTES;
+
+  buffer_size = wsize * max_bytes + 1; /* Reused below. */
+  if ((buffer = (char *)malloc(buffer_size)) == NULL) {
+    return NULL;
+  }
+
+  /* convert it */
+  buffer[0] = '\0';
+  /* set initial state if state-dependent encoding */
+  wc = (wchar_t)'a';
+  b = wctomb(NULL, wc);
+  if (b == 0)
+    state_dependent = 0;
+  else
+    state_dependent = 1;
+  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];
+    }
+    b = wctomb(buf, wc);
+    if (escape_all) {
+      if (b == 1 && (uch)buf[0] <= 0x7f) {
+        /* ASCII */
+        strncat(buffer, buf, b);
+      } else {
+        /* use escape for wide character */
+        char *escape_string = wide_to_escape_string(wide_string[i]);
+        strcat(buffer, escape_string);
+        free(escape_string);
+      }
+    } else if (b > 0) {
+      /* multi-byte char */
+      strncat(buffer, buf, b);
+    } else {
+      /* no MB for this wide */
+        /* use escape for wide character */
+        size_t buffer_len;
+        size_t escape_string_len;
+        char *escape_string;
+        int err_msg = 0;
+
+        escape_string = wide_to_escape_string(wide_string[i]);
+        buffer_len = strlen( buffer);
+        escape_string_len = strlen( escape_string);
+
+        /* Append escape string, as space allows. */
+        /* 2022-07-18 SMS, et al.  CVE-2022-0529 */
+        if (escape_string_len > buffer_size- buffer_len- 1)
+        {
+            escape_string_len = buffer_size- buffer_len- 1;
+            if (err_msg == 0)
+            {
+                err_msg = 1;
+                Info(slide, 0x401, ((char *)slide,
+                 LoadFarString( UFilenameTooLongTrunc)));
+            }
+        }
+        strncat( buffer, escape_string, escape_string_len);
+        free(escape_string);
+    }
+  }
+  if ((local_string = (char *)malloc(strlen(buffer) + 1)) != NULL) {
+    strcpy(local_string, buffer);
+  }
+  free(buffer);
+
+  return local_string;
+}
+#endif /* !WIN32 */
+
+#if 0 /* currently unused */
+/* convert local string to display character set string */
+char *local_to_display_string(local_string)
+  ZCONST char *local_string;
+{
+  char *display_string;
+
+  /* For Windows, OEM string should never be bigger than ANSI string, says
+     CharToOem description.
+     For all other ports, just make a copy of local_string.
+  */
+  if ((display_string = (char *)malloc(strlen(local_string) + 1)) == NULL) {
+    return NULL;
+  }
+
+  strcpy(display_string, local_string);
+
+#ifdef EBCDIC
+  {
+    char *ebc;
+
+    if ((ebc = malloc(strlen(display_string) + 1)) ==  NULL) {
+      return NULL;
+    }
+    strtoebc(ebc, display_string);
+    free(display_string);
+    display_string = ebc;
+  }
+#endif
+
+  return display_string;
+}
+#endif /* unused */
+
+/* UTF-8 to local */
+char *utf8_to_local_string(utf8_string, escape_all)
+  ZCONST char *utf8_string;
+  int escape_all;
+{
+  zwchar *wide;
+  char *loc = NULL;
+
+  wide = utf8_to_wide_string( utf8_string);
+
+  /* 2022-07-25 SMS, et al.  CVE-2022-0530 */
+  if (wide != NULL)
+  {
+    loc = wide_to_local_string( wide, escape_all);
+    free( wide);
+  }
+
+  return loc;
+}
+
+#if 0 /* currently unused */
+/* convert multi-byte character string to wide character string */
+zwchar *local_to_wide_string(local_string)
+  ZCONST char *local_string;
+{
+  int wsize;
+  wchar_t *wc_string;
+  zwchar *wide_string;
+
+  /* for now try to convert as string - fails if a bad char in string */
+  wsize = mbstowcs(NULL, local_string, strlen(local_string) + 1);
+  if (wsize == (size_t)-1) {
+    /* could not convert */
+    return NULL;
+  }
+
+  /* convert it */
+  if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) {
+    return NULL;
+  }
+  wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1);
+  wc_string[wsize] = (wchar_t) 0;
+
+  /* in case wchar_t is not zwchar */
+  if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) {
+    return NULL;
+  }
+  for (wsize = 0; wide_string[wsize] = (zwchar)wc_string[wsize]; wsize++) ;
+  wide_string[wsize] = (zwchar) 0;
+  free(wc_string);
+
+  return wide_string;
+}
+
+
+/* convert wide string to UTF-8 */
+char *wide_to_utf8_string(wide_string)
+  ZCONST zwchar *wide_string;
+{
+  int mbcount;
+  char *utf8_string;
+
+  /* get size of utf8 string */
+  mbcount = ucs4_string_to_utf8(wide_string, NULL, 0);
+  if (mbcount == -1)
+    return NULL;
+  if ((utf8_string = (char *) malloc(mbcount + 1)) == NULL) {
+    return NULL;
+  }
+  mbcount = ucs4_string_to_utf8(wide_string, utf8_string, mbcount + 1);
+  if (mbcount == -1)
+    return NULL;
+
+  return utf8_string;
+}
+#endif /* unused */
+
+/* convert UTF-8 string to wide string */
+zwchar *utf8_to_wide_string(utf8_string)
+  ZCONST char *utf8_string;
+{
+  int wcount;
+  zwchar *wide_string;
+
+  wcount = utf8_to_ucs4_string(utf8_string, NULL, 0);
+  if (wcount == -1)
+    return NULL;
+  if ((wide_string = (zwchar *) malloc((wcount + 1) * sizeof(zwchar)))
+      == NULL) {
+    return NULL;
+  }
+  wcount = utf8_to_ucs4_string(utf8_string, wide_string, wcount + 1);
+
+  return wide_string;
+}
+
+#endif /* UNICODE_WCHAR */
+#endif /* UNICODE_SUPPORT */
+
+
+
+
+
+#ifdef USE_EF_UT_TIME
+
+#ifdef IZ_HAVE_UXUIDGID
+static int read_ux3_value(dbuf, uidgid_sz, p_uidgid)
+    ZCONST uch *dbuf;   /* buffer a uid or gid value */
+    unsigned uidgid_sz; /* size of uid/gid value */
+    ulg *p_uidgid;      /* return storage: uid or gid value */
+{
+    zusz_t uidgid64;
+
+    switch (uidgid_sz) {
+      case 2:
+        *p_uidgid = (ulg)makeword(dbuf);
+        break;
+      case 4:
+        *p_uidgid = (ulg)makelong(dbuf);
+        break;
+      case 8:
+        uidgid64 = makeint64(dbuf);
+#ifndef LARGE_FILE_SUPPORT
+        if (uidgid64 == (zusz_t)0xffffffffL)
+            return FALSE;
+#endif
+        *p_uidgid = (ulg)uidgid64;
+        if ((zusz_t)(*p_uidgid) != uidgid64)
+            return FALSE;
+        break;
+    }
+    return TRUE;
+}
+#endif /* IZ_HAVE_UXUIDGID */
+
+
+/*******************************/
+/* Function ef_scan_for_izux() */
+/*******************************/
+
+unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
+                          z_utim, z_uidgid)
+    ZCONST uch *ef_buf; /* buffer containing extra field */
+    unsigned ef_len;    /* total length of extra field */
+    int ef_is_c;        /* flag indicating "is central extra field" */
+    ulg dos_mdatetime;  /* last_mod_file_date_time in DOS format */
+    iztimes *z_utim;    /* return storage: atime, mtime, ctime */
+    ulg *z_uidgid;      /* return storage: uid and gid */
+{
+    unsigned flags = 0;
+    unsigned eb_id;
+    unsigned eb_len;
+    int have_new_type_eb = 0;
+    long i_time;        /* buffer for Unix style 32-bit integer time value */
+#ifdef TIME_T_TYPE_DOUBLE
+    int ut_in_archive_sgn = 0;
+#else
+    int ut_zip_unzip_compatible = FALSE;
+#endif
+
+/*---------------------------------------------------------------------------
+    This function scans the extra field for EF_TIME, EF_IZUNIX2, EF_IZUNIX, or
+    EF_PKUNIX blocks containing Unix-style time_t (GMT) values for the entry's
+    access, creation, and modification time.
+    If a valid block is found, the time stamps are copied to the iztimes
+    structure (provided the z_utim pointer is not NULL).
+    If a IZUNIX2 block is found or the IZUNIX block contains UID/GID fields,
+    and the z_uidgid array pointer is valid (!= NULL), the owner info is
+    transfered as well.
+    The presence of an EF_TIME or EF_IZUNIX2 block results in ignoring all
+    data from probably present obsolete EF_IZUNIX blocks.
+    If multiple blocks of the same type are found, only the information from
+    the last block is used.
+    The return value is a combination of the EF_TIME Flags field with an
+    additional flag bit 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))
+        return 0;
+
+    TTrace((stderr,"\nef_scan_for_izux: scanning extra field of length %u\n",
+      ef_len));
+
+    while (ef_len >= EB_HEADSIZE) {
+        eb_id = makeword(EB_ID + ef_buf);
+        eb_len = makeword(EB_LEN + ef_buf);
+
+        if (eb_len > (ef_len - EB_HEADSIZE)) {
+            /* discovered some extra field inconsistency! */
+            TTrace((stderr,
+              "ef_scan_for_izux: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+
+        switch (eb_id) {
+          case EF_TIME:
+            flags &= ~0x0ff;    /* ignore previous IZUNIX or EF_TIME fields */
+            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);
+                if ((flags & EB_UT_FL_MTIME)) {
+                    if ((eb_idx+4) <= eb_len) {
+                        i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+                        eb_idx += 4;
+                        TTrace((stderr,"  UT e.f. modification time = %ld\n",
+                                i_time));
+
+#ifdef TIME_T_TYPE_DOUBLE
+                        if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                            if (dos_mdatetime == DOSTIME_MINIMUM) {
+                              ut_in_archive_sgn = -1;
+                              z_utim->mtime =
+                                (time_t)((long)i_time | (~(long)0x7fffffffL));
+                            } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+                              ut_in_archive_sgn = 1;
+                              z_utim->mtime =
+                                (time_t)((ulg)i_time & (ulg)0xffffffffL);
+                            } else {
+                              ut_in_archive_sgn = 0;
+                              /* cannot determine sign of mtime;
+                                 without modtime: ignore complete UT field */
+                              flags &= ~0x0ff;  /* no time_t times available */
+                              TTrace((stderr,
+                                "  UT modtime range error; ignore e.f.!\n"));
+                              break;            /* stop scanning this field */
+                            }
+                        } else {
+                            /* cannot determine, safe assumption is FALSE */
+                            ut_in_archive_sgn = 0;
+                            z_utim->mtime = (time_t)i_time;
+                        }
+#else /* !TIME_T_TYPE_DOUBLE */
+                        if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                            ut_zip_unzip_compatible =
+                              ((time_t)0x80000000L < (time_t)0L)
+                              ? (dos_mdatetime == DOSTIME_MINIMUM)
+                              : (dos_mdatetime >= DOSTIME_2038_01_18);
+                            if (!ut_zip_unzip_compatible) {
+                              /* UnZip interprets mtime differently than Zip;
+                                 without modtime: ignore complete UT field */
+                              flags &= ~0x0ff;  /* no time_t times available */
+                              TTrace((stderr,
+                                "  UT modtime range error; ignore e.f.!\n"));
+                              break;            /* stop scanning this field */
+                            }
+                        } else {
+                            /* cannot determine, safe assumption is FALSE */
+                            ut_zip_unzip_compatible = FALSE;
+                        }
+                        z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+                    } else {
+                        flags &= ~EB_UT_FL_MTIME;
+                        TTrace((stderr,"  UT e.f. truncated; no modtime\n"));
+                    }
+                }
+                if (ef_is_c) {
+                    break;      /* central version of TIME field ends here */
+                }
+
+                if (flags & EB_UT_FL_ATIME) {
+                    if ((eb_idx+4) <= eb_len) {
+                        i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+                        eb_idx += 4;
+                        TTrace((stderr,"  UT e.f. access time = %ld\n",
+                                i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+                        if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                            if (ut_in_archive_sgn == -1)
+                              z_utim->atime =
+                                (time_t)((long)i_time | (~(long)0x7fffffffL));
+                            } else if (ut_in_archive_sgn == 1) {
+                              z_utim->atime =
+                                (time_t)((ulg)i_time & (ulg)0xffffffffL);
+                            } else {
+                              /* sign of 32-bit time is unknown -> ignore it */
+                              flags &= ~EB_UT_FL_ATIME;
+                              TTrace((stderr,
+                                "  UT access time range error: skip time!\n"));
+                            }
+                        } else {
+                            z_utim->atime = (time_t)i_time;
+                        }
+#else /* !TIME_T_TYPE_DOUBLE */
+                        if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+                            !ut_zip_unzip_compatible) {
+                            flags &= ~EB_UT_FL_ATIME;
+                            TTrace((stderr,
+                              "  UT access time range error: skip time!\n"));
+                        } else {
+                            z_utim->atime = (time_t)i_time;
+                        }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+                    } else {
+                        flags &= ~EB_UT_FL_ATIME;
+                    }
+                }
+                if (flags & EB_UT_FL_CTIME) {
+                    if ((eb_idx+4) <= eb_len) {
+                        i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+                        TTrace((stderr,"  UT e.f. creation time = %ld\n",
+                                i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+                        if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                            if (ut_in_archive_sgn == -1)
+                              z_utim->ctime =
+                                (time_t)((long)i_time | (~(long)0x7fffffffL));
+                            } else if (ut_in_archive_sgn == 1) {
+                              z_utim->ctime =
+                                (time_t)((ulg)i_time & (ulg)0xffffffffL);
+                            } else {
+                              /* sign of 32-bit time is unknown -> ignore it */
+                              flags &= ~EB_UT_FL_CTIME;
+                              TTrace((stderr,
+                              "  UT creation time range error: skip time!\n"));
+                            }
+                        } else {
+                            z_utim->ctime = (time_t)i_time;
+                        }
+#else /* !TIME_T_TYPE_DOUBLE */
+                        if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+                            !ut_zip_unzip_compatible) {
+                            flags &= ~EB_UT_FL_CTIME;
+                            TTrace((stderr,
+                              "  UT creation time range error: skip time!\n"));
+                        } else {
+                            z_utim->ctime = (time_t)i_time;
+                        }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+                    } else {
+                        flags &= ~EB_UT_FL_CTIME;
+                    }
+                }
+            }
+            break;
+
+          case EF_IZUNIX2:
+            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 &= 0x0ff;
+            }
+#ifdef IZ_HAVE_UXUIDGID
+            if (have_new_type_eb > 1)
+                break;          /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
+            if (eb_len == EB_UX2_MINLEN && z_uidgid != NULL) {
+                z_uidgid[0] = (ulg)makeword((EB_HEADSIZE+EB_UX2_UID) + ef_buf);
+                z_uidgid[1] = (ulg)makeword((EB_HEADSIZE+EB_UX2_GID) + ef_buf);
+                flags |= EB_UX2_VALID;   /* signal success */
+            }
+#endif
+            break;
+
+          case EF_IZUNIX3:
+            /* new 3rd generation Unix ef */
+            have_new_type_eb = 2;
+
+            /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
+            flags &= 0x0ff;
+        /*
+          Version       1 byte      version of this extra field, currently 1
+          UIDSize       1 byte      Size of UID field
+          UID           Variable    UID for this entry
+          GIDSize       1 byte      Size of GID field
+          GID           Variable    GID for this entry
+        */
+
+#ifdef IZ_HAVE_UXUIDGID
+            if ((eb_len >= EB_UX3_MINLEN)
+                && (z_uidgid != NULL)
+                && ((*((EB_HEADSIZE + 0) + ef_buf) == 1)))
+                    /* only know about version 1 */
+            {
+                uch uid_size;
+                uch gid_size;
+
+                uid_size = *((EB_HEADSIZE + 1) + ef_buf);
+                gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
+
+                if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+                                    uid_size, &z_uidgid[0])
+                    &&
+                     read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
+                                    gid_size, &z_uidgid[1]) )
+                {
+                    flags |= EB_UX2_VALID;   /* signal success */
+                }
+            }
+#endif /* IZ_HAVE_UXUIDGID */
+            break;
+
+          case EF_IZUNIX:
+          case EF_PKUNIX:       /* PKUNIX e.f. layout is identical to IZUNIX */
+            if (eb_len >= EB_UX_MINLEN) {
+                TTrace((stderr,"ef_scan_for_izux: found %s extra field\n",
+                        (eb_id == EF_IZUNIX ? "IZUNIX" : "PKUNIX")));
+                if (have_new_type_eb > 0) {
+                    break;      /* Ignore IZUNIX extra field block ! */
+                }
+                if (z_utim != NULL) {
+                    flags |= (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
+                    i_time = (long)makelong((EB_HEADSIZE+EB_UX_MTIME)+ef_buf);
+                    TTrace((stderr,"  Unix EF modtime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+                    if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                        if (dos_mdatetime == DOSTIME_MINIMUM) {
+                            ut_in_archive_sgn = -1;
+                            z_utim->mtime =
+                              (time_t)((long)i_time | (~(long)0x7fffffffL));
+                        } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+                            ut_in_archive_sgn = 1;
+                            z_utim->mtime =
+                              (time_t)((ulg)i_time & (ulg)0xffffffffL);
+                        } else {
+                            ut_in_archive_sgn = 0;
+                            /* cannot determine sign of mtime;
+                               without modtime: ignore complete UT field */
+                            flags &= ~0x0ff;    /* no time_t times available */
+                            TTrace((stderr,
+                                  "  UX modtime range error: ignore e.f.!\n"));
+                        }
+                    } else {
+                        /* cannot determine, safe assumption is FALSE */
+                        ut_in_archive_sgn = 0;
+                        z_utim->mtime = (time_t)i_time;
+                    }
+#else /* !TIME_T_TYPE_DOUBLE */
+                    if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                        ut_zip_unzip_compatible =
+                          ((time_t)0x80000000L < (time_t)0L)
+                          ? (dos_mdatetime == DOSTIME_MINIMUM)
+                          : (dos_mdatetime >= DOSTIME_2038_01_18);
+                        if (!ut_zip_unzip_compatible) {
+                            /* UnZip interpretes mtime differently than Zip;
+                               without modtime: ignore complete UT field */
+                            flags &= ~0x0ff;    /* no time_t times available */
+                            TTrace((stderr,
+                                  "  UX modtime range error: ignore e.f.!\n"));
+                        }
+                    } else {
+                        /* cannot determine, safe assumption is FALSE */
+                        ut_zip_unzip_compatible = FALSE;
+                    }
+                    z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+                    i_time = (long)makelong((EB_HEADSIZE+EB_UX_ATIME)+ef_buf);
+                    TTrace((stderr,"  Unix EF actime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+                    if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+                        if (ut_in_archive_sgn == -1)
+                            z_utim->atime =
+                              (time_t)((long)i_time | (~(long)0x7fffffffL));
+                        } else if (ut_in_archive_sgn == 1) {
+                            z_utim->atime =
+                              (time_t)((ulg)i_time & (ulg)0xffffffffL);
+                        } else if (flags & 0x0ff) {
+                            /* sign of 32-bit time is unknown -> ignore it */
+                            flags &= ~EB_UT_FL_ATIME;
+                            TTrace((stderr,
+                                "  UX access time range error: skip time!\n"));
+                        }
+                    } else {
+                        z_utim->atime = (time_t)i_time;
+                    }
+#else /* !TIME_T_TYPE_DOUBLE */
+                    if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+                        !ut_zip_unzip_compatible && (flags & 0x0ff)) {
+                        /* atime not in range of UnZip's time_t */
+                        flags &= ~EB_UT_FL_ATIME;
+                        TTrace((stderr,
+                                "  UX access time range error: skip time!\n"));
+                    } else {
+                        z_utim->atime = (time_t)i_time;
+                    }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+                }
+#ifdef IZ_HAVE_UXUIDGID
+                if (eb_len >= EB_UX_FULLSIZE && z_uidgid != NULL) {
+                    z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX_UID) + ef_buf);
+                    z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX_GID) + ef_buf);
+                    flags |= EB_UX2_VALID;
+                }
+#endif /* IZ_HAVE_UXUIDGID */
+            }
+            break;
+
+          default:
+            break;
+        }
+
+        /* Skip this extra field block */
+        ef_buf += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+
+    return flags;
+}
+
+#endif /* USE_EF_UT_TIME */
+
+
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+
+#define SPARKID_2 0x30435241    /* = "ARC0" */
+
+/*******************************/
+/* Function getRISCOSexfield() */
+/*******************************/
+
+zvoid *getRISCOSexfield(ef_buf, ef_len)
+    ZCONST uch *ef_buf; /* buffer containing extra field */
+    unsigned ef_len;    /* total length of extra field */
+{
+    unsigned eb_id;
+    unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+    This function scans the extra field for a Acorn SPARK filetype ef-block.
+    If a valid block is found, the function returns a pointer to the start
+    of the SPARK_EF block in the extra field buffer.  Otherwise, a NULL
+    pointer is returned.
+  ---------------------------------------------------------------------------*/
+
+    if (ef_len == 0 || ef_buf == NULL)
+        return NULL;
+
+    Trace((stderr,"\ngetRISCOSexfield: scanning extra field of length %u\n",
+      ef_len));
+
+    while (ef_len >= EB_HEADSIZE) {
+        eb_id = makeword(EB_ID + ef_buf);
+        eb_len = makeword(EB_LEN + ef_buf);
+
+        if (eb_len > (ef_len - EB_HEADSIZE)) {
+            /* discovered some extra field inconsistency! */
+            Trace((stderr,
+              "getRISCOSexfield: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+
+        if (eb_id == EF_SPARK && (eb_len == 24 || eb_len == 20)) {
+            if (makelong(EB_HEADSIZE + ef_buf) == SPARKID_2) {
+                /* Return a pointer to the valid SPARK filetype ef block */
+                return (zvoid *)ef_buf;
+            }
+        }
+
+        /* Skip this extra field block */
+        ef_buf += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+
+    return NULL;
+}
+
+#endif /* (RISCOS || ACORN_FTYPE_NFS) */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/configure
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/configure	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/configure	(revision 5)
@@ -0,0 +1,669 @@
+:
+#!/bin/sh -x
+# The above : is necessary on some buggy systems.
+
+# configure: Guess values for system-dependent variables
+# Output the flag definitions to the file "flags".
+# Parameters: $1 = $(CC), $2 = $(CFLAGS), $3 = $(IZ_BZIP2)
+# To construct unzip automatically using this file, type
+# "make -f unix/Makefile generic".
+# If this fails, then type "make list" to get a list of special targets.
+
+trap "rm -f conftest* core a.out; exit 1" 1 2 3 15
+
+CC=${1-cc}
+CFLAGS=${2}
+CFLAGSR=${CFLAGS}
+IZ_BZIP2=${3}
+CFLAGS="${CFLAGS} -I. -DUNIX"
+LFLAGS1=""
+LFLAGS2="-s"
+LN="ln -s"
+
+CFLAGS_OPT=''
+CFLAGS_BZ=''
+BZLF=''
+
+echo "Check C compiler operation"
+cat > conftest.c << _EOF_
+int main()
+{
+   return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c
+status=$?
+if test $status -ne 0; then
+  echo ''
+  echo "C compiler \"${CC}\" does not work as expected."
+  echo "Failing command was: $CC $CFLAGS -c conftest.c"
+  exit $status
+else
+  echo '  Ok'
+fi
+
+echo 'Check C compiler type (optimization options)'
+# Sun C?
+cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __SUNPRO_C
+   bad code
+#endif
+   return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+if test $? -eq 0; then
+  CFLAGS_OPT='-xO3'
+  echo "  Sun C ($CFLAGS_OPT)"
+else
+  # Tru64 DEC/Compaq/HP C?
+  cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __DECC
+   bad code
+#endif
+   return 0;
+}
+_EOF_
+  $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+  if test $? -eq 0; then
+    CFLAGS_OPT='-O3'
+    echo "  DEC C ($CFLAGS_OPT)"
+  else
+    # HP-UX HP C?
+    cat > conftest.c << _EOF_
+int main()
+{
+#ifdef __GNUC__
+   bad code
+#endif
+#ifndef __hpux
+   bad code
+#endif
+   return 0;
+}
+_EOF_
+    $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+    if test $? -eq 0; then
+      # HP-UX, not GCC.  Lame bundled or real ANSI compiler?
+      CFLAGS_OPT_TRY="+O3 +Onolimit"
+      $CC $CFLAGS $CFLAGS_OPT_TRY -c conftest.c 2>&1 | \
+       grep '(Bundled)' > /dev/null
+      if test $? -ne 0; then
+        CFLAGS_OPT="$CFLAGS_OPT_TRY"
+        echo "  HP-UX ANSI C ($CFLAGS_OPT)"
+      else
+        echo '  HP-UX Bundled C (no opt)'
+      fi
+    else
+      # GNU C?
+      cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __GNUC__
+   bad code
+#endif
+   return 0;
+}
+_EOF_
+      $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+      if test $? -eq 0; then
+        CFLAGS_OPT='-O3'
+        echo "  GNU C ($CFLAGS_OPT)"
+	# Special Mac OS X shared library "ld" option?
+        if test ` uname -s 2> /dev/null ` = 'Darwin'; then
+          lf='-Wl,-search_paths_first'
+          $CC $CFLAGS $lf conftest.c > /dev/null 2>/dev/null
+          if test $? -eq 0; then
+            BZLF=${lf}
+          fi
+          rm -f conftest
+        fi
+      else
+        CFLAGS_OPT='-O'
+        echo "  Other-unknown C ($CFLAGS_OPT)"
+      fi
+    fi
+  fi
+fi
+
+# optimization flags
+if test -n "${CFLAGS_OPT}"; then
+  CFLAGSR="${CFLAGSR} ${CFLAGS_OPT}"
+  CFLAGS_BZ="${CFLAGS_BZ} ${CFLAGS_OPT}"
+fi
+
+echo Check for the C preprocessor
+# on SVR4, cc -E does not produce correct assembler files. Need /lib/cpp.
+CPP="${CC} -E"
+# solaris as(1) needs -P, maybe others as well ?
+[ -f /usr/ccs/lib/cpp ] && CPP="/usr/ccs/lib/cpp -P"
+[ -f /usr/lib/cpp ] && CPP=/usr/lib/cpp
+[ -f /lib/cpp ] && CPP=/lib/cpp
+[ -f /usr/bin/cpp ] && CPP=/usr/bin/cpp
+[ -f /xenix ] && CPP="${CC} -E"
+[ -f /lynx.os ] && CPP="${CC} -E"
+
+echo "#include <stdio.h>" > conftest.c
+$CPP conftest.c >/dev/null 2>/dev/null || CPP="${CC} -E"
+
+echo Check if we can use asm code
+CRC32OA=""
+if eval "$CPP crc_i386.S > _crc_i386.s 2>/dev/null"; then
+  if test ! -s _crc_i386.s || grep error < _crc_i386.s > /dev/null; then
+    :
+  elif eval "$CC -c _crc_i386.s >/dev/null 2>/dev/null" && [ -f _crc_i386.o ]; then
+    CFLAGSR="${CFLAGSR} -DASM_CRC"
+    CRC32OA="crc_gcc.o"
+    echo "int foo() { return 0;}" > conftest.c
+    $CC -c conftest.c >/dev/null 2>/dev/null
+    echo Check if compiler generates underlines
+    nm conftest.o | grep "(^|[^_])foo" >/dev/null 2>/dev/null
+    [ $? -eq 0 ] && CPP="${CPP} -DNO_UNDERLINE"
+  fi
+fi
+rm -f _crc_i386.s _crc_i386.o
+
+# ANSI options for compilers that don't have __STDC__ defined by default
+# Currently HPUX, pyramid, Dynix, AIX, OSF/1 and ultrix
+
+echo Check for ANSI options
+cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __STDC__
+   forget it
+#endif
+   return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  for OPT in "-Aa -D_HPUX_SOURCE" -Xa -qlanglvl=ansi -std1 -std
+  do
+    $CC $CFLAGS $OPT -c conftest.c > /dev/null 2>/dev/null
+    [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} ${OPT}" && break
+  done
+fi
+
+echo Check for prototypes
+echo "int main(int argc, char *argv[]) { return 0; }" > conftest.c
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_PROTO"
+
+# const check currently handles mips cc and non ANSI compilers.
+# does it need more ?
+echo Check the handling of const
+cat > conftest.c << _EOF_
+typedef int charset[2];
+int main()
+{
+  const charset x;
+  const char *foo;
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_CONST"
+
+echo Check for time_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+#include <time.h>
+int main()
+{
+  time_t t;
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_TIME_T"
+
+echo Check for size_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+int main()
+{
+  size_t s;
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_SIZE_T"
+
+echo Check for off_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+int main()
+{
+  off_t s;
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_OFF_T"
+
+# Added 11/4/2003 EG
+# Revised 8/12/04 EG
+# Now we set the 64-bit file environment and check the size of off_t
+echo Check for Large File Support
+cat > conftest.c << _EOF_
+# define _LARGEFILE_SOURCE       /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64       /* select default interface as 64 bit */
+# define _LARGE_FILES        /* some OSes need this for 64-bit off_t */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+int main()
+{
+  off_t offset;
+  struct stat s;
+  /* see if have 64-bit off_t */
+  if (sizeof(offset) < 8)
+    return 1;
+  printf("  off_t is %d bytes\n", sizeof(off_t));
+  /* see if have 64-bit stat */
+  if (sizeof(s.st_size) < 8) {
+    printf("  s.st_size is %d bytes\n", sizeof(s.st_size));
+    return 2;
+  }
+  return 3;
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  echo -- no Large File Support
+else
+# run it
+  ./conftest
+  r=$?
+  if [ $r -eq 1 ]; then
+    echo -- no Large File Support - no 64-bit off_t
+  elif [ $r -eq 2 ]; then
+    echo -- no Large File Support - no 64-bit stat
+  elif [ $r -eq 3 ]; then
+    echo -- yes we have Large File Support!
+    CFLAGSR="${CFLAGSR} -DLARGE_FILE_SUPPORT"
+  else
+    echo -- no Large File Support - conftest returned $r
+  fi
+fi
+
+# Added 11/24/2005 EG
+# Check for wide char for Unicode support
+echo Check for wide char support
+cat > conftest.c << _EOF_
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+int main()
+{
+  size_t wsize;
+  wchar_t *wide_string;
+
+  if ((wide_string = (wchar_t *)malloc(4 * sizeof(wchar_t))) == NULL) {
+    return 0;
+  }
+  /* get wide string */
+  wsize = mbstowcs(wide_string, "foo", 3);
+  wide_string[wsize] = (wchar_t) NULL;
+#ifndef __STDC_ISO_10646__
+  return 1;
+#else
+  printf("  __STDC_ISO_10646__ = %d\n", __STDC_ISO_10646__);
+  return 2;
+#endif
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  echo "-- no Unicode (wchar_t) support"
+else
+# have wide char support
+# run it
+  ./conftest
+  r=$?
+  if [ $r -eq 0 ]; then
+    echo -- no Unicode wchar_t support - wchar_t allocation error
+  elif [ $r -eq 1 ]; then
+    echo -- no Unicode support - wchar_t encoding unspecified
+  elif [ $r -eq 2 ]; then
+    echo -- have wchar_t with known UCS encoding - enabling Unicode support!
+    CFLAGSR="${CFLAGSR} -DUNICODE_SUPPORT -DUNICODE_WCHAR"
+  else
+    echo "-- no Unicode (wchar_t) support - conftest returned $r"
+  fi
+fi
+
+echo "Check for setlocale support (needed for UNICODE Native check)"
+cat > conftest.c << _EOF_
+#include <locale.h>
+int main()
+{
+  char *loc = setlocale(LC_CTYPE, "");
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+if [ $? -eq 0 ]; then
+  echo "-- have setlocale, can check for charset type"
+  echo "--  - enabling UTF8-native support!"
+  CFLAGSR="${CFLAGSR} -DUNICODE_SUPPORT -DUTF8_MAYBE_NATIVE"
+else
+  echo "-- no Unicode (UTF-8 native) support!"
+  CFLAGSR="${CFLAGSR} -DNO_SETLOCALE"
+fi
+
+# from configure 2.4i (Onno) 12/5/04
+echo Check for gcc no-builtin flag
+# -fno-builtin since version 2
+cat > conftest.c << _EOF_
+int main()
+{
+#if __GNUC__ >= 2
+   return 0;
+#else
+   forget it
+#endif
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -eq 0 ] && BFLAG="-fno-builtin"
+
+# Check for missing functions
+# add NO_'function_name' to flags if missing
+for func in fchmod fchown lchown nl_langinfo
+do
+  echo Check for $func
+  echo "int main(){ $func(); return 0; }" > conftest.c
+  $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null
+  [ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_`echo $func | tr '[a-z]' '[A-Z]'`"
+done
+
+# Check (seriously) for a working lchmod.
+echo 'Check for lchmod'
+temp_file="/tmp/unzip_test_$$"
+temp_link="link_$$"
+( echo '#include <unistd.h>' ; \
+  echo "int main() { lchmod(\"${temp_file}\", 0666); }" \
+) > conftest.c
+ln -s "${temp_link}" "${temp_file}" && \
+ $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null && \
+ ./conftest
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_LCHMOD"
+rm -f "${temp_file}"
+
+echo Check for memset
+echo "int main(){ char k; memset(&k,0,0); return 0; }" > conftest.c
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DZMEM"
+
+echo Check for errno declaration
+cat > conftest.c << _EOF_
+#include <errno.h>
+main()
+{
+  errno = 0;
+  return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_ERRNO"
+
+echo Check for directory libraries
+cat > conftest.c << _EOF_
+int main() { return closedir(opendir(".")); }
+_EOF_
+
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  OPT=""
+  for lib in ndir dir ucb bsd BSD PW x dirent
+  do
+    $CC -o conftest conftest.c -l$lib >/dev/null 2>/dev/null
+    [ $? -eq 0 ] && OPT=-l$lib && break
+  done
+  if [ ${OPT} ]; then
+    LFLAGS2="${LFLAGS2} ${OPT}"
+  else
+    CFLAGSR="${CFLAGSR} -DNO_DIR"
+  fi
+fi
+
+# Dynix/ptx 1.3 needed this
+echo Check for readlink
+echo "int main(){ return readlink(); }" > conftest.c
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  $CC -o conftest conftest.c -lseq >/dev/null 2>/dev/null
+  [ $? -eq 0 ] && LFLAGS2="${LFLAGS2} -lseq"
+fi
+
+echo Check for directory include file
+OPT=""
+for inc in dirent.h sys/ndir.h ndir.h sys/dir.h
+do
+   echo "#include <$inc>" > conftest.c
+   $CPP conftest.c > /dev/null 2>/dev/null
+   [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+echo Check for non existent include files
+for inc in stdlib.h stddef.h unistd.h fcntl.h string.h langinfo.h
+do
+   echo "#include <$inc>" > conftest.c
+   $CPP conftest.c >/dev/null 2>/dev/null
+   [ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_`echo $inc | tr '[a-z]./' '[A-Z]__'`"
+done
+
+echo Check for term I/O include file
+OPT=""
+for inc in termios.h termio.h sgtty.h
+do
+   echo "#include <$inc>" > conftest.c
+   $CPP conftest.c > /dev/null 2>/dev/null
+   [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+echo Check for MBCS include files
+OPT=""
+for inc in mbstring.h mbctype.h
+do
+   echo "#include <$inc>" > conftest.c
+   $CPP conftest.c > /dev/null 2>/dev/null
+   [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+# Check for MBCS support
+echo Check for MBCS support
+cat > conftest.c << _EOF_
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#ifdef HAVE_MBSTRING_H
+#  include <mbstring.h>
+#endif
+int main()
+{
+  char *tst;
+  tst = "Hallo";
+  return mblen(tst, MB_CUR_MAX);
+}
+_EOF_
+# compile it
+$CC ${CFLAGS} ${CFLAGSR} -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+  echo "-- no MBCS support"
+  CFLAGSR="${CFLAGSR} -DNO_MBCS"
+else
+#
+  echo "-- have MBCS support"
+  CFLAGSR="${CFLAGSR} -D_MBCS"
+# check for library-supplied functions
+# add FUNCTION_NAME='function_name' to flags if found
+  for func in mbschr mbsrchr
+  do
+    echo Check for MBCS $func
+    echo "int main() { $func(); return 0; }" > conftest.c
+    $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null
+    [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} -D`echo $func | tr '[a-z]' '[A-Z]'`=$func"
+  done
+fi
+
+# needed for AIX (and others ?) when mmap is used
+echo Check for valloc
+cat > conftest.c << _EOF_
+main()
+{
+#ifdef MMAP
+    valloc();
+#endif
+}
+_EOF_
+$CC ${CFLAGS} -c conftest.c > /dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_VALLOC"
+
+echo Check for /usr/local/bin and /usr/local/man
+BINDIR=$HOME/bin
+[ -d /usr/local/bin ] && BINDIR=/usr/local/bin
+
+MANDIR=manl
+[ -d /usr/man/manl ]       && MANDIR=/usr/man/manl
+[ -d /usr/local/man/manl ] && MANDIR=/usr/local/man/manl
+[ -d /usr/local/man/man1 ] && MANDIR=/usr/local/man/man1
+
+echo Checking for OS specialties
+if [ -f /usr/bin/hostinfo ]; then
+  if /usr/bin/hostinfo | grep NeXT > /dev/null; then
+    CFLAGSR="${CFLAGSR} -posix"
+    LFLAGS1="${LFLAGS1} -posix -object"
+  fi
+# XXX ATT6300, Cray
+elif [ -f /xenix ]; then
+  if uname -p | grep 286 > /dev/null; then
+    CFLAGSR="${CFLAGSR} -LARGE -Mel2 -DMEDIUM_MEM -DWSIZE=16384 -DNO_VOID"
+    LFLAGS1="${LFLAGS1} -LARGE -Mel2"
+  fi
+elif uname -X >/dev/null 2>/dev/null; then
+# SCO shared library check
+  echo "int main() { return 0;}" > conftest.c
+  $CC -o conftest conftest.c -lc_s -nointl >/dev/null 2> /dev/null
+  [ $? -eq 0 ] && LFLAGS2="-lc_s -nointl"
+else
+  SYSTEM=`uname -s 2>/dev/null` || SYSTEM="unknown"
+  echo "int main() { return 0;}" > conftest.c
+  case $SYSTEM in
+     OSF1|ULTRIX)
+        echo Check for -Olimit option
+        $CC ${CFLAGS} -Olimit 1000 -o conftest conftest.c >/dev/null 2>/dev/null
+        [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} -Olimit 1000"
+        ;;
+###     HP-UX)
+###        echo Check for +Onolimit option
+###        $CC ${CFLAGS} +Onolimit -o conftest conftest.c >/dev/null 2>/dev/null
+###        [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} +Onolimit"
+###        ;;
+###     SunOS)
+###        CFLAGSR="${CFLAGSR} -D_FILE_OFFSET_BITS=64"
+###        ;;
+  esac
+fi
+
+echo Check for symbolic links
+ln -s /dev/null null > /dev/null 2>/dev/null || LN=ln
+
+rm -f a.out conftest.c conftest.o conftest null
+
+
+# bzip2
+
+echo "Check bzip2 support"
+D_USE_BZ2=""
+LIBBZ2=""
+L_BZ2=""
+CC_BZ="${CC}"
+
+if test -n "${IZ_BZIP2}" -a "${IZ_BZIP2}" != "bzip2" ; then
+  echo "  Check for bzip2 compiled library in IZ_BZIP2 (${IZ_BZIP2})"
+  if test -f "${IZ_BZIP2}/libbz2.a"; then
+#
+#   A bzip2 library built with BZ_NO_STDIO should have an
+#   unresolved external, "bz_internal_error".  The default,
+#   full-function library will not mention it.
+#
+    nm ${IZ_BZIP2}/libbz2.a | grep bz_internal_error > /dev/null
+    if test $? -eq 0; then
+      echo "    Found bzip2 BZ_NO_STDIO library, ${IZ_BZIP2}/libbz2.a"
+      if test -f "${IZ_BZIP2}/bzlib.h"; then
+        LIBBZ2="${IZ_BZIP2}/libbz2.a"
+        D_USE_BZ2="-DUSE_BZIP2"
+        L_BZ2="${BZLF} -lbz2"
+        echo "-- Found bzip2 library - linking in bzip2"
+      else
+        echo "    ${IZ_BZIP2}/bzlib.h not found"
+        echo "-- Since IZ_BZIP2 defined (!= \"bzip2\"),"
+        echo "-- => skipping OS and bzip2 dir checks."
+        echo "-- NO bzip2 support !"
+      fi
+    else
+      echo "    Found bzip2 library, ${IZ_BZIP2}/libbz2.a,"
+      echo "      but library not compiled with BZ_NO_STDIO."
+      echo "    ERROR: This (default) variant of bzip2 library is NOT"
+      echo "      supported with UnZip because of its incompatible"
+      echo "      error handling!"
+      echo "      Please see the UnZip installation instructions in"
+      echo "      the INSTALL text file."
+      echo "    Skipping bzip2 support..."
+    fi
+  else
+    echo "    ${IZ_BZIP2}/libbz2.a not found"
+    echo "-- Since IZ_BZIP2 defined (!= \"bzip2\"),"
+    echo "-- => skipping OS and bzip2 dir checks."
+    echo "-- NO bzip2 support !"
+  fi
+else
+  echo "  Check for bzip2 sources in unzip's bzip2 subdirectory"
+  if test -f "${IZ_BZIP2}/bzlib.c" -a -f "${IZ_BZIP2}/bzlib.h"; then
+    echo "-- Found bzip2 source in ${IZ_BZIP2}/ directory"
+    echo "-- Will try to build bzip2 library from source and link in"
+    LIBBZ2="${IZ_BZIP2}/libbz2.a"
+    D_USE_BZ2="-DUSE_BZIP2"
+    L_BZ2="${BZLF} -lbz2"
+  else
+    echo "  Check if OS already has bzip2 library installed"
+    cat > conftest.c << _EOF_
+#include "bzlib.h"
+int main()
+{
+  bz_stream strm;
+  BZ2_bzCompressEnd(&strm);
+  return 0;
+}
+_EOF_
+    $CC $CFLAGS -o conftest conftest.c -lbz2 > /dev/null 2>/dev/null
+    if test $? -eq 0; then
+      echo "-- OS supports bzip2 - linking in bzip2"
+      D_USE_BZ2="-DUSE_BZIP2"
+      L_BZ2="${BZLF} -lbz2"
+    else
+      echo "-- Either bzlib.h or libbz2.a not found - no bzip2"
+    fi
+  fi
+fi
+
+
+echo CC=\"${CC}\" CF=\"${CFLAGSR} ${D_USE_BZ2}\" CRCA_O=\"${CRC32OA}\" \
+       AS=\"${CC} -c\" LFLAGS1=\"${LFLAGS1}\" LF2=\"${LFLAGS2}\" \
+       CC_BZ=\"${CC_BZ}\" CFLAGS_BZ=\"${CFLAGS_BZ}\" \
+       IZ_BZIP2=\"${IZ_BZIP2}\" D_USE_BZ2=\"${D_USE_BZ2}\" \
+       L_BZ2=\"${L_BZ2}\" LIBBZ2=\"${LIBBZ2}\"  > flags

Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/unix/configure
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c	(revision 5)
@@ -0,0 +1,2013 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+
+  unix.c
+
+  Unix-specific routines for use with Info-ZIP's UnZip 5.41 and later.
+
+  Contains:  readdir()
+             do_wild()           <-- generic enough to put in fileio.c?
+             mapattr()
+             mapname()
+             checkdir()
+             mkdir()
+             close_outfile()
+             defer_dir_attribs()
+             set_direc_attribs()
+             stamp_file()
+             version()
+
+  ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#include <iconv.h>
+#include <langinfo.h>
+
+#ifdef SCO_XENIX
+#  define SYSNDIR
+#else  /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
+#  if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
+#    define DIRENT
+#  endif
+#endif
+#if defined(_AIX) || defined(__mpexl)
+#  define DIRENT
+#endif
+#ifdef COHERENT
+#  if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
+#    define DIRENT
+#  endif
+#endif
+
+#ifdef _POSIX_VERSION
+#  ifndef DIRENT
+#    define DIRENT
+#  endif
+#endif
+
+#ifdef DIRENT
+#  include <dirent.h>
+#else
+#  ifdef SYSV
+#    ifdef SYSNDIR
+#      include <sys/ndir.h>
+#    else
+#      include <ndir.h>
+#    endif
+#  else /* !SYSV */
+#    ifndef NO_SYSDIR
+#      include <sys/dir.h>
+#    endif
+#  endif /* ?SYSV */
+#  ifndef dirent
+#    define dirent direct
+#  endif
+#endif /* ?DIRENT */
+
+#ifdef SET_DIR_ATTRIB
+typedef struct uxdirattr {      /* struct for holding unix style directory */
+    struct uxdirattr *next;     /*  info until can be sorted and set at end */
+    char *fn;                   /* filename of directory */
+    union {
+        iztimes t3;             /* mtime, atime, ctime */
+        ztimbuf t2;             /* modtime, actime */
+    } u;
+    unsigned perms;             /* same as min_info.file_attr */
+    int have_uidgid;            /* flag */
+    ulg uidgid[2];
+    char fnbuf[1];              /* buffer stub for directory name */
+} uxdirattr;
+#define UxAtt(d)  ((uxdirattr *)d)    /* typecast shortcut */
+#endif /* SET_DIR_ATTRIB */
+
+#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 in mapname(), checkdir() */
+/* static int renamed_fullpath; */      /* ditto */
+
+static unsigned filtattr OF((__GPRO__ unsigned perms));
+
+
+/*****************************/
+/* Strings used multiple     */
+/* times in unix.c           */
+/*****************************/
+
+#ifndef MTS
+/* messages of code for setting file/directory attributes */
+static ZCONST char CannotSetItemUidGid[] =
+  "warning:  cannot set UID %lu and/or GID %lu for %s\n          %s\n";
+static ZCONST char CannotSetUidGid[] =
+  " (warning) cannot set UID %lu and/or GID %lu\n          %s";
+static ZCONST char CannotSetItemTimestamps[] =
+  "warning:  cannot set modif./access times for %s\n          %s\n";
+static ZCONST char CannotSetTimestamps[] =
+  " (warning) cannot set modif./access times\n          %s";
+#endif /* !MTS */
+
+
+#ifndef SFX
+#ifdef NO_DIR                  /* for AT&T 3B1 */
+
+#define opendir(path) fopen(path,"r")
+#define closedir(dir) fclose(dir)
+typedef FILE DIR;
+typedef struct zdir {
+    FILE *dirhandle;
+    struct dirent *entry;
+} DIR
+DIR *opendir OF((ZCONST char *dirspec));
+void closedir OF((DIR *dirp));
+struct dirent *readdir OF((DIR *dirp));
+
+DIR *opendir(dirspec)
+    ZCONST char *dirspec;
+{
+    DIR *dirp;
+
+    if ((dirp = malloc(sizeof(DIR)) != NULL) {
+        if ((dirp->dirhandle = fopen(dirspec, "r")) == NULL) {
+            free(dirp);
+            dirp = NULL;
+        }
+    }
+    return dirp;
+}
+
+void closedir(dirp)
+    DIR *dirp;
+{
+    fclose(dirp->dirhandle);
+    free(dirp);
+}
+
+/*
+ *  Apparently originally by Rich Salz.
+ *  Cleaned up and modified by James W. Birdsall.
+ */
+struct dirent *readdir(dirp)
+    DIR *dirp;
+{
+
+    if (dirp == NULL)
+        return NULL;
+
+    for (;;)
+        if (fread(&(dirp->entry), sizeof (struct dirent), 1,
+                  dirp->dirhandle) == 0)
+            return (struct dirent *)NULL;
+        else if ((dirp->entry).d_ino)
+            return &(dirp->entry);
+
+} /* end function readdir() */
+
+#endif /* NO_DIR */
+
+
+/**********************/
+/* Function do_wild() */   /* for porting: dir separator; match(ignore_case) */
+/**********************/
+
+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 unxcfg.h:
+    static DIR *wild_dir = (DIR *)NULL;
+    static ZCONST char *wildname;
+    static char *dirname, matchname[FILNAMSIZ];
+    static int notfirstcall=FALSE, have_dirname, dirnamelen;
+*/
+    struct dirent *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 */
+        if ((G.wildname = (ZCONST char *)strrchr(wildspec, '/')) == NULL) {
+            G.dirname = ".";
+            G.dirnamelen = 1;
+            G.have_dirname = FALSE;
+            G.wildname = wildspec;
+        } else {
+            ++G.wildname;     /* point at character after '/' */
+            G.dirnamelen = G.wildname - wildspec;
+            if ((G.dirname = (char *)malloc(G.dirnamelen+1)) == (char *)NULL) {
+                Info(slide, 0x201, ((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;
+        }
+
+        if ((G.wild_dir = (zvoid *)opendir(G.dirname)) != (zvoid *)NULL) {
+            while ((file = readdir((DIR *)G.wild_dir)) !=
+                   (struct dirent *)NULL) {
+                Trace((stderr, "do_wild:  readdir returns %s\n",
+                  FnFilter1(file->d_name)));
+                if (file->d_name[0] == '.' && G.wildname[0] != '.')
+                    continue; /* Unix:  '*' and '?' do not match leading dot */
+                if (match(file->d_name, G.wildname, 0 WISEP) &&/*0=case sens.*/
+                    /* skip "." and ".." directory entries */
+                    strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
+                    Trace((stderr, "do_wild:  match() succeeds\n"));
+                    if (G.have_dirname) {
+                        strcpy(G.matchname, G.dirname);
+                        strcpy(G.matchname+G.dirnamelen, file->d_name);
+                    } else
+                        strcpy(G.matchname, file->d_name);
+                    return G.matchname;
+                }
+            }
+            /* if we get to here directory is exhausted, so close it */
+            closedir((DIR *)G.wild_dir);
+            G.wild_dir = (zvoid *)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 ((DIR *)G.wild_dir == (DIR *)NULL) {
+        G.notfirstcall = FALSE; /* nothing left--reset for new wildspec */
+        if (G.have_dirname)
+            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.
+     */
+    while ((file = readdir((DIR *)G.wild_dir)) != (struct dirent *)NULL) {
+        Trace((stderr, "do_wild:  readdir returns %s\n",
+          FnFilter1(file->d_name)));
+        if (file->d_name[0] == '.' && G.wildname[0] != '.')
+            continue;   /* Unix:  '*' and '?' do not match leading dot */
+        if (match(file->d_name, G.wildname, 0 WISEP)) { /* 0 == case sens. */
+            Trace((stderr, "do_wild:  match() succeeds\n"));
+            if (G.have_dirname) {
+                /* strcpy(G.matchname, G.dirname); */
+                strcpy(G.matchname+G.dirnamelen, file->d_name);
+            } else
+                strcpy(G.matchname, file->d_name);
+            return G.matchname;
+        }
+    }
+
+    closedir((DIR *)G.wild_dir);  /* at least one entry read; nothing left */
+    G.wild_dir = (zvoid *)NULL;
+    G.notfirstcall = FALSE;       /* reset for new wildspec */
+    if (G.have_dirname)
+        free(G.dirname);
+    return (char *)NULL;
+
+} /* end function do_wild() */
+
+#endif /* !SFX */
+
+
+
+
+#ifndef S_ISUID
+# define S_ISUID        0004000 /* set user id on execution */
+#endif
+#ifndef S_ISGID
+# define S_ISGID        0002000 /* set group id on execution */
+#endif
+#ifndef S_ISVTX
+# define S_ISVTX        0001000 /* save swapped text even after use */
+#endif
+
+/************************/
+/*  Function filtattr() */
+/************************/
+/* This is used to clear or keep the SUID and SGID bits on file permissions.
+ * It's possible that a file in an archive could have one of these bits set
+ * and, unknown to the person unzipping, could allow others to execute the
+ * file as the user or group.  The new option -K bypasses this check.
+ */
+
+static unsigned filtattr(__G__ perms)
+    __GDEF
+    unsigned perms;
+{
+    /* keep setuid/setgid/tacky perms? */
+    if (!uO.K_flag)
+        perms &= ~(S_ISUID | S_ISGID | S_ISVTX);
+
+    return (0xffff & perms);
+} /* end function filtattr() */
+
+
+
+
+
+/**********************/
+/* Function mapattr() */
+/**********************/
+
+int mapattr(__G)
+    __GDEF
+{
+    int r;
+    ulg tmp = G.crec.external_file_attributes;
+
+    G.pInfo->file_attr = 0;
+    /* initialized to 0 for check in "default" branch below... */
+
+    switch (G.pInfo->hostnum) {
+        case AMIGA_:
+            tmp = (unsigned)(tmp>>17 & 7);   /* Amiga RWE bits */
+            G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
+            break;
+        case THEOS_:
+            tmp &= 0xF1FFFFFFL;
+            if ((tmp & 0xF0000000L) != 0x40000000L)
+                tmp &= 0x01FFFFFFL;     /* not a dir, mask all ftype bits */
+            else
+                tmp &= 0x41FFFFFFL;     /* leave directory bit as set */
+            /* fall through! */
+        case UNIX_:
+        case VMS_:
+        case ACORN_:
+        case ATARI_:
+        case ATHEOS_:
+        case BEOS_:
+        case QDOS_:
+        case TANDEM_:
+            r = FALSE;
+            G.pInfo->file_attr = (unsigned)(tmp >> 16);
+            if (G.pInfo->file_attr == 0 && G.extra_field) {
+                /* Some (non-Info-ZIP) implementations of Zip for Unix and
+                 * VMS (and probably others ??) leave 0 in the upper 16-bit
+                 * part of the external_file_attributes field. Instead, they
+                 * store file permission attributes in some extra field.
+                 * As a work-around, we search for the presence of one of
+                 * these extra fields and fall back to the MSDOS compatible
+                 * part of external_file_attributes if one of the known
+                 * e.f. types has been detected.
+                 * Later, we might implement extraction of the permission
+                 * bits from the VMS extra field. But for now, the work-around
+                 * should be sufficient to provide "readable" extracted files.
+                 * (For ASI Unix e.f., an experimental remap of the e.f.
+                 * mode value IS already provided!)
+                 */
+                ush ebID;
+                unsigned ebLen;
+                uch *ef = G.extra_field;
+                unsigned ef_len = G.crec.extra_field_length;
+
+                while (!r && ef_len >= EB_HEADSIZE) {
+                    ebID = makeword(ef);
+                    ebLen = (unsigned)makeword(ef+EB_LEN);
+                    if (ebLen > (ef_len - EB_HEADSIZE))
+                        /* discoverd some e.f. inconsistency! */
+                        break;
+                    switch (ebID) {
+                      case EF_ASIUNIX:
+                        if (ebLen >= (EB_ASI_MODE+2)) {
+                            G.pInfo->file_attr =
+                              (unsigned)makeword(ef+(EB_HEADSIZE+EB_ASI_MODE));
+                            /* force stop of loop: */
+                            ef_len = (ebLen + EB_HEADSIZE);
+                            break;
+                        }
+                        /* else: fall through! */
+                      case EF_PKVMS:
+                        /* "found nondecypherable e.f. with perm. attr" */
+                        r = TRUE;
+                      default:
+                        break;
+                    }
+                    ef_len -= (ebLen + EB_HEADSIZE);
+                    ef += (ebLen + EB_HEADSIZE);
+                }
+            }
+            if (!r) {
+#ifdef SYMLINKS
+                /* Check if the file is a (POSIX-compatible) symbolic link.
+                 * We restrict symlink support to those "made-by" hosts that
+                 * are known to support symbolic links.
+                 */
+                G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
+                                   SYMLINK_HOST(G.pInfo->hostnum);
+#endif
+                return 0;
+            }
+            /* fall through! */
+        /* all remaining cases:  expand MSDOS read-only bit into write perms */
+        case FS_FAT_:
+            /* PKWARE's PKZip for Unix marks entries as FS_FAT_, but stores the
+             * Unix attributes in the upper 16 bits of the external attributes
+             * field, just like Info-ZIP's Zip for Unix.  We try to use that
+             * value, after a check for consistency with the MSDOS attribute
+             * bits (see below).
+             */
+            G.pInfo->file_attr = (unsigned)(tmp >> 16);
+            /* fall through! */
+        case FS_HPFS_:
+        case FS_NTFS_:
+        case MAC_:
+        case TOPS20_:
+        default:
+            /* Ensure that DOS subdir bit is set when the entry's name ends
+             * in a '/'.  Some third-party Zip programs fail to set the subdir
+             * bit for directory entries.
+             */
+            if ((tmp & 0x10) == 0) {
+                extent fnlen = strlen(G.filename);
+                if (fnlen > 0 && G.filename[fnlen-1] == '/')
+                    tmp |= 0x10;
+            }
+            /* read-only bit --> write perms; subdir bit --> dir exec bit */
+            tmp = !(tmp & 1) << 1  |  (tmp & 0x10) >> 4;
+            if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6)) {
+                /* keep previous G.pInfo->file_attr setting, when its "owner"
+                 * part appears to be consistent with DOS attribute flags!
+                 */
+#ifdef SYMLINKS
+                /* Entries "made by FS_FAT_" could have been zipped on a
+                 * system that supports POSIX-style symbolic links.
+                 */
+                G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
+                                   (G.pInfo->hostnum == FS_FAT_);
+#endif
+                return 0;
+            }
+            G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
+            break;
+    } /* end switch (host-OS-created-by) */
+
+    /* for originating systems with no concept of "group," "other," "system": */
+    umask( (int)(tmp=umask(0)) );    /* apply mask to expanded r/w(/x) perms */
+    G.pInfo->file_attr &= ~tmp;
+
+    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 */
+    char *pp, *cp=(char *)NULL;    /* character pointers */
+    char *lastsemi=(char *)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 = MPN_OK;
+    register unsigned workch;      /* hold the character being tested */
+
+
+/*---------------------------------------------------------------------------
+    Initialize various pointers and counters and stuff.
+  ---------------------------------------------------------------------------*/
+
+    if (G.pInfo->vollabel)
+        return MPN_VOL_LABEL;   /* can't set disk volume labels in Unix */
+
+    /* 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 */
+
+    /* user gave full pathname:  don't prepend rootpath */
+    G.renamed_fullpath = (renamed && (*G.filename == '/'));
+
+    if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
+        return MPN_NOMEM;       /* initialize path buffer, unless no memory */
+
+    *pathcomp = '\0';           /* initialize translation buffer */
+    pp = pathcomp;              /* point to translation buffer */
+    if (uO.jflag)               /* junking directories */
+        cp = (char *)strrchr(G.filename, '/');
+    if (cp == (char *)NULL)     /* no '/' or not junking dirs */
+        cp = G.filename;        /* point to internal zipfile-member pathname */
+    else
+        ++cp;                   /* point to start of last component of path */
+
+/*---------------------------------------------------------------------------
+    Begin main loop through characters in filename.
+  ---------------------------------------------------------------------------*/
+
+    while ((workch = (uch)*cp++) != 0) {
+
+        switch (workch) {
+            case '/':             /* can assume -j flag not given */
+                *pp = '\0';
+                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 direct. semi-colons alone */
+                break;
+
+#ifdef __CYGWIN__   /* Cygwin runs on Win32, apply FAT/NTFS filename rules */
+            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;
+#endif
+
+            case ';':             /* VMS version (or DEC-20 attrib?) */
+                lastsemi = pp;
+                *pp++ = ';';      /* keep for now; remove VMS ";##" */
+                break;            /*  later, if requested */
+
+#ifdef ACORN_FTYPE_NFS
+            case ',':             /* NFS filetype extension */
+                lastcomma = pp;
+                *pp++ = ',';      /* keep for now; may need to remove */
+                break;            /*  later, if requested */
+#endif
+
+#ifdef MTS
+            case ' ':             /* change spaces to underscore under */
+                *pp++ = '_';      /*  MTS; leave as spaces under Unix */
+                break;
+#endif
+
+            default:
+                /* disable control character filter when requested,
+                 * else allow 8-bit characters (e.g. UTF-8) in filenames:
+                 */
+                if (uO.cflxflag ||
+                    (isprint(workch) || (128 <= workch && workch <= 254)))
+                    *pp++ = (char)workch;
+        } /* 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) 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.filename[strlen(G.filename) - 1] == '/') {
+        checkdir(__G__ G.filename, GETPATH);
+        if (G.created_dir) {
+            if (QCOND2) {
+                Info(slide, 0, ((char *)slide, "   creating: %s\n",
+                  FnFilter1(G.filename)));
+            }
+#ifndef NO_CHMOD
+            /* Filter out security-relevant attributes bits. */
+            G.pInfo->file_attr = filtattr(__G__ G.pInfo->file_attr);
+            /* When extracting non-UNIX directories or when extracting
+             * without UID/GID restoration or SGID preservation, any
+             * SGID flag inherited from the parent directory should be
+             * maintained to allow files extracted into this new folder
+             * to inherit the GID setting from the parent directory.
+             */
+            if (G.pInfo->hostnum != UNIX_ || !(uO.X_flag || uO.K_flag)) {
+                /* preserve SGID bit when inherited from parent dir */
+                if (!SSTAT(G.filename, &G.statbuf)) {
+                    G.pInfo->file_attr |= G.statbuf.st_mode & S_ISGID;
+                } else {
+                    perror("Could not read directory attributes");
+                }
+            }
+
+            /* set approx. dir perms (make sure can still read/write in dir) */
+            if (chmod(G.filename, G.pInfo->file_attr | 0700))
+                perror("chmod (directory attributes) error");
+#endif
+            /* set dir time (note trailing '/') */
+            return (error & ~MPN_MASK) | MPN_CREATED_DIR;
+        }
+        /* 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 VMS version numbers (appended ";###") */
+    if (!uO.V_flag && lastsemi) {
+        pp = lastsemi + 1;
+        while (isdigit((uch)(*pp)))
+            ++pp;
+        if (*pp == '\0')          /* only digits between ';' and end:  nuke */
+            *lastsemi = '\0';
+    }
+
+    /* On UNIX (and compatible systems), "." and ".." are reserved for
+     * directory navigation and cannot be used as regular file names.
+     * These reserved one-dot and two-dot names are mapped to "_" and "__".
+     */
+    if (strcmp(pathcomp, ".") == 0)
+        *pathcomp = '_';
+    else if (strcmp(pathcomp, "..") == 0)
+        strcpy(pathcomp, "__");
+
+#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 */
+
+    if (*pathcomp == '\0') {
+        Info(slide, 1, ((char *)slide, "mapname:  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);
+
+    return error;
+
+} /* end function mapname() */
+
+
+
+
+#if 0  /*========== NOTES ==========*/
+
+  extract-to dir:      a:path/
+  buildpath:           path1/path2/ ...   (NULL-terminated)
+  pathcomp:                filename
+
+  mapname():
+    loop over chars in zipfile member name
+      checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
+        (d:/tmp/unzip/)                    (disk:[tmp.unzip.)
+        (d:/tmp/unzip/jj/)                 (disk:[tmp.unzip.jj.)
+        (d:/tmp/unzip/jj/temp/)            (disk:[tmp.unzip.jj.temp.)
+    finally add filename itself and check for existence? (could use with rename)
+        (d:/tmp/unzip/jj/temp/msg.outdir)  (disk:[tmp.unzip.jj.temp]msg.outdir)
+    checkdir(name, GETPATH)     -->  copy path to name and free space
+
+#endif /* 0 */
+
+
+
+
+/***********************/
+/* Function checkdir() */
+/***********************/
+
+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 *buildpath; */  /* full path (so far) to extracted file */
+ /* static char *end;       */  /* pointer to end of 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) {
+        int too_long = FALSE;
+#ifdef SHORT_NAMES
+        char *old_end = end;
+#endif
+
+        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
+        while ((*G.end = *pathcomp++) != '\0')
+            ++G.end;
+#ifdef SHORT_NAMES   /* path components restricted to 14 chars, typically */
+        if ((G.end-old_end) > FILENAME_MAX)  /* GRR:  proper constant? */
+            *(G.end = old_end + FILENAME_MAX) = '\0';
+#endif
+
+        /* GRR:  could do better check, see if overrunning buffer as we go:
+         * check end-buildpath 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.end-G.buildpath) > FILNAMSIZ-3)
+            too_long = TRUE;                    /* check if extracting dir? */
+        if (SSTAT(G.buildpath, &G.statbuf)) {   /* path doesn't exist */
+            if (!G.create_dirs) { /* told not to create (freshening) */
+                free(G.buildpath);
+                return MPN_INF_SKIP;    /* path doesn't exist: nothing to do */
+            }
+            if (too_long) {
+                Info(slide, 1, ((char *)slide,
+                  "checkdir error:  path too long: %s\n",
+                  FnFilter1(G.buildpath)));
+                free(G.buildpath);
+                /* no room for filenames:  fatal */
+                return MPN_ERR_TOOLONG;
+            }
+            if (mkdir(G.buildpath, 0777) == -1) {   /* create the directory */
+                Info(slide, 1, ((char *)slide,
+                  "checkdir error:  cannot create %s\n\
+                 %s\n\
+                 unable to process %s.\n",
+                  FnFilter2(G.buildpath),
+                  strerror(errno),
+                  FnFilter1(G.filename)));
+                free(G.buildpath);
+                /* 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 error:  %s exists but is not directory\n\
+                 unable to process %s.\n",
+              FnFilter2(G.buildpath), FnFilter1(G.filename)));
+            free(G.buildpath);
+            /* path existed but wasn't dir */
+            return MPN_ERR_SKIP;
+        }
+        if (too_long) {
+            Info(slide, 1, ((char *)slide,
+              "checkdir error:  path too long: %s\n", FnFilter1(G.buildpath)));
+            free(G.buildpath);
+            /* no room for filenames:  fatal */
+            return MPN_ERR_TOOLONG;
+        }
+        *G.end++ = '/';
+        *G.end = '\0';
+        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
+        return MPN_OK;
+
+    } /* end if (FUNCTION == APPEND_DIR) */
+
+/*---------------------------------------------------------------------------
+    GETPATH:  copy full path to the string pointed at by pathcomp, and free
+    G.buildpath.
+  ---------------------------------------------------------------------------*/
+
+    if (FUNCTION == GETPATH) {
+        strcpy(pathcomp, G.buildpath);
+        Trace((stderr, "getting and freeing path [%s]\n",
+          FnFilter1(pathcomp)));
+        free(G.buildpath);
+        G.buildpath = G.end = (char *)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) {
+#ifdef SHORT_NAMES
+        char *old_end = end;
+#endif
+
+        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
+        while ((*G.end = *pathcomp++) != '\0') {
+            ++G.end;
+#ifdef SHORT_NAMES  /* truncate name at 14 characters, typically */
+            if ((G.end-old_end) > FILENAME_MAX)    /* GRR:  proper constant? */
+                *(G.end = old_end + FILENAME_MAX) = '\0';
+#endif
+            if ((G.end-G.buildpath) >= FILNAMSIZ) {
+                *--G.end = '\0';
+                Info(slide, 0x201, ((char *)slide,
+                  "checkdir warning:  path too long; truncating\n\
+                   %s\n                -> %s\n",
+                  FnFilter1(G.filename), FnFilter2(G.buildpath)));
+                return MPN_INF_TRUNC;   /* filename truncated */
+            }
+        }
+        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
+        /* could check for existence here, prompt for new name... */
+        return MPN_OK;
+    }
+
+/*---------------------------------------------------------------------------
+    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.
+  ---------------------------------------------------------------------------*/
+
+/* GRR:  for VMS and TOPS-20, add up to 13 to strlen */
+
+    if (FUNCTION == INIT) {
+        Trace((stderr, "initializing buildpath to "));
+#ifdef ACORN_FTYPE_NFS
+        if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+
+                                          (uO.acorn_nfs_ext ? 5 : 1)))
+#else
+        if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+1))
+#endif
+            == (char *)NULL)
+            return MPN_NOMEM;
+        if ((G.rootlen > 0) && !G.renamed_fullpath) {
+            strcpy(G.buildpath, G.rootpath);
+            G.end = G.buildpath + G.rootlen;
+        } else {
+            *G.buildpath = '\0';
+            G.end = G.buildpath;
+        }
+        Trace((stderr, "[%s]\n", FnFilter1(G.buildpath)));
+        return MPN_OK;
+    }
+
+/*---------------------------------------------------------------------------
+    ROOT:  if appropriate, store the path in rootpath and create it if
+    necessary; 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.
+  ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+    if (FUNCTION == ROOT) {
+        Trace((stderr, "initializing root path to [%s]\n",
+          FnFilter1(pathcomp)));
+        if (pathcomp == (char *)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) {
+            char *tmproot;
+
+            if ((tmproot = (char *)malloc(G.rootlen+2)) == (char *)NULL) {
+                G.rootlen = 0;
+                return MPN_NOMEM;
+            }
+            strcpy(tmproot, pathcomp);
+            if (tmproot[G.rootlen-1] == '/') {
+                tmproot[--G.rootlen] = '\0';
+            }
+            if (G.rootlen > 0 && (SSTAT(tmproot, &G.statbuf) ||
+                                  !S_ISDIR(G.statbuf.st_mode)))
+            {   /* path does not exist */
+                if (!G.create_dirs /* || iswild(tmproot) */ ) {
+                    free(tmproot);
+                    G.rootlen = 0;
+                    /* skip (or treat as stored file) */
+                    return MPN_INF_SKIP;
+                }
+                /* create the directory (could add loop here scanning tmproot
+                 * to create more than one level, but why really necessary?) */
+                if (mkdir(tmproot, 0777) == -1) {
+                    Info(slide, 1, ((char *)slide,
+                      "checkdir:  cannot create extraction directory: %s\n\
+           %s\n",
+                      FnFilter1(tmproot), strerror(errno)));
+                    free(tmproot);
+                    G.rootlen = 0;
+                    /* path didn't exist, tried to create, and failed: */
+                    /* file exists, or 2+ subdir levels required */
+                    return MPN_ERR_SKIP;
+                }
+            }
+            tmproot[G.rootlen++] = '/';
+            tmproot[G.rootlen] = '\0';
+            if ((G.rootpath = (char *)realloc(tmproot, G.rootlen+1)) == NULL) {
+                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) {
+            free(G.rootpath);
+            G.rootlen = 0;
+        }
+        return MPN_OK;
+    }
+
+    return MPN_INVALID; /* should never reach */
+
+} /* end function checkdir() */
+
+
+
+
+
+#ifdef NO_MKDIR
+
+/********************/
+/* Function mkdir() */
+/********************/
+
+int mkdir(path, mode)
+    ZCONST char *path;
+    int mode;   /* ignored */
+/*
+ * returns:   0 - successful
+ *           -1 - failed (errno not set, however)
+ */
+{
+    char command[FILNAMSIZ+40]; /* buffer for system() call */
+
+    /* GRR 930416:  added single quotes around path to avoid bug with
+     * creating directories with ampersands in name; not yet tested */
+    sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
+    if (system(command))
+        return -1;
+    return 0;
+}
+
+#endif /* NO_MKDIR */
+
+
+
+
+#if (!defined(MTS) || defined(SET_DIR_ATTRIB))
+static int get_extattribs OF((__GPRO__ iztimes *pzt, ulg z_uidgid[2]));
+
+static int get_extattribs(__G__ pzt, z_uidgid)
+    __GDEF
+    iztimes *pzt;
+    ulg z_uidgid[2];
+{
+/*---------------------------------------------------------------------------
+    Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
+    time:  adjust base year from 1980 to 1970, do usual conversions from
+    yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
+    light savings time differences.  If we have a Unix extra field, however,
+    we're laughing:  both mtime and atime are ours.  On the other hand, we
+    then have to check for restoration of UID/GID.
+  ---------------------------------------------------------------------------*/
+    int have_uidgid_flg;
+    unsigned eb_izux_flg;
+
+    eb_izux_flg = (G.extra_field ? ef_scan_for_izux(G.extra_field,
+                   G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
+#ifdef IZ_CHECK_TZ
+                   (G.tz_is_valid ? pzt : NULL),
+#else
+                   pzt,
+#endif
+                   z_uidgid) : 0);
+    if (eb_izux_flg & EB_UT_FL_MTIME) {
+        TTrace((stderr, "\nget_extattribs:  Unix e.f. modif. time = %ld\n",
+          pzt->mtime));
+    } else {
+        pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+    }
+    if (eb_izux_flg & EB_UT_FL_ATIME) {
+        TTrace((stderr, "get_extattribs:  Unix e.f. access time = %ld\n",
+          pzt->atime));
+    } else {
+        pzt->atime = pzt->mtime;
+        TTrace((stderr, "\nget_extattribs:  modification/access times = %ld\n",
+          pzt->mtime));
+    }
+
+    /* if -X option was specified and we have UID/GID info, restore it */
+    have_uidgid_flg =
+#ifdef RESTORE_UIDGID
+            (uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
+#else
+            0;
+#endif
+    return have_uidgid_flg;
+}
+#endif /* !MTS || SET_DIR_ATTRIB */
+
+
+
+#ifndef MTS
+
+/****************************/
+/* Function CloseError()    */
+/***************************/
+
+int CloseError(__G)
+    __GDEF
+{
+    int errval = PK_OK;
+    
+    if (fclose(G.outfile) < 0) {
+          switch (errno) {
+                case ENOSPC:
+                    /* Do we need this on fileio.c? */
+                    Info(slide, 0x4a1, ((char *)slide, "%s: write error (disk full?).   Continue? (y/n/^C) ",
+                          FnFilter1(G.filename)));
+                    fgets(G.answerbuf, 9, stdin);
+                    if (*G.answerbuf == 'y')     /* stop writing to this file */
+                        G.disk_full = 1;         /* pass to next */
+                    else
+                        G.disk_full = 2;         /* no: exit program */
+          
+                    errval = PK_DISK;
+                    break;
+
+                default:
+                    errval = PK_WARN;
+          }
+     }
+     return errval;
+} /* End of CloseError() */
+
+/****************************/
+/* Function close_outfile() */
+/****************************/
+
+int close_outfile(__G) 
+    __GDEF
+{
+    union {
+        iztimes t3;             /* mtime, atime, ctime */
+        ztimbuf t2;             /* modtime, actime */
+    } zt;
+    ulg z_uidgid[2];
+    int have_uidgid_flg;
+    int errval = PK_OK;
+
+    have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
+
+/*---------------------------------------------------------------------------
+    If symbolic links are supported, allocate storage for a symlink control
+    structure, put the uncompressed "data" and other required info in it, and
+    add the structure to the "deferred symlinks" chain.  Since we know it's a
+    symbolic link to start with, we shouldn't have 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
+        /* size of the symlink entry is the sum of
+         *  (struct size (includes 1st '\0') + 1 additional trailing '\0'),
+         *  system specific attribute data size (might be 0),
+         *  and the lengths of name and link target.
+         */
+        extent slnk_entrysize = (sizeof(slinkentry) + 1) + attribsize +
+                                ucsize + strlen(G.filename);
+        slinkentry *slnk_entry;
+
+        if (slnk_entrysize < ucsize) {
+            Info(slide, 0x201, ((char *)slide,
+              "warning:  symbolic link (%s) failed: mem alloc overflow\n",
+              FnFilter1(G.filename)));
+            errval = CloseError(G.outfile, G.filename);
+            return errval ? errval : PK_WARN;
+        }
+
+        if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
+            Info(slide, 0x201, ((char *)slide,
+              "warning:  symbolic link (%s) failed: no mem\n",
+              FnFilter1(G.filename)));
+            errval = CloseError(G.outfile, G.filename);
+            return errval ? errval : PK_WARN;
+        }
+        slnk_entry->next = NULL;
+        slnk_entry->targetlen = ucsize;
+        slnk_entry->attriblen = attribsize;
+# ifdef SET_SYMLINK_ATTRIBS
+        memcpy(slnk_entry->buf, &(G.pInfo->file_attr),
+               sizeof(unsigned));
+        if (have_uidgid_flg)
+            memcpy(slnk_entry->buf + 4, 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);
+
+        /* 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);
+            errval = CloseError(G.outfile, G.filename);
+            return errval ? errval : PK_WARN;
+        }
+        errval = CloseError(G.outfile, G.filename); /* close "link" file for good... */
+        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;
+        return errval;
+    }
+#endif /* SYMLINKS */
+
+#ifdef QLZIP
+    if (G.extra_field) {
+        static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len));
+
+        qlfix(__G__ G.extra_field, G.lrec.extra_field_length);
+    }
+#endif
+
+#if (defined(NO_FCHOWN))
+    errval = CloseError(G.outfile, G.filename);
+#endif
+
+    /* if -X option was specified and we have UID/GID info, restore it */
+    if (have_uidgid_flg
+        /* check that both uid and gid values fit into their data sizes */
+        && ((ulg)(uid_t)(z_uidgid[0]) == z_uidgid[0])
+        && ((ulg)(gid_t)(z_uidgid[1]) == z_uidgid[1])) {
+        TTrace((stderr, "close_outfile:  restoring Unix UID/GID info\n"));
+#if (defined(NO_FCHOWN))
+        if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
+#else
+        if (fchown(fileno(G.outfile), (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
+#endif
+        {
+            if (uO.qflag)
+                Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+                  z_uidgid[0], z_uidgid[1], FnFilter1(G.filename),
+                  strerror(errno)));
+            else
+                Info(slide, 0x201, ((char *)slide, CannotSetUidGid,
+                  z_uidgid[0], z_uidgid[1], strerror(errno)));
+        }
+    }
+
+#if (!defined(NO_FCHOWN) && defined(NO_FCHMOD))
+    errval = CloseError(G.outfile, G.filename);
+#endif
+
+#if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
+/*---------------------------------------------------------------------------
+    Change the file permissions from default ones to those stored in the
+    zipfile.
+  ---------------------------------------------------------------------------*/
+
+    if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
+        perror("fchmod (file attributes) error");
+
+    errval = CloseError(G.outfile, G.filename);
+#endif /* !NO_FCHOWN && !NO_FCHMOD */
+
+    /* skip restoring time stamps on user's request */
+    if (uO.D_flag <= 1) {
+        /* set the file's access and modification times */
+        if (utime(G.filename, &(zt.t2))) {
+            if (uO.qflag)
+                Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
+                  FnFilter1(G.filename), strerror(errno)));
+            else
+                Info(slide, 0x201, ((char *)slide, CannotSetTimestamps,
+                  strerror(errno)));
+        }
+    }
+
+#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
+/*---------------------------------------------------------------------------
+    Change the file permissions from default ones to those stored in the
+    zipfile.
+  ---------------------------------------------------------------------------*/
+
+#ifndef NO_CHMOD
+    if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr)))
+        perror("chmod (file attributes) error");
+#endif
+#endif /* NO_FCHOWN || NO_FCHMOD */
+
+    return errval;
+} /* end function close_outfile() */
+
+#endif /* !MTS */
+
+
+#if (defined(SYMLINKS) && defined(SET_SYMLINK_ATTRIBS))
+int set_symlnk_attribs(__G__ slnk_entry)
+    __GDEF
+    slinkentry *slnk_entry;
+{
+    if (slnk_entry->attriblen > 0) {
+# if (!defined(NO_LCHOWN))
+      if (slnk_entry->attriblen > sizeof(unsigned)) {
+        ulg *z_uidgid_p = (zvoid *)(slnk_entry->buf + sizeof(unsigned));
+        /* check that both uid and gid values fit into their data sizes */
+        if (((ulg)(uid_t)(z_uidgid_p[0]) == z_uidgid_p[0]) &&
+            ((ulg)(gid_t)(z_uidgid_p[1]) == z_uidgid_p[1])) {
+          TTrace((stderr,
+            "set_symlnk_attribs:  restoring Unix UID/GID info for\n\
+        %s\n",
+            FnFilter1(slnk_entry->fname)));
+          if (lchown(slnk_entry->fname,
+                     (uid_t)z_uidgid_p[0], (gid_t)z_uidgid_p[1]))
+          {
+            Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+              z_uidgid_p[0], z_uidgid_p[1], FnFilter1(slnk_entry->fname),
+              strerror(errno)));
+          }
+        }
+      }
+# endif /* !NO_LCHOWN */
+# if (!defined(NO_LCHMOD))
+      TTrace((stderr,
+        "set_symlnk_attribs:  restoring Unix attributes for\n        %s\n",
+        FnFilter1(slnk_entry->fname)));
+      if (lchmod(slnk_entry->fname,
+                 filtattr(__G__ *(unsigned *)(zvoid *)slnk_entry->buf)))
+          perror("lchmod (file attributes) error");
+# endif /* !NO_LCHMOD */
+    }
+    /* currently, no error propagation... */
+    return PK_OK;
+} /* end function set_symlnk_attribs() */
+#endif /* SYMLINKS && SET_SYMLINK_ATTRIBS */
+
+
+#ifdef SET_DIR_ATTRIB
+/* messages of code for setting directory attributes */
+#  ifndef NO_CHMOD
+  static ZCONST char DirlistChmodFailed[] =
+    "warning:  cannot set permissions for %s\n          %s\n";
+#  endif
+
+
+int defer_dir_attribs(__G__ pd)
+    __GDEF
+    direntry **pd;
+{
+    uxdirattr *d_entry;
+
+    d_entry = (uxdirattr *)malloc(sizeof(uxdirattr) + strlen(G.filename));
+    *pd = (direntry *)d_entry;
+    if (d_entry == (uxdirattr *)NULL) {
+        return PK_MEM;
+    }
+    d_entry->fn = d_entry->fnbuf;
+    strcpy(d_entry->fn, G.filename);
+
+    d_entry->perms = G.pInfo->file_attr;
+
+    d_entry->have_uidgid = get_extattribs(__G__ &(d_entry->u.t3),
+                                          d_entry->uidgid);
+    return PK_OK;
+} /* end function defer_dir_attribs() */
+
+
+int set_direc_attribs(__G__ d)
+    __GDEF
+    direntry *d;
+{
+    int errval = PK_OK;
+
+    if (UxAtt(d)->have_uidgid &&
+        /* check that both uid and gid values fit into their data sizes */
+        ((ulg)(uid_t)(UxAtt(d)->uidgid[0]) == UxAtt(d)->uidgid[0]) &&
+        ((ulg)(gid_t)(UxAtt(d)->uidgid[1]) == UxAtt(d)->uidgid[1]) &&
+        chown(UxAtt(d)->fn, (uid_t)UxAtt(d)->uidgid[0],
+              (gid_t)UxAtt(d)->uidgid[1]))
+    {
+        Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+          UxAtt(d)->uidgid[0], UxAtt(d)->uidgid[1], FnFilter1(d->fn),
+          strerror(errno)));
+        if (!errval)
+            errval = PK_WARN;
+    }
+    /* Skip restoring directory time stamps on user' request. */
+    if (uO.D_flag <= 0) {
+        /* restore directory timestamps */
+        if (utime(d->fn, &UxAtt(d)->u.t2)) {
+            Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
+              FnFilter1(d->fn), strerror(errno)));
+            if (!errval)
+                errval = PK_WARN;
+        }
+    }
+#ifndef NO_CHMOD
+    if (chmod(d->fn, UxAtt(d)->perms)) {
+        Info(slide, 0x201, ((char *)slide, DirlistChmodFailed,
+          FnFilter1(d->fn), strerror(errno)));
+        if (!errval)
+            errval = PK_WARN;
+    }
+#endif /* !NO_CHMOD */
+    return errval;
+} /* end function set_direc_attribs() */
+
+#endif /* SET_DIR_ATTRIB */
+
+
+
+
+#ifdef TIMESTAMP
+
+/***************************/
+/*  Function stamp_file()  */
+/***************************/
+
+int stamp_file(fname, modtime)
+    ZCONST char *fname;
+    time_t modtime;
+{
+    ztimbuf tp;
+
+    tp.modtime = tp.actime = modtime;
+    return (utime(fname, &tp));
+
+} /* end function stamp_file() */
+
+#endif /* TIMESTAMP */
+
+
+
+
+#ifndef SFX
+
+/************************/
+/*  Function version()  */
+/************************/
+
+void version(__G)
+    __GDEF
+{
+#if (defined(__GNUC__) && defined(NX_CURRENT_COMPILER_RELEASE))
+    char cc_namebuf[40];
+    char cc_versbuf[40];
+#else
+#if (defined(__SUNPRO_C))
+    char cc_versbuf[17];
+#else
+#if (defined(__HP_cc) || defined(__IBMC__))
+    char cc_versbuf[25];
+#else
+#if (defined(__DECC_VER))
+    char cc_versbuf[17];
+    int cc_verstyp;
+#else
+#if (defined(CRAY) && defined(_RELEASE))
+    char cc_versbuf[40];
+#endif /* (CRAY && _RELEASE) */
+#endif /* __DECC_VER */
+#endif /* __HP_cc || __IBMC__ */
+#endif /* __SUNPRO_C */
+#endif /* (__GNUC__ && NX_CURRENT_COMPILER_RELEASE) */
+
+#if ((defined(CRAY) || defined(cray)) && defined(_UNICOS))
+    char os_namebuf[40];
+#else
+#if defined(__NetBSD__)
+    char os_namebuf[40];
+#endif
+#endif
+
+    /* Pyramid, NeXT have problems with huge macro expansion, too:  no Info() */
+    sprintf((char *)slide, LoadFarString(CompiledWith),
+
+#ifdef __GNUC__
+#  ifdef NX_CURRENT_COMPILER_RELEASE
+      (sprintf(cc_namebuf, "NeXT DevKit %d.%02d ",
+        NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100),
+       cc_namebuf),
+      (strlen(__VERSION__) > 8)? "(gcc)" :
+        (sprintf(cc_versbuf, "(gcc %s)", __VERSION__), cc_versbuf),
+#  else
+      "gcc ", __VERSION__,
+#  endif
+#else
+#if defined(__SUNPRO_C)
+      "Sun C ", (sprintf(cc_versbuf, "version %x", __SUNPRO_C), cc_versbuf),
+#else
+#if (defined(__HP_cc))
+      "HP C ",
+      (((__HP_cc% 100) == 0) ?
+      (sprintf(cc_versbuf, "version A.%02d.%02d",
+      (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100))) :
+      (sprintf(cc_versbuf, "version A.%02d.%02d.%02d",
+      (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100), (__HP_cc% 100))),
+      cc_versbuf),
+#else
+#if (defined(__DECC_VER))
+      "DEC C ",
+      (sprintf(cc_versbuf, "%c%d.%d-%03d",
+               ((cc_verstyp = (__DECC_VER / 10000) % 10) == 6 ? 'T' :
+                (cc_verstyp == 8 ? 'S' : 'V')),
+               __DECC_VER / 10000000,
+               (__DECC_VER % 10000000) / 100000, __DECC_VER % 1000),
+               cc_versbuf),
+#else
+#if defined(CRAY) && defined(_RELEASE)
+      "cc ", (sprintf(cc_versbuf, "version %d", _RELEASE), cc_versbuf),
+#else
+#ifdef __IBMC__
+      "IBM C ",
+      (sprintf(cc_versbuf, "version %d.%d.%d",
+               (__IBMC__ / 100), ((__IBMC__ / 10) % 10), (__IBMC__ % 10)),
+               cc_versbuf),
+#else
+#ifdef __VERSION__
+#   ifndef IZ_CC_NAME
+#    define IZ_CC_NAME "cc "
+#   endif
+      IZ_CC_NAME, __VERSION__
+#else
+#   ifndef IZ_CC_NAME
+#    define IZ_CC_NAME "cc"
+#   endif
+      IZ_CC_NAME, "",
+#endif /* ?__VERSION__ */
+#endif /* ?__IBMC__ */
+#endif /* ?(CRAY && _RELEASE) */
+#endif /* ?__DECC_VER */
+#endif /* ?__HP_cc */
+#endif /* ?__SUNPRO_C */
+#endif /* ?__GNUC__ */
+
+#ifndef IZ_OS_NAME
+#  define IZ_OS_NAME "Unix"
+#endif
+      IZ_OS_NAME,
+
+#if defined(sgi) || defined(__sgi)
+      " (Silicon Graphics IRIX)",
+#else
+#ifdef sun
+#  ifdef sparc
+#    ifdef __SVR4
+      " (Sun SPARC/Solaris)",
+#    else /* may or may not be SunOS */
+      " (Sun SPARC)",
+#    endif
+#  else
+#  if defined(sun386) || defined(i386)
+      " (Sun 386i)",
+#  else
+#  if defined(mc68020) || defined(__mc68020__)
+      " (Sun 3)",
+#  else /* mc68010 or mc68000:  Sun 2 or earlier */
+      " (Sun 2)",
+#  endif
+#  endif
+#  endif
+#else
+#ifdef __hpux
+      " (HP-UX)",
+#else
+#ifdef __osf__
+      " (DEC OSF/1)",
+#else
+#ifdef _AIX
+      " (IBM AIX)",
+#else
+#ifdef aiws
+      " (IBM RT/AIX)",
+#else
+#if defined(CRAY) || defined(cray)
+#  ifdef _UNICOS
+      (sprintf(os_namebuf, " (Cray UNICOS release %d)", _UNICOS), os_namebuf),
+#  else
+      " (Cray UNICOS)",
+#  endif
+#else
+#if defined(uts) || defined(UTS)
+      " (Amdahl UTS)",
+#else
+#ifdef NeXT
+#  ifdef mc68000
+      " (NeXTStep/black)",
+#  else
+      " (NeXTStep for Intel)",
+#  endif
+#else              /* the next dozen or so are somewhat order-dependent */
+#ifdef LINUX
+#  ifdef __ELF__
+      " (Linux ELF)",
+#  else
+      " (Linux a.out)",
+#  endif
+#else
+#ifdef MINIX
+      " (Minix)",
+#else
+#ifdef M_UNIX
+      " (SCO Unix)",
+#else
+#ifdef M_XENIX
+      " (SCO Xenix)",
+#else
+#ifdef __NetBSD__
+#  ifdef NetBSD0_8
+      (sprintf(os_namebuf, " (NetBSD 0.8%c)", (char)(NetBSD0_8 - 1 + 'A')),
+       os_namebuf),
+#  else
+#  ifdef NetBSD0_9
+      (sprintf(os_namebuf, " (NetBSD 0.9%c)", (char)(NetBSD0_9 - 1 + 'A')),
+       os_namebuf),
+#  else
+#  ifdef NetBSD1_0
+      (sprintf(os_namebuf, " (NetBSD 1.0%c)", (char)(NetBSD1_0 - 1 + 'A')),
+       os_namebuf),
+#  else
+      (BSD4_4 == 0.5)? " (NetBSD before 0.9)" : " (NetBSD 1.1 or later)",
+#  endif
+#  endif
+#  endif
+#else
+#ifdef __FreeBSD__
+      (BSD4_4 == 0.5)? " (FreeBSD 1.x)" : " (FreeBSD 2.0 or later)",
+#else
+#ifdef __bsdi__
+      (BSD4_4 == 0.5)? " (BSD/386 1.0)" : " (BSD/386 1.1 or later)",
+#else
+#ifdef __386BSD__
+      (BSD4_4 == 1)? " (386BSD, post-4.4 release)" : " (386BSD)",
+#else
+#ifdef __CYGWIN__
+      " (Cygwin)",
+#else
+#if defined(i686) || defined(__i686) || defined(__i686__)
+      " (Intel 686)",
+#else
+#if defined(i586) || defined(__i586) || defined(__i586__)
+      " (Intel 586)",
+#else
+#if defined(i486) || defined(__i486) || defined(__i486__)
+      " (Intel 486)",
+#else
+#if defined(i386) || defined(__i386) || defined(__i386__)
+      " (Intel 386)",
+#else
+#ifdef pyr
+      " (Pyramid)",
+#else
+#ifdef ultrix
+#  ifdef mips
+      " (DEC/MIPS)",
+#  else
+#  ifdef vax
+      " (DEC/VAX)",
+#  else /* __alpha? */
+      " (DEC/Alpha)",
+#  endif
+#  endif
+#else
+#ifdef gould
+      " (Gould)",
+#else
+#ifdef MTS
+      " (MTS)",
+#else
+#ifdef __convexc__
+      " (Convex)",
+#else
+#ifdef __QNX__
+      " (QNX 4)",
+#else
+#ifdef __QNXNTO__
+      " (QNX Neutrino)",
+#else
+#ifdef Lynx
+      " (LynxOS)",
+#else
+#ifdef __APPLE__
+#  ifdef __i386__
+      " Mac OS X Intel i32",
+#  else
+#  ifdef __ppc__
+      " Mac OS X PowerPC",
+#  else
+#  ifdef __ppc64__
+      " Mac OS X PowerPC64",
+#  else
+      " Mac OS X",
+#  endif /* __ppc64__ */
+#  endif /* __ppc__ */
+#  endif /* __i386__ */
+#else
+      "",
+#endif /* Apple */
+#endif /* Lynx */
+#endif /* QNX Neutrino */
+#endif /* QNX 4 */
+#endif /* Convex */
+#endif /* MTS */
+#endif /* Gould */
+#endif /* DEC */
+#endif /* Pyramid */
+#endif /* 386 */
+#endif /* 486 */
+#endif /* 586 */
+#endif /* 686 */
+#endif /* Cygwin */
+#endif /* 386BSD */
+#endif /* BSDI BSD/386 */
+#endif /* NetBSD */
+#endif /* FreeBSD */
+#endif /* SCO Xenix */
+#endif /* SCO Unix */
+#endif /* Minix */
+#endif /* Linux */
+#endif /* NeXT */
+#endif /* Amdahl */
+#endif /* Cray */
+#endif /* RT/AIX */
+#endif /* AIX */
+#endif /* OSF/1 */
+#endif /* HP-UX */
+#endif /* Sun */
+#endif /* SGI */
+
+#ifdef __DATE__
+      " on ", __DATE__
+#else
+      "", ""
+#endif
+    );
+
+    (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
+
+} /* end function version() */
+
+#endif /* !SFX */
+
+
+
+
+#ifdef QLZIP
+
+struct qdirect  {
+    long            d_length __attribute__ ((packed));  /* file length */
+    unsigned char   d_access __attribute__ ((packed));  /* file access type */
+    unsigned char   d_type __attribute__ ((packed));    /* file type */
+    long            d_datalen __attribute__ ((packed)); /* data length */
+    long            d_reserved __attribute__ ((packed));/* Unused */
+    short           d_szname __attribute__ ((packed));  /* size of name */
+    char            d_name[36] __attribute__ ((packed));/* name area */
+    long            d_update __attribute__ ((packed));  /* last update */
+    long            d_refdate __attribute__ ((packed));
+    long            d_backup __attribute__ ((packed));   /* EOD */
+};
+
+#define LONGID  "QDOS02"
+#define EXTRALEN (sizeof(struct qdirect) + 8)
+#define JBLONGID    "QZHD"
+#define JBEXTRALEN  (sizeof(jbextra)  - 4 * sizeof(char))
+
+typedef struct {
+    char        eb_header[4] __attribute__ ((packed));  /* place_holder */
+    char        longid[8] __attribute__ ((packed));
+    struct      qdirect     header __attribute__ ((packed));
+} qdosextra;
+
+typedef struct {
+    char        eb_header[4];                           /* place_holder */
+    char        longid[4];
+    struct      qdirect     header;
+} jbextra;
+
+
+
+/*  The following two functions SH() and LG() convert big-endian short
+ *  and long numbers into native byte order.  They are some kind of
+ *  counterpart to the generic UnZip's makeword() and makelong() functions.
+ */
+static ush SH(ush val)
+{
+    uch swapbuf[2];
+
+    swapbuf[1] = (uch)(val & 0xff);
+    swapbuf[0] = (uch)(val >> 8);
+    return (*(ush *)swapbuf);
+}
+
+
+
+static ulg LG(ulg val)
+{
+    /*  convert the big-endian unsigned long number `val' to the machine
+     *  dependent representation
+     */
+    ush swapbuf[2];
+
+    swapbuf[1] = SH((ush)(val & 0xffff));
+    swapbuf[0] = SH((ush)(val >> 16));
+    return (*(ulg *)swapbuf);
+}
+
+
+
+static void qlfix(__G__ ef_ptr, ef_len)
+    __GDEF
+    uch *ef_ptr;
+    unsigned ef_len;
+{
+    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,
+              "qlfix: block length %u > rest ef_size %u\n", eb_len,
+              ef_len - EB_HEADSIZE));
+            break;
+        }
+
+        switch (eb_id) {
+          case EF_QDOS:
+          {
+            struct _ntc_
+            {
+                long id;
+                long dlen;
+            } ntc;
+            long dlen = 0;
+
+            qdosextra   *extra = (qdosextra *)ef_ptr;
+            jbextra     *jbp   = (jbextra   *)ef_ptr;
+
+            if (!strncmp(extra->longid, LONGID, strlen(LONGID)))
+            {
+                if (eb_len != EXTRALEN)
+                    if (uO.qflag)
+                        Info(slide, 0x201, ((char *)slide,
+                          "warning:  invalid length in Qdos field for %s\n",
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x201, ((char *)slide,
+                          "warning:  invalid length in Qdos field"));
+
+                if (extra->header.d_type)
+                {
+                    dlen = extra->header.d_datalen;
+                }
+            }
+
+            if (!strncmp(jbp->longid, JBLONGID, strlen(JBLONGID)))
+            {
+                if (eb_len != JBEXTRALEN)
+                    if (uO.qflag)
+                        Info(slide, 0x201, ((char *)slide,
+                          "warning:  invalid length in QZ field for %s\n",
+                          FnFilter1(G.filename)));
+                    else
+                        Info(slide, 0x201, ((char *)slide,
+                          "warning:  invalid length in QZ field"));
+                if (jbp->header.d_type)
+                {
+                    dlen = jbp->header.d_datalen;
+                }
+            }
+
+            if ((long)LG(dlen) > 0)
+            {
+                zfseeko(G.outfile, -8, SEEK_END);
+                fread(&ntc, 8, 1, G.outfile);
+                if (ntc.id != *(long *)"XTcc")
+                {
+                    ntc.id = *(long *)"XTcc";
+                    ntc.dlen = dlen;
+                    fwrite (&ntc, 8, 1, G.outfile);
+                }
+                Info(slide, 0x201, ((char *)slide, "QData = %d", LG(dlen)));
+            }
+            return;     /* finished, cancel further extra field scanning */
+          }
+
+          default:
+            Trace((stderr,"qlfix: unknown extra field block, ID=%d\n",
+               eb_id));
+        }
+
+        /* Skip this extra field block */
+        ef_ptr += (eb_len + EB_HEADSIZE);
+        ef_len -= (eb_len + EB_HEADSIZE);
+    }
+}
+#endif /* QLZIP */
+
+
+typedef struct {
+    char *local_charset;
+    char *archive_charset;
+} CHARSET_MAP;
+
+/* A mapping of local <-> archive charsets used by default to convert filenames
+ * of DOS/Windows Zip archives. Currently very basic. */
+static CHARSET_MAP dos_charset_map[] = {
+    { "ANSI_X3.4-1968", "CP850" },
+    { "ISO-8859-1", "CP850" },
+    { "CP1252", "CP850" },
+    { "UTF-8", "CP866" },
+    { "KOI8-R", "CP866" },
+    { "KOI8-U", "CP866" },
+    { "ISO-8859-5", "CP866" }
+};
+
+char OEM_CP[MAX_CP_NAME] = "";
+char ISO_CP[MAX_CP_NAME] = "";
+
+/* Try to guess the default value of OEM_CP based on the current locale.
+ * ISO_CP is left alone for now. */
+void init_conversion_charsets()
+{
+    const char *local_charset;
+    int i;
+
+    /* Make a guess only if OEM_CP not already set. */ 
+    if(*OEM_CP == '\0') {
+    	local_charset = nl_langinfo(CODESET);
+    	for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
+    		if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
+    			strncpy(OEM_CP, dos_charset_map[i].archive_charset,
+    					MAX_CP_NAME - 1);
+
+			OEM_CP[MAX_CP_NAME - 1] = '\0';
+    			break;
+    		}
+    }
+}
+
+/* Convert a string from one encoding to the current locale using iconv().
+ * Be as non-intrusive as possible. If error is encountered during covertion
+ * just leave the string intact. */
+static void charset_to_intern(char *string, char *from_charset)
+{
+    iconv_t cd;
+    char *s,*d, *buf;
+    size_t slen, dlen, buflen;
+    const char *local_charset;
+
+    if(*from_charset == '\0')
+    	return;
+
+    buf = NULL;
+    local_charset = nl_langinfo(CODESET);
+
+    if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
+        return;
+
+    slen = strlen(string);
+    s = string;
+
+    /*  Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
+     *  as this function also gets called with G.outbuf in fileio.c
+     */
+    buflen = FILNAMSIZ;
+    if (OUTBUFSIZ + 1 < FILNAMSIZ)
+    {
+        buflen = OUTBUFSIZ + 1;
+    }
+
+    d = buf = malloc(buflen);
+    if(!d)
+    	goto cleanup;
+
+    bzero(buf,buflen);
+    dlen = buflen - 1;
+
+    if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
+    	goto cleanup;
+    strncpy(string, buf, buflen);
+
+    cleanup:
+    free(buf);
+    iconv_close(cd);
+}
+
+/* Convert a string from OEM_CP to the current locale charset. */
+inline void oem_intern(char *string)
+{
+    charset_to_intern(string, OEM_CP);
+}
+
+/* Convert a string from ISO_CP to the current locale charset. */
+inline void iso_intern(char *string)
+{
+    charset_to_intern(string, ISO_CP);
+}
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h	(revision 5)
@@ -0,0 +1,256 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+    Unix specific configuration section:
+  ---------------------------------------------------------------------------*/
+
+#ifndef __unxcfg_h
+#define __unxcfg_h
+
+
+/* LARGE FILE SUPPORT - 10/6/04 EG */
+/* This needs to be set before the includes so they set the right sizes */
+
+#if (defined(NO_LARGE_FILE_SUPPORT) && defined(LARGE_FILE_SUPPORT))
+#  undef LARGE_FILE_SUPPORT
+#endif
+
+/* Automatically set ZIP64_SUPPORT if LFS */
+#ifdef LARGE_FILE_SUPPORT
+# if (!defined(NO_ZIP64_SUPPORT) && !defined(ZIP64_SUPPORT))
+#   define ZIP64_SUPPORT
+# endif
+#endif
+
+/* NO_ZIP64_SUPPORT takes preceedence over ZIP64_SUPPORT */
+#if defined(NO_ZIP64_SUPPORT) && defined(ZIP64_SUPPORT)
+#  undef ZIP64_SUPPORT
+#endif
+
+#ifdef LARGE_FILE_SUPPORT
+  /* 64-bit Large File Support */
+
+  /* The following Large File Summit (LFS) defines turn on large file support
+     on Linux (probably 2.4 or later kernel) and many other unixen */
+
+  /* These have to be before any include that sets types so the large file
+     versions of the types are set in the includes */
+
+# define _LARGEFILE_SOURCE      /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64   /* select default interface as 64 bit */
+# define _LARGE_FILES           /* some OSes need this for 64-bit off_t */
+# define __USE_LARGEFILE64
+#endif /* LARGE_FILE_SUPPORT */
+
+
+#include <sys/types.h>          /* off_t, time_t, dev_t, ... */
+#include <sys/stat.h>
+
+#ifdef NO_OFF_T
+  typedef long zoff_t;
+#else
+  typedef off_t zoff_t;
+#endif
+#define ZOFF_T_DEFINED
+typedef struct stat z_stat;
+#define Z_STAT_DEFINED
+
+#ifndef COHERENT
+#  include <fcntl.h>            /* O_BINARY for open() w/o CR/LF translation */
+#else /* COHERENT */
+#  ifdef _I386
+#    include <fcntl.h>          /* Coherent 4.0.x, Mark Williams C */
+#  else
+#    include <sys/fcntl.h>      /* Coherent 3.10, Mark Williams C */
+#  endif
+#  define SHORT_SYMS
+#  ifndef __COHERENT__          /* Coherent 4.2 has tzset() */
+#    define tzset  settz
+#  endif
+#endif /* ?COHERENT */
+
+#ifndef NO_PARAM_H
+#  ifdef NGROUPS_MAX
+#    undef NGROUPS_MAX      /* SCO bug:  defined again in <sys/param.h> */
+#  endif
+#  ifdef BSD
+#    define TEMP_BSD        /* may be defined again in <sys/param.h> */
+#    undef BSD
+#  endif
+#  include <sys/param.h>    /* conflict with <sys/types.h>, some systems? */
+#  ifdef TEMP_BSD
+#    undef TEMP_BSD
+#    ifndef BSD
+#      define BSD
+#    endif
+#  endif
+#endif /* !NO_PARAM_H */
+
+#ifdef __osf__
+#  define DIRENT
+#  ifdef BSD
+#    undef BSD
+#  endif
+#endif /* __osf__ */
+
+#ifdef __CYGWIN__
+#  include <unistd.h>
+#  define DIRENT
+#  define HAVE_TERMIOS_H
+#  ifndef timezone
+#    define timezone _timezone
+#  endif
+#endif
+
+#ifdef BSD
+#  include <sys/time.h>
+#  include <sys/timeb.h>
+#  if (defined(_AIX) || defined(__GLIBC__) || defined(__GNU__))
+#    include <time.h>
+#  endif
+#else
+#  include <time.h>
+   struct tm *gmtime(), *localtime();
+#endif
+
+#if (defined(BSD4_4) || (defined(SYSV) && defined(MODERN)))
+#  include <unistd.h>           /* this includes utime.h on SGIs */
+#  if (defined(BSD4_4) || defined(linux) || defined(__GLIBC__))
+#    include <utime.h>
+#    define GOT_UTIMBUF
+#  endif
+#  if (!defined(GOT_UTIMBUF) && (defined(__hpux) || defined(__SUNPRO_C)))
+#    include <utime.h>
+#    define GOT_UTIMBUF
+#  endif
+#  if (!defined(GOT_UTIMBUF) && defined(__GNU__))
+#    include <utime.h>
+#    define GOT_UTIMBUF
+#  endif
+#endif
+#if (defined(__DGUX__) && !defined(GOT_UTIMBUF))
+   /* DG/UX requires this because of a non-standard struct utimebuf */
+#  include <utime.h>
+#  define GOT_UTIMBUF
+#endif
+
+#if (defined(V7) || defined(pyr_bsd))
+#  define strchr   index
+#  define strrchr  rindex
+#endif
+#ifdef V7
+#  define O_RDONLY 0
+#  define O_WRONLY 1
+#  define O_RDWR   2
+#endif
+
+#if defined(NO_UNICODE_SUPPORT) && defined(UNICODE_SUPPORT)
+   /* disable Unicode (UTF-8) support when requested */
+#  undef UNICODE_SUPPORT
+#endif
+
+#if (defined(_MBCS) && defined(NO_MBCS))
+   /* disable MBCS support when requested */
+#  undef _MBCS
+#endif
+
+#if (!defined(NO_SETLOCALE) && !defined(_MBCS))
+# if (!defined(UNICODE_SUPPORT) || !defined(UTF8_MAYBE_NATIVE))
+   /* enable setlocale here, unless this happens later for UTF-8 and/or
+    * MBCS support */
+#  include <locale.h>
+#  ifndef SETLOCALE
+#    define SETLOCALE(category, locale) setlocale(category, locale)
+#  endif
+# endif
+#endif
+#ifndef NO_SETLOCALE
+# if (!defined(NO_WORKING_ISPRINT) && !defined(HAVE_WORKING_ISPRINT))
+   /* enable "enhanced" unprintable chars detection in fnfilter() */
+#  define HAVE_WORKING_ISPRINT
+# endif
+#endif
+
+#ifdef MINIX
+#  include <stdio.h>
+#endif
+#if (!defined(HAVE_STRNICMP) & !defined(NO_STRNICMP))
+#  define NO_STRNICMP
+#endif
+#ifndef DATE_FORMAT
+#  define DATE_FORMAT DF_MDY    /* GRR:  customize with locale.h somehow? */
+#endif
+#define lenEOL          1
+#ifdef EBCDIC
+#  define PutNativeEOL  *q++ = '\n';
+#else
+#  define PutNativeEOL  *q++ = native(LF);
+#endif
+#define SCREENSIZE(ttrows, ttcols)  screensize(ttrows, ttcols)
+#define SCREENWIDTH     80
+#define SCREENLWRAP     1
+#define USE_EF_UT_TIME
+#if (!defined(NO_LCHOWN) || !defined(NO_LCHMOD))
+#  define SET_SYMLINK_ATTRIBS
+#endif
+#ifdef MTS
+#  ifdef SET_DIR_ATTRIB
+#    undef SET_DIR_ATTRIB
+#  endif
+#else /* !MTS */
+#  define SET_DIR_ATTRIB
+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))   /* GRR 970513 */
+#    define TIMESTAMP
+#  endif
+#  define RESTORE_UIDGID
+#endif /* ?MTS */
+
+/* Static variables that we have to add to Uz_Globs: */
+#define SYSTEM_SPECIFIC_GLOBALS \
+    int created_dir, renamed_fullpath;\
+    char *rootpath, *buildpath, *end;\
+    ZCONST char *wildname;\
+    char *dirname, matchname[FILNAMSIZ];\
+    int rootlen, have_dirname, dirnamelen, notfirstcall;\
+    zvoid *wild_dir;
+
+/* created_dir, and renamed_fullpath are used by both mapname() and    */
+/*    checkdir().                                                      */
+/* rootlen, rootpath, buildpath and end are used by checkdir().        */
+/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
+/*    and notfirstcall are used by do_wild().                          */
+
+
+#define MAX_CP_NAME 25 + 1 
+   
+#ifdef SETLOCALE
+#  undef SETLOCALE
+#endif
+#define SETLOCALE(category, locale) setlocale(category, locale)
+#include <locale.h>
+   
+#ifdef _ISO_INTERN
+#  undef _ISO_INTERN
+#endif
+#define _ISO_INTERN(str1) iso_intern(str1)
+
+#ifdef _OEM_INTERN
+#  undef _OEM_INTERN
+#endif
+#ifndef IZ_OEM2ISO_ARRAY
+#  define IZ_OEM2ISO_ARRAY
+#endif
+#define _OEM_INTERN(str1) oem_intern(str1)
+
+void iso_intern(char *);
+void oem_intern(char *);
+void init_conversion_charsets(void);
+   
+#endif /* !__unxcfg_h */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix	(revision 5)

Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/unix
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch/unzip60-new/unzip.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unzip.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unzip.c	(revision 5)
@@ -0,0 +1,2747 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+
+  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.
+
+  UnZip 6.0 adds 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.
+
+  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!
+
+  Author:  Greg Roelofs, newt@pobox.com, http://pobox.com/~newt/
+           23 August 1990 -> April 1997
+
+  ---------------------------------------------------------------------------
+
+  Version:  unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
+              Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
+              AtheOS, BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos
+              and TOPS-20.
+
+  Copyrights:  see accompanying file "LICENSE" in UnZip source distribution.
+               (This software is free but NOT IN THE PUBLIC DOMAIN.)
+
+  ---------------------------------------------------------------------------*/
+
+
+
+#define __UNZIP_C       /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"      /* includes, typedefs, macros, prototypes, etc. */
+#include "crypt.h"
+#include "unzvers.h"
+
+#ifndef WINDLL          /* The WINDLL port uses windll/windll.c instead... */
+
+/***************************/
+/* Local type declarations */
+/***************************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+typedef struct _sign_info
+    {
+        struct _sign_info *previous;
+        void (*sighandler)(int);
+        int sigtype;
+    } savsigs_info;
+#endif
+
+/*******************/
+/* Local Functions */
+/*******************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
+                                int signal_type, void (*newhandler)(int)));
+#endif
+#ifndef SFX
+static void  help_extended      OF((__GPRO));
+static void  show_version_info  OF((__GPRO));
+#endif
+
+
+/*************/
+/* Constants */
+/*************/
+
+#include "consts.h"  /* all constant global variables are in here */
+                     /* (non-constant globals were moved to globals.c) */
+
+/* constant local variables: */
+
+#ifndef SFX
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+   static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
+   static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
+   static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
+   static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
+#ifdef RISCOS
+   static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
+#endif /* RISCOS */
+  static ZCONST char Far NoMemEnvArguments[] =
+    "envargs:  cannot get memory for arguments";
+#endif /* !_WIN32_WCE */
+  static ZCONST char Far CmdLineParamTooLong[] =
+    "error:  command line parameter #%d exceeds internal size limit\n";
+#endif /* !SFX */
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+  static ZCONST char Far CantSaveSigHandler[] =
+    "error:  cannot save signal handler settings\n";
+#endif
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+   static ZCONST char Far NotExtracting[] =
+     "caution:  not extracting; -d ignored\n";
+   static ZCONST char Far MustGiveExdir[] =
+     "error:  must specify directory to which to extract with -d option\n";
+   static ZCONST char Far OnlyOneExdir[] =
+     "error:  -d option used more than once (only one exdir allowed)\n";
+#endif
+#if (defined(UNICODE_SUPPORT) && !defined(UNICODE_WCHAR))
+  static ZCONST char Far UTF8EscapeUnSupp[] =
+    "warning:  -U \"escape all non-ASCII UTF-8 chars\" is not supported\n";
+#endif
+
+#if CRYPT
+   static ZCONST char Far MustGivePasswd[] =
+     "error:  must give decryption password with -P option\n";
+#endif
+
+#ifndef SFX
+   static ZCONST char Far Zfirst[] =
+   "error:  -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
+#endif
+static ZCONST char Far InvalidOptionsMsg[] = "error:\
+  -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
+static ZCONST char Far IgnoreOOptionMsg[] =
+  "caution:  both -n and -o specified; ignoring -o\n";
+
+/* usage() strings */
+#ifndef SFX
+#ifdef VMS
+   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 */
+   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 */
+#if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
+   static ZCONST char Far Example2[] =
+     "";                /* no room:  too many local3[] items */
+#else /* !OS2 */
+#ifdef MACOS
+   static ZCONST char Far Example2[] = ""; /* not needed */
+#else /* !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 */
+
+/* local1[]:  command options */
+#if defined(TIMESTAMP)
+   static ZCONST char Far local1[] =
+     "  -T  timestamp archive to latest";
+#else /* !TIMESTAMP */
+   static ZCONST char Far local1[] = "";
+#endif /* ?TIMESTAMP */
+
+/* local2[] and local3[]:  modifier options */
+#ifdef DOS_FLX_H68_OS2_W32
+#ifdef FLEXOS
+   static ZCONST char Far local2[] = "";
+#else
+   static ZCONST char Far local2[] =
+     " -$  label removables (-$$ => fixed disks)";
+#endif
+#ifdef OS2
+#ifdef MORE
+   static ZCONST char Far local3[] = "\
+  -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\
+                                             -M  pipe through \"more\" pager\n";
+#else
+   static ZCONST char Far local3[] = " \
+ -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !OS2 */
+#ifdef WIN32
+#ifdef NTSD_EAS
+#ifdef MORE
+   static ZCONST char Far local3[] = "\
+  -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\
+                                             -M  pipe through \"more\" pager\n";
+#else
+   static ZCONST char Far local3[] = " \
+ -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !NTSD_EAS */
+#ifdef MORE
+   static ZCONST char Far local3[] = "\
+  -M  pipe through \"more\" pager            \
+  -s  spaces in filenames => '_'\n\n";
+#else
+   static ZCONST char Far local3[] = " \
+                                            -s  spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#endif /* ?NTSD_EAS */
+#else /* !WIN32 */
+#ifdef MORE
+   static ZCONST char Far local3[] = "  -\
+M  pipe through \"more\" pager              -s  spaces in filenames => '_'\n\n";
+#else
+   static ZCONST char Far local3[] = "\
+                                             -s  spaces in filenames => '_'\n";
+#endif
+#endif /* ?WIN32 */
+#endif /* ?OS2 || ?WIN32 */
+#else /* !DOS_FLX_OS2_W32 */
+#ifdef VMS
+   static ZCONST char Far local2[] = " -X  restore owner/ACL protection info";
+#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\
+  (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
+\n\n";
+#else
+   static ZCONST char Far local3[] = "\n\
+  -Y  treat \".nnn\" as \";nnn\" version         -2  force ODS2 names\n\
+  --D restore dir (-D: no) timestamps\n\
+  (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
+\n\n";
+#endif
+#else /* !VMS */
+#ifdef ATH_BEO_UNX
+   static ZCONST char Far local2[] = " -X  restore UID/GID info";
+#ifdef MORE
+   static ZCONST char Far local3[] = "\
+  -K  keep setuid/setgid/tacky permissions   -M  pipe through \"more\" pager\n";
+#else
+   static ZCONST char Far local3[] = "\
+  -K  keep setuid/setgid/tacky permissions\n";
+#endif
+#else /* !ATH_BEO_UNX */
+#ifdef TANDEM
+   static ZCONST char Far local2[] = "\
+ -X  restore Tandem User ID                 -r  remove file extensions\n\
+  -b  create 'C' (180) text files          ";
+#ifdef MORE
+   static ZCONST char Far local3[] = " \
+                                            -M  pipe through \"more\" pager\n";
+#else
+   static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !TANDEM */
+#ifdef AMIGA
+   static ZCONST char Far local2[] = " -N  restore comments as filenotes";
+#ifdef MORE
+   static ZCONST char Far local3[] = " \
+                                            -M  pipe through \"more\" pager\n";
+#else
+   static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !AMIGA */
+#ifdef MACOS
+   static ZCONST char Far local2[] = " -E  show Mac info during extraction";
+   static ZCONST char Far local3[] = " \
+ -i  ignore filenames in mac extra info     -J  junk (ignore) Mac extra info\n\
+\n";
+#else /* !MACOS */
+#ifdef MORE
+   static ZCONST char Far local2[] = " -M  pipe through \"more\" pager";
+   static ZCONST char Far local3[] = "\n";
+#else
+   static ZCONST char Far local2[] = "";   /* Atari, Mac, CMS/MVS etc. */
+   static ZCONST char Far local3[] = "";
+#endif
+#endif /* ?MACOS */
+#endif /* ?AMIGA */
+#endif /* ?TANDEM */
+#endif /* ?ATH_BEO_UNX */
+#endif /* ?VMS */
+#endif /* ?DOS_FLX_OS2_W32 */
+#endif /* !SFX */
+
+#ifndef NO_ZIPINFO
+#ifdef VMS
+   static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
+#else
+   static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
+#endif
+
+static ZCONST char Far ZipInfoUsageLine1[] = "\
+ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
+\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\
+                                         -v  verbose, multi-page format\n";
+
+#ifndef UNIX
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\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";
+#else /* UNIX */
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+  -h  print header line       -t  print totals for listed files or for all\n\
+  -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
+\n %c-C%c be case-insensitive   %s\
+  -x  exclude filenames that follow from listing\n\
+  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
+  -I CHARSET  specify a character encoding for UNIX and other archives\n";
+#endif /* !UNIX */
+#ifdef MORE
+   static ZCONST char Far ZipInfoUsageLine4[] =
+     "  -M  page output through built-in \"more\"\n";
+#else /* !MORE */
+   static ZCONST char Far ZipInfoUsageLine4[] = "";
+#endif /* ?MORE */
+#endif /* !NO_ZIPINFO */
+
+#ifdef BETA
+#  ifdef VMSCLI
+   /* BetaVersion[] is also used in vms/cmdline.c:  do not make it static */
+     ZCONST char Far BetaVersion[] = "%s\
+        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+#  else
+     static ZCONST char Far BetaVersion[] = "%s\
+        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+#  endif
+#endif
+
+#ifdef SFX
+#  ifdef VMSCLI
+   /* UnzipSFXBanner[] is also used in vms/cmdline.c:  do not make it static */
+     ZCONST char Far UnzipSFXBanner[] =
+#  else
+     static ZCONST char Far UnzipSFXBanner[] =
+#  endif
+     "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (http://www.info-zip.org).\n";
+#  ifdef SFX_EXDIR
+     static ZCONST char Far UnzipSFXOpts[] =
+    "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
+#  else
+     static ZCONST char Far UnzipSFXOpts[] =
+       "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
+#  endif
+#else /* !SFX */
+   static ZCONST char Far CompileOptions[] =
+     "UnZip special compilation options:\n";
+   static ZCONST char Far CompileOptFormat[] = "        %s\n";
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+   static ZCONST char Far EnvOptions[] =
+     "\nUnZip and ZipInfo environment options:\n";
+   static ZCONST char Far EnvOptFormat[] = "%16s:  %.1024s\n";
+#endif
+   static ZCONST char Far None[] = "[none]";
+#  ifdef ACORN_FTYPE_NFS
+     static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
+#  endif
+#  ifdef ASM_CRC
+     static ZCONST char Far AsmCRC[] = "ASM_CRC";
+#  endif
+#  ifdef ASM_INFLATECODES
+     static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
+#  endif
+#  ifdef CHECK_VERSIONS
+     static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
+#  endif
+#  ifdef COPYRIGHT_CLEAN
+     static ZCONST char Far Copyright_Clean[] =
+     "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
+#  endif
+#  ifdef DEBUG
+     static ZCONST char Far UDebug[] = "DEBUG";
+#  endif
+#  ifdef DEBUG_TIME
+     static ZCONST char Far DebugTime[] = "DEBUG_TIME";
+#  endif
+#  ifdef DLL
+     static ZCONST char Far Dll[] = "DLL";
+#  endif
+#  ifdef DOSWILD
+     static ZCONST char Far DosWild[] = "DOSWILD";
+#  endif
+#  ifdef LZW_CLEAN
+     static ZCONST char Far LZW_Clean[] =
+     "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
+#  endif
+#  ifndef MORE
+     static ZCONST char Far No_More[] = "NO_MORE";
+#  endif
+#  ifdef NO_ZIPINFO
+     static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
+#  endif
+#  ifdef NTSD_EAS
+     static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
+#  endif
+#  if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+     static ZCONST char Far W32NoIZTimeFix[] = "NO_W32TIMES_IZFIX";
+#  endif
+#  ifdef OLD_THEOS_EXTRA
+     static ZCONST char Far OldTheosExtra[] =
+     "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
+#  endif
+#  ifdef OS2_EAS
+     static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
+#  endif
+#  ifdef QLZIP
+     static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
+#  endif
+#  ifdef REENTRANT
+     static ZCONST char Far Reentrant[] = "REENTRANT";
+#  endif
+#  ifdef REGARGS
+     static ZCONST char Far RegArgs[] = "REGARGS";
+#  endif
+#  ifdef RETURN_CODES
+     static ZCONST char Far Return_Codes[] = "RETURN_CODES";
+#  endif
+#  ifdef SET_DIR_ATTRIB
+     static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
+#  endif
+#  ifdef SYMLINKS
+     static ZCONST char Far SymLinkSupport[] =
+     "SYMLINKS (symbolic links supported, if RTL and file system permit)";
+#  endif
+#  ifdef TIMESTAMP
+     static ZCONST char Far TimeStamp[] = "TIMESTAMP";
+#  endif
+#  ifdef UNIXBACKUP
+     static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
+#  endif
+#  ifdef USE_EF_UT_TIME
+     static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
+#  endif
+#  ifndef LZW_CLEAN
+     static ZCONST char Far Use_Unshrink[] =
+     "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
+#  endif
+#  ifndef COPYRIGHT_CLEAN
+     static ZCONST char Far Use_Smith_Code[] =
+     "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
+#  endif
+#  ifdef USE_DEFLATE64
+     static ZCONST char Far Use_Deflate64[] =
+     "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
+#  endif
+#  ifdef UNICODE_SUPPORT
+#   ifdef UTF8_MAYBE_NATIVE
+#    ifdef UNICODE_WCHAR
+       /* direct native UTF-8 check AND charset transform via wchar_t */
+       static ZCONST char Far Use_Unicode[] =
+       "UNICODE_SUPPORT [wide-chars, char coding: %s] (handle UTF-8 paths)";
+#    else
+       /* direct native UTF-8 check, only */
+       static ZCONST char Far Use_Unicode[] =
+       "UNICODE_SUPPORT [char coding: %s] (handle UTF-8 paths)";
+#    endif
+       static ZCONST char Far SysChUTF8[] = "UTF-8";
+       static ZCONST char Far SysChOther[] = "other";
+#   else /* !UTF8_MAYBE_NATIVE */
+       /* charset transform via wchar_t, no native UTF-8 support */
+       static ZCONST char Far Use_Unicode[] =
+       "UNICODE_SUPPORT [wide-chars] (handle UTF-8 paths)";
+#   endif /* ?UTF8_MAYBE_NATIVE */
+#  endif /* UNICODE_SUPPORT */
+#  ifdef _MBCS
+     static ZCONST char Far Have_MBCS_Support[] =
+     "MBCS-support (multibyte character support, MB_CUR_MAX = %u)";
+#  endif
+#  ifdef MULT_VOLUME
+     static ZCONST char Far Use_MultiVol[] =
+     "MULT_VOLUME (multi-volume archives supported)";
+#  endif
+#  ifdef LARGE_FILE_SUPPORT
+     static ZCONST char Far Use_LFS[] =
+     "LARGE_FILE_SUPPORT (large files over 2 GiB supported)";
+#  endif
+#  ifdef ZIP64_SUPPORT
+     static ZCONST char Far Use_Zip64[] =
+     "ZIP64_SUPPORT (archives using Zip64 for large files supported)";
+#  endif
+#  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+#    ifdef USE_DJGPP_ENV
+       static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
+#    endif
+#    ifdef USE_DJGPP_GLOB
+       static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
+#    endif
+#  endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+#  ifdef USE_VFAT
+     static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
+#  endif
+#  ifdef USE_ZLIB
+     static ZCONST char Far UseZlib[] =
+     "USE_ZLIB (compiled with version %s; using version %s)";
+#  endif
+#  ifdef USE_BZIP2
+     static ZCONST char Far UseBZip2[] =
+     "USE_BZIP2 (PKZIP 4.6+, using bzip2 lib version %s)";
+#  endif
+#  ifdef VMS_TEXT_CONV
+     static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
+#  endif
+#  ifdef VMSCLI
+     static ZCONST char Far VmsCLI[] = "VMSCLI";
+#  endif
+#  ifdef VMSWILD
+     static ZCONST char Far VmsWild[] = "VMSWILD";
+#  endif
+#  ifdef WILD_STOP_AT_DIR
+     static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
+#  endif
+#  if CRYPT
+#    ifdef PASSWD_FROM_STDIN
+       static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
+#    endif
+     static ZCONST char Far Decryption[] =
+       "        [decryption, version %d.%d%s of %s]\n";
+     static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
+#  endif
+#  ifndef __RSXNT__
+#    ifdef __EMX__
+       static ZCONST char Far EnvEMX[] = "EMX";
+       static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
+#    endif
+#    if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+       static ZCONST char Far EnvGO32[] = "GO32";
+       static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
+#    endif
+#  endif /* !__RSXNT__ */
+
+#ifdef VMS
+/* UnzipUsageLine1[] is also used in vms/cmdline.c:  do not make it static */
+   ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP.  For more details see: unzip -v.\n\n";
+# ifdef COPYRIGHT_CLEAN
+   static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+   static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+#else /* !VMS */
+# ifdef COPYRIGHT_CLEAN
+   static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+   static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+# define UnzipUsageLine1v       UnzipUsageLine1
+#endif /* ?VMS */
+
+static ZCONST char Far UnzipUsageLine2v[] = "\
+Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
+\nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
+\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\
+  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;\
+\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\
+  file[.zip] may be a wildcard.  %s\n";
+#endif /* ?VM_CMS */
+#endif /* ?MACOS */
+
+#ifdef NO_ZIPINFO
+#  define ZIPINFO_MODE_OPTION  ""
+   static ZCONST char Far ZipInfoMode[] =
+     "(ZipInfo mode is disabled in this version.)";
+#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\
+  -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 */
+#ifdef VM_CMS
+static ZCONST char Far UnzipUsageLine3[] = "\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\
+  -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 */
+
+/* There is not enough space on a standard 80x25 Windows console screen for
+ * the additional line advertising the UTF-8 debugging options. This may
+ * eventually also be the case for other ports. Probably, the -U option need
+ * not be shown on the introductory screen at all. [Chr. Spieler, 2008-02-09]
+ *
+ * Likely, other advanced options should be moved to an extended help page and
+ * the option to list that page put here.  [E. Gordon, 2008-3-16]
+ */
+#if (defined(UNICODE_SUPPORT) && !defined(WIN32))
+#ifdef VMS
+static ZCONST char Far UnzipUsageLine4[] = "\
+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  junk paths (do not make directories)   -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";
+#elif (defined UNIX)
+static ZCONST char Far UnzipUsageLine4[] = "\
+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  junk paths (do not make directories)   -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\
+  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
+  -I CHARSET  specify a character encoding for UNIX and other archives\n\n";
+#else /* !VMS */
+static ZCONST char Far UnzipUsageLine4[] = "\
+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  junk paths (do not make directories)   -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 */
+#ifdef VMS
+static ZCONST char Far UnzipUsageLine4[] = "\
+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  junk paths (do not make directories)   -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 */
+static ZCONST char Far UnzipUsageLine4[] = "\
+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  junk paths (do not make directories)   -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 */
+
+static ZCONST char Far UnzipUsageLine5[] = "\
+See \"unzip -hh\" or unzip.txt for more help.  Examples:\n\
+  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip\n\
+%s\
+  unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
+#endif /* ?SFX */
+
+
+
+
+
+/*****************************/
+/*  main() / UzpMain() stub  */
+/*****************************/
+
+int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
+    int argc;
+    char *argv[];
+{
+    int r;
+
+    CONSTRUCTGLOBALS();
+    r = unzip(__G__ argc, argv);
+    DESTROYGLOBALS();
+    RETURN(r);
+}
+
+
+
+
+/*******************************/
+/*  Primary UnZip entry point  */
+/*******************************/
+
+int unzip(__G__ argc, argv)
+    __GDEF
+    int argc;
+    char *argv[];
+{
+#ifndef NO_ZIPINFO
+    char *p;
+#endif
+#if (defined(DOS_FLX_H68_NLM_OS2_W32) || !defined(SFX))
+    int i;
+#endif
+    int retcode, error=FALSE;
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef REENTRANT
+    savsigs_info *oldsighandlers = NULL;
+#   define SET_SIGHANDLER(sigtype, newsighandler) \
+      if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
+                                      (newsighandler))) > PK_WARN) \
+          goto cleanup_and_exit
+#else
+#   define SET_SIGHANDLER(sigtype, newsighandler) \
+      signal((sigtype), (newsighandler))
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+    /* initialize international char support to the current environment */
+    SETLOCALE(LC_CTYPE, "");
+
+#ifdef UNICODE_SUPPORT
+    /* see if can use UTF-8 Unicode locale */
+# ifdef UTF8_MAYBE_NATIVE
+    {
+        char *codeset;
+#  if !(defined(NO_NL_LANGINFO) || defined(NO_LANGINFO_H))
+        /* get the codeset (character set encoding) currently used */
+#       include <langinfo.h>
+
+        codeset = nl_langinfo(CODESET);
+#  else /* NO_NL_LANGINFO || NO_LANGINFO_H */
+        /* query the current locale setting for character classification */
+        codeset = setlocale(LC_CTYPE, NULL);
+        if (codeset != NULL) {
+            /* extract the codeset portion of the locale name */
+            codeset = strchr(codeset, '.');
+            if (codeset != NULL) ++codeset;
+        }
+#  endif /* ?(NO_NL_LANGINFO || NO_LANGINFO_H) */
+        /* is the current codeset UTF-8 ? */
+        if ((codeset != NULL) && (strcmp(codeset, "UTF-8") == 0)) {
+            /* successfully found UTF-8 char coding */
+            G.native_is_utf8 = TRUE;
+        } else {
+            /* Current codeset is not UTF-8 or cannot be determined. */
+            G.native_is_utf8 = FALSE;
+        }
+        /* Note: At least for UnZip, trying to change the process codeset to
+         *       UTF-8 does not work.  For the example Linux setup of the
+         *       UnZip maintainer, a successful switch to "en-US.UTF-8"
+         *       resulted in garbage display of all non-basic ASCII characters.
+         */
+    }
+# endif /* UTF8_MAYBE_NATIVE */
+
+    /* initialize Unicode */
+    G.unicode_escape_all = 0;
+    G.unicode_mismatch = 0;
+
+    G.unipath_version = 0;
+    G.unipath_checksum = 0;
+    G.unipath_filename = NULL;
+#endif /* UNICODE_SUPPORT */
+
+
+#ifdef UNIX
+    init_conversion_charsets();
+#endif
+
+#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
+    extern void DebugMalloc(void);
+
+    atexit(DebugMalloc);
+#endif
+
+#ifdef MALLOC_WORK
+    /* The following (rather complex) expression determines the allocation
+       size of the decompression work area.  It simulates what the
+       combined "union" and "struct" declaration of the "static" work
+       area reservation achieves automatically at compile time.
+       Any decent compiler should evaluate this expression completely at
+       compile time and provide constants to the zcalloc() call.
+       (For better readability, some subexpressions are encapsulated
+       in temporarly defined macros.)
+     */
+#   define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
+#   define UZ_NUMOF_CHUNKS \
+      (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
+                 (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
+    G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
+#   undef UZ_SLIDE_CHUNK
+#   undef UZ_NUMOF_CHUNKS
+    G.area.shrink.Parent = (shrint *)G.area.Slide;
+    G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
+    G.area.shrink.Stack = G.area.Slide +
+                           (sizeof(shrint) + sizeof(uch))*(HSIZE);
+#endif
+
+/*---------------------------------------------------------------------------
+    Set signal handler for restoring echo, warn of zipfile corruption, etc.
+  ---------------------------------------------------------------------------*/
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef SIGINT
+    SET_SIGHANDLER(SIGINT, handler);
+#endif
+#ifdef SIGTERM                 /* some systems really have no SIGTERM */
+    SET_SIGHANDLER(SIGTERM, handler);
+#endif
+#if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
+    SET_SIGHANDLER(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+    SET_SIGHANDLER(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+    SET_SIGHANDLER(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+    SET_SIGHANDLER(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+    SET_SIGHANDLER(SIGSEGV, handler);
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+#if (defined(WIN32) && defined(__RSXNT__))
+    for (i = 0 ; i < argc; i++) {
+        _ISO_INTERN(argv[i]);
+    }
+#endif
+
+/*---------------------------------------------------------------------------
+    Macintosh initialization code.
+  ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+    {
+        int a;
+
+        for (a = 0;  a < 4;  ++a)
+            G.rghCursor[a] = GetCursor(a+128);
+        G.giCursor = 0;
+    }
+#endif
+
+/*---------------------------------------------------------------------------
+    NetWare initialization code.
+  ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+    InitUnZipConsole();
+#endif
+
+/*---------------------------------------------------------------------------
+    Acorn RISC OS initialization code.
+  ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+    set_prefix();
+#endif
+
+/*---------------------------------------------------------------------------
+    Theos initialization code.
+  ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+    /* The easiest way found to force creation of libraries when selected
+     * members are to be unzipped. Explicitly add libraries names to the
+     * arguments list before the first member of the library.
+     */
+    if (! _setargv(&argc, &argv)) {
+        Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
+        retcode = PK_MEM;
+        goto cleanup_and_exit;
+    }
+#endif
+
+/*---------------------------------------------------------------------------
+    Sanity checks.  Commentary by Otis B. Driftwood and Fiorello:
+
+    D:  It's all right.  That's in every contract.  That's what they
+        call a sanity clause.
+
+    F:  Ha-ha-ha-ha-ha.  You can't fool me.  There ain't no Sanity
+        Claus.
+  ---------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+# ifdef LARGE_FILE_SUPPORT
+  /* test if we can support large files - 10/6/04 EG */
+    if (sizeof(zoff_t) < 8) {
+        Info(slide, 0x401, ((char *)slide, "LARGE_FILE_SUPPORT set but not supported\n"));
+        retcode = PK_BADERR;
+        goto cleanup_and_exit;
+    }
+    /* test if we can show 64-bit values */
+    {
+        zoff_t z = ~(zoff_t)0;  /* z should be all 1s now */
+        char *sz;
+
+        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
+        if ((sz[0] != 'F') || (strlen(sz) != 16))
+        {
+            z = 0;
+        }
+
+        /* shift z so only MSB is set */
+        z <<= 63;
+        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
+        if ((sz[0] != '8') || (strlen(sz) != 16))
+        {
+            Info(slide, 0x401, ((char *)slide,
+              "Can't show 64-bit values correctly\n"));
+            retcode = PK_BADERR;
+            goto cleanup_and_exit;
+        }
+    }
+# endif /* LARGE_FILE_SUPPORT */
+
+    /* 2004-11-30 SMS.
+       Test the NEXTBYTE macro for proper operation.
+    */
+    {
+        int test_char;
+        static uch test_buf[2] = { 'a', 'b' };
+
+        G.inptr = test_buf;
+        G.incnt = 1;
+
+        test_char = NEXTBYTE;           /* Should get 'a'. */
+        if (test_char == 'a')
+        {
+            test_char = NEXTBYTE;       /* Should get EOF, not 'b'. */
+        }
+        if (test_char != EOF)
+        {
+            Info(slide, 0x401, ((char *)slide,
+ "NEXTBYTE macro failed.  Try compiling with ALT_NEXTBYTE defined?"));
+
+            retcode = PK_BADERR;
+            goto cleanup_and_exit;
+        }
+    }
+#endif /* DEBUG */
+
+/*---------------------------------------------------------------------------
+    First figure out if we're running in UnZip mode or ZipInfo mode, and put
+    the appropriate environment-variable options into the queue.  Then rip
+    through any command-line options lurking about...
+  ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+    G.argv0 = argv[0];
+#if (defined(OS2) || defined(WIN32))
+    G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
+#else
+    G.zipfn = G.argv0;
+#endif
+
+#ifdef VMSCLI
+    {
+        ulg status = vms_unzip_cmdline(&argc, &argv);
+        if (!(status & 1)) {
+            retcode = (int)status;
+            goto cleanup_and_exit;
+        }
+    }
+#endif /* VMSCLI */
+
+    uO.zipinfo_mode = FALSE;
+    error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
+
+#else /* !SFX */
+
+#ifdef RISCOS
+    /* get the extensions to swap from environment */
+    getRISCOSexts(ENV_UNZIPEXTS);
+#endif
+
+#ifdef MSDOS
+    /* extract MKS extended argument list from environment (before envargs!) */
+    mksargs(&argc, &argv);
+#endif
+
+#ifdef VMSCLI
+    {
+        ulg status = vms_unzip_cmdline(&argc, &argv);
+        if (!(status & 1)) {
+            retcode = (int)status;
+            goto cleanup_and_exit;
+        }
+    }
+#endif /* VMSCLI */
+
+    G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
+
+#ifndef NO_ZIPINFO
+    for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
+        if (*p == DIR_END
+#ifdef DIR_END2
+            || *p == DIR_END2
+#endif
+           )
+            break;
+    }
+    ++p;
+
+#ifdef THEOS
+    if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
+        strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
+#else
+    if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
+        STRNICMP(p, "ii", 2) == 0 ||
+#endif
+        (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
+    {
+        uO.zipinfo_mode = TRUE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
+                             LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
+            perror(LoadFarString(NoMemEnvArguments));
+#endif
+    } else
+#endif /* !NO_ZIPINFO */
+    {
+        uO.zipinfo_mode = FALSE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
+                             LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
+            perror(LoadFarString(NoMemEnvArguments));
+#endif
+    }
+
+    if (!error) {
+        /* Check the length of all passed command line parameters.
+         * Command arguments might get sent through the Info() message
+         * system, which uses the sliding window area as string buffer.
+         * As arguments may additionally get fed through one of the FnFilter
+         * macros, we require all command line arguments to be shorter than
+         * WSIZE/4 (and ca. 2 standard line widths for fixed message text).
+         */
+        for (i = 1 ; i < argc; i++) {
+           if (strlen(argv[i]) > ((WSIZE>>2) - 160)) {
+               Info(slide, 0x401, ((char *)slide,
+                 LoadFarString(CmdLineParamTooLong), i));
+               retcode = PK_PARAM;
+               goto cleanup_and_exit;
+           }
+        }
+#ifndef NO_ZIPINFO
+        if (uO.zipinfo_mode)
+            error = zi_opts(__G__ &argc, &argv);
+        else
+#endif /* !NO_ZIPINFO */
+            error = uz_opts(__G__ &argc, &argv);
+    }
+
+#endif /* ?SFX */
+
+    if ((argc < 0) || error) {
+        retcode = error;
+        goto cleanup_and_exit;
+    }
+
+/*---------------------------------------------------------------------------
+    Now get the zipfile name from the command line and then process any re-
+    maining options and file specifications.
+  ---------------------------------------------------------------------------*/
+
+#ifdef DOS_FLX_H68_NLM_OS2_W32
+    /* convert MSDOS-style 'backward slash' directory separators to Unix-style
+     * 'forward slashes' for user's convenience (include zipfile name itself)
+     */
+#ifdef SFX
+    for (G.pfnames = argv, i = argc;  i > 0;  --i) {
+#else
+    /* argc does not include the zipfile specification */
+    for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
+#endif
+#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 */
+
+#ifndef SFX
+    G.wildzipfn = *argv++;
+#endif
+
+#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
+
+    G.filespecs = argc;
+    G.xfilespecs = 0;
+
+    if (argc > 0) {
+        char **pp = argv-1;
+
+        G.pfnames = argv;
+        while (*++pp)
+            if (strcmp(*pp, "-x") == 0) {
+                if (pp > argv) {
+                    *pp = 0;              /* terminate G.pfnames */
+                    G.filespecs = pp - G.pfnames;
+                } else {
+                    G.pfnames = (char **)fnames;  /* defaults */
+                    G.filespecs = 0;
+                }
+                G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
+                G.xfilespecs = argc - G.filespecs - 1;
+                break;                    /* skip rest of args */
+            }
+        G.process_all_files = FALSE;
+    } else
+        G.process_all_files = TRUE;      /* for speed */
+
+#else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
+
+    G.filespecs = argc;
+    G.xfilespecs = 0;
+
+    if (argc > 0) {
+        int in_files=FALSE, in_xfiles=FALSE;
+        char **pp = argv-1;
+
+        G.process_all_files = FALSE;
+        G.pfnames = argv;
+        while (*++pp) {
+            Trace((stderr, "pp - argv = %d\n", pp-argv));
+#ifdef CMS_MVS
+            if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
+#else
+            if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
+#endif
+                int firstarg = (pp == argv);
+
+                uO.exdir = (*pp) + 2;
+                if (in_files) {      /* ... zipfile ... -d exdir ... */
+                    *pp = (char *)NULL;         /* terminate G.pfnames */
+                    G.filespecs = pp - G.pfnames;
+                    in_files = FALSE;
+                } else if (in_xfiles) {
+                    *pp = (char *)NULL;         /* terminate G.pxnames */
+                    G.xfilespecs = pp - G.pxnames;
+                    /* "... -x xlist -d exdir":  nothing left */
+                }
+                /* first check for "-dexdir", then for "-d exdir" */
+                if (*uO.exdir == '\0') {
+                    if (*++pp)
+                        uO.exdir = *pp;
+                    else {
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(MustGiveExdir)));
+                        /* don't extract here by accident */
+                        retcode = PK_PARAM;
+                        goto cleanup_and_exit;
+                    }
+                }
+                if (firstarg) { /* ... zipfile -d exdir ... */
+                    if (pp[1]) {
+                        G.pfnames = pp + 1;  /* argv+2 */
+                        G.filespecs = argc - (G.pfnames-argv);  /* for now... */
+                    } else {
+                        G.process_all_files = TRUE;
+                        G.pfnames = (char **)fnames;  /* GRR: necessary? */
+                        G.filespecs = 0;     /* GRR: necessary? */
+                        break;
+                    }
+                }
+            } else if (!in_xfiles) {
+                if (strcmp(*pp, "-x") == 0) {
+                    in_xfiles = TRUE;
+                    if (pp == G.pfnames) {
+                        G.pfnames = (char **)fnames;  /* defaults */
+                        G.filespecs = 0;
+                    } else if (in_files) {
+                        *pp = 0;                   /* terminate G.pfnames */
+                        G.filespecs = pp - G.pfnames;  /* adjust count */
+                        in_files = FALSE;
+                    }
+                    G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
+                    G.xfilespecs = argc - (G.pxnames-argv);  /* anything left */
+                } else
+                    in_files = TRUE;
+            }
+        }
+    } else
+        G.process_all_files = TRUE;      /* for speed */
+
+    if (uO.exdir != (char *)NULL && !G.extract_flag)    /* -d ignored */
+        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
+#endif /* ?(SFX && !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
+
+
+/*---------------------------------------------------------------------------
+    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;
+        free(thissigsav);
+    }
+#endif
+#if (defined(MALLOC_WORK) && !defined(REENTRANT))
+    if (G.area.Slide != (uch *)NULL) {
+        free(G.area.Slide);
+        G.area.Slide = (uch *)NULL;
+    }
+#endif
+#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 = 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) {
+        free(savsig);
+    } else {
+        savsig->previous = *p_savedhandler_chain;
+        *p_savedhandler_chain = savsig;
+    }
+    return PK_OK;
+
+} /* end function setsignalhandler() */
+
+#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
+
+
+
+
+
+/**********************/
+/* Function uz_opts() */
+/**********************/
+
+int uz_opts(__G__ pargc, pargv)
+    __GDEF
+    int *pargc;
+    char ***pargv;
+{
+    char **argv, *s;
+    int argc, c, error=FALSE, negative=0, showhelp=0;
+
+
+    argc = *pargc;
+    argv = *pargv;
+
+#ifdef UNIX
+    extern char OEM_CP[MAX_CP_NAME];
+    extern char ISO_CP[MAX_CP_NAME];
+#endif
+    
+    while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
+        s = *argv + 1;
+        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
+#ifdef CMS_MVS
+            switch (tolower(c))
+#else
+            switch (c)
+#endif
+            {
+                case ('-'):
+                    ++negative;
+                    break;
+#ifdef RISCOS
+                case ('/'):
+                    if (negative) {   /* negative not allowed with -/ swap */
+                        Info(slide, 0x401, ((char *)slide,
+                          "error:  must give extensions list"));
+                        return(PK_PARAM);  /* don't extract here by accident */
+                    }
+                    exts2swap = s; /* override Unzip$Exts */
+                    s += strlen(s);
+                    break;
+#endif
+                case ('a'):
+                    if (negative) {
+                        uO.aflag = MAX(uO.aflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.aflag;
+                    break;
+#if (defined(DLL) && defined(API_DOC))
+                case ('A'):    /* extended help for API */
+                    APIhelp(__G__ argc, argv);
+                    *pargc = -1;  /* signal to exit successfully */
+                    return 0;
+#endif
+                case ('b'):
+                    if (negative) {
+#if (defined(TANDEM) || defined(VMS))
+                        uO.bflag = MAX(uO.bflag-negative,0);
+#endif
+                        negative = 0;   /* do nothing:  "-b" is default */
+                    } else {
+#ifdef VMS
+                        if (uO.aflag == 0)
+                           ++uO.bflag;
+#endif
+#ifdef TANDEM
+                        ++uO.bflag;
+#endif
+                        uO.aflag = 0;
+                    }
+                    break;
+#ifdef UNIXBACKUP
+                case ('B'): /* -B: back up existing files */
+                    if (negative)
+                        uO.B_flag = FALSE, negative = 0;
+                    else
+                        uO.B_flag = TRUE;
+                    break;
+#endif
+                case ('c'):
+                    if (negative) {
+                        uO.cflag = FALSE, negative = 0;
+#ifdef NATIVE
+                        uO.aflag = 0;
+#endif
+                    } else {
+                        uO.cflag = TRUE;
+#ifdef NATIVE
+                        uO.aflag = 2;   /* so you can read it on the screen */
+#endif
+#ifdef DLL
+                        if (G.redirect_text)
+                            G.redirect_data = 2;
+#endif
+                    }
+                    break;
+#ifndef CMS_MVS
+                case ('C'):    /* -C:  match filenames case-insensitively */
+                    if (negative)
+                        uO.C_flag = FALSE, negative = 0;
+                    else
+                        uO.C_flag = TRUE;
+                    break;
+#endif /* !CMS_MVS */
+#if (!defined(SFX) || defined(SFX_EXDIR))
+                case ('d'):
+                    if (negative) {   /* negative not allowed with -d exdir */
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(MustGiveExdir)));
+                        return(PK_PARAM);  /* don't extract here by accident */
+                    }
+                    if (uO.exdir != (char *)NULL) {
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(OnlyOneExdir)));
+                        return(PK_PARAM);    /* GRR:  stupid restriction? */
+                    } else {
+                        /* first check for "-dexdir", then for "-d exdir" */
+                        uO.exdir = s;
+                        if (*uO.exdir == '\0') {
+                            if (argc > 1) {
+                                --argc;
+                                uO.exdir = *++argv;
+                                if (*uO.exdir == '-') {
+                                    Info(slide, 0x401, ((char *)slide,
+                                      LoadFarString(MustGiveExdir)));
+                                    return(PK_PARAM);
+                                }
+                                /* else uO.exdir points at extraction dir */
+                            } else {
+                                Info(slide, 0x401, ((char *)slide,
+                                  LoadFarString(MustGiveExdir)));
+                                return(PK_PARAM);
+                            }
+                        }
+                        /* uO.exdir now points at extraction dir (-dexdir or
+                         *  -d exdir); point s at end of exdir to avoid mis-
+                         *  interpretation of exdir characters as more options
+                         */
+                        if (*s != 0)
+                            while (*++s != 0)
+                                ;
+                    }
+                    break;
+#endif /* !SFX || SFX_EXDIR */
+#if (!defined(NO_TIMESTAMPS))
+                case ('D'):    /* -D: Skip restoring dir (or any) timestamp. */
+                    if (negative) {
+                        uO.D_flag = MAX(uO.D_flag-negative,0);
+                        negative = 0;
+                    } else
+                        uO.D_flag++;
+                    break;
+#endif /* (!NO_TIMESTAMPS) */
+                case ('e'):    /* just ignore -e, -x options (extract) */
+                    break;
+#ifdef MACOS
+                case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
+                    if( negative ) {
+                        uO.E_flag = FALSE, negative = 0;
+                    } else {
+                        uO.E_flag = TRUE;
+                    }
+                    break;
+#endif /* MACOS */
+                case ('f'):    /* "freshen" (extract only newer files) */
+                    if (negative)
+                        uO.fflag = uO.uflag = FALSE, negative = 0;
+                    else
+                        uO.fflag = uO.uflag = TRUE;
+                    break;
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+                case ('F'):    /* Acorn filetype & NFS extension handling */
+                    if (negative)
+                        uO.acorn_nfs_ext = FALSE, negative = 0;
+                    else
+                        uO.acorn_nfs_ext = TRUE;
+                    break;
+#endif /* RISCOS || ACORN_FTYPE_NFS */
+                case ('h'):    /* just print help message and quit */
+                    if (showhelp == 0) {
+#ifndef SFX
+                        if (*s == 'h')
+                            showhelp = 2;
+                        else
+#endif /* !SFX */
+                        {
+                            showhelp = 1;
+                        }
+                    }
+                    break;
+#ifdef MACOS
+                case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
+                    if( negative ) {
+                        uO.i_flag = FALSE, negative = 0;
+                    } else {
+                        uO.i_flag = TRUE;
+                    }
+                    break;
+#endif  /* MACOS */
+#ifdef UNIX
+    			case ('I'):
+                    if (negative) {
+                        Info(slide, 0x401, ((char *)slide,
+                          "error:  encodings can't be negated"));
+                        return(PK_PARAM);
+    				} else {
+    					if(*s) { /* Handle the -Icharset case */
+    						/* Assume that charsets can't start with a dash to spot arguments misuse */
+    						if(*s == '-') { 
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+                ISO_CP[MAX_CP_NAME - 1] = '\0';
+    					} else { /* -I charset */
+    						++argv;
+    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						s = *argv;
+    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+                ISO_CP[MAX_CP_NAME - 1] = '\0';
+    					}
+    					while(*(++s)); /* No params straight after charset name */
+    				}
+    				break;
+#endif /* ?UNIX */
+                case ('j'):    /* junk pathnames/directory structure */
+                    if (negative)
+                        uO.jflag = FALSE, negative = 0;
+                    else
+                        uO.jflag = TRUE;
+                    break;
+#if (defined(ATH_BEO) || defined(MACOS))
+                case ('J'):    /* Junk AtheOS, BeOS or MacOS file attributes */
+                    if( negative ) {
+                        uO.J_flag = FALSE, negative = 0;
+                    } else {
+                        uO.J_flag = TRUE;
+                    }
+                    break;
+#endif /* ATH_BEO || MACOS */
+#ifdef ATH_BEO_UNX
+                case ('K'):
+                    if (negative) {
+                        uO.K_flag = FALSE, negative = 0;
+                    } else {
+                        uO.K_flag = TRUE;
+                    }
+                    break;
+#endif /* ATH_BEO_UNX */
+#ifndef SFX
+                case ('l'):
+                    if (negative) {
+                        uO.vflag = MAX(uO.vflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.vflag;
+                    break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+                case ('L'):    /* convert (some) filenames to lowercase */
+                    if (negative) {
+                        uO.L_flag = MAX(uO.L_flag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.L_flag;
+                    break;
+#endif /* !CMS_MVS */
+#ifdef MORE
+#ifdef CMS_MVS
+                case ('m'):
+#endif
+                case ('M'):    /* send all screen output through "more" fn. */
+/* GRR:  eventually check for numerical argument => height */
+                    if (negative)
+                        G.M_flag = FALSE, negative = 0;
+                    else
+                        G.M_flag = TRUE;
+                    break;
+#endif /* MORE */
+                case ('n'):    /* don't overwrite any files */
+                    if (negative)
+                        uO.overwrite_none = FALSE, negative = 0;
+                    else
+                        uO.overwrite_none = TRUE;
+                    break;
+#ifdef AMIGA
+                case ('N'):    /* restore comments as filenotes */
+                    if (negative)
+                        uO.N_flag = FALSE, negative = 0;
+                    else
+                        uO.N_flag = TRUE;
+                    break;
+#endif /* AMIGA */
+                case ('o'):    /* OK to overwrite files without prompting */
+                    if (negative) {
+                        uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.overwrite_all;
+                    break;
+#ifdef UNIX
+    			case ('O'):
+                    if (negative) {
+                        Info(slide, 0x401, ((char *)slide,
+                          "error:  encodings can't be negated"));
+                        return(PK_PARAM);
+    				} else {
+    					if(*s) { /* Handle the -Ocharset case */
+    						/* Assume that charsets can't start with a dash to spot arguments misuse */
+    						if(*s == '-') { 
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+                OEM_CP[MAX_CP_NAME - 1] = '\0';
+    					} else { /* -O charset */
+    						++argv;
+    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -O argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						s = *argv;
+    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+                OEM_CP[MAX_CP_NAME - 1] = '\0';
+    					}
+    					while(*(++s)); /* No params straight after charset name */
+    				}
+    				break;
+#endif /* ?UNIX */
+                case ('p'):    /* pipes:  extract to stdout, no messages */
+                    if (negative) {
+                        uO.cflag = FALSE;
+                        uO.qflag = MAX(uO.qflag-999,0);
+                        negative = 0;
+                    } else {
+                        uO.cflag = TRUE;
+                        uO.qflag += 999;
+                    }
+                    break;
+#if CRYPT
+                /* GRR:  yes, this is highly insecure, but dozens of people
+                 * have pestered us for this, so here we go... */
+                case ('P'):
+                    if (negative) {   /* negative not allowed with -P passwd */
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(MustGivePasswd)));
+                        return(PK_PARAM);  /* don't extract here by accident */
+                    }
+                    if (uO.pwdarg != (char *)NULL) {
+/*
+                        GRR:  eventually support multiple passwords?
+                        Info(slide, 0x401, ((char *)slide,
+                          LoadFarString(OnlyOnePasswd)));
+                        return(PK_PARAM);
+ */
+                    } else {
+                        /* first check for "-Ppasswd", then for "-P passwd" */
+                        uO.pwdarg = s;
+                        if (*uO.pwdarg == '\0') {
+                            if (argc > 1) {
+                                --argc;
+                                uO.pwdarg = *++argv;
+                                if (*uO.pwdarg == '-') {
+                                    Info(slide, 0x401, ((char *)slide,
+                                      LoadFarString(MustGivePasswd)));
+                                    return(PK_PARAM);
+                                }
+                                /* else pwdarg points at decryption password */
+                            } else {
+                                Info(slide, 0x401, ((char *)slide,
+                                  LoadFarString(MustGivePasswd)));
+                                return(PK_PARAM);
+                            }
+                        }
+                        /* pwdarg now points at decryption password (-Ppasswd or
+                         *  -P passwd); point s at end of passwd to avoid mis-
+                         *  interpretation of passwd characters as more options
+                         */
+                        if (*s != 0)
+                            while (*++s != 0)
+                                ;
+                    }
+                    break;
+#endif /* CRYPT */
+                case ('q'):    /* quiet:  fewer comments/messages */
+                    if (negative) {
+                        uO.qflag = MAX(uO.qflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.qflag;
+                    break;
+#ifdef QDOS
+                case ('Q'):   /* QDOS flags */
+                    qlflag ^= strtol(s, &s, 10);
+                    break;    /* we XOR this as we can config qlflags */
+#endif
+#ifdef TANDEM
+                case ('r'):    /* remove file extensions */
+                    if (negative)
+                        uO.rflag = FALSE, negative = 0;
+                    else
+                        uO.rflag = TRUE;
+                    break;
+#endif /* TANDEM */
+#ifdef DOS_FLX_NLM_OS2_W32
+                case ('s'):    /* spaces in filenames:  allow by default */
+                    if (negative)
+                        uO.sflag = FALSE, negative = 0;
+                    else
+                        uO.sflag = TRUE;
+                    break;
+#endif /* DOS_FLX_NLM_OS2_W32 */
+#ifdef VMS
+                /* VMS:  extract "text" files in Stream_LF format (-a[a]) */
+                case ('S'):
+                    if (negative)
+                        uO.S_flag = FALSE, negative = 0;
+                    else
+                        uO.S_flag = TRUE;
+                    break;
+#endif /* VMS */
+                case ('t'):
+                    if (negative)
+                        uO.tflag = FALSE, negative = 0;
+                    else
+                        uO.tflag = TRUE;
+                    break;
+#ifdef TIMESTAMP
+                case ('T'):
+                    if (negative)
+                        uO.T_flag = FALSE, negative = 0;
+                    else
+                        uO.T_flag = TRUE;
+                    break;
+#endif
+                case ('u'):    /* update (extract only new and newer files) */
+                    if (negative)
+                        uO.uflag = FALSE, negative = 0;
+                    else
+                        uO.uflag = TRUE;
+                    break;
+#ifdef UNICODE_SUPPORT
+                case ('U'):    /* escape UTF-8, or disable UTF-8 support */
+                    if (negative) {
+                        uO.U_flag = MAX(uO.U_flag-negative,0);
+                        negative = 0;
+                    } else
+                        uO.U_flag++;
+                    break;
+#else /* !UNICODE_SUPPORT */
+#ifndef CMS_MVS
+                case ('U'):    /* obsolete; to be removed in version 6.0 */
+                    if (negative)
+                        uO.L_flag = TRUE, negative = 0;
+                    else
+                        uO.L_flag = FALSE;
+                    break;
+#endif /* !CMS_MVS */
+#endif /* ?UNICODE_SUPPORT */
+#ifndef SFX
+                case ('v'):    /* verbose */
+                    if (negative) {
+                        uO.vflag = MAX(uO.vflag-negative,0);
+                        negative = 0;
+                    } else if (uO.vflag)
+                        ++uO.vflag;
+                    else
+                        uO.vflag = 2;
+                    break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+                case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
+                    if (negative)
+                        uO.V_flag = FALSE, negative = 0;
+                    else
+                        uO.V_flag = TRUE;
+                    break;
+#endif /* !CMS_MVS */
+#ifdef WILD_STOP_AT_DIR
+                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
+                    if (negative)
+                        uO.W_flag = FALSE, negative = 0;
+                    else
+                        uO.W_flag = TRUE;
+                    break;
+#endif /* WILD_STOP_AT_DIR */
+                case ('x'):    /* extract:  default */
+#ifdef SFX
+                    /* when 'x' is the only option in this argument, and the
+                     * next arg is not an option, assume this initiates an
+                     * exclusion list (-x xlist):  terminate option-scanning
+                     * and leave uz_opts with argv still pointing to "-x";
+                     * the xlist is processed later
+                     */
+                    if (s - argv[0] == 2 && *s == '\0' &&
+                        argc > 1 && argv[1][0] != '-') {
+                        /* break out of nested loops without "++argv;--argc" */
+                        goto opts_done;
+                    }
+#endif /* SFX */
+                    break;
+#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
+                case ('X'):   /* restore owner/protection info (need privs?) */
+                    if (negative) {
+                        uO.X_flag = MAX(uO.X_flag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.X_flag;
+                    break;
+#endif /* RESTORE_UIDGID || RESTORE_ACL */
+#ifdef VMS
+                case ('Y'):    /* Treat ".nnn" as ";nnn" version. */
+                    if (negative)
+                        uO.Y_flag = FALSE, negative = 0;
+                    else
+                        uO.Y_flag = TRUE;
+                    break;
+#endif /* VMS */
+                case ('z'):    /* display only the archive comment */
+                    if (negative) {
+                        uO.zflag = MAX(uO.zflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.zflag;
+                    break;
+#ifndef SFX
+                case ('Z'):    /* should have been first option (ZipInfo) */
+                    Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
+                    error = TRUE;
+                    break;
+#endif /* !SFX */
+#ifdef VMS
+                case ('2'):    /* Force ODS2-compliant names. */
+                    if (negative)
+                        uO.ods2_flag = FALSE, negative = 0;
+                    else
+                        uO.ods2_flag = TRUE;
+                    break;
+#endif /* VMS */
+#ifdef DOS_H68_OS2_W32
+                case ('$'):
+                    if (negative) {
+                        uO.volflag = MAX(uO.volflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.volflag;
+                    break;
+#endif /* DOS_H68_OS2_W32 */
+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
+                case (':'):    /* allow "parent dir" path components */
+                    if (negative) {
+                        uO.ddotflag = MAX(uO.ddotflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.ddotflag;
+                    break;
+#endif /* !RISCOS && !CMS_MVS && !TANDEM */
+#ifdef UNIX
+                case ('^'):    /* allow control chars in filenames */
+                    if (negative) {
+                        uO.cflxflag = MAX(uO.cflxflag-negative,0);
+                        negative = 0;
+                    } else
+                        ++uO.cflxflag;
+                    break;
+#endif /* UNIX */
+                default:
+                    error = TRUE;
+                    break;
+
+            } /* end switch */
+        } /* end while (not end of argument string) */
+    } /* end while (not done with switches) */
+
+/*---------------------------------------------------------------------------
+    Check for nonsensical combinations of options.
+  ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
+#endif
+
+    if (showhelp > 0) {         /* just print help message and quit */
+        *pargc = -1;
+#ifndef SFX
+        if (showhelp == 2) {
+            help_extended(__G);
+            return PK_OK;
+        } else
+#endif /* !SFX */
+        {
+            return USAGE(PK_OK);
+        }
+    }
+
+    if ((uO.cflag && (uO.tflag || uO.uflag)) ||
+        (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
+    {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
+        error = TRUE;
+    }
+    if (uO.aflag > 2)
+        uO.aflag = 2;
+#ifdef VMS
+    if (uO.bflag > 2)
+        uO.bflag = 2;
+    /* Clear -s flag when converting text files. */
+    if (uO.aflag <= 0)
+        uO.S_flag = 0;
+#endif /* VMS */
+    if (uO.overwrite_all && uO.overwrite_none) {
+        Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
+        uO.overwrite_all = FALSE;
+    }
+#ifdef MORE
+    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func. useless */
+        G.M_flag = 0;
+#endif
+
+#ifdef SFX
+    if (error)
+#else
+    if ((argc-- == 0) || error)
+#endif
+    {
+        *pargc = argc;
+        *pargv = argv;
+#ifndef SFX
+        if (uO.vflag >= 2 && argc == -1) {              /* "unzip -v" */
+            show_version_info(__G);
+            return PK_OK;
+        }
+        if (!G.noargs && !error)
+            error = TRUE;       /* had options (not -h or -v) but no zipfile */
+#endif /* !SFX */
+        return USAGE(error);
+    }
+
+#ifdef SFX
+    /* print our banner unless we're being fairly quiet */
+    if (uO.qflag < 2)
+        Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+          LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+    /* always print the beta warning:  no unauthorized distribution!! */
+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+      "SFX"));
+#endif
+#endif /* SFX */
+
+    if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
+#ifdef TIMESTAMP
+                                                     || uO.T_flag
+#endif
+                                                                 )
+        G.extract_flag = FALSE;
+    else
+        G.extract_flag = TRUE;
+
+    *pargc = argc;
+    *pargv = argv;
+    return PK_OK;
+
+} /* end function uz_opts() */
+
+
+
+
+/********************/
+/* Function usage() */
+/********************/
+
+#ifdef SFX
+#  ifdef VMS
+#    define LOCAL "X.\n\
+(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
+#  endif
+#  ifdef UNIX
+#    define LOCAL "X"
+#  endif
+#  ifdef DOS_OS2_W32
+#    define LOCAL "s$"
+#  endif
+#  if (defined(FLEXOS) || defined(NLM))
+#    define LOCAL "s"
+#  endif
+#  ifdef AMIGA
+#    define LOCAL "N"
+#  endif
+   /* Default for all other systems: */
+#  ifndef LOCAL
+#    define LOCAL ""
+#  endif
+
+#  ifndef NO_TIMESTAMP
+#    ifdef MORE
+#      define SFXOPT1 "DM"
+#    else
+#      define SFXOPT1 "D"
+#    endif
+#  else
+#    ifdef MORE
+#      define SFXOPT1 "M"
+#    else
+#      define SFXOPT1 ""
+#    endif
+#  endif
+
+int usage(__G__ error)   /* return PK-type error code */
+    __GDEF
+    int error;
+{
+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+      UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+      LoadFarStringSmall(VersionDate)));
+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
+      SFXOPT1, LOCAL));
+#ifdef BETA
+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+      "SFX"));
+#endif
+
+    if (error)
+        return PK_PARAM;
+    else
+        return PK_COOL;     /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+
+
+
+
+#else /* !SFX */
+#  ifdef VMS
+#    define QUOT '\"'
+#    define QUOTS "\""
+#  else
+#    define QUOT ' '
+#    define QUOTS ""
+#  endif
+
+int usage(__G__ error)   /* return PK-type error code */
+    __GDEF
+    int error;
+{
+    int flag = (error? 1 : 0);
+
+
+/*---------------------------------------------------------------------------
+    Print either ZipInfo usage or UnZip usage, depending on incantation.
+    (Strings must be no longer than 512 bytes for Turbo C, apparently.)
+  ---------------------------------------------------------------------------*/
+
+    if (uO.zipinfo_mode) {
+
+#ifndef NO_ZIPINFO
+
+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
+          ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+          LoadFarStringSmall(VersionDate),
+          LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
+          LoadFarStringSmall(ZipInfoUsageLine4)));
+#ifdef VMS
+        Info(slide, flag, ((char *)slide, "\n\
+You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
+\n"));
+#endif
+
+#endif /* !NO_ZIPINFO */
+
+    } else {   /* UnZip mode */
+
+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+          LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+        Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
+#endif
+
+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
+          ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
+#ifdef VMS
+        if (!error)  /* 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)));
+
+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
+          LoadFarStringSmall(local2), LoadFarStringSmall2(local3)));
+
+        /* 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)));
+
+    } /* end if (uO.zipinfo_mode) */
+
+    if (error)
+        return PK_PARAM;
+    else
+        return PK_COOL;     /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+#endif /* ?SFX */
+
+
+
+
+#ifndef SFX
+
+/* Print extended help to stdout. */
+static void help_extended(__G)
+    __GDEF
+{
+    extent i;             /* counter for help array */
+
+    /* help array */
+    static ZCONST char *text[] = {
+  "",
+  "Extended Help for UnZip",
+  "",
+  "See the UnZip Manual for more detailed help",
+  "",
+  "",
+  "UnZip lists and extracts files in zip archives.  The default action is to",
+  "extract zipfile entries to the current directory, creating directories as",
+  "needed.  With appropriate options, UnZip lists the contents of archives",
+  "instead.",
+  "",
+  "Basic unzip command line:",
+  "  unzip [-Z] options archive[.zip] [file ...] [-x xfile ...] [-d exdir]",
+  "",
+  "Some examples:",
+  "  unzip -l foo.zip        - list files in short format in archive foo.zip",
+  "",
+  "  unzip -t foo            - test the files in archive foo",
+  "",
+  "  unzip -Z foo            - list files using more detailed zipinfo format",
+  "",
+  "  unzip foo               - unzip the contents of foo in current dir",
+  "",
+  "  unzip -a foo            - unzip foo and convert text files to local OS",
+  "",
+  "If unzip is run in zipinfo mode, a more detailed list of archive contents",
+  "is provided.  The -Z option sets zipinfo mode and changes the available",
+  "options.",
+  "",
+  "Basic zipinfo command line:",
+  "  zipinfo options archive[.zip] [file ...] [-x xfile ...]",
+  "  unzip -Z options archive[.zip] [file ...] [-x xfile ...]",
+  "",
+  "Below, Mac OS refers to Mac OS before Mac OS X.  Mac OS X is a Unix based",
+  "port and is referred to as Unix Apple.",
+  "",
+  "",
+  "unzip options:",
+  "  -Z   Switch to zipinfo mode.  Must be first option.",
+  "  -hh  Display extended help.",
+  "  -A   [OS/2, Unix DLL] Print extended help for DLL.",
+  "  -c   Extract files to stdout/screen.  As -p but include names.  Also,",
+  "         -a allowed and EBCDIC conversions done if needed.",
+  "  -f   Freshen by extracting only if older file on disk.",
+  "  -l   List files using short form.",
+  "  -p   Extract files to pipe (stdout).  Only file data is output and all",
+  "         files extracted in binary mode (as stored).",
+  "  -t   Test archive files.",
+  "  -T   Set timestamp on archive(s) to that of newest file.  Similar to",
+  "       zip -o but faster.",
+  "  -u   Update existing older files on disk as -f and extract new files.",
+  "  -v   Use verbose list format.  If given alone as unzip -v show version",
+  "         information.  Also can be added to other list commands for more",
+  "         verbose output.",
+  "  -z   Display only archive comment.",
+  "",
+  "unzip modifiers:",
+  "  -a   Convert text files to local OS format.  Convert line ends, EOF",
+  "         marker, and from or to EBCDIC character set as needed.",
+  "  -b   Treat all files as binary.  [Tandem] Force filecode 180 ('C').",
+  "         [VMS] Autoconvert binary files.  -bb forces convert of all files.",
+  "  -B   [UNIXBACKUP compile option enabled] Save a backup copy of each",
+  "         overwritten file in foo~ or foo~99999 format.",
+  "  -C   Use case-insensitive matching.",
+  "  -D   Skip restoration of timestamps for extracted directories.  On VMS this",
+  "         is on by default and -D essentially becames -DD.",
+  "  -DD  Skip restoration of timestamps for all entries.",
+  "  -E   [MacOS (not Unix Apple)]  Display contents of MacOS extra field during",
+  "         restore.",
+  "  -F   [Acorn] Suppress removal of NFS filetype extension.  [Non-Acorn if",
+  "         ACORN_FTYPE_NFS] Translate filetype and append to name.",
+  "  -i   [MacOS] Ignore filenames in MacOS extra field.  Instead, use name in",
+  "         standard header.",
+  "  -j   Junk paths and deposit all files in extraction directory.",
+  "  -J   [BeOS] Junk file attributes.  [MacOS] Ignore MacOS specific info.",
+  "  -K   [AtheOS, BeOS, Unix] Restore SUID/SGID/Tacky file attributes.",
+  "  -L   Convert to lowercase any names from uppercase only file system.",
+  "  -LL  Convert all files to lowercase.",
+  "  -M   Pipe all output through internal pager similar to Unix more(1).",
+  "  -n   Never overwrite existing files.  Skip extracting that file, no prompt.",
+  "  -N   [Amiga] Extract file comments as Amiga filenotes.",
+  "  -o   Overwrite existing files without prompting.  Useful with -f.  Use with",
+  "         care.",
+  "  -P p Use password p to decrypt files.  THIS IS INSECURE!  Some OS show",
+  "         command line to other users.",
+  "  -q   Perform operations quietly.  The more q (as in -qq) the quieter.",
+  "  -s   [OS/2, NT, MS-DOS] Convert spaces in filenames to underscores.",
+  "  -S   [VMS] Convert text files (-a, -aa) into Stream_LF format.",
+  "  -U   [UNICODE enabled] Show non-local characters as #Uxxxx or #Lxxxxxx ASCII",
+  "         text escapes where x is hex digit.  [Old] -U used to leave names",
+  "         uppercase if created on MS-DOS, VMS, etc.  See -L.",
+  "  -UU  [UNICODE enabled] Disable use of stored UTF-8 paths.  Note that UTF-8",
+  "         paths stored as native local paths are still processed as Unicode.",
+  "  -V   Retain VMS file version numbers.",
+  "  -W   [Only if WILD_STOP_AT_DIR] Modify pattern matching so ? and * do not",
+  "         match directory separator /, but ** does.  Allows matching at specific",
+  "         directory levels.",
+  "  -X   [VMS, Unix, OS/2, NT, Tandem] Restore UICs and ACL entries under VMS,",
+  "         or UIDs/GIDs under Unix, or ACLs under certain network-enabled",
+  "         versions of OS/2, or security ACLs under Windows NT.  Can require",
+  "         user privileges.",
+  "  -XX  [NT] Extract NT security ACLs after trying to enable additional",
+  "         system privileges.",
+  "  -Y   [VMS] Treat archived name endings of .nnn as VMS version numbers.",
+  "  -$   [MS-DOS, OS/2, NT] Restore volume label if extraction medium is",
+  "         removable.  -$$ allows fixed media (hard drives) to be labeled.",
+  "  -/ e [Acorn] Use e as extension list.",
+  "  -:   [All but Acorn, VM/CMS, MVS, Tandem] Allow extract archive members into",
+  "         locations outside of current extraction root folder.  This allows",
+  "         paths such as ../foo to be extracted above the current extraction",
+  "         directory, which can be a security problem.",
+  "  -^   [Unix] Allow control characters in names of extracted entries.  Usually",
+  "         this is not a good thing and should be avoided.",
+  "  -2   [VMS] Force unconditional conversion of names to ODS-compatible names.",
+  "         Default is to exploit destination file system, preserving cases and",
+  "         extended name characters on ODS5 and applying ODS2 filtering on ODS2.",
+  "",
+  "",
+  "Wildcards:",
+  "  Internally unzip supports the following wildcards:",
+  "    ?       (or %% or #, depending on OS) matches any single character",
+  "    *       matches any number of characters, including zero",
+  "    [list]  matches char in list (regex), can do range [ac-f], all but [!bf]",
+  "  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",
+  "  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 ...",
+  "",
+  "Multi-part (split) archives (archives created as a set of split files):",
+  "  Currently split archives are not readable by unzip.  A workaround is",
+  "  to use zip to convert the split archive to a single-file archive and",
+  "  use unzip on that.  See the manual page for Zip 3.0 or later.",
+  "",
+  "Streaming (piping into unzip):",
+  "  Currently unzip does not support streaming.  The funzip utility can be",
+  "  used to process the first entry in a stream.",
+  "    cat archive | funzip",
+  "",
+  "Testing archives:",
+  "  -t        test contents of archive",
+  "  This can be modified using -q for quieter operation, and -qq for even",
+  "  quieter operation.",
+  "",
+  "Unicode:",
+  "  If compiled with Unicode support, unzip automatically handles archives",
+  "  with Unicode entries.  Currently Unicode on Win32 systems is limited.",
+  "  Characters not in the current character set are shown as ASCII escapes",
+  "  in the form #Uxxxx where the Unicode character number fits in 16 bits,",
+  "  or #Lxxxxxx where it doesn't, where x is the ASCII character for a hex",
+  "  digit.",
+  "",
+  "",
+  "zipinfo options (these are used in zipinfo mode (unzip -Z ...)):",
+  "  -1  List names only, one per line.  No headers/trailers.  Good for scripts.",
+  "  -2  List names only as -1, but include headers, trailers, and comments.",
+  "  -s  List archive entries in short Unix ls -l format.  Default list format.",
+  "  -m  List in long Unix ls -l format.  As -s, but includes compression %.",
+  "  -l  List in long Unix ls -l format.  As -m, but compression in bytes.",
+  "  -v  List zipfile information in verbose, multi-page format.",
+  "  -h  List header line.  Includes archive name, actual size, total files.",
+  "  -M  Pipe all output through internal pager similar to Unix more(1) command.",
+  "  -t  List totals for files listed or for all files.  Includes uncompressed",
+  "        and compressed sizes, and compression factors.",
+  "  -T  Print file dates and times in a sortable decimal format (yymmdd.hhmmss)",
+  "        Default date and time format is a more human-readable version.",
+  "  -U  [UNICODE] If entry has a UTF-8 Unicode path, display any characters",
+  "        not in current character set as text #Uxxxx and #Lxxxxxx escapes",
+  "        representing the Unicode character number of the character in hex.",
+  "  -UU [UNICODE]  Disable use of any UTF-8 path information.",
+  "  -z  Include archive comment if any in listing.",
+  "",
+  "",
+  "funzip stream extractor:",
+  "  funzip extracts the first member in an archive to stdout.  Typically",
+  "  used to unzip the first member of a stream or pipe.  If a file argument",
+  "  is given, read from that file instead of stdin.",
+  "",
+  "funzip command line:",
+  "  funzip [-password] [input[.zip|.gz]]",
+  "",
+  "",
+  "unzipsfx self extractor:",
+  "  Self-extracting archives made with unzipsfx are no more (or less)",
+  "  portable across different operating systems than unzip executables.",
+  "  In general, a self-extracting archive made on a particular Unix system,",
+  "  for example, will only self-extract under the same flavor of Unix.",
+  "  Regular unzip may still be used to extract embedded archive however.",
+  "",
+  "unzipsfx command line:",
+  "  <unzipsfx+archive_filename>  [-options] [file(s) ... [-x xfile(s) ...]]",
+  "",
+  "unzipsfx options:",
+  "  -c, -p - Output to pipe.  (See above for unzip.)",
+  "  -f, -u - Freshen and Update, as for unzip.",
+  "  -t     - Test embedded archive.  (Can be used to list contents.)",
+  "  -z     - Print archive comment.  (See unzip above.)",
+  "",
+  "unzipsfx modifiers:",
+  "  Most unzip modifiers are supported.  These include",
+  "  -a     - Convert text files.",
+  "  -n     - Never overwrite.",
+  "  -o     - Overwrite without prompting.",
+  "  -q     - Quiet operation.",
+  "  -C     - Match names case-insensitively.",
+  "  -j     - Junk paths.",
+  "  -V     - Keep version numbers.",
+  "  -s     - Convert spaces to underscores.",
+  "  -$     - Restore volume label.",
+  "",
+  "If unzipsfx compiled with SFX_EXDIR defined, -d option also available:",
+  "  -d exd - Extract to directory exd.",
+  "By default, all files extracted to current directory.  This option",
+  "forces extraction to specified directory.",
+  "",
+  "See unzipsfx manual page for more information.",
+  ""
+    };
+
+    for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+    {
+        Info(slide, 0, ((char *)slide, "%s\n", text[i]));
+    }
+} /* end function help_extended() */
+
+
+
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+#if (!defined(MODERN) || defined(NO_STDLIB_H))
+/* Declare getenv() to be sure (might be missing in some environments) */
+extern char *getenv();
+#endif
+#endif
+
+/********************************/
+/* Function show_version_info() */
+/********************************/
+
+static void show_version_info(__G)
+    __GDEF
+{
+    if (uO.qflag > 3)                           /* "unzip -vqqqq" */
+        Info(slide, 0, ((char *)slide, "%d\n",
+          (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
+    else {
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+        char *envptr;
+#endif
+        int numopts = 0;
+
+        Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+          LoadFarStringSmall(VersionDate)));
+        Info(slide, 0, ((char *)slide,
+          LoadFarString(UnzipUsageLine2v)));
+        version(__G);
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
+#ifdef ACORN_FTYPE_NFS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(AcornFtypeNFS)));
+        ++numopts;
+#endif
+#ifdef ASM_CRC
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(AsmCRC)));
+        ++numopts;
+#endif
+#ifdef ASM_INFLATECODES
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(AsmInflateCodes)));
+        ++numopts;
+#endif
+#ifdef CHECK_VERSIONS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Check_Versions)));
+        ++numopts;
+#endif
+#ifdef COPYRIGHT_CLEAN
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Copyright_Clean)));
+        ++numopts;
+#endif
+#ifdef DEBUG
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(UDebug)));
+        ++numopts;
+#endif
+#ifdef DEBUG_TIME
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(DebugTime)));
+        ++numopts;
+#endif
+#ifdef DLL
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Dll)));
+        ++numopts;
+#endif
+#ifdef DOSWILD
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(DosWild)));
+        ++numopts;
+#endif
+#ifdef LZW_CLEAN
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(LZW_Clean)));
+        ++numopts;
+#endif
+#ifndef MORE
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(No_More)));
+        ++numopts;
+#endif
+#ifdef NO_ZIPINFO
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(No_ZipInfo)));
+        ++numopts;
+#endif
+#ifdef NTSD_EAS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(NTSDExtAttrib)));
+        ++numopts;
+#endif
+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(W32NoIZTimeFix)));
+        ++numopts;
+#endif
+#ifdef OLD_THEOS_EXTRA
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(OldTheosExtra)));
+        ++numopts;
+#endif
+#ifdef OS2_EAS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(OS2ExtAttrib)));
+        ++numopts;
+#endif
+#ifdef QLZIP
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(SMSExFldOnUnix)));
+        ++numopts;
+#endif
+#ifdef REENTRANT
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Reentrant)));
+        ++numopts;
+#endif
+#ifdef REGARGS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(RegArgs)));
+        ++numopts;
+#endif
+#ifdef RETURN_CODES
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Return_Codes)));
+        ++numopts;
+#endif
+#ifdef SET_DIR_ATTRIB
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(SetDirAttrib)));
+        ++numopts;
+#endif
+#ifdef SYMLINKS
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(SymLinkSupport)));
+        ++numopts;
+#endif
+#ifdef TIMESTAMP
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(TimeStamp)));
+        ++numopts;
+#endif
+#ifdef UNIXBACKUP
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(UnixBackup)));
+        ++numopts;
+#endif
+#ifdef USE_EF_UT_TIME
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_EF_UT_time)));
+        ++numopts;
+#endif
+#ifndef COPYRIGHT_CLEAN
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_Smith_Code)));
+        ++numopts;
+#endif
+#ifndef LZW_CLEAN
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_Unshrink)));
+        ++numopts;
+#endif
+#ifdef USE_DEFLATE64
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_Deflate64)));
+        ++numopts;
+#endif
+#ifdef UNICODE_SUPPORT
+# ifdef UTF8_MAYBE_NATIVE
+        sprintf((char *)(slide+256), LoadFarStringSmall(Use_Unicode),
+          LoadFarStringSmall2(G.native_is_utf8 ? SysChUTF8 : SysChOther));
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          (char *)(slide+256)));
+# else
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_Unicode)));
+# endif
+        ++numopts;
+#endif
+#ifdef _MBCS
+        sprintf((char *)(slide+256), LoadFarStringSmall(Have_MBCS_Support),
+          (unsigned int)MB_CUR_MAX);
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          (char *)(slide+256)));
+        ++numopts;
+#endif
+#ifdef MULT_VOLUME
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_MultiVol)));
+        ++numopts;
+#endif
+#ifdef LARGE_FILE_SUPPORT
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_LFS)));
+        ++numopts;
+#endif
+#ifdef ZIP64_SUPPORT
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_Zip64)));
+        ++numopts;
+#endif
+#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+#  ifdef USE_DJGPP_ENV
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_DJGPP_Env)));
+        ++numopts;
+#  endif
+#  ifdef USE_DJGPP_GLOB
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_DJGPP_Glob)));
+        ++numopts;
+#  endif
+#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+#ifdef USE_VFAT
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(Use_VFAT_support)));
+        ++numopts;
+#endif
+#ifdef USE_ZLIB
+        sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
+          ZLIB_VERSION, zlibVersion());
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          (char *)(slide+256)));
+        ++numopts;
+#endif
+#ifdef USE_BZIP2
+        sprintf((char *)(slide+256), LoadFarStringSmall(UseBZip2),
+          BZ2_bzlibVersion());
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          (char *)(slide+256)));
+        ++numopts;
+#endif
+#ifdef VMS_TEXT_CONV
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(VmsTextConv)));
+        ++numopts;
+#endif
+#ifdef VMSCLI
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(VmsCLI)));
+        ++numopts;
+#endif
+#ifdef VMSWILD
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(VmsWild)));
+        ++numopts;
+#endif
+#ifdef WILD_STOP_AT_DIR
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(WildStopAtDir)));
+        ++numopts;
+#endif
+#if CRYPT
+# ifdef PASSWD_FROM_STDIN
+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+          LoadFarStringSmall(PasswdStdin)));
+# endif
+        Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
+          CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
+          LoadFarStringSmall(CryptDate)));
+        ++numopts;
+#endif /* CRYPT */
+        if (numopts == 0)
+            Info(slide, 0, ((char *)slide,
+              LoadFarString(CompileOptFormat),
+              LoadFarStringSmall(None)));
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
+        envptr = getenv(LoadFarStringSmall(EnvUnZip));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvUnZip),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+        envptr = getenv(LoadFarStringSmall(EnvUnZip2));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvUnZip2),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+        envptr = getenv(LoadFarStringSmall(EnvZipInfo));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvZipInfo),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+        envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvZipInfo2),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+#ifndef __RSXNT__
+#ifdef __EMX__
+        envptr = getenv(LoadFarStringSmall(EnvEMX));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvEMX),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+        envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvEMXOPT),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+#endif /* __EMX__ */
+#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+        envptr = getenv(LoadFarStringSmall(EnvGO32));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvGO32),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+        envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvGO32TMP),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+#endif /* __GO32__ && !(__DJGPP__ >= 2) */
+#endif /* !__RSXNT__ */
+#ifdef RISCOS
+        envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+          LoadFarStringSmall(EnvUnZipExts),
+          (envptr == (char *)NULL || *envptr == 0)?
+          LoadFarStringSmall2(None) : envptr));
+#endif /* RISCOS */
+#endif /* !_WIN32_WCE */
+    }
+} /* end function show_version() */
+
+#endif /* !SFX */
+#endif /* !WINDLL */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h	(revision 5)
@@ -0,0 +1,3132 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+
+  unzpriv.h
+
+  This header file contains private (internal) macros, typedefs, prototypes
+  and global-variable declarations used by all of the UnZip source files.
+  In a prior life it was part of the main unzip.h header, but now it is only
+  included by that header if UNZIP_INTERNAL is defined.
+
+  ---------------------------------------------------------------------------*/
+
+
+
+#ifndef __unzpriv_h   /* prevent multiple inclusions */
+#define __unzpriv_h
+
+/* First thing: Signal all following code that we compile UnZip utilities! */
+#ifndef UNZIP
+#  define UNZIP
+#endif
+
+/* GRR 960204:  MORE defined here in preparation for removal altogether */
+#ifndef MORE
+# ifndef RISCOS
+#  define MORE
+# endif
+#endif
+
+/* fUnZip should never need to be reentrant */
+#ifdef FUNZIP
+#  ifdef REENTRANT
+#    undef REENTRANT
+#  endif
+#  ifdef DLL
+#    undef DLL
+#  endif
+#  ifdef SFX            /* fUnZip is NOT the sfx stub! */
+#    undef SFX
+#  endif
+#  ifdef USE_BZIP2      /* fUnZip does not support bzip2 decompression */
+#    undef USE_BZIP2
+#  endif
+#endif
+
+#if (defined(USE_ZLIB) && !defined(HAVE_ZL_INFLAT64) && !defined(NO_DEFLATE64))
+   /* zlib does not (yet?) provide Deflate64(tm) support */
+#  define NO_DEFLATE64
+#endif
+
+#ifdef NO_DEFLATE64
+   /* disable support for Deflate64(tm) */
+#  ifdef USE_DEFLATE64
+#    undef USE_DEFLATE64
+#  endif
+#else
+   /* enable Deflate64(tm) support unless compiling for SFX stub */
+#  if (!defined(USE_DEFLATE64) && !defined(SFX))
+#    define USE_DEFLATE64
+#  endif
+#endif
+
+/* disable bzip2 support for SFX stub, unless explicitly requested */
+#if (defined(SFX) && !defined(BZIP2_SFX) && defined(USE_BZIP2))
+#  undef USE_BZIP2
+#endif
+
+#if (defined(NO_VMS_TEXT_CONV) || defined(VMS))
+#  ifdef VMS_TEXT_CONV
+#    undef VMS_TEXT_CONV
+#  endif
+#else
+#  if (!defined(VMS_TEXT_CONV) && !defined(SFX))
+#    define VMS_TEXT_CONV
+#  endif
+#endif
+
+/* Enable -B option per default on specific systems, to allow backing up
+ * files that would be overwritten.
+ * (This list of systems must be kept in sync with the list of systems
+ * that add the B_flag to the UzpOpts structure, see unzip.h.)
+ */
+#if (!defined(NO_UNIXBACKUP) && !defined(UNIXBACKUP))
+#  if defined(UNIX) || defined(OS2) || defined(WIN32)
+#    define UNIXBACKUP
+#  endif
+#endif
+
+#if (defined(DLL) && !defined(REENTRANT))
+#  define REENTRANT
+#endif
+
+#if (!defined(DYNAMIC_CRC_TABLE) && !defined(FUNZIP))
+#  define DYNAMIC_CRC_TABLE
+#endif
+
+#if (defined(DYNAMIC_CRC_TABLE) && !defined(REENTRANT))
+#  ifndef DYNALLOC_CRCTAB
+#    define DYNALLOC_CRCTAB
+#  endif
+#endif
+
+/*---------------------------------------------------------------------------
+    OS-dependent configuration for UnZip internals
+  ---------------------------------------------------------------------------*/
+
+/* Some compiler distributions for Win32/i386 systems try to emulate
+ * a Unix (POSIX-compatible) environment.
+ */
+#if (defined(WIN32) && defined(UNIX))
+   /* UnZip does not support merging both ports in a single executable. */
+#  if (defined(FORCE_WIN32_OVER_UNIX) && defined(FORCE_UNIX_OVER_WIN32))
+     /* conflicting choice requests -> we prefer the Win32 environment */
+#    undef FORCE_UNIX_OVER_WIN32
+#  endif
+#  ifdef FORCE_WIN32_OVER_UNIX
+     /* native Win32 support was explicitly requested... */
+#    undef UNIX
+#  else
+     /* use the POSIX (Unix) emulation features by default... */
+#    undef WIN32
+#  endif
+#endif
+
+/* bad or (occasionally?) missing stddef.h: */
+#if (defined(M_XENIX) || defined(DNIX))
+#  define NO_STDDEF_H
+#endif
+
+#if (defined(M_XENIX) && !defined(M_UNIX))   /* SCO Xenix only, not SCO Unix */
+#  define SCO_XENIX
+#  define NO_LIMITS_H        /* no limits.h, but MODERN defined */
+#  define NO_UID_GID         /* no uid_t/gid_t */
+#  define size_t int
+#endif
+
+#ifdef realix   /* Modcomp Real/IX, real-time SysV.3 variant */
+#  define SYSV
+#  define NO_UID_GID         /* no uid_t/gid_t */
+#endif
+
+#if (defined(_AIX) && !defined(_ALL_SOURCE))
+#  define _ALL_SOURCE
+#endif
+
+#if defined(apollo)          /* defines __STDC__ */
+#    define NO_STDLIB_H
+#endif
+
+#ifdef DNIX
+#  define SYSV
+#  define SHORT_NAMES         /* 14-char limitation on path components */
+/* #  define FILENAME_MAX  14 */
+#  define FILENAME_MAX  NAME_MAX    /* GRR:  experiment */
+#endif
+
+#if (defined(SYSTEM_FIVE) || defined(__SYSTEM_FIVE))
+#  ifndef SYSV
+#    define SYSV
+#  endif
+#endif /* SYSTEM_FIVE || __SYSTEM_FIVE */
+#if (defined(M_SYSV) || defined(M_SYS5))
+#  ifndef SYSV
+#    define SYSV
+#  endif
+#endif /* M_SYSV || M_SYS5 */
+/* __SVR4 and __svr4__ catch Solaris on at least some combos of compiler+OS */
+#if (defined(__SVR4) || defined(__svr4__) || defined(sgi) || defined(__hpux))
+#  ifndef SYSV
+#    define SYSV
+#  endif
+#endif /* __SVR4 || __svr4__ || sgi || __hpux */
+#if (defined(LINUX) || defined(__QNX__))
+#  ifndef SYSV
+#    define SYSV
+#  endif
+#endif /* LINUX || __QNX__ */
+
+#if (defined(ultrix) || defined(__ultrix) || defined(bsd4_2))
+#  if (!defined(BSD) && !defined(SYSV))
+#    define BSD
+#  endif
+#endif /* ultrix || __ultrix || bsd4_2 */
+#if (defined(sun) || defined(pyr) || defined(CONVEX))
+#  if (!defined(BSD) && !defined(SYSV))
+#    define BSD
+#  endif
+#endif /* sun || pyr || CONVEX */
+
+#ifdef pyr  /* Pyramid:  has BSD and AT&T "universes" */
+#  ifdef BSD
+#    define pyr_bsd
+#    define USE_STRINGS_H  /* instead of more common string.h */
+#    define ZMEM           /* ZMEM now uses bcopy/bzero: not in AT&T universe */
+#  endif                   /* (AT&T memcpy claimed to be very slow, though) */
+#  define DECLARE_ERRNO
+#endif /* pyr */
+
+/* stat() bug for Borland, VAX C RTL, and Atari ST MiNT on TOS
+ * filesystems:  returns 0 for wildcards!  (returns 0xffffffff on Minix
+ * filesystem or `U:' drive under Atari MiNT.)  Watcom C was previously
+ * included on this list; it would be good to know what version the problem
+ * was fixed at, if it did exist.  */
+#if (defined(__TURBOC__) && !defined(WIN32))
+/*#  define WILD_STAT_BUG*/
+#endif
+#if (defined(VMS) || defined(__MINT__))
+#  define WILD_STAT_BUG
+#endif
+
+/*---------------------------------------------------------------------------
+    OS-dependent includes
+  ---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------
+    API (DLL) section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+#  define MAIN   UZ_EXP UzpMain   /* was UzpUnzip */
+#  ifdef OS2DLL
+#    undef Info
+#    define REDIRECTC(c)             varputchar(__G__ c)
+#    define REDIRECTPRINT(buf,size)  varmessage(__G__ buf, size)
+#    define FINISH_REDIRECT()        finish_REXX_redirect(__G)
+#  else
+#    define REDIRECTC(c)
+#    define REDIRECTPRINT(buf,size)  0
+#    define FINISH_REDIRECT()        close_redirect(__G)
+#  endif
+#endif
+
+/*---------------------------------------------------------------------------
+    Acorn RISCOS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+#  include "acorn/riscos.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    Amiga section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef AMIGA
+#  include "amiga/amiga.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    AOS/VS section (somewhat similar to Unix, apparently):
+  ---------------------------------------------------------------------------*/
+
+#ifdef AOS_VS
+#  ifdef __FILEIO_C
+#    include "aosvs/aosvs.h"
+#  endif
+#endif
+
+/*---------------------------------------------------------------------------
+    Atari ST section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef ATARI
+#  include <time.h>
+#  include <stat.h>
+#  include <fcntl.h>
+#  include <limits.h>
+#  define SYMLINKS
+#  define EXE_EXTENSION  ".tos"
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT  DF_DMY
+#  endif
+#  define DIR_END        '/'
+#  define INT_SPRINTF
+#  define timezone      _timezone
+#  define lenEOL        2
+#  define PutNativeEOL  {*q++ = native(CR); *q++ = native(LF);}
+#  undef SHORT_NAMES
+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+#    define TIMESTAMP
+#  endif
+#endif
+
+/*---------------------------------------------------------------------------
+    AtheOS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef __ATHEOS__
+#  include "atheos/athcfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    BeOS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef __BEOS__
+#  include "beos/beocfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    Human68k/X680x0 section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef __human68k__
+   /* DO NOT DEFINE DOS_OS2 HERE!  If Human68k is so much */
+   /*  like MS-DOS and/or OS/2, create DOS_H68_OS2 macro. */
+#  if (!defined(_MBCS) && !defined(NO_MBCS))
+     /* enable MBCS support by default for this system */
+#    define _MBCS
+#  endif
+#  if (defined(_MBCS) && defined(NO_MBCS))
+     /* disable MBCS support when explicitely requested */
+#    undef _MBCS
+#  endif
+#  include <time.h>
+#  include <fcntl.h>
+#  include <io.h>
+#  include <conio.h>
+#  include <sys/stat.h>
+#  ifdef HAVE_MBSTRING_H
+#    include <mbstring.h>
+#  endif
+#  ifdef HAVE_MBCTYPE_H
+#    include <mbctype.h>
+#  else
+#    ifndef _ismbblead
+#      define _ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c)))
+#    endif
+#  endif
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT DF_YMD   /* Japanese standard */
+#  endif
+#  define lenEOL        1
+#  define PutNativeEOL  *q++ = native(LF);
+#  define INT_SPRINTF
+#  define SYMLINKS
+#  ifdef SFX
+#    define MAIN main_sfx
+#  endif
+#endif
+
+/*---------------------------------------------------------------------------
+    Mac section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+#  include "maccfg.h"
+#endif /* MACOS */
+
+/*---------------------------------------------------------------------------
+    MS-DOS, OS/2, FLEXOS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+#  ifdef MORE
+#    undef MORE
+#  endif
+#  ifdef OS2_EAS
+#    undef OS2_EAS
+#  endif
+#endif
+
+#if (defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)))
+#  ifndef MSC
+#    define MSC               /* This should work for older MSC, too!  */
+#  endif
+#endif
+
+#if (defined(MSDOS) || defined(OS2) || defined(FLEXOS))
+#  include <sys/types.h>      /* off_t, time_t, dev_t, ... */
+#  include <sys/stat.h>
+#  include <io.h>             /* lseek(), open(), setftime(), dup(), creat() */
+#  include <time.h>           /* localtime() */
+#  include <fcntl.h>          /* O_BINARY for open() w/o CR/LF translation */
+
+#  ifdef OS2                  /* defined for all OS/2 compilers */
+#    include "os2/os2cfg.h"
+#  else
+#    ifdef FLEXOS
+#      include "flexos/flxcfg.h"
+#    else
+#      include "msdos/doscfg.h"
+#    endif
+#  endif
+
+#  if (defined(_MSC_VER) && (_MSC_VER == 700) && !defined(GRR))
+    /*
+     * ARGH.  MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not
+     *  1970 Jan 1 00:00.  So we have to diddle time_t's appropriately:  add or
+     *  subtract 70 years' worth of seconds; i.e., number of days times 86400;
+     *  i.e., (70*365 regular days + 17 leap days + 1 1899 day) * 86400 ==
+     *  (25550 + 17 + 1) * 86400 == 2209075200 seconds.  We know time_t is an
+     *  unsigned long (ulg) on the only system with this bug.
+     */
+#    define TIMET_TO_NATIVE(x)  (x) += (ulg)2209075200L;
+#    define NATIVE_TO_TIMET(x)  (x) -= (ulg)2209075200L;
+#  endif
+#  if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0450))
+#    define timezone      _timezone
+#  endif
+#  if (defined(__GO32__) || defined(FLEXOS))
+#    define DIR_END       '/'
+#  else
+#    define DIR_END       '\\'  /* OS uses '\\' as directory separator */
+#    define DIR_END2      '/'   /* also check for '/' (RTL may convert) */
+#  endif
+#  ifdef DATE_FORMAT
+#    undef DATE_FORMAT
+#  endif
+#  define DATE_FORMAT     dateformat()
+#  define lenEOL          2
+#  define PutNativeEOL    {*q++ = native(CR); *q++ = native(LF);}
+#  if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
+#    define USE_EF_UT_TIME
+#  endif
+#endif /* MSDOS || OS2 || FLEXOS */
+
+/*---------------------------------------------------------------------------
+    MTS section (piggybacks UNIX, I think):
+  ---------------------------------------------------------------------------*/
+
+#ifdef MTS
+#  include <sys/types.h>      /* off_t, time_t, dev_t, ... */
+#  include <sys/stat.h>
+#  include <sys/file.h>       /* MTS uses this instead of fcntl.h */
+#  include <timeb.h>
+#  include <time.h>
+#  include <unix.h>           /* some important non-ANSI routines */
+#  define mkdir(s,n) (-1)     /* no "make directory" capability */
+#  define EBCDIC              /* set EBCDIC conversion on */
+#  define NO_STRNICMP         /* unzip's is as good the one in MTS */
+#  define USE_FWRITE
+#  define close_outfile()  fclose(G.outfile)   /* can't set time on files */
+#  define umask(n)            /* don't have umask() on MTS */
+#  define FOPWT         "w"   /* open file for writing in TEXT mode */
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT DF_MDY
+#  endif
+#  define lenEOL        1
+#  define PutNativeEOL  *q++ = native(LF);
+#endif /* MTS */
+
+ /*---------------------------------------------------------------------------
+    Novell Netware NLM section
+  ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+#  include "netware/nlmcfg.h"
+#endif
+
+ /*---------------------------------------------------------------------------
+    QDOS section
+  ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+#  define DIRENT
+#  include <fcntl.h>
+#  include <unistd.h>
+#  include <sys/stat.h>
+#  include <time.h>
+#  include "qdos/izqdos.h"
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT DF_MDY
+#  endif
+#  define lenEOL        1
+#  define PutNativeEOL  *q++ = native(LF);
+#  define DIR_END       '_'
+#  define RETURN        QReturn
+#  undef PATH_MAX
+#  define PATH_MAX      36
+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+#    define TIMESTAMP
+#  endif
+#  define SCREENSIZE(ttrows, ttcols)  screensize(ttrows, ttcols)
+#  define SCREENWIDTH 80
+#endif
+
+/*---------------------------------------------------------------------------
+    Tandem NSK section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef TANDEM
+#  include "tandem.h"
+#  include <fcntl.h>
+#  ifndef __INT32
+     /* We are compiling with non-WIDE memory model, int = 16 bits */
+#    ifndef INT_16BIT
+#      define INT_16BIT   /* report "int" size is 16-bit to inflate setup */
+#    endif
+#    ifdef USE_DEFLATE64
+       /* Following required for 64k WSIZE of Deflate64 support */
+#      define MED_MEM     /* else OUTBUFSIZ is 64K and fails in do_string */
+#      define INBUFSIZ  8192  /* but larger buffer for real OSes */
+#    endif
+#  endif
+   /* use a single LF delimiter so that writes to 101 text files work */
+#  define PutNativeEOL  *q++ = native(LF);
+#  define lenEOL        1
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT  DF_DMY
+#  endif
+#  define SCREENLINES   25
+   /* USE_EF_UT_TIME is set in tandem.h */
+#  define RESTORE_UIDGID
+#  define NO_STRNICMP
+#endif
+
+/*---------------------------------------------------------------------------
+    THEOS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+#  include "theos/thscfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    TOPS-20 section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+#  include <sys/types.h>        /* off_t, time_t, dev_t, ... */
+#  include <sys/stat.h>
+#  include <sys/param.h>
+#  include <sys/time.h>
+#  include <sys/timeb.h>
+#  include <sys/file.h>
+#  include <timex.h>
+#  include <monsym.h>           /* get amazing monsym() macro */
+   extern int open(), close(), read();
+   extern int stat(), unlink(), jsys(), fcntl();
+   extern long lseek(), dup(), creat();
+#  define strchr    index       /* GRR: necessary? */
+#  define strrchr   rindex
+#  define REALLY_SHORT_SYMS
+#  define NO_MKDIR
+#  ifndef HAVE_STRNICMP
+#    define NO_STRNICMP           /* probably not provided by TOPS20 C RTL  */
+#  endif
+#  define DIR_BEG       '<'
+#  define DIR_END       '>'
+#  define DIR_EXT       ".directory"
+#  ifndef DATE_FORMAT
+#    define DATE_FORMAT DF_MDY
+#  endif
+#  define EXE_EXTENSION ".exe"  /* just a guess... */
+#endif /* TOPS20 */
+
+/*---------------------------------------------------------------------------
+    Unix section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef UNIX
+#  include "unix/unxcfg.h"
+#endif /* UNIX */
+
+/*---------------------------------------------------------------------------
+    VM/CMS and MVS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+#  include "vmmvs.h"
+#  define CLOSE_INFILE()  close_infile(__G)
+#endif
+
+/*---------------------------------------------------------------------------
+    VMS section:
+  ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+#  include "vms/vmscfg.h"
+#endif /* VMS */
+
+/*---------------------------------------------------------------------------
+    Win32 (Windows 95/NT) section:
+  ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && !defined(POCKET_UNZIP) && !defined(_WIN32_WCE))
+#  include "win32/w32cfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+    Win32 Windows CE section (also POCKET_UNZIP)
+  ---------------------------------------------------------------------------*/
+
+#if (defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+#  include "wince/wcecfg.h"
+#endif
+
+
+
+/* ----------------------------------------------------------------------------
+   MUST BE AFTER LARGE FILE INCLUDES
+   ---------------------------------------------------------------------------- */
+/* This stuff calls in types and messes up large file includes.  It needs to
+   go after large file defines in local includes.
+   I am guessing that moving them here probably broke some ports, but hey.
+   10/31/2004 EG */
+/* ----------------------------------------------------------------------------
+   Common includes
+   ---------------------------------------------------------------------------- */
+
+/* Some ports apply specific adjustments which must be in effect before
+   reading the "standard" include headers.
+ */
+
+#ifdef EFT
+#  define Z_OFF_T off_t  /* Amdahl UTS nonsense ("extended file types") */
+#else
+#if (defined(UNIX) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64))
+#  define Z_OFF_T off_t /* 64bit offsets to support 2GB < zipfile size < 4GB */
+#else
+#  define Z_OFF_T long
+#endif
+#endif
+
+#ifndef ZOFF_T_DEFINED
+   typedef Z_OFF_T zoff_t;
+#  define ZOFF_T_DEFINED
+#endif
+#ifndef Z_STAT_DEFINED
+   typedef struct stat z_stat;
+#  define Z_STAT_DEFINED
+#endif
+
+#ifndef MINIX            /* Minix needs it after all the other includes (?) */
+#  include <stdio.h>
+#endif
+
+#include <ctype.h>       /* skip for VMS, to use tolower() function? */
+#include <errno.h>       /* used in mapname() */
+#ifdef USE_STRINGS_H
+#  include <strings.h>   /* strcpy, strcmp, memcpy, index/rindex, etc. */
+#else
+#  include <string.h>    /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */
+#endif
+#if (defined(MODERN) && !defined(NO_LIMITS_H))
+#  include <limits.h>    /* MAX/MIN constant symbols for system types... */
+#endif
+
+/* this include must be down here for SysV.4, for some reason... */
+#include <signal.h>      /* used in unzip.c, fileio.c */
+
+
+#ifdef MODERN
+#  ifndef NO_STDDEF_H
+#    include <stddef.h>
+#  endif
+#  ifndef NO_STDLIB_H
+#    include <stdlib.h>  /* standard library prototypes, malloc(), etc. */
+#  endif
+   typedef size_t extent;
+#else /* !MODERN */
+#  ifndef AOS_VS         /* mostly modern? */
+     Z_OFF_T lseek();
+#    ifdef VAXC          /* not fully modern, but has stdlib.h and void */
+#      include <stdlib.h>
+#    else
+       char *malloc();
+#    endif /* ?VAXC */
+#  endif /* !AOS_VS */
+   typedef unsigned int extent;
+#endif /* ?MODERN */
+
+
+
+
+/*************/
+/*  Defines  */
+/*************/
+
+#define UNZIP_BZ2VERS   46
+#ifdef ZIP64_SUPPORT
+# ifdef USE_BZIP2
+#  define UNZIP_VERSION   UNZIP_BZ2VERS
+# else
+#  define UNZIP_VERSION   45
+# endif
+#else
+#ifdef USE_DEFLATE64
+#  define UNZIP_VERSION   21   /* compatible with PKUNZIP 4.0 */
+#else
+#  define UNZIP_VERSION   20   /* compatible with PKUNZIP 2.0 */
+#endif
+#endif
+#define VMS_UNZIP_VERSION 42   /* if OS-needed-to-extract is VMS:  can do */
+
+#if (defined(MSDOS) || defined(OS2))
+#  define DOS_OS2
+#endif
+
+#if (defined(OS2) || defined(WIN32))
+#  define OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(WIN32))
+#  define DOS_OS2_W32
+#  define DOS_W32_OS2          /* historical:  don't use */
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(__human68k__))
+#  define DOS_H68_OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(FLEXOS))
+#  define DOS_FLX_OS2
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(FLEXOS))
+#  define DOS_FLX_OS2_W32
+#endif
+
+#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS))
+#  define DOS_FLX_H68_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_OS2) || defined(NLM))
+#  define DOS_FLX_NLM_OS2
+#endif
+
+#if (defined(DOS_FLX_OS2_W32) || defined(NLM))
+#  define DOS_FLX_NLM_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_H68_OS2_W32) || defined(NLM))
+#  define DOS_FLX_H68_NLM_OS2_W32
+#endif
+
+#if (defined(TOPS20) || defined(VMS))
+#  define T20_VMS
+#endif
+
+#if (defined(MSDOS) || defined(T20_VMS))
+#  define DOS_T20_VMS
+#endif
+
+#if (defined(__ATHEOS__) || defined(__BEOS__))
+#  define ATH_BEO
+#endif
+
+#if (defined(ATH_BEO) || defined(UNIX))
+#  define ATH_BEO_UNX
+#endif
+
+#if (defined(ATH_BEO_UNX) || defined(THEOS))
+#  define ATH_BEO_THS_UNX
+#endif
+
+/* clean up with a few defaults */
+#ifndef DIR_END
+#  define DIR_END       '/'     /* last char before program name or filename */
+#endif
+#ifndef DATE_FORMAT
+# ifdef DATEFMT_ISO_DEFAULT
+#  define DATE_FORMAT   DF_YMD  /* defaults to invariant ISO-style */
+# else
+#  define DATE_FORMAT   DF_MDY  /* defaults to US convention */
+# endif
+#endif
+#ifndef DATE_SEPCHAR
+#  define DATE_SEPCHAR  '-'
+#endif
+#ifndef CLOSE_INFILE
+#  define CLOSE_INFILE()  close(G.zipfd)
+#endif
+#ifndef RETURN
+#  define RETURN        return  /* only used in main() */
+#endif
+#ifndef EXIT
+#  define EXIT          exit
+#endif
+#ifndef USAGE
+#  define USAGE(ret)    usage(__G__ (ret))    /* used in unzip.c, zipinfo.c */
+#endif
+#ifndef TIMET_TO_NATIVE         /* everybody but MSC 7.0 and Macintosh */
+#  define TIMET_TO_NATIVE(x)
+#  define NATIVE_TO_TIMET(x)
+#endif
+#ifndef STRNICMP
+#  ifdef NO_STRNICMP
+#    define STRNICMP zstrnicmp
+#  else
+#    define STRNICMP strnicmp
+#  endif
+#endif
+
+
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_UNX) || defined(RISCOS))
+#  ifndef HAVE_UNLINK
+#    define HAVE_UNLINK
+#  endif
+#endif
+#if (defined(AOS_VS) || defined(ATARI)) /* GRR: others? */
+#  ifndef HAVE_UNLINK
+#    define HAVE_UNLINK
+#  endif
+#endif
+
+/* OS-specific exceptions to the "ANSI <--> INT_SPRINTF" rule */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+#  if (defined(SYSV) || defined(CONVEX) || defined(NeXT) || defined(BSD4_4))
+#    define INT_SPRINTF      /* sprintf() returns int:  SysVish/Posix */
+#  endif
+#  if (defined(DOS_FLX_NLM_OS2_W32) || defined(VMS) || defined(AMIGA))
+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI */
+#  endif
+#  if (defined(ultrix) || defined(__ultrix)) /* Ultrix 4.3 and newer */
+#    if (defined(POSIX) || defined(__POSIX))
+#      define INT_SPRINTF    /* sprintf() returns int:  ANSI/Posix */
+#    endif
+#    ifdef __GNUC__
+#      define PCHAR_SPRINTF  /* undetermined actual return value */
+#    endif
+#  endif
+#  if (defined(__osf__) || defined(_AIX) || defined(CMS_MVS) || defined(THEOS))
+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI/Posix */
+#  endif
+#  if defined(sun)
+#    define PCHAR_SPRINTF    /* sprintf() returns char *:  SunOS cc *and* gcc */
+#  endif
+#endif
+
+/* defaults that we hope will take care of most machines in the future */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+#  ifdef __STDC__
+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI */
+#  endif
+#  ifndef INT_SPRINTF
+#    define PCHAR_SPRINTF    /* sprintf() returns char *:  BSDish */
+#  endif
+#endif
+
+#define MSG_STDERR(f)  (f & 1)        /* bit 0:  0 = stdout, 1 = stderr */
+#define MSG_INFO(f)    ((f & 6) == 0) /* bits 1 and 2:  0 = info */
+#define MSG_WARN(f)    ((f & 6) == 2) /* bits 1 and 2:  1 = warning */
+#define MSG_ERROR(f)   ((f & 6) == 4) /* bits 1 and 2:  2 = error */
+#define MSG_FATAL(f)   ((f & 6) == 6) /* bits 1 and 2:  (3 = fatal error) */
+#define MSG_ZFN(f)     (f & 0x0008)   /* bit 3:  1 = print zipfile name */
+#define MSG_FN(f)      (f & 0x0010)   /* bit 4:  1 = print filename */
+#define MSG_LNEWLN(f)  (f & 0x0020)   /* bit 5:  1 = leading newline if !SOL */
+#define MSG_TNEWLN(f)  (f & 0x0040)   /* bit 6:  1 = trailing newline if !SOL */
+#define MSG_MNEWLN(f)  (f & 0x0080)   /* bit 7:  1 = trailing NL for prompts */
+/* the following are subject to change */
+#define MSG_NO_WGUI(f) (f & 0x0100)   /* bit 8:  1 = skip if Windows GUI */
+#define MSG_NO_AGUI(f) (f & 0x0200)   /* bit 9:  1 = skip if Acorn GUI */
+#define MSG_NO_DLL2(f) (f & 0x0400)   /* bit 10:  1 = skip if OS/2 DLL */
+#define MSG_NO_NDLL(f) (f & 0x0800)   /* bit 11:  1 = skip if WIN32 DLL */
+#define MSG_NO_WDLL(f) (f & 0x1000)   /* bit 12:  1 = skip if Windows DLL */
+
+#if (defined(MORE) && !defined(SCREENLINES))
+#  ifdef DOS_FLX_NLM_OS2_W32
+#    define SCREENLINES 25  /* can be (should be) a function instead */
+#  else
+#    define SCREENLINES 24  /* VT-100s are assumed to be minimal hardware */
+#  endif
+#endif
+#if (defined(MORE) && !defined(SCREENSIZE))
+#  ifndef SCREENWIDTH
+#    define SCREENSIZE(scrrows, scrcols) { \
+          if ((scrrows) != NULL) *(scrrows) = SCREENLINES; }
+#  else
+#    define SCREENSIZE(scrrows, scrcols) { \
+          if ((scrrows) != NULL) *(scrrows) = SCREENLINES; \
+          if ((scrcols) != NULL) *(scrcols) = SCREENWIDTH; }
+#  endif
+#endif
+
+#if (defined(__16BIT__) || defined(MED_MEM) || defined(SMALL_MEM))
+# define DIR_BLKSIZ  64     /* number of directory entries per block
+                             *  (should fit in 4096 bytes, usually) */
+#else
+# define DIR_BLKSIZ 16384   /* use more memory, to reduce long-range seeks */
+#endif
+
+#ifndef WSIZE
+#  ifdef USE_DEFLATE64
+#    define WSIZE   65536L  /* window size--must be a power of two, and */
+#  else                     /*  at least 64K for PKZip's deflate64 method */
+#    define WSIZE   0x8000  /* window size--must be a power of two, and */
+#  endif                    /*  at least 32K for zip's deflate method */
+#endif
+
+#ifdef __16BIT__
+#  ifndef INT_16BIT
+#    define INT_16BIT       /* on 16-bit systems int size is 16 bits */
+#  endif
+#else
+#  define nearmalloc  malloc
+#  define nearfree    free
+#  if (!defined(__IBMC__) || !defined(OS2))
+#    ifndef near
+#      define near
+#    endif
+#    ifndef far
+#      define far
+#    endif
+#  endif
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && !defined(DYNAMIC_CRC_TABLE))
+#  undef DYNALLOC_CRCTAB
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
+#  undef DYNALLOC_CRCTAB   /* not safe with reentrant code */
+#endif
+
+#if (defined(USE_ZLIB) && !defined(USE_OWN_CRCTAB))
+#  ifdef DYNALLOC_CRCTAB
+#    undef DYNALLOC_CRCTAB
+#  endif
+#endif
+
+#if (defined(USE_ZLIB) && defined(ASM_CRC))
+#  undef ASM_CRC
+#endif
+
+#ifdef USE_ZLIB
+#  ifdef IZ_CRC_BE_OPTIMIZ
+#    undef IZ_CRC_BE_OPTIMIZ
+#  endif
+#  ifdef IZ_CRC_LE_OPTIMIZ
+#    undef IZ_CRC_LE_OPTIMIZ
+#  endif
+#endif
+#if (!defined(IZ_CRC_BE_OPTIMIZ) && !defined(IZ_CRC_LE_OPTIMIZ))
+#  ifdef IZ_CRCOPTIM_UNFOLDTBL
+#    undef IZ_CRCOPTIM_UNFOLDTBL
+#  endif
+#endif
+
+#ifndef INBUFSIZ
+#  if (defined(MED_MEM) || defined(SMALL_MEM))
+#    define INBUFSIZ  2048  /* works for MS-DOS small model */
+#  else
+#    define INBUFSIZ  8192  /* larger buffers for real OSes */
+#  endif
+#endif
+
+#if (defined(INT_16BIT) && (defined(USE_DEFLATE64) || lenEOL > 1))
+   /* For environments using 16-bit integers OUTBUFSIZ must be limited to
+    * less than 64k (do_string() uses "unsigned" in calculations involving
+    * OUTBUFSIZ).  This is achieved by defining MED_MEM when WSIZE = 64k (aka
+    * Deflate64 support enabled) or EOL markers contain multiple characters.
+    * (The rule gets applied AFTER the default rule for INBUFSIZ because it
+    * is not neccessary to reduce INBUFSIZE in this case.)
+    */
+#  if (!defined(SMALL_MEM) && !defined(MED_MEM))
+#    define MED_MEM
+#  endif
+#endif
+
+/* Logic for case of small memory, length of EOL > 1:  if OUTBUFSIZ == 2048,
+ * OUTBUFSIZ>>1 == 1024 and OUTBUFSIZ>>7 == 16; therefore rawbuf is 1008 bytes
+ * and transbuf 1040 bytes.  Have room for 32 extra EOL chars; 1008/32 == 31.5
+ * chars/line, smaller than estimated 35-70 characters per line for C source
+ * and normal text.  Hence difference is sufficient for most "average" files.
+ * (Argument scales for larger OUTBUFSIZ.)
+ */
+#ifdef SMALL_MEM          /* i.e., 16-bit OSes:  MS-DOS, OS/2 1.x, etc. */
+#  define LoadFarString(x)       fLoadFarString(__G__ (x))
+#  define LoadFarStringSmall(x)  fLoadFarStringSmall(__G__ (x))
+#  define LoadFarStringSmall2(x) fLoadFarStringSmall2(__G__ (x))
+#  if (defined(_MSC_VER) && (_MSC_VER >= 600))
+#    define zfstrcpy(dest, src)  _fstrcpy((dest), (src))
+#    define zfstrcmp(s1, s2)     _fstrcmp((s1), (s2))
+#  endif
+#  if !(defined(SFX) || defined(FUNZIP))
+#    if (defined(_MSC_VER))
+#      define zfmalloc(sz)       _fmalloc((sz))
+#      define zffree(x)          _ffree(x)
+#    endif
+#    if (defined(__TURBOC__))
+#      include <alloc.h>
+#      define zfmalloc(sz)       farmalloc((unsigned long)(sz))
+#      define zffree(x)          farfree(x)
+#    endif
+#  endif /* !(SFX || FUNZIP) */
+#  ifndef Far
+#    define Far far  /* __far only works for MSC 6.00, not 6.0a or Borland */
+#  endif
+#  define OUTBUFSIZ INBUFSIZ
+#  if (lenEOL == 1)
+#    define RAWBUFSIZ (OUTBUFSIZ>>1)
+#  else
+#    define RAWBUFSIZ ((OUTBUFSIZ>>1) - (OUTBUFSIZ>>7))
+#  endif
+#  define TRANSBUFSIZ (OUTBUFSIZ-RAWBUFSIZ)
+   typedef short  shrint;            /* short/int or "shrink int" (unshrink) */
+#else
+#  define zfstrcpy(dest, src)       strcpy((dest), (src))
+#  define zfstrcmp(s1, s2)          strcmp((s1), (s2))
+#  define zfmalloc                  malloc
+#  define zffree(x)                 free(x)
+#  ifdef QDOS
+#    define LoadFarString(x)        Qstrfix(x)   /* fix up _ for '.' */
+#    define LoadFarStringSmall(x)   Qstrfix(x)
+#    define LoadFarStringSmall2(x)  Qstrfix(x)
+#  else
+#    define LoadFarString(x)        (char *)(x)
+#    define LoadFarStringSmall(x)   (char *)(x)
+#    define LoadFarStringSmall2(x)  (char *)(x)
+#  endif
+#  ifdef MED_MEM
+#    define OUTBUFSIZ 0xFF80         /* can't malloc arrays of 0xFFE8 or more */
+#    define TRANSBUFSIZ 0xFF80
+     typedef short  shrint;
+#  else
+#    define OUTBUFSIZ (lenEOL*WSIZE) /* more efficient text conversion */
+#    define TRANSBUFSIZ (lenEOL*OUTBUFSIZ)
+#    ifdef AMIGA
+       typedef short shrint;
+#    else
+       typedef int  shrint;          /* for efficiency/speed, we hope... */
+#    endif
+#  endif /* ?MED_MEM */
+#  define RAWBUFSIZ OUTBUFSIZ
+#endif /* ?SMALL_MEM */
+
+#ifndef Far
+#  define Far
+#endif
+
+#ifndef Cdecl
+#  define Cdecl
+#endif
+
+#ifndef MAIN
+#  define MAIN  main
+#endif
+
+#ifdef SFX      /* disable some unused features for SFX executables */
+#  ifndef NO_ZIPINFO
+#    define NO_ZIPINFO
+#  endif
+#  ifdef TIMESTAMP
+#    undef TIMESTAMP
+#  endif
+#endif
+
+#ifdef SFX
+#  ifdef CHEAP_SFX_AUTORUN
+#    ifndef NO_SFX_EXDIR
+#      define NO_SFX_EXDIR
+#    endif
+#  endif
+#  ifndef NO_SFX_EXDIR
+#    ifndef SFX_EXDIR
+#      define SFX_EXDIR
+#    endif
+#  else
+#    ifdef SFX_EXDIR
+#      undef SFX_EXDIR
+#    endif
+#  endif
+#endif
+
+/* user may have defined both by accident...  NOTIMESTAMP takes precedence */
+#if (defined(TIMESTAMP) && defined(NOTIMESTAMP))
+#  undef TIMESTAMP
+#endif
+
+#if (!defined(COPYRIGHT_CLEAN) && !defined(USE_SMITH_CODE))
+#  define COPYRIGHT_CLEAN
+#endif
+
+/* The LZW patent is expired worldwide since 2004-Jul-07, so USE_UNSHRINK
+ * is now enabled by default.  See unshrink.c.
+ */
+#if (!defined(LZW_CLEAN) && !defined(USE_UNSHRINK))
+#  define USE_UNSHRINK
+#endif
+
+#ifndef O_BINARY
+#  define O_BINARY  0
+#endif
+
+#ifndef PIPE_ERROR
+#  ifndef EPIPE
+#    define EPIPE -1
+#  endif
+#  define PIPE_ERROR (errno == EPIPE)
+#endif
+
+/* File operations--use "b" for binary if allowed or fixed length 512 on VMS */
+#ifdef VMS
+#  define FOPR  "r","ctx=stm"
+#  define FOPM  "r+","ctx=stm","rfm=fix","mrs=512"
+#  define FOPW  "w","ctx=stm","rfm=fix","mrs=512"
+#  define FOPWR "w+","ctx=stm","rfm=fix","mrs=512"
+#endif /* VMS */
+
+#ifdef CMS_MVS
+/* Binary files must be RECFM=F,LRECL=1 for ftell() to get correct pos */
+/* ...unless byteseek is used.  Let's try that for a while.            */
+#  define FOPR "rb,byteseek"
+#  define FOPM "r+b,byteseek"
+#  ifdef MVS
+#    define FOPW "wb,recfm=u,lrecl=32760,byteseek" /* New binary files */
+#    define FOPWE "wb"                             /* Existing binary files */
+#    define FOPWT "w,lrecl=133"                    /* New text files */
+#    define FOPWTE "w"                             /* Existing text files */
+#  else
+#    define FOPW "wb,recfm=v,lrecl=32760"
+#    define FOPWT "w"
+#  endif
+#endif /* CMS_MVS */
+
+#ifdef TOPS20          /* TOPS-20 MODERN?  You kidding? */
+#  define FOPW "w8"
+#endif /* TOPS20 */
+
+/* Defaults when nothing special has been defined previously. */
+#ifdef MODERN
+#  ifndef FOPR
+#    define FOPR "rb"
+#  endif
+#  ifndef FOPM
+#    define FOPM "r+b"
+#  endif
+#  ifndef FOPW
+#    define FOPW "wb"
+#  endif
+#  ifndef FOPWT
+#    define FOPWT "wt"
+#  endif
+#  ifndef FOPWR
+#    define FOPWR "w+b"
+#  endif
+#else /* !MODERN */
+#  ifndef FOPR
+#    define FOPR "r"
+#  endif
+#  ifndef FOPM
+#    define FOPM "r+"
+#  endif
+#  ifndef FOPW
+#    define FOPW "w"
+#  endif
+#  ifndef FOPWT
+#    define FOPWT "w"
+#  endif
+#  ifndef FOPWR
+#    define FOPWR "w+"
+#  endif
+#endif /* ?MODERN */
+
+/*
+ * If <limits.h> exists on most systems, should include that, since it may
+ * define some or all of the following:  NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
+ * _POSIX_PATH_MAX.
+ */
+#ifdef DOS_FLX_NLM_OS2_W32
+#  include <limits.h>
+#endif
+
+/* 2008-07-22 SMS.
+ * Unfortunately, on VMS, <limits.h> exists, and is included by <stdlib.h>
+ * (so it's pretty much unavoidable), and it defines PATH_MAX to a fixed
+ * short value (256, correct only for older systems without ODS-5 support),
+ * rather than one based on the real RMS NAM[L] situation.  So, we
+ * artificially undefine it here, to allow our better-defined _MAX_PATH
+ * (see vms/vmscfg.h) to be used.
+ */
+#ifdef VMS
+#  undef PATH_MAX
+#endif
+
+#ifndef PATH_MAX
+#  ifdef MAXPATHLEN
+#    define PATH_MAX      MAXPATHLEN    /* in <sys/param.h> on some systems */
+#  else
+#    ifdef _MAX_PATH
+#      define PATH_MAX    _MAX_PATH
+#    else
+#      if FILENAME_MAX > 255
+#        define PATH_MAX  FILENAME_MAX  /* used like PATH_MAX on some systems */
+#      else
+#        define PATH_MAX  1024
+#      endif
+#    endif /* ?_MAX_PATH */
+#  endif /* ?MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+/*
+ * buffer size required to hold the longest legal local filepath
+ * (including the trailing '\0')
+ */
+#define FILNAMSIZ  PATH_MAX
+
+#ifdef UNICODE_SUPPORT
+# if !(defined(UTF8_MAYBE_NATIVE) || defined(UNICODE_WCHAR))
+#  undef UNICODE_SUPPORT
+# endif
+#endif
+/* 2007-09-18 SMS.
+ * Include <locale.h> here if it will be needed later for Unicode.
+ * Otherwise, SETLOCALE may be defined here, and then defined again
+ * (differently) when <locale.h> is read later.
+ */
+#ifdef UNICODE_SUPPORT
+# ifdef UNICODE_WCHAR
+#  if !(defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+#   include <wchar.h>
+#   include <wctype.h>
+#  endif
+# endif
+# ifndef _MBCS  /* no need to include <locale.h> twice, see below */
+#   include <locale.h>
+#   ifndef SETLOCALE
+#     define SETLOCALE(category, locale) setlocale(category, locale)
+#   endif
+# endif
+#endif /* UNICODE_SUPPORT */
+
+/* DBCS support for Info-ZIP  (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ */
+#ifdef _MBCS
+#  include <locale.h>
+   /* Multi Byte Character Set */
+#  define ___MBS_TMP_DEF  char *___tmp_ptr;
+#  define ___TMP_PTR      ___tmp_ptr
+#  ifndef CLEN
+#    define NEED_UZMBCLEN
+#    define CLEN(ptr) (int)uzmbclen((ZCONST unsigned char *)(ptr))
+#  endif
+#  ifndef PREINCSTR
+#    define PREINCSTR(ptr) (ptr += CLEN(ptr))
+#  endif
+#  define POSTINCSTR(ptr) (___TMP_PTR=(char *)(ptr), PREINCSTR(ptr),___TMP_PTR)
+   char *plastchar OF((ZCONST char *ptr, extent len));
+#  define lastchar(ptr, len) ((int)(unsigned)*plastchar(ptr, len))
+#  ifndef MBSCHR
+#    define NEED_UZMBSCHR
+#    define MBSCHR(str,c) (char *)uzmbschr((ZCONST unsigned char *)(str), c)
+#  endif
+#  ifndef MBSRCHR
+#    define NEED_UZMBSRCHR
+#    define MBSRCHR(str,c) (char *)uzmbsrchr((ZCONST unsigned char *)(str), c)
+#  endif
+#  ifndef SETLOCALE
+#    define SETLOCALE(category, locale) setlocale(category, locale)
+#  endif
+#else /* !_MBCS */
+#  define ___MBS_TMP_DEF
+#  define ___TMP_PTR
+#  define CLEN(ptr) 1
+#  define PREINCSTR(ptr) (++(ptr))
+#  define POSTINCSTR(ptr) ((ptr)++)
+#  define plastchar(ptr, len) (&ptr[(len)-1])
+#  define lastchar(ptr, len) (ptr[(len)-1])
+#  define MBSCHR(str, c) strchr(str, c)
+#  define MBSRCHR(str, c) strrchr(str, c)
+#  ifndef SETLOCALE
+#    define SETLOCALE(category, locale)
+#  endif
+#endif /* ?_MBCS */
+#define INCSTR(ptr) PREINCSTR(ptr)
+
+
+#if (defined(MALLOC_WORK) && !defined(MY_ZCALLOC))
+   /* Any system without a special calloc function */
+# ifndef zcalloc
+#  define zcalloc(items, size) \
+          (zvoid far *)calloc((unsigned)(items), (unsigned)(size))
+# endif
+# ifndef zcfree
+#  define zcfree    free
+# endif
+#endif /* MALLOC_WORK && !MY_ZCALLOC */
+
+#if (defined(CRAY) && defined(ZMEM))
+#  undef ZMEM
+#endif
+
+#ifdef ZMEM
+#  undef ZMEM
+#  define memcmp(b1,b2,len)      bcmp(b2,b1,len)
+#  define memcpy(dest,src,len)   bcopy(src,dest,len)
+#  define memzero                bzero
+#else
+#  define memzero(dest,len)      memset(dest,0,len)
+#endif
+
+#ifndef TRUE
+#  define TRUE      1   /* sort of obvious */
+#endif
+#ifndef FALSE
+#  define FALSE     0
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET  0
+#  define SEEK_CUR  1
+#  define SEEK_END  2
+#endif
+
+#if (!defined(S_IEXEC) && defined(S_IXUSR))
+#  define S_IEXEC   S_IXUSR
+#endif
+
+#if (defined(UNIX) && defined(S_IFLNK) && !defined(MTS))
+#  define SYMLINKS
+#  ifndef S_ISLNK
+#    define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)
+#  endif
+#endif /* UNIX && S_IFLNK && !MTS */
+
+#ifndef S_ISDIR
+#  ifdef CMS_MVS
+#    define S_ISDIR(m)  (FALSE)
+#  else
+#    define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
+# endif
+#endif
+
+#ifndef IS_VOLID
+#  define IS_VOLID(m)  ((m) & 0x08)
+#endif
+
+/***********************************/
+/*  LARGE_FILE_SUPPORT             */
+/***********************************/
+/* This whole section lifted from Zip 3b tailor.h
+
+ * Types are in OS dependent headers (eg, w32cfg.h)
+ *
+ * LARGE_FILE_SUPPORT and ZIP64_SUPPORT are automatically
+ * set in OS dependent headers (for some ports) based on the port and compiler.
+ *
+ * Function prototypes are below as OF is defined earlier in this file
+ * but after OS dependent header is included.
+ *
+ * E. Gordon 9/21/2003
+ * Updated 1/28/2004
+ * Lifted and placed here 6/7/2004 - Myles Bennett
+ */
+#ifdef LARGE_FILE_SUPPORT
+  /* 64-bit Large File Support */
+
+/* ---------------------------- */
+
+# if defined(UNIX) || defined(VMS)
+
+    /* 64-bit stat functions */
+#   define zstat stat
+#   define zfstat fstat
+
+    /* 64-bit fseeko */
+#   define zlseek lseek
+#   define zfseeko fseeko
+
+    /* 64-bit ftello */
+#   define zftello ftello
+
+    /* 64-bit fopen */
+#   define zfopen fopen
+#   define zfdopen fdopen
+
+# endif /* UNIX || VMS */
+
+/* ---------------------------- */
+
+# ifdef WIN32
+
+#   if defined(_MSC_VER) || defined(__MINGW32__) || defined(__LCC__)
+    /* MS C (VC), MinGW GCC port and LCC-32 use the MS C Runtime lib */
+
+      /* 64-bit stat functions */
+#     define zstat _stati64
+#     define zfstat _fstati64
+
+      /* 64-bit lseek */
+#     define zlseek _lseeki64
+
+#     if defined(_MSC_VER) && (_MSC_VER >= 1400)
+        /* Beginning with VS 8.0 (Visual Studio 2005, MSC 14), the Microsoft
+           C rtl publishes its (previously internal) implmentations of
+           "fseeko" and "ftello" for 64-bit file offsets. */
+        /* 64-bit fseeko */
+#       define zfseeko _fseeki64
+        /* 64-bit ftello */
+#       define zftello _ftelli64
+
+#     else /* not (defined(_MSC_VER) && (_MSC_VER >= 1400)) */
+
+#     if defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__ >= 0x800)
+        /* Up-to-date versions of MinGW define the macro __MSVCRT_VERSION__
+           to denote the version of the MS C rtl dll used for linking.  When
+           configured to link against the runtime of MS Visual Studio 8 (or
+           newer), the built-in 64-bit fseek/ftell functions are available. */
+        /* 64-bit fseeko */
+#       define zfseeko _fseeki64
+        /* 64-bit ftello */
+#       define zftello _ftelli64
+
+#     else /* !(defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__>=0x800)) */
+        /* The version of the C runtime is lower than MSC 14 or unknown. */
+
+        /* The newest MinGW port contains built-in extensions to the MSC rtl
+           that provide fseeko and ftello, but our implementations will do
+           for now. */
+       /* 64-bit fseeko */
+       int zfseeko OF((FILE *, zoff_t, int));
+
+       /* 64-bit ftello */
+       zoff_t zftello OF((FILE *));
+
+#     endif /* ? (__MSVCRT_VERSION__ >= 0x800) */
+#     endif /* ? (_MSC_VER >= 1400) */
+
+      /* 64-bit fopen */
+#     define zfopen fopen
+#     define zfdopen fdopen
+
+#   endif /* _MSC_VER || __MINGW__ || __LCC__ */
+
+#   ifdef __CYGWIN__
+    /* CYGWIN GCC Posix emulator on Windows
+       (configuration not yet finished/tested)  */
+
+      /* 64-bit stat functions */
+#     define zstat _stati64
+#     define zfstat _fstati64
+
+      /* 64-bit lseek */
+#     define zlseek _lseeki64
+
+      /* 64-bit fseeko */
+#     define zfseeko fseeko
+
+      /* 64-bit ftello */
+#     define zftello ftello
+
+      /* 64-bit fopen */
+#     define zfopen fopen
+#     define zfdopen fdopen
+
+#   endif
+#   if defined(__WATCOMC__) || defined(__BORLANDC__)
+    /* WATCOM C and Borland C provide their own C runtime libraries,
+       but they are sufficiently compatible with MS CRTL. */
+
+      /* 64-bit stat functions */
+#     define zstat _stati64
+#     define zfstat _fstati64
+
+#   ifdef __WATCOMC__
+      /* 64-bit lseek */
+#     define zlseek _lseeki64
+#   endif
+
+      /* 64-bit fseeko */
+      int zfseeko OF((FILE *, zoff_t, int));
+
+      /* 64-bit ftello */
+      zoff_t zftello OF((FILE *));
+
+      /* 64-bit fopen */
+#     define zfopen fopen
+#     define zfdopen fdopen
+
+#   endif
+#   ifdef __IBMC__
+      /* IBM C */
+
+      /* 64-bit stat functions */
+
+      /* 64-bit fseeko */
+
+      /* 64-bit ftello */
+
+      /* 64-bit fopen */
+
+#   endif
+
+# endif /* WIN32 */
+
+#else
+  /* No Large File Support */
+
+# ifndef REGULUS  /* returns the inode number on success(!)...argh argh argh */
+#   define zstat stat
+# endif
+# define zfstat fstat
+# define zlseek lseek
+# define zfseeko fseek
+# define zftello ftell
+# define zfopen fopen
+# define zfdopen fdopen
+
+# if defined(UNIX) || defined(VMS) || defined(WIN32)
+    /* For these systems, implement "64bit file vs. 32bit prog" check  */
+#   ifndef DO_SAFECHECK_2GB
+#     define DO_SAFECHECK_2GB
+#   endif
+# endif
+
+#endif
+
+/* No "64bit file vs. 32bit prog" check for SFX stub, to save space */
+#if (defined(DO_SAFECHECK_2GB) && defined(SFX))
+#  undef DO_SAFECHECK_2GB
+#endif
+
+#ifndef SSTAT
+#  ifdef WILD_STAT_BUG
+#    define SSTAT(path,pbuf) (iswild(path) || zstat(path,pbuf))
+#  else
+#    define SSTAT    zstat
+#  endif
+#endif
+
+
+/* Default fzofft() format selection. */
+
+#ifndef FZOFFT_FMT
+
+#  ifdef LARGE_FILE_SUPPORT
+#    define FZOFFT_FMT "ll"
+#    define FZOFFT_HEX_WID_VALUE "16"
+#  else /* def LARGE_FILE_SUPPORT */
+#    define FZOFFT_FMT "l"
+#    define FZOFFT_HEX_WID_VALUE "8"
+#  endif /* def LARGE_FILE_SUPPORT */
+
+#endif /* ndef FZOFFT_FMT */
+
+#define FZOFFT_HEX_WID ((char *) -1)
+#define FZOFFT_HEX_DOT_WID ((char *) -2)
+
+#define FZOFFT_NUM 4            /* Number of chambers. */
+#define FZOFFT_LEN 24           /* Number of characters/chamber. */
+
+
+#ifdef SHORT_SYMS                   /* Mark Williams C, ...? */
+#  define extract_or_test_files     xtr_or_tst_files
+#  define extract_or_test_member    xtr_or_tst_member
+#endif
+
+#ifdef REALLY_SHORT_SYMS            /* TOPS-20 linker:  first 6 chars */
+#  define process_cdir_file_hdr     XXpcdfh
+#  define process_local_file_hdr    XXplfh
+#  define extract_or_test_files     XXxotf  /* necessary? */
+#  define extract_or_test_member    XXxotm  /* necessary? */
+#  define check_for_newer           XXcfn
+#  define overwrite_all             XXoa
+#  define process_all_files         XXpaf
+#  define extra_field               XXef
+#  define explode_lit8              XXel8
+#  define explode_lit4              XXel4
+#  define explode_nolit8            XXnl8
+#  define explode_nolit4            XXnl4
+#  define cpdist8                   XXcpdist8
+#  define inflate_codes             XXic
+#  define inflate_stored            XXis
+#  define inflate_fixed             XXif
+#  define inflate_dynamic           XXid
+#  define inflate_block             XXib
+#  define maxcodemax                XXmax
+#endif
+
+#ifndef S_TIME_T_MAX            /* max value of signed (>= 32-bit) time_t */
+#  define S_TIME_T_MAX  ((time_t)(ulg)0x7fffffffL)
+#endif
+#ifndef U_TIME_T_MAX            /* max value of unsigned (>= 32-bit) time_t */
+#  define U_TIME_T_MAX  ((time_t)(ulg)0xffffffffL)
+#endif
+#ifdef DOSTIME_MINIMUM          /* min DOSTIME value (1980-01-01) */
+#  undef DOSTIME_MINIMUM
+#endif
+#define DOSTIME_MINIMUM ((ulg)0x00210000L)
+#ifdef DOSTIME_2038_01_18       /* approximate DOSTIME equivalent of */
+#  undef DOSTIME_2038_01_18     /*  the signed-32-bit time_t limit */
+#endif
+#define DOSTIME_2038_01_18 ((ulg)0x74320000L)
+
+#ifdef QDOS
+#  define ZSUFX         "_zip"
+#  define ALT_ZSUFX     ".zip"
+#else
+#  ifdef RISCOS
+#    define ZSUFX       "/zip"
+#  else
+#    define ZSUFX       ".zip"
+#  endif
+#  define ALT_ZSUFX     ".ZIP"   /* Unix-only so far (only case-sensitive fs) */
+#endif
+
+#define CENTRAL_HDR_SIG   "\001\002"   /* the infamous "PK" signature bytes, */
+#define LOCAL_HDR_SIG     "\003\004"   /*  w/o "PK" (so unzip executable not */
+#define END_CENTRAL_SIG   "\005\006"   /*  mistaken for zipfile itself) */
+#define EXTD_LOCAL_SIG    "\007\010"   /* [ASCII "\113" == EBCDIC "\080" ??] */
+
+/** internal-only return codes **/
+#define IZ_DIR            76   /* potential zipfile is a directory */
+/* special return codes for mapname() */
+#define MPN_OK            0      /* mapname successful */
+#define MPN_INF_TRUNC    (1<<8)  /* caution - filename truncated */
+#define MPN_INF_SKIP     (2<<8)  /* info  - skipped because nothing to do */
+#define MPN_ERR_SKIP     (3<<8)  /* error - entry skipped */
+#define MPN_ERR_TOOLONG  (4<<8)  /* error - path too long */
+#define MPN_NOMEM        (10<<8) /* error - out of memory, file skipped */
+#define MPN_CREATED_DIR  (16<<8) /* directory created: set time & permission */
+#define MPN_VOL_LABEL    (17<<8) /* volume label, but can't set on hard disk */
+#define MPN_INVALID      (99<<8) /* internal logic error, should never reach */
+/* mask for internal mapname&checkdir return codes */
+#define MPN_MASK          0x7F00
+/* error code for extracting/testing extra field blocks */
+#define IZ_EF_TRUNC       79   /* local extra field truncated (PKZIP'd) */
+
+/* choice of activities for do_string() */
+#define SKIP              0             /* skip header block */
+#define DISPLAY           1             /* display archive comment (ASCII) */
+#define DISPL_8           5             /* display file comment (ext. ASCII) */
+#define DS_FN             2             /* read filename (ext. ASCII, chead) */
+#define DS_FN_C           2             /* read filename from central header */
+#define DS_FN_L           6             /* read filename from local header */
+#define EXTRA_FIELD       3             /* copy extra field into buffer */
+#define DS_EF             3
+#ifdef AMIGA
+#  define FILENOTE        4             /* convert file comment to filenote */
+#endif
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+#  define CHECK_AUTORUN   7             /* copy command, display remainder */
+#  define CHECK_AUTORUN_Q 8             /* copy command, skip remainder */
+#endif
+
+#define DOES_NOT_EXIST    -1   /* return values for check_for_newer() */
+#define EXISTS_AND_OLDER  0
+#define EXISTS_AND_NEWER  1
+
+#define OVERWRT_QUERY     0    /* status values for G.overwrite_mode */
+#define OVERWRT_ALWAYS    1
+#define OVERWRT_NEVER     2
+
+#define IS_OVERWRT_ALL    (G.overwrite_mode == OVERWRT_ALWAYS)
+#define IS_OVERWRT_NONE   (G.overwrite_mode == OVERWRT_NEVER)
+
+#ifdef VMS
+  /* return codes for VMS-specific open_outfile() function */
+# define OPENOUT_OK       0   /* file openend normally */
+# define OPENOUT_FAILED   1   /* file open failed */
+# define OPENOUT_SKIPOK   2   /* file not opened, skip at error level OK */
+# define OPENOUT_SKIPWARN 3   /* file not opened, skip at error level WARN */
+#endif /* VMS */
+
+#define ROOT              0    /* checkdir() extract-to path:  called once */
+#define INIT              1    /* allocate buildpath:  called once per member */
+#define APPEND_DIR        2    /* append a dir comp.:  many times per member */
+#define APPEND_NAME       3    /* append actual filename:  once per member */
+#define GETPATH           4    /* retrieve the complete path and free it */
+#define END               5    /* free root path prior to exiting program */
+
+/* version_made_by codes (central dir):  make sure these */
+/*  are not defined on their respective systems!! */
+#define FS_FAT_           0    /* filesystem used by MS-DOS, OS/2, Win32 */
+#define AMIGA_            1
+#define VMS_              2
+#define UNIX_             3
+#define VM_CMS_           4
+#define ATARI_            5    /* what if it's a minix filesystem? [cjh] */
+#define FS_HPFS_          6    /* filesystem used by OS/2 (and NT 3.x) */
+#define MAC_              7    /* HFS filesystem used by MacOS */
+#define Z_SYSTEM_         8
+#define CPM_              9
+#define TOPS20_           10
+#define FS_NTFS_          11   /* filesystem used by Windows NT */
+#define QDOS_             12
+#define ACORN_            13   /* Archimedes Acorn RISC OS */
+#define FS_VFAT_          14   /* filesystem used by Windows 95, NT */
+#define MVS_              15
+#define BEOS_             16   /* hybrid POSIX/database filesystem */
+#define TANDEM_           17   /* Tandem NSK */
+#define THEOS_            18   /* THEOS */
+#define MAC_OSX_          19   /* Mac OS/X (Darwin) */
+#define ATHEOS_           30   /* AtheOS */
+#define NUM_HOSTS         31   /* index of last system + 1 */
+/* don't forget to update zipinfo.c appropiately if NUM_HOSTS changes! */
+
+#define STORED            0    /* compression methods */
+#define SHRUNK            1
+#define REDUCED1          2
+#define REDUCED2          3
+#define REDUCED3          4
+#define REDUCED4          5
+#define IMPLODED          6
+#define TOKENIZED         7
+#define DEFLATED          8
+#define ENHDEFLATED       9
+#define DCLIMPLODED      10
+#define BZIPPED          12
+#define LZMAED           14
+#define IBMTERSED        18
+#define IBMLZ77ED        19
+#define WAVPACKED        97
+#define PPMDED           98
+#define NUM_METHODS      17     /* number of known method IDs */
+/* don't forget to update list.c (list_files()), extract.c and zipinfo.c
+ * appropriately if NUM_METHODS changes */
+
+/* (the PK-class error codes are public and have been moved into unzip.h) */
+
+#define DF_MDY            0    /* date format 10/26/91 (USA only) */
+#define DF_DMY            1    /* date format 26/10/91 (most of the world) */
+#define DF_YMD            2    /* date format 91/10/26 (a few countries) */
+
+/*---------------------------------------------------------------------------
+    Extra-field block ID values and offset info.
+  ---------------------------------------------------------------------------*/
+/* extra-field ID values, all little-endian: */
+#define EF_PKSZ64    0x0001    /* PKWARE's 64-bit filesize extensions */
+#define EF_AV        0x0007    /* PKWARE's authenticity verification */
+#define EF_EFS       0x0008    /* PKWARE's extended language encoding */
+#define EF_OS2       0x0009    /* OS/2 extended attributes */
+#define EF_PKW32     0x000a    /* PKWARE's Win95/98/WinNT filetimes */
+#define EF_PKVMS     0x000c    /* PKWARE's VMS */
+#define EF_PKUNIX    0x000d    /* PKWARE's Unix */
+#define EF_PKFORK    0x000e    /* PKWARE's future stream/fork descriptors */
+#define EF_PKPATCH   0x000f    /* PKWARE's patch descriptor */
+#define EF_PKPKCS7   0x0014    /* PKWARE's PKCS#7 store for X.509 Certs */
+#define EF_PKFX509   0x0015    /* PKWARE's file X.509 Cert&Signature ID */
+#define EF_PKCX509   0x0016    /* PKWARE's central dir X.509 Cert ID */
+#define EF_PKENCRHD  0x0017    /* PKWARE's Strong Encryption header */
+#define EF_PKRMCTL   0x0018    /* PKWARE's Record Management Controls*/
+#define EF_PKLSTCS7  0x0019    /* PKWARE's PKCS#7 Encr. Recipient Cert List */
+#define EF_PKIBM     0x0065    /* PKWARE's IBM S/390 & AS/400 attributes */
+#define EF_PKIBM2    0x0066    /* PKWARE's IBM S/390 & AS/400 compr. attribs */
+#define EF_IZVMS     0x4d49    /* Info-ZIP's VMS ("IM") */
+#define EF_IZUNIX    0x5855    /* Info-ZIP's first Unix[1] ("UX") */
+#define EF_IZUNIX2   0x7855    /* Info-ZIP's second Unix[2] ("Ux") */
+#define EF_IZUNIX3   0x7875    /* Info-ZIP's newest Unix[3] ("ux") */
+#define EF_TIME      0x5455    /* universal timestamp ("UT") */
+#define EF_UNIPATH   0x7075    /* Info-ZIP Unicode Path ("up") */
+#define EF_UNICOMNT  0x6375    /* Info-ZIP Unicode Comment ("uc") */
+#define EF_MAC3      0x334d    /* Info-ZIP's new Macintosh (= "M3") */
+#define EF_JLMAC     0x07c8    /* Johnny Lee's old Macintosh (= 1992) */
+#define EF_ZIPIT     0x2605    /* Thomas Brown's Macintosh (ZipIt) */
+#define EF_ZIPIT2    0x2705    /* T. Brown's Mac (ZipIt) v 1.3.8 and newer ? */
+#define EF_SMARTZIP  0x4d63    /* Mac SmartZip by Marco Bambini */
+#define EF_VMCMS     0x4704    /* Info-ZIP's VM/CMS ("\004G") */
+#define EF_MVS       0x470f    /* Info-ZIP's MVS ("\017G") */
+#define EF_ACL       0x4c41    /* (OS/2) access control list ("AL") */
+#define EF_NTSD      0x4453    /* NT security descriptor ("SD") */
+#define EF_ATHEOS    0x7441    /* AtheOS ("At") */
+#define EF_BEOS      0x6542    /* BeOS ("Be") */
+#define EF_QDOS      0xfb4a    /* SMS/QDOS ("J\373") */
+#define EF_AOSVS     0x5356    /* AOS/VS ("VS") */
+#define EF_SPARK     0x4341    /* David Pilling's Acorn/SparkFS ("AC") */
+#define EF_TANDEM    0x4154    /* Tandem NSK ("TA") */
+#define EF_THEOS     0x6854    /* Jean-Michel Dubois' Theos "Th" */
+#define EF_THEOSO    0x4854    /* old Theos port */
+#define EF_MD5       0x4b46    /* Fred Kantor's MD5 ("FK") */
+#define EF_ASIUNIX   0x756e    /* ASi's Unix ("nu") */
+
+#define EB_HEADSIZE       4    /* length of extra field block header */
+#define EB_ID             0    /* offset of block ID in header */
+#define EB_LEN            2    /* offset of data length field in header */
+#define EB_UCSIZE_P       0    /* offset of ucsize field in compr. data */
+#define EB_CMPRHEADLEN    6    /* lenght of compression header */
+
+#define EB_UX_MINLEN      8    /* minimal "UX" field contains atime, mtime */
+#define EB_UX_FULLSIZE    12   /* full "UX" field (atime, mtime, uid, gid) */
+#define EB_UX_ATIME       0    /* offset of atime in "UX" extra field data */
+#define EB_UX_MTIME       4    /* offset of mtime in "UX" extra field data */
+#define EB_UX_UID         8    /* byte offset of UID in "UX" field data */
+#define EB_UX_GID         10   /* byte offset of GID in "UX" field data */
+
+#define EB_UX2_MINLEN     4    /* minimal "Ux" field contains UID/GID */
+#define EB_UX2_UID        0    /* byte offset of UID in "Ux" field data */
+#define EB_UX2_GID        2    /* byte offset of GID in "Ux" field data */
+#define EB_UX2_VALID      (1 << 8)      /* UID/GID present */
+
+#define EB_UX3_MINLEN     7    /* minimal "ux" field size (2-byte UID/GID) */
+
+#define EB_UT_MINLEN      1    /* minimal UT field contains Flags byte */
+#define EB_UT_FLAGS       0    /* byte offset of Flags field */
+#define EB_UT_TIME1       1    /* byte offset of 1st time value */
+#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_FLGS_OFFS      4    /* offset of flags area in generic compressed
+                                  extra field blocks (BEOS, MAC, and others) */
+#define EB_OS2_HLEN       4    /* size of OS2/ACL compressed data header */
+#define EB_BEOS_HLEN      5    /* length of BeOS&AtheOS e.f attribute header */
+#define EB_BE_FL_UNCMPR   0x01 /* "BeOS&AtheOS attribs uncompr." bit flag */
+#define EB_MAC3_HLEN      14   /* length of Mac3 attribute block header */
+#define EB_SMARTZIP_HLEN  64   /* fixed length of the SmartZip extra field */
+#define EB_M3_FL_DATFRK   0x01 /* "this entry is data fork" flag */
+#define EB_M3_FL_UNCMPR   0x04 /* "Mac3 attributes uncompressed" bit flag */
+#define EB_M3_FL_TIME64   0x08 /* "Mac3 time fields are 64 bit wide" flag */
+#define EB_M3_FL_NOUTC    0x10 /* "Mac3 timezone offset fields missing" flag */
+
+#define EB_NTSD_C_LEN     4    /* length of central NT security data */
+#define EB_NTSD_L_LEN     5    /* length of minimal local NT security data */
+#define EB_NTSD_VERSION   4    /* offset of NTSD version byte */
+#define EB_NTSD_MAX_VER   (0)  /* maximum version # we know how to handle */
+
+#define EB_PKVMS_MINLEN   4    /* minimum data length of PKVMS extra block */
+
+#define EB_ASI_CRC32      0    /* offset of ASI Unix field's crc32 checksum */
+#define EB_ASI_MODE       4    /* offset of ASI Unix permission mode field */
+
+#define EB_IZVMS_HLEN     12   /* length of IZVMS attribute block header */
+#define EB_IZVMS_FLGS     4    /* offset of compression type flag */
+#define EB_IZVMS_UCSIZ    6    /* offset of ucsize field in IZVMS header */
+#define EB_IZVMS_BCMASK   07   /* 3 bits for compression type */
+#define EB_IZVMS_BCSTOR   0    /*  Stored */
+#define EB_IZVMS_BC00     1    /*  0byte -> 0bit compression */
+#define EB_IZVMS_BCDEFL   2    /*  Deflated */
+
+
+/*---------------------------------------------------------------------------
+    True sizes of the various headers (excluding their 4-byte signatures),
+    as defined by PKWARE--so it is not likely that these will ever change.
+    But if they do, make sure both these defines AND the typedefs below get
+    updated accordingly.
+
+    12/27/2006
+    The Zip64 End Of Central Directory record is variable size and now
+    comes in two flavors, version 1 and the new version 2 that supports
+    central directory encryption.  We only use the old fields at the
+    top of the Zip64 EOCDR, and this block is a fixed size still, but
+    need to be aware of the stuff following.
+  ---------------------------------------------------------------------------*/
+#define LREC_SIZE    26   /* lengths of local file headers, central */
+#define CREC_SIZE    42   /*  directory headers, end-of-central-dir */
+#define ECREC_SIZE   18   /*  record, zip64 end-of-cent-dir locator */
+#define ECLOC64_SIZE 16   /*  and zip64 end-of-central-dir record,  */
+#define ECREC64_SIZE 52   /*  respectively                          */
+
+#define MAX_BITS    13                 /* used in unshrink() */
+#define HSIZE       (1 << MAX_BITS)    /* size of global work area */
+
+#define LF     10        /* '\n' on ASCII machines; must be 10 due to EBCDIC */
+#define CR     13        /* '\r' on ASCII machines; must be 13 due to EBCDIC */
+#define CTRLZ  26        /* DOS & OS/2 EOF marker (used in fileio.c, vms.c) */
+
+#ifdef EBCDIC
+#  define foreign(c)    ascii[(uch)(c)]
+#  define native(c)     ebcdic[(uch)(c)]
+#  define NATIVE        "EBCDIC"
+#  define NOANSIFILT
+#endif
+
+#ifdef VMS
+#  define ENV_UNZIP       "UNZIP_OPTS"     /* names of environment variables */
+#  define ENV_ZIPINFO     "ZIPINFO_OPTS"
+#endif /* VMS */
+#ifdef RISCOS
+#  define ENV_UNZIP       "Unzip$Options"
+#  define ENV_ZIPINFO     "Zipinfo$Options"
+#  define ENV_UNZIPEXTS   "Unzip$Exts"
+#endif /* RISCOS */
+#ifndef ENV_UNZIP
+#  define ENV_UNZIP       "UNZIP"          /* the standard names */
+#  define ENV_ZIPINFO     "ZIPINFO"
+#endif
+#define ENV_UNZIP2        "UNZIPOPT"     /* alternate names, for zip compat. */
+#define ENV_ZIPINFO2      "ZIPINFOOPT"
+
+#if (!defined(QQ) && !defined(NOQQ))
+#  define QQ
+#endif
+
+#ifdef QQ                         /* Newtware version:  no file */
+#  define QCOND     (!uO.qflag)   /*  comments with -vq or -vqq */
+#else                             /* Bill Davidsen version:  no way to */
+#  define QCOND     (longhdr)     /*  kill file comments when listing */
+#endif
+
+#ifdef OLD_QQ
+#  define QCOND2    (uO.qflag < 2)
+#else
+#  define QCOND2    (!uO.qflag)
+#endif
+
+#ifdef WILD_STOP_AT_DIR
+#  define __WDLPRO  , int sepc
+#  define __WDL     , sepc
+#  define __WDLDEF  int sepc;
+#  define WISEP     , (uO.W_flag ? '/' : '\0')
+#else
+#  define __WDLPRO
+#  define __WDL
+#  define __WDLDEF
+#  define WISEP
+#endif
+
+
+
+
+/**************/
+/*  Typedefs  */
+/**************/
+
+#ifdef ZIP64_SUPPORT
+# ifndef Z_UINT8_DEFINED
+#   if (defined(__GNUC__) || defined(__hpux) || defined(__SUNPRO_C))
+  typedef unsigned long long    z_uint8;
+#   else
+  typedef unsigned __int64      z_uint8;
+#   endif
+#   define Z_UINT8_DEFINED
+# endif
+#endif
+#ifndef Z_UINT4_DEFINED
+# if (defined(MODERN) && !defined(NO_LIMITS_H))
+#  if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
+     typedef unsigned int       z_uint4;
+#    define Z_UINT4_DEFINED
+#  else
+#  if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
+     typedef unsigned long      z_uint4;
+#    define Z_UINT4_DEFINED
+#  else
+#  if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
+     typedef unsigned short     z_uint4;
+#    define Z_UINT4_DEFINED
+#  endif
+#  endif
+#  endif
+# endif /* MODERN && !NO_LIMITS_H */
+#endif /* !Z_UINT4_DEFINED */
+#ifndef Z_UINT4_DEFINED
+  typedef ulg                   z_uint4;
+# define Z_UINT4_DEFINED
+#endif
+
+/* The following three user-defined unsigned integer types are used for
+   holding zipfile entities (required widths without / with Zip64 support):
+   a) sizes and offset of zipfile entries
+      (4 bytes / 8 bytes)
+   b) enumeration and counts of zipfile entries
+      (2 bytes / 8 bytes)
+      Remark: internally, we use 4 bytes for archive member counting in the
+              No-Zip64 case, because UnZip supports more than 64k entries for
+              classic Zip archives without Zip64 extensions.
+   c) enumeration and counts of zipfile volumes of multivolume archives
+      (2 bytes / 4 bytes)
+ */
+#ifdef ZIP64_SUPPORT
+  typedef  z_uint8              zusz_t;     /* zipentry sizes & offsets */
+  typedef  z_uint8              zucn_t;     /* archive entry counts */
+  typedef  z_uint4              zuvl_t;     /* multivolume numbers */
+# define MASK_ZUCN64            (~(zucn_t)0)
+/* In case we ever get to support an environment where z_uint8 may be WIDER
+   than 64 bit wide, we will have to apply a construct similar to
+     #define MASK_ZUCN64        (~(zucn_t)0 & (zucn_t)0xffffffffffffffffULL)
+   for the 64-bit mask.
+ */
+#else
+  typedef  ulg                  zusz_t;     /* zipentry sizes & offsets */
+  typedef  unsigned int         zucn_t;     /* archive entry counts */
+  typedef  unsigned short       zuvl_t;     /* multivolume numbers */
+# define MASK_ZUCN64            (~(zucn_t)0)
+#endif
+#define MASK_ZUCN16             ((zucn_t)0xFFFF)
+
+#ifdef NO_UID_GID
+#  ifdef UID_USHORT
+     typedef unsigned short  uid_t;    /* TI SysV.3 */
+     typedef unsigned short  gid_t;
+#  else
+     typedef unsigned int    uid_t;    /* SCO Xenix */
+     typedef unsigned int    gid_t;
+#  endif
+#endif
+
+#if (defined(GOT_UTIMBUF) || defined(sgi) || defined(ATARI))
+   typedef struct utimbuf ztimbuf;
+#else
+   typedef struct ztimbuf {
+       time_t actime;        /* new access time */
+       time_t modtime;       /* new modification time */
+   } ztimbuf;
+#endif
+
+typedef struct iztimes {
+   time_t atime;             /* new access time */
+   time_t mtime;             /* new modification time */
+   time_t ctime;             /* used for creation time; NOT same as st_ctime */
+} iztimes;
+
+#ifdef SET_DIR_ATTRIB
+   typedef struct direntry {    /* head of system-specific struct holding */
+       struct direntry *next;   /*  defered directory attributes info */
+       char *fn;                /* filename of directory */
+       char buf[1];             /* start of system-specific internal data */
+   } direntry;
+#endif /* SET_DIR_ATTRIB */
+
+#ifdef SYMLINKS
+   typedef struct slinkentry {  /* info for deferred symlink creation */
+       struct slinkentry *next; /* pointer to next entry in chain */
+       extent targetlen;        /* length of target filespec */
+       extent attriblen;        /* length of system-specific attrib data */
+       char *target;            /* pointer to target filespec */
+       char *fname;             /* pointer to name of link */
+       char buf[1];             /* data/name/link buffer */
+   } slinkentry;
+#endif /* SYMLINKS */
+
+typedef struct min_info {
+    zoff_t offset;
+    zusz_t compr_size;       /* compressed size (needed if extended header) */
+    zusz_t uncompr_size;     /* uncompressed size (needed if extended header) */
+    ulg crc;                 /* crc (needed if extended header) */
+    zuvl_t diskstart;        /* no of volume where this entry starts */
+    uch hostver;
+    uch hostnum;
+    unsigned file_attr;      /* local flavor, as used by creat(), chmod()... */
+    unsigned encrypted : 1;  /* file encrypted: decrypt before uncompressing */
+    unsigned ExtLocHdr : 1;  /* use time instead of CRC for decrypt check */
+    unsigned textfile : 1;   /* file is text (according to zip) */
+    unsigned textmode : 1;   /* file is to be extracted as text */
+    unsigned lcflag : 1;     /* convert filename to lowercase */
+    unsigned vollabel : 1;   /* "file" is an MS-DOS volume (disk) label */
+#ifdef SYMLINKS
+    unsigned symlink : 1;    /* file is a symbolic link */
+#endif
+    unsigned HasUxAtt : 1;   /* crec ext_file_attr has Unix style mode bits */
+#ifdef UNICODE_SUPPORT
+    unsigned GPFIsUTF8: 1;   /* crec gen_purpose_flag UTF-8 bit 11 is set */
+#endif
+#ifndef SFX
+    char Far *cfilname;      /* central header version of filename */
+#endif
+} min_info;
+
+typedef struct VMStimbuf {
+    char *revdate;    /* (both roughly correspond to Unix modtime/st_mtime) */
+    char *credate;
+} VMStimbuf;
+
+/*---------------------------------------------------------------------------
+    Zipfile work area declarations.
+  ---------------------------------------------------------------------------*/
+
+#ifdef MALLOC_WORK
+   union work {
+     struct {                 /* unshrink(): */
+       shrint *Parent;          /* pointer to (8192 * sizeof(shrint)) */
+       uch *value;              /* pointer to 8KB char buffer */
+       uch *Stack;              /* pointer to another 8KB char buffer */
+     } shrink;
+     uch *Slide;              /* explode(), inflate(), unreduce() */
+   };
+#else /* !MALLOC_WORK */
+   union work {
+     struct {                 /* unshrink(): */
+       shrint Parent[HSIZE];    /* (8192 * sizeof(shrint)) == 16KB minimum */
+       uch value[HSIZE];        /* 8KB */
+       uch Stack[HSIZE];        /* 8KB */
+     } shrink;                  /* total = 32KB minimum; 80KB on Cray/Alpha */
+     uch Slide[WSIZE];        /* explode(), inflate(), unreduce() */
+   };
+#endif /* ?MALLOC_WORK */
+
+#define slide  G.area.Slide
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+#  define redirSlide G.redirect_sldptr
+#else
+#  define redirSlide G.area.Slide
+#endif
+
+/*---------------------------------------------------------------------------
+    Zipfile layout declarations.  If these headers ever change, make sure the
+    xxREC_SIZE defines (above) change with them!
+  ---------------------------------------------------------------------------*/
+
+   typedef uch   local_byte_hdr[ LREC_SIZE ];
+#      define L_VERSION_NEEDED_TO_EXTRACT_0     0
+#      define L_VERSION_NEEDED_TO_EXTRACT_1     1
+#      define L_GENERAL_PURPOSE_BIT_FLAG        2
+#      define L_COMPRESSION_METHOD              4
+#      define L_LAST_MOD_DOS_DATETIME           6
+#      define L_CRC32                           10
+#      define L_COMPRESSED_SIZE                 14
+#      define L_UNCOMPRESSED_SIZE               18
+#      define L_FILENAME_LENGTH                 22
+#      define L_EXTRA_FIELD_LENGTH              24
+
+   typedef uch   cdir_byte_hdr[ CREC_SIZE ];
+#      define C_VERSION_MADE_BY_0               0
+#      define C_VERSION_MADE_BY_1               1
+#      define C_VERSION_NEEDED_TO_EXTRACT_0     2
+#      define C_VERSION_NEEDED_TO_EXTRACT_1     3
+#      define C_GENERAL_PURPOSE_BIT_FLAG        4
+#      define C_COMPRESSION_METHOD              6
+#      define C_LAST_MOD_DOS_DATETIME           8
+#      define C_CRC32                           12
+#      define C_COMPRESSED_SIZE                 16
+#      define C_UNCOMPRESSED_SIZE               20
+#      define C_FILENAME_LENGTH                 24
+#      define C_EXTRA_FIELD_LENGTH              26
+#      define C_FILE_COMMENT_LENGTH             28
+#      define C_DISK_NUMBER_START               30
+#      define C_INTERNAL_FILE_ATTRIBUTES        32
+#      define C_EXTERNAL_FILE_ATTRIBUTES        34
+#      define C_RELATIVE_OFFSET_LOCAL_HEADER    38
+
+   typedef uch   ec_byte_rec[ ECREC_SIZE+4 ];
+/*     define SIGNATURE                         0   space-holder only */
+#      define NUMBER_THIS_DISK                  4
+#      define NUM_DISK_WITH_START_CEN_DIR       6
+#      define NUM_ENTRIES_CEN_DIR_THS_DISK      8
+#      define TOTAL_ENTRIES_CENTRAL_DIR         10
+#      define SIZE_CENTRAL_DIRECTORY            12
+#      define OFFSET_START_CENTRAL_DIRECTORY    16
+#      define ZIPFILE_COMMENT_LENGTH            20
+
+   typedef uch   ec_byte_loc64[ ECLOC64_SIZE+4 ];
+#      define NUM_DISK_START_EOCDR64            4
+#      define OFFSET_START_EOCDR64              8
+#      define NUM_THIS_DISK_LOC64               16
+
+   typedef uch   ec_byte_rec64[ ECREC64_SIZE+4 ];
+#      define ECREC64_LENGTH                    4
+#      define EC_VERSION_MADE_BY_0              12
+#      define EC_VERSION_NEEDED_0               14
+#      define NUMBER_THIS_DSK_REC64             16
+#      define NUM_DISK_START_CEN_DIR64          20
+#      define NUM_ENTRIES_CEN_DIR_THS_DISK64    24
+#      define TOTAL_ENTRIES_CENTRAL_DIR64       32
+#      define SIZE_CENTRAL_DIRECTORY64          40
+#      define OFFSET_START_CENTRAL_DIRECT64     48
+
+
+/* The following structs are used to hold all header data of a zip entry.
+   Traditionally, the structs' layouts followed the data layout of the
+   corresponding zipfile header structures.  However, the zipfile header
+   layouts were designed in the old ages of 16-bit CPUs, they are subject
+   to structure padding and/or alignment issues on newer systems with a
+   "natural word width" of more than 2 bytes.
+   Please note that the structure members are now reordered by size
+   (top-down), to prevent internal padding and optimize memory usage!
+ */
+   typedef struct local_file_header {                 /* LOCAL */
+       zusz_t csize;
+       zusz_t ucsize;
+       ulg last_mod_dos_datetime;
+       ulg crc32;
+       uch version_needed_to_extract[2];
+       ush general_purpose_bit_flag;
+       ush compression_method;
+       ush filename_length;
+       ush extra_field_length;
+   } local_file_hdr;
+
+   typedef struct central_directory_file_header {     /* CENTRAL */
+       zusz_t csize;
+       zusz_t ucsize;
+       zusz_t relative_offset_local_header;
+       ulg last_mod_dos_datetime;
+       ulg crc32;
+       ulg external_file_attributes;
+       zuvl_t disk_number_start;
+       ush internal_file_attributes;
+       uch version_made_by[2];
+       uch version_needed_to_extract[2];
+       ush general_purpose_bit_flag;
+       ush compression_method;
+       ush filename_length;
+       ush extra_field_length;
+       ush file_comment_length;
+   } cdir_file_hdr;
+
+   typedef struct end_central_dir_record {            /* END CENTRAL */
+       zusz_t size_central_directory;
+       zusz_t offset_start_central_directory;
+       zucn_t num_entries_centrl_dir_ths_disk;
+       zucn_t total_entries_central_dir;
+       zuvl_t number_this_disk;
+       zuvl_t num_disk_start_cdir;
+       int have_ecr64;                  /* valid Zip64 ecdir-record exists */
+       int is_zip64_archive;            /* Zip64 ecdir-record is mandatory */
+       ush zipfile_comment_length;
+   } ecdir_rec;
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits are 0..16.  e == 31 is EOB (end of block), e == 32
+   means that v is a literal, 32 < e < 64 means that v is a pointer to
+   the next table, which codes (e & 31)  bits, and lastly e == 99 indicates
+   an unused code.  If a code with e == 99 is looked up, this implies an
+   error in the data. */
+
+struct huft {
+    uch e;                /* number of extra bits or operation */
+    uch b;                /* number of bits in this code or subcode */
+    union {
+        ush n;            /* literal, length base, or distance base */
+        struct huft *t;   /* pointer to next level of table */
+    } v;
+};
+
+
+typedef struct _APIDocStruct {
+    char *compare;
+    char *function;
+    char *syntax;
+    char *purpose;
+} APIDocStruct;
+
+
+
+
+/*************/
+/*  Globals  */
+/*************/
+
+#if (defined(OS2) && !defined(FUNZIP))
+#  include "os2/os2data.h"
+#endif
+
+#include "globals.h"
+
+
+
+/*************************/
+/*  Function Prototypes  */
+/*************************/
+
+/*---------------------------------------------------------------------------
+    Functions in unzip.c (initialization routines):
+  ---------------------------------------------------------------------------*/
+
+#ifndef WINDLL
+   int    MAIN                   OF((int argc, char **argv));
+   int    unzip                  OF((__GPRO__ int argc, char **argv));
+   int    uz_opts                OF((__GPRO__ int *pargc, char ***pargv));
+   int    usage                  OF((__GPRO__ int error));
+#endif /* !WINDLL */
+
+/*---------------------------------------------------------------------------
+    Functions in process.c (main driver routines):
+  ---------------------------------------------------------------------------*/
+
+int      process_zipfiles        OF((__GPRO));
+void     free_G_buffers          OF((__GPRO));
+/* static int    do_seekable     OF((__GPRO__ int lastchance)); */
+/* static int    find_ecrec      OF((__GPRO__ long searchlen)); */
+/* static int    process_central_comment OF((__GPRO)); */
+int      process_cdir_file_hdr   OF((__GPRO));
+int      process_local_file_hdr  OF((__GPRO));
+int      getZip64Data            OF((__GPRO__ ZCONST uch *ef_buf,
+                                     unsigned ef_len));
+#ifdef UNICODE_SUPPORT
+  int    getUnicodeData          OF((__GPRO__ ZCONST uch *ef_buf,
+                                     unsigned ef_len));
+#endif
+unsigned ef_scan_for_izux        OF((ZCONST uch *ef_buf, unsigned ef_len,
+                                     int ef_is_c, ulg dos_mdatetime,
+                                     iztimes *z_utim, ulg *z_uidgid));
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+   zvoid *getRISCOSexfield       OF((ZCONST uch *ef_buf, unsigned ef_len));
+#endif
+
+#ifndef SFX
+
+/*---------------------------------------------------------------------------
+    Functions in zipinfo.c (`zipinfo-style' listing routines):
+  ---------------------------------------------------------------------------*/
+
+#ifndef NO_ZIPINFO
+#ifndef WINDLL
+   int   zi_opts                 OF((__GPRO__ int *pargc, char ***pargv));
+#endif
+void     zi_end_central          OF((__GPRO));
+int      zipinfo                 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));*/
+#endif /* !NO_ZIPINFO */
+
+/*---------------------------------------------------------------------------
+    Functions in list.c (generic zipfile-listing routines):
+  ---------------------------------------------------------------------------*/
+
+int      list_files              OF((__GPRO));
+#ifdef TIMESTAMP
+   int   get_time_stamp          OF((__GPRO__  time_t *last_modtime,
+                                     ulg *nmember));
+#endif
+int      ratio                   OF((zusz_t uc, zusz_t c));
+void     fnprint                 OF((__GPRO));
+
+#endif /* !SFX */
+
+/*---------------------------------------------------------------------------
+    Functions in fileio.c:
+  ---------------------------------------------------------------------------*/
+
+int      open_input_file      OF((__GPRO));
+int      open_outfile         OF((__GPRO));                    /* also vms.c */
+void     undefer_input        OF((__GPRO));
+void     defer_leftover_input OF((__GPRO));
+unsigned readbuf              OF((__GPRO__ char *buf, register unsigned len));
+int      readbyte             OF((__GPRO));
+int      fillinbuf            OF((__GPRO));
+int      seek_zipf            OF((__GPRO__ zoff_t abs_offset));
+#ifdef FUNZIP
+   int   flush                OF((__GPRO__ ulg size));  /* actually funzip.c */
+#else
+   int   flush                OF((__GPRO__ uch *buf, ulg size, int unshrink));
+#endif
+/* static int  disk_error     OF((__GPRO)); */
+void     handler              OF((int signal));
+time_t   dos_to_unix_time     OF((ulg dos_datetime));
+int      check_for_newer      OF((__GPRO__ char *filename)); /* os2,vmcms,vms */
+int      do_string            OF((__GPRO__ unsigned int length, int option));
+ush      makeword             OF((ZCONST uch *b));
+ulg      makelong             OF((ZCONST uch *sig));
+zusz_t   makeint64            OF((ZCONST uch *sig));
+char    *fzofft               OF((__GPRO__ zoff_t val,
+                                  ZCONST char *pre, ZCONST char *post));
+#if (!defined(STR_TO_ISO) || defined(NEED_STR2ISO))
+   char *str2iso              OF((char *dst, ZCONST char *src));
+#endif
+#if (!defined(STR_TO_OEM) || defined(NEED_STR2OEM))
+   char *str2oem              OF((char *dst, ZCONST char *src));
+#endif
+#ifdef NO_STRNICMP
+   int   zstrnicmp            OF((register ZCONST char *s1,
+                                  register ZCONST char *s2,
+                                  register unsigned n));
+#endif
+#ifdef REGULUS
+   int   zstat                OF((ZCONST char *p, struct stat *s));
+#endif
+#ifdef ZMEM   /* MUST be ifdef'd because of conflicts with the standard def. */
+   zvoid *memset OF((register zvoid *, register int, register unsigned int));
+   int    memcmp OF((register ZCONST zvoid*, register ZCONST zvoid *,
+                     register unsigned int));
+   zvoid *memcpy OF((register zvoid *, register ZCONST zvoid *,
+                     register unsigned int));
+#endif
+#ifdef NEED_UZMBCLEN
+   extent uzmbclen          OF((ZCONST unsigned char *ptr));
+#endif
+#ifdef NEED_UZMBSCHR
+   unsigned char *uzmbschr  OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef NEED_UZMBSRCHR
+   unsigned char *uzmbsrchr OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef SMALL_MEM
+   char *fLoadFarString       OF((__GPRO__ const char Far *sz));
+   char *fLoadFarStringSmall  OF((__GPRO__ const char Far *sz));
+   char *fLoadFarStringSmall2 OF((__GPRO__ const char Far *sz));
+   #ifndef zfstrcpy
+     char Far * Far zfstrcpy  OF((char Far *s1, const char Far *s2));
+   #endif
+   #if (!defined(SFX) && !defined(zfstrcmp))
+     int Far zfstrcmp         OF((const char Far *s1, const char Far *s2));
+   #endif
+#endif
+
+
+/*---------------------------------------------------------------------------
+    Functions in extract.c:
+  ---------------------------------------------------------------------------*/
+
+int    extract_or_test_files     OF((__GPRO));
+/* static int   store_info          OF((void)); */
+/* static int   extract_or_test_member   OF((__GPRO)); */
+/* static int   TestExtraField   OF((__GPRO__ uch *ef, unsigned ef_len)); */
+/* static int   test_OS2         OF((__GPRO__ uch *eb, unsigned eb_size)); */
+/* static int   test_NT          OF((__GPRO__ uch *eb, unsigned eb_size)); */
+#ifndef SFX
+  unsigned find_compr_idx        OF((unsigned compr_methodnum));
+#endif
+int    memextract                OF((__GPRO__ uch *tgt, ulg tgtsize,
+                                     ZCONST uch *src, ulg srcsize));
+int    memflush                  OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+   uch   *extract_izvms_block    OF((__GPRO__ ZCONST uch *ebdata,
+                                     unsigned size, unsigned *retlen,
+                                     ZCONST uch *init, unsigned needlen));
+#endif
+char  *fnfilter                  OF((ZCONST char *raw, uch *space,
+                                     extent size));
+
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+wchar_t *fnfilterw               OF((ZCONST wchar_t *src, wchar_t *dst,
+                                     extent siz));
+#endif
+
+
+/*---------------------------------------------------------------------------
+    Decompression functions:
+  ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) && !defined(FUNZIP))
+int    explode                   OF((__GPRO));                  /* explode.c */
+#endif
+int    huft_free                 OF((struct huft *t));          /* inflate.c */
+int    huft_build                OF((__GPRO__ ZCONST unsigned *b, unsigned n,
+                                     unsigned s, ZCONST ush *d, ZCONST uch *e,
+                                     struct huft **t, unsigned *m));
+#ifdef USE_ZLIB
+   int    UZinflate              OF((__GPRO__ int is_defl64));  /* inflate.c */
+#  define inflate_free(x)        inflateEnd(&((Uz_Globs *)(&G))->dstrm)
+#else
+   int    inflate                OF((__GPRO__ int is_defl64));  /* inflate.c */
+   int    inflate_free           OF((__GPRO));                  /* inflate.c */
+#endif /* ?USE_ZLIB */
+#if (!defined(SFX) && !defined(FUNZIP))
+#ifndef COPYRIGHT_CLEAN
+   int    unreduce               OF((__GPRO));                 /* unreduce.c */
+/* static void  LoadFollowers    OF((__GPRO__ f_array *follower, uch *Slen));
+                                                                * unreduce.c */
+#endif /* !COPYRIGHT_CLEAN */
+#ifndef LZW_CLEAN
+   int    unshrink               OF((__GPRO));                 /* unshrink.c */
+/* static void  partial_clear    OF((__GPRO));                  * unshrink.c */
+#endif /* !LZW_CLEAN */
+#endif /* !SFX && !FUNZIP */
+#ifdef USE_BZIP2
+   int    UZbunzip2              OF((__GPRO));                  /* extract.c */
+   void   bz_internal_error      OF((int bzerrcode));           /* ubz2err.c */
+#endif
+
+/*---------------------------------------------------------------------------
+    Internal API functions (only included in DLL versions):
+  ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+   void     setFileNotFound       OF((__GPRO));                     /* api.c */
+   int      unzipToMemory         OF((__GPRO__ char *zip, char *file,
+                                      UzpBuffer *retstr));          /* api.c */
+   int      redirect_outfile      OF((__GPRO));                     /* api.c */
+   int      writeToMemory         OF((__GPRO__ ZCONST uch *rawbuf,
+                                      extent size));                /* api.c */
+   int      close_redirect        OF((__GPRO));                     /* api.c */
+   /* this obsolescent entry point kept for compatibility: */
+   int      UzpUnzip              OF((int argc, char **argv));/* use UzpMain */
+#ifdef OS2DLL
+   int      varmessage            OF((__GPRO__ ZCONST uch *buf, ulg size));
+   int      varputchar            OF((__GPRO__ int c));         /* rexxapi.c */
+   int      finish_REXX_redirect  OF((__GPRO));                 /* rexxapi.c */
+#endif
+#ifdef API_DOC
+   void     APIhelp               OF((__GPRO__ int argc, char **argv));
+#endif                                                          /* apihelp.c */
+#endif /* DLL */
+
+/*---------------------------------------------------------------------------
+    MSDOS-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef MSDOS
+#if (!defined(FUNZIP) && !defined(SFX) && !defined(WINDLL))
+   void     check_for_windows     OF((ZCONST char *app));         /* msdos.c */
+#endif
+#if (defined(__GO32__) || defined(__EMX__))
+   unsigned _dos_getcountryinfo(void *);                          /* msdos.c */
+#if (!defined(__DJGPP__) || (__DJGPP__ < 2))
+   unsigned _dos_setftime(int, unsigned, unsigned);               /* msdos.c */
+   unsigned _dos_setfileattr(const char *, unsigned);             /* msdos.c */
+   unsigned _dos_creat(const char *, unsigned, int *);            /* msdos.c */
+   void _dos_getdrive(unsigned *);                                /* msdos.c */
+   unsigned _dos_close(int);                                      /* msdos.c */
+#endif /* !__DJGPP__ || (__DJGPP__ < 2) */
+#endif /* __GO32__ || __EMX__ */
+#endif
+
+/*---------------------------------------------------------------------------
+    OS/2-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef OS2   /* GetFileTime conflicts with something in Win32 header files */
+#if (defined(REENTRANT) && defined(USETHREADID))
+   ulg   GetThreadId          OF((void));
+#endif
+   int   GetCountryInfo       OF((void));                           /* os2.c */
+   long  GetFileTime          OF((ZCONST char *name));              /* os2.c */
+/* static void  SetPathAttrTimes OF((__GPRO__ int flags, int dir));    os2.c */
+/* static int   SetEAs        OF((__GPRO__ const char *path,
+                                  void *eablock));                     os2.c */
+/* static int   SetACL        OF((__GPRO__ const char *path,
+                                  void *eablock));                     os2.c */
+/* static int   IsFileNameValid OF((const char *name));                os2.c */
+/* static void  map2fat       OF((char *pathcomp, char **pEndFAT));    os2.c */
+/* static int   SetLongNameEA OF((char *name, char *longname));        os2.c */
+/* static void  InitNLS       OF((void));                              os2.c */
+   int   IsUpperNLS           OF((int nChr));                       /* os2.c */
+   int   ToLowerNLS           OF((int nChr));                       /* os2.c */
+   void  DebugMalloc          OF((void));                           /* os2.c */
+#endif
+
+/*---------------------------------------------------------------------------
+    QDOS-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+   int    QMatch              (uch, uch);
+   void   QFilename           (__GPRO__ char *);
+   char  *Qstrfix             (char *);
+   int    QReturn             (int zip_error);
+#endif
+
+/*---------------------------------------------------------------------------
+    TOPS20-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+   int    upper               OF((char *s));                     /* tops20.c */
+   int    enquote             OF((char *s));                     /* tops20.c */
+   int    dequote             OF((char *s));                     /* tops20.c */
+   int    fnlegal             OF(()); /* error if prototyped? */ /* tops20.c */
+#endif
+
+/*---------------------------------------------------------------------------
+    VM/CMS- and MVS-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+   extent getVMMVSexfield     OF((char *type, uch *ef_block, unsigned datalen));
+   FILE  *vmmvs_open_infile   OF((__GPRO));                       /* vmmvs.c */
+   void   close_infile        OF((__GPRO));                       /* vmmvs.c */
+#endif
+
+/*---------------------------------------------------------------------------
+    VMS-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+   int    check_format        OF((__GPRO));                         /* vms.c */
+/* int    open_outfile        OF((__GPRO));           * (see fileio.c) vms.c */
+/* int    flush               OF((__GPRO__ uch *rawbuf, unsigned size,
+                                  int final_flag));   * (see fileio.c) vms.c */
+   char  *vms_msg_text        OF((void));                           /* vms.c */
+#ifdef RETURN_CODES
+   void   return_VMS          OF((__GPRO__ int zip_error));         /* vms.c */
+#else
+   void   return_VMS          OF((int zip_error));                  /* vms.c */
+#endif
+#ifdef VMSCLI
+   ulg    vms_unzip_cmdline   OF((int *, char ***));            /* cmdline.c */
+   int    VMSCLI_usage        OF((__GPRO__ int error));         /* cmdline.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+    WIN32-only functions:
+  ---------------------------------------------------------------------------*/
+
+#ifdef WIN32
+   int   IsWinNT        OF((void));                               /* win32.c */
+#ifdef NTSD_EAS
+   void  process_defer_NT     OF((__GPRO));                       /* win32.c */
+   int   test_NTSD      OF((__GPRO__ uch *eb, unsigned eb_size,
+                            uch *eb_ucptr, ulg eb_ucsize));       /* win32.c */
+#  define TEST_NTSD     test_NTSD
+#endif
+#ifdef W32_STAT_BANDAID
+   int   zstat_win32    OF((__W32STAT_GLOBALS__
+                            const char *path, z_stat *buf));      /* win32.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+    Miscellaneous/shared functions:
+  ---------------------------------------------------------------------------*/
+
+Uz_Globs *globalsCtor    OF((void));                            /* globals.c */
+
+int      envargs         OF((int *Pargc, char ***Pargv,
+                             ZCONST char *envstr, ZCONST char *envstr2));
+                                                                /* envargs.c */
+void     mksargs         OF((int *argcp, char ***argvp));       /* envargs.c */
+
+int      match           OF((ZCONST char *s, ZCONST char *p,
+                             int ic __WDLPRO));                   /* match.c */
+int      iswild          OF((ZCONST char *p));                    /* match.c */
+
+/* declarations of public CRC-32 functions have been moved into crc32.h
+   (free_crc_table(), get_crc_table(), crc32())                      crc32.c */
+
+int      dateformat      OF((void));                                /* local */
+char     dateseparator   OF((void));                                /* local */
+#ifndef WINDLL
+   void  version         OF((__GPRO));                              /* local */
+#endif
+int      mapattr         OF((__GPRO));                              /* local */
+int      mapname         OF((__GPRO__ int renamed));                /* local */
+int      checkdir        OF((__GPRO__ char *pathcomp, int flag));   /* local */
+char    *do_wild         OF((__GPRO__ ZCONST char *wildzipfn));     /* local */
+char    *GetLoadPath     OF((__GPRO));                              /* local */
+#if (defined(MORE) && (defined(ATH_BEO_UNX) || defined(QDOS) || defined(VMS)))
+   int screensize        OF((int *tt_rows, int *tt_cols));          /* local */
+# if defined(VMS)
+   int screenlinewrap    OF((void));                                /* local */
+# endif
+#endif /* MORE && (ATH_BEO_UNX || QDOS || VMS) */
+#ifdef OS2_W32
+   int   SetFileSize     OF((FILE *file, zusz_t filesize));         /* local */
+#endif
+#ifndef MTS /* macro in MTS */
+   int  close_outfile   OF((__GPRO));                              /* local */
+#endif
+#ifdef SET_SYMLINK_ATTRIBS
+   int  set_symlnk_attribs  OF((__GPRO__ slinkentry *slnk_entry));  /* local */
+#endif
+#ifdef SET_DIR_ATTRIB
+   int   defer_dir_attribs  OF((__GPRO__ direntry **pd));           /* local */
+   int   set_direc_attribs  OF((__GPRO__ direntry *d));             /* local */
+#endif
+#ifdef TIMESTAMP
+# ifdef WIN32
+   int   stamp_file      OF((__GPRO__
+                             ZCONST char *fname, time_t modtime));  /* local */
+# else
+   int   stamp_file      OF((ZCONST char *fname, time_t modtime));  /* local */
+# endif
+#endif
+#ifdef NEED_ISO_OEM_INIT
+   void  prepare_ISO_OEM_translat   OF((__GPRO));                   /* local */
+#endif
+#if (defined(MALLOC_WORK) && defined(MY_ZCALLOC))
+   zvoid far *zcalloc    OF((unsigned int, unsigned int));
+   zvoid zcfree          OF((zvoid far *));
+#endif /* MALLOC_WORK && MY_ZCALLOC */
+#ifdef SYSTEM_SPECIFIC_CTOR
+   void  SYSTEM_SPECIFIC_CTOR   OF((__GPRO));                       /* local */
+#endif
+#ifdef SYSTEM_SPECIFIC_DTOR
+   void  SYSTEM_SPECIFIC_DTOR   OF((__GPRO));                       /* local */
+#endif
+
+
+
+
+
+/************/
+/*  Macros  */
+/************/
+
+#ifndef MAX
+#  define MAX(a,b)   ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#  define MIN(a,b)   ((a) < (b) ? (a) : (b))
+#endif
+
+#ifdef DEBUG
+#  if (defined(THEOS) && defined(NO_BOGUS_SPC))
+#    define NO_DEBUG_IN_MACROS
+#    define Trace(x)   _fprintf x
+#  else
+#    define Trace(x)   fprintf x
+#  endif
+#else
+#  define Trace(x)
+#endif
+
+#ifdef DEBUG_TIME
+#  define TTrace(x)  fprintf x
+#else
+#  define TTrace(x)
+#endif
+
+#ifdef NO_DEBUG_IN_MACROS
+#  define MTrace(x)
+#else
+#  define MTrace(x)  Trace(x)
+#endif
+
+#if (defined(UNIX) || defined(T20_VMS)) /* generally old systems */
+#  define ToLower(x)   ((char)(isupper((int)x)? tolower((int)x) : x))
+#else
+#  define ToLower      tolower          /* assumed "smart"; used in match() */
+#endif
+
+#ifdef USE_STRM_INPUT
+   /* ``Replace'' the unbuffered UNIX style I/O function with similar
+    * standard C functions from <stdio.h>.
+    */
+#  define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
+#  ifdef zlseek
+#    undef zlseek
+#  endif
+#  define zlseek(fd,o,w) zfseeko((FILE *)(fd),(o),(w))
+#  define close(fd) fclose((FILE *)(fd))
+#endif /* USE_STRM_INPUT */
+
+/* The return value of the Info() "macro function" is never checked in
+ * UnZip. Otherwise, to get the same behaviour as for (*G.message)(), the
+ * Info() definition for "FUNZIP" would have to be corrected:
+ * #define Info(buf,flag,sprf_arg) \
+ *      (fputs((char *)(sprintf sprf_arg, (buf)), \
+ *             (flag)&1? stderr : stdout) < 0)
+ */
+#ifndef Info   /* may already have been defined for redirection */
+#  ifdef FUNZIP
+#    define Info(buf,flag,sprf_arg) \
+     fputs((char *)(sprintf sprf_arg, (buf)), (flag)&1? stderr : stdout)
+#  else
+#    ifdef INT_SPRINTF  /* optimized version for "int sprintf()" flavour */
+#      define Info(buf,flag,sprf_arg) \
+       (*G.message)((zvoid *)&G, (uch *)(buf), (ulg)sprintf sprf_arg, (flag))
+#    else          /* generic version, does not use sprintf() return value */
+#      define Info(buf,flag,sprf_arg) \
+       (*G.message)((zvoid *)&G, (uch *)(buf), \
+                     (ulg)(sprintf sprf_arg, strlen((char *)(buf))), (flag))
+#    endif
+#  endif
+#endif /* !Info */
+
+/*  This wrapper macro around fzofft() is just defined to "hide" the
+ *  argument needed to reference the global storage buffers.
+ */
+#define FmZofft(val, pre, post) fzofft(__G__ val, pre, post)
+
+/*  The following macro wrappers around the fnfilter function are used many
+ *  times to prepare archive entry names or name components for displaying
+ *  listings and (warning/error) messages. They use sections in the upper half
+ *  of 'slide' as buffer, since their output is normally fed through the
+ *  Info() macro with 'slide' (the start of this area) as message buffer.
+ */
+#define FnFilter1(fname) \
+        fnfilter((fname), slide + (extent)(WSIZE>>1), (extent)(WSIZE>>2))
+#define FnFilter2(fname) \
+        fnfilter((fname), slide + (extent)((WSIZE>>1) + (WSIZE>>2)),\
+                 (extent)(WSIZE>>2))
+
+#ifndef FUNZIP   /* used only in inflate.c */
+#  define MESSAGE(str,len,flag)  (*G.message)((zvoid *)&G,(str),(len),(flag))
+#endif
+
+#if 0            /* Optimization: use the (const) result of crc32(0L,NULL,0) */
+#  define CRCVAL_INITIAL  crc32(0L, NULL, 0)
+#else
+#  define CRCVAL_INITIAL  0L
+#endif
+
+#ifdef SYMLINKS
+   /* This macro defines the Zip "made by" hosts that are considered
+      to support storing symbolic link entries. */
+#  define SYMLINK_HOST(hn) ((hn) == UNIX_ || (hn) == ATARI_ || \
+      (hn) == ATHEOS_ || (hn) == BEOS_ || (hn) == VMS_)
+#endif
+
+#ifndef TEST_NTSD               /* "NTSD valid?" checking function */
+#  define TEST_NTSD     NULL    /*   ... is not available */
+#endif
+
+#define SKIP_(length) if(length&&((error=do_string(__G__ length,SKIP))!=0))\
+  {error_in_archive=error; if(error>1) return error;}
+
+/*
+ *  Skip a variable-length field, and report any errors.  Used in zipinfo.c
+ *  and unzip.c in several functions.
+ *
+ *  macro SKIP_(length)
+ *      ush length;
+ *  {
+ *      if (length && ((error = do_string(length, SKIP)) != 0)) {
+ *          error_in_archive = error;   /-* might be warning *-/
+ *          if (error > 1)              /-* fatal *-/
+ *              return (error);
+ *      }
+ *  }
+ *
+ */
+
+
+#ifdef FUNZIP
+#  define FLUSH(w)  flush(__G__ (ulg)(w))
+#  define NEXTBYTE  getc(G.in)   /* redefined in crypt.h if full version */
+#else
+#  define FLUSH(w)  ((G.mem_mode) ? memflush(__G__ redirSlide,(ulg)(w)) \
+                                  : flush(__G__ redirSlide,(ulg)(w),0))
+#  define NEXTBYTE  (G.incnt-- > 0 ? (int)(*G.inptr++) : readbyte(__G))
+#endif
+
+
+#define READBITS(nbits,zdest) {if(nbits>G.bits_left) {int temp; G.zipeof=1;\
+  while (G.bits_left<=8*(int)(sizeof(G.bitbuf)-1) && (temp=NEXTBYTE)!=EOF) {\
+  G.bitbuf|=(ulg)temp<<G.bits_left; G.bits_left+=8; G.zipeof=0;}}\
+  zdest=(shrint)((unsigned)G.bitbuf&mask_bits[nbits]);G.bitbuf>>=nbits;\
+  G.bits_left-=nbits;}
+
+/*
+ * macro READBITS(nbits,zdest)    * only used by unreduce and unshrink *
+ *  {
+ *      if (nbits > G.bits_left) {  * fill G.bitbuf, 8*sizeof(ulg) bits *
+ *          int temp;
+ *
+ *          G.zipeof = 1;
+ *          while (G.bits_left <= 8*(int)(sizeof(G.bitbuf)-1) &&
+ *                 (temp = NEXTBYTE) != EOF) {
+ *              G.bitbuf |= (ulg)temp << G.bits_left;
+ *              G.bits_left += 8;
+ *              G.zipeof = 0;
+ *          }
+ *      }
+ *      zdest = (shrint)((unsigned)G.bitbuf & mask_bits[nbits]);
+ *      G.bitbuf >>= nbits;
+ *      G.bits_left -= nbits;
+ *  }
+ *
+ */
+
+
+/* GRR:  should use StringLower for STRLOWER macro if possible */
+
+/*
+ *  Copy the zero-terminated string in str1 into str2, converting any
+ *  uppercase letters to lowercase as we go.  str2 gets zero-terminated
+ *  as well, of course.  str1 and str2 may be the same character array.
+ */
+#ifdef _MBCS
+#  define STRLOWER(str1, str2) \
+   { \
+       char  *p, *q, c; unsigned i; \
+       p = (char *)(str1); \
+       q = (char *)(str2); \
+       while ((c = *p) != '\0') { \
+           if ((i = CLEN(p)) > 1) { \
+               while (i--) *q++ = *p++; \
+           } else { \
+               *q++ = (char)(isupper((int)(c))? tolower((int)(c)) : c); \
+               p++; \
+           } \
+       } \
+       *q = '\0'; \
+   }
+#else
+#  define STRLOWER(str1, str2) \
+   { \
+       char  *p, *q; \
+       p = (char *)(str1) - 1; \
+       q = (char *)(str2); \
+       while (*++p) \
+           *q++ = (char)(isupper((int)(*p))? tolower((int)(*p)) : *p); \
+       *q = '\0'; \
+   }
+#endif
+/*
+ *  NOTES:  This macro makes no assumptions about the characteristics of
+ *    the tolower() function or macro (beyond its existence), nor does it
+ *    make assumptions about the structure of the character set (i.e., it
+ *    should work on EBCDIC machines, too).  The fact that either or both
+ *    of isupper() and tolower() may be macros has been taken into account;
+ *    watch out for "side effects" (in the C sense) when modifying this
+ *    macro.
+ */
+
+#ifndef foreign
+#  define foreign(c)  (c)
+#endif
+
+#ifndef native
+#  define native(c)   (c)
+#  define A_TO_N(str1)
+#else
+#  ifndef NATIVE
+#    define NATIVE     "native chars"
+#  endif
+#  define A_TO_N(str1) {register uch *p;\
+     for (p=(uch *)(str1); *p; p++) *p=native(*p);}
+#endif
+/*
+ *  Translate the zero-terminated string in str1 from ASCII to the native
+ *  character set. The translation is performed in-place and uses the
+ *  "native" macro to translate each character.
+ *
+ *  NOTE:  Using the "native" macro means that is it the only part of unzip
+ *    which knows which translation table (if any) is actually in use to
+ *    produce the native character set.  This makes adding new character set
+ *    translation tables easy, insofar as all that is needed is an appropriate
+ *    "native" macro definition and the translation table itself.  Currently,
+ *    the only non-ASCII native character set implemented is EBCDIC, but this
+ *    may not always be so.
+ */
+
+
+/* default setup for internal codepage: assume ISO 8859-1 compatibility!! */
+#if (!defined(NATIVE) && !defined(CRTL_CP_IS_ISO) && !defined(CRTL_CP_IS_OEM))
+#  define CRTL_CP_IS_ISO
+#endif
+
+
+/*  Translate "extended ASCII" chars (OEM coding for DOS and OS/2; else
+ *  ISO-8859-1 [ISO Latin 1, Win Ansi,...]) into the internal "native"
+ *  code page.  As with A_TO_N(), conversion is done in place.
+ */
+#ifndef _ISO_INTERN
+#  ifdef CRTL_CP_IS_OEM
+#    ifndef IZ_ISO2OEM_ARRAY
+#      define IZ_ISO2OEM_ARRAY
+#    endif
+#    define _ISO_INTERN(str1) if (iso2oem) {register uch *p;\
+       for (p=(uch *)(str1); *p; p++)\
+         *p = native((*p & 0x80) ? iso2oem[*p & 0x7f] : *p);}
+#  else
+#    define _ISO_INTERN(str1)   A_TO_N(str1)
+#  endif
+#endif
+
+#ifndef _OEM_INTERN
+#  ifdef CRTL_CP_IS_OEM
+#    define _OEM_INTERN(str1)   A_TO_N(str1)
+#  else
+#    ifndef IZ_OEM2ISO_ARRAY
+#      define IZ_OEM2ISO_ARRAY
+#    endif
+#    define _OEM_INTERN(str1) if (oem2iso) {register uch *p;\
+       for (p=(uch *)(str1); *p; p++)\
+         *p = native((*p & 0x80) ? oem2iso[*p & 0x7f] : *p);}
+#  endif
+#endif
+
+#ifndef STR_TO_ISO
+#  ifdef CRTL_CP_IS_ISO
+#    define STR_TO_ISO          strcpy
+#  else
+#    define STR_TO_ISO          str2iso
+#    define NEED_STR2ISO
+#  endif
+#endif
+
+#ifndef STR_TO_OEM
+#  ifdef CRTL_CP_IS_OEM
+#    define STR_TO_OEM          strcpy
+#  else
+#    define STR_TO_OEM          str2oem
+#    define NEED_STR2OEM
+#  endif
+#endif
+
+#if (!defined(INTERN_TO_ISO) && !defined(ASCII2ISO))
+#  ifdef CRTL_CP_IS_OEM
+     /* know: "ASCII" is "OEM" */
+#    define ASCII2ISO(c) \
+       ((((c) & 0x80) && oem2iso) ? oem2iso[(c) & 0x7f] : (c))
+#    if (defined(NEED_STR2ISO) && !defined(CRYP_USES_OEM2ISO))
+#      define CRYP_USES_OEM2ISO
+#    endif
+#  else
+     /* assume: "ASCII" is "ISO-ANSI" */
+#    define ASCII2ISO(c) (c)
+#  endif
+#endif
+
+#if (!defined(INTERN_TO_OEM) && !defined(ASCII2OEM))
+#  ifdef CRTL_CP_IS_OEM
+     /* know: "ASCII" is "OEM" */
+#    define ASCII2OEM(c) (c)
+#  else
+     /* assume: "ASCII" is "ISO-ANSI" */
+#    define ASCII2OEM(c) \
+       ((((c) & 0x80) && iso2oem) ? iso2oem[(c) & 0x7f] : (c))
+#    if (defined(NEED_STR2OEM) && !defined(CRYP_USES_ISO2OEM))
+#      define CRYP_USES_ISO2OEM
+#    endif
+#  endif
+#endif
+
+/* codepage conversion setup for testp() in crypt.c */
+#ifdef CRTL_CP_IS_ISO
+#  ifndef STR_TO_CP2
+#    define STR_TO_CP2  STR_TO_OEM
+#  endif
+#else
+#  ifdef CRTL_CP_IS_OEM
+#    ifndef STR_TO_CP2
+#      define STR_TO_CP2  STR_TO_ISO
+#    endif
+#  else /* native internal CP is neither ISO nor OEM */
+#    ifndef STR_TO_CP1
+#      define STR_TO_CP1  STR_TO_ISO
+#    endif
+#    ifndef STR_TO_CP2
+#      define STR_TO_CP2  STR_TO_OEM
+#    endif
+#  endif
+#endif
+
+
+/* Convert filename (and file comment string) into "internal" charset.
+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
+ * codepage when made on
+ *  -> DOS (this includes 16-bit Windows 3.1)  (FS_FAT_)
+ *  -> OS/2                                    (FS_HPFS_)
+ *  -> Win95/WinNT with Nico Mak's WinZip      (FS_NTFS_ && hostver == "5.0")
+ * EXCEPTIONS:
+ *  PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
+ *  the filename stored in the local header is coded in Windows ANSI (CP 1252
+ *  resp. ISO 8859-1 on US and western Europe locale settings).
+ *  Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
+ *  filenames stored in BOTH the local and the central header are coded
+ *  in the local system's codepage (usually ANSI codings like ISO 8859-1).
+ *
+ * All other ports are assumed to code zip entry filenames in ISO 8859-1.
+ */
+#ifndef Ext_ASCII_TO_Native
+#  define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
+    if (((hostnum) == FS_FAT_ && \
+         !(((islochdr) || (isuxatt)) && \
+           ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+        (hostnum) == FS_HPFS_ || \
+        ((hostnum) == FS_NTFS_ /* && (hostver) == 50 */ )) { \
+        _OEM_INTERN((string)); \
+    } else { \
+        _ISO_INTERN((string)); \
+    }
+#endif
+
+
+
+/**********************/
+/*  Global constants  */
+/**********************/
+
+   extern ZCONST unsigned near mask_bits[17];
+   extern ZCONST char *fnames[2];
+
+#ifdef EBCDIC
+   extern ZCONST uch ebcdic[];
+#endif
+#ifdef IZ_ISO2OEM_ARRAY
+   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[];
+#endif
+
+   extern ZCONST char Far  VersionDate[];
+   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[];
+
+#ifndef SFX
+   extern ZCONST char Far  Zipnfo[];
+   extern ZCONST char Far  CompiledWith[];
+#endif /* !SFX */
+
+
+
+/***********************************/
+/*  Global (shared?) RTL variables */
+/***********************************/
+
+#ifdef DECLARE_ERRNO
+   extern int             errno;
+#endif
+
+/*---------------------------------------------------------------------
+    Unicode Support
+    28 August 2005
+  ---------------------------------------------------------------------*/
+#if (defined(UNICODE_SUPPORT) && defined(UNICODE_WCHAR))
+
+  /* Default character when a zwchar too big for wchar_t */
+# define zwchar_to_wchar_t_default_char '_'
+
+  /* Default character string when wchar_t does not convert to mb */
+# define wide_to_mb_default_string "_"
+
+  /* wide character type */
+  typedef unsigned long zwchar;
+
+  /* UTF-8 related conversion functions, currently found in process.c */
+
+# if 0 /* currently unused */
+  /* check if string is all ASCII */
+  int is_ascii_string OF((ZCONST char *mbstring));
+# endif /* unused */
+
+  /* convert UTF-8 string to multi-byte string */
+  char *utf8_to_local_string OF((ZCONST char *utf8_string, int escape_all));
+
+  /* convert UTF-8 string to wide string */
+  zwchar *utf8_to_wide_string OF((ZCONST char *utf8_string));
+
+  /* convert wide string to multi-byte string */
+  char *wide_to_local_string OF((ZCONST zwchar *wide_string, int escape_all));
+
+# if 0 /* currently unused */
+  /* convert local string to multi-byte display string */
+  char *local_to_display_string OF((ZCONST char *local_string));
+# endif /* unused */
+
+  /* convert wide character to escape string */
+  char *wide_to_escape_string OF((unsigned long));
+
+# define utf8_to_escaped_string(utf8_string) \
+         utf8_to_local_string(utf8_string, TRUE)
+
+# if 0 /* currently unused */
+  /* convert escape string to wide character */
+  unsigned long escape_string_to_wide OF((ZCONST char *escape_string));
+
+  /* convert local to UTF-8 */
+  char *local_to_utf8_string OF ((ZCONST char *local_string));
+
+  /* convert local to wide string */
+  zwchar *local_to_wide_string OF ((ZCONST char *local_string));
+
+  /* convert wide string to UTF-8 */
+  char *wide_to_utf8_string OF((ZCONST zwchar *wide_string));
+# endif /* unused */
+
+#endif /* UNICODE_SUPPORT && UNICODE_WCHAR */
+
+
+#endif /* !__unzpriv_h */
Index: unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c	(revision 5)
@@ -0,0 +1,2394 @@
+/*
+  Copyright (c) 1990-2009 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
+*/
+/*---------------------------------------------------------------------------
+
+  zipinfo.c                                              Greg Roelofs et al.
+
+  This file contains all of the ZipInfo-specific listing routines for UnZip.
+
+  Contains:  zi_opts()
+             zi_end_central()
+             zipinfo()
+             zi_long()
+             zi_short()
+             zi_time()
+
+  ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+
+#ifndef NO_ZIPINFO  /* strings use up too much space in small-memory systems */
+
+/* Define OS-specific attributes for use on ALL platforms--the S_xxxx
+ * versions of these are defined differently (or not defined) by different
+ * compilers and operating systems. */
+
+#define UNX_IFMT       0170000     /* Unix file type mask */
+#define UNX_IFREG      0100000     /* Unix regular file */
+#define UNX_IFSOCK     0140000     /* Unix socket (BSD, not SysV or Amiga) */
+#define UNX_IFLNK      0120000     /* Unix symbolic link (not SysV, Amiga) */
+#define UNX_IFBLK      0060000     /* Unix block special       (not Amiga) */
+#define UNX_IFDIR      0040000     /* Unix directory */
+#define UNX_IFCHR      0020000     /* Unix character special   (not Amiga) */
+#define UNX_IFIFO      0010000     /* Unix fifo    (BCC, not MSC or Amiga) */
+#define UNX_ISUID      04000       /* Unix set user id on execution */
+#define UNX_ISGID      02000       /* Unix set group id on execution */
+#define UNX_ISVTX      01000       /* Unix directory permissions control */
+#define UNX_ENFMT      UNX_ISGID   /* Unix record locking enforcement flag */
+#define UNX_IRWXU      00700       /* Unix read, write, execute: owner */
+#define UNX_IRUSR      00400       /* Unix read permission: owner */
+#define UNX_IWUSR      00200       /* Unix write permission: owner */
+#define UNX_IXUSR      00100       /* Unix execute permission: owner */
+#define UNX_IRWXG      00070       /* Unix read, write, execute: group */
+#define UNX_IRGRP      00040       /* Unix read permission: group */
+#define UNX_IWGRP      00020       /* Unix write permission: group */
+#define UNX_IXGRP      00010       /* Unix execute permission: group */
+#define UNX_IRWXO      00007       /* Unix read, write, execute: other */
+#define UNX_IROTH      00004       /* Unix read permission: other */
+#define UNX_IWOTH      00002       /* Unix write permission: other */
+#define UNX_IXOTH      00001       /* Unix execute permission: other */
+
+#define VMS_IRUSR      UNX_IRUSR   /* VMS read/owner */
+#define VMS_IWUSR      UNX_IWUSR   /* VMS write/owner */
+#define VMS_IXUSR      UNX_IXUSR   /* VMS execute/owner */
+#define VMS_IRGRP      UNX_IRGRP   /* VMS read/group */
+#define VMS_IWGRP      UNX_IWGRP   /* VMS write/group */
+#define VMS_IXGRP      UNX_IXGRP   /* VMS execute/group */
+#define VMS_IROTH      UNX_IROTH   /* VMS read/other */
+#define VMS_IWOTH      UNX_IWOTH   /* VMS write/other */
+#define VMS_IXOTH      UNX_IXOTH   /* VMS execute/other */
+
+#define AMI_IFMT       06000       /* Amiga file type mask */
+#define AMI_IFDIR      04000       /* Amiga directory */
+#define AMI_IFREG      02000       /* Amiga regular file */
+#define AMI_IHIDDEN    00200       /* to be supported in AmigaDOS 3.x */
+#define AMI_ISCRIPT    00100       /* executable script (text command file) */
+#define AMI_IPURE      00040       /* allow loading into resident memory */
+#define AMI_IARCHIVE   00020       /* not modified since bit was last set */
+#define AMI_IREAD      00010       /* can be opened for reading */
+#define AMI_IWRITE     00004       /* can be opened for writing */
+#define AMI_IEXECUTE   00002       /* executable image, a loadable runfile */
+#define AMI_IDELETE    00001       /* can be deleted */
+
+#define THS_IFMT    0xF000         /* Theos file type mask */
+#define THS_IFIFO   0x1000         /* pipe */
+#define THS_IFCHR   0x2000         /* char device */
+#define THS_IFSOCK  0x3000         /* socket */
+#define THS_IFDIR   0x4000         /* directory */
+#define THS_IFLIB   0x5000         /* library */
+#define THS_IFBLK   0x6000         /* block device */
+#define THS_IFREG   0x8000         /* regular file */
+#define THS_IFREL   0x9000         /* relative (direct) */
+#define THS_IFKEY   0xA000         /* keyed */
+#define THS_IFIND   0xB000         /* indexed */
+#define THS_IFRND   0xC000         /* ???? */
+#define THS_IFR16   0xD000         /* 16 bit real mode program */
+#define THS_IFP16   0xE000         /* 16 bit protected mode prog */
+#define THS_IFP32   0xF000         /* 32 bit protected mode prog */
+#define THS_IMODF   0x0800         /* modified */
+#define THS_INHID   0x0400         /* not hidden */
+#define THS_IEUSR   0x0200         /* erase permission: owner */
+#define THS_IRUSR   0x0100         /* read permission: owner */
+#define THS_IWUSR   0x0080         /* write permission: owner */
+#define THS_IXUSR   0x0040         /* execute permission: owner */
+#define THS_IROTH   0x0004         /* read permission: other */
+#define THS_IWOTH   0x0002         /* write permission: other */
+#define THS_IXOTH   0x0001         /* execute permission: other */
+
+#ifdef OLD_THEOS_EXTRA
+#  include "theos/oldstat.h"
+#endif
+
+#ifndef NSK_UNSTRUCTURED
+# define NSK_UNSTRUCTURED   0
+#endif
+#ifndef NSK_OBJECTFILECODE
+# define NSK_OBJECTFILECODE 100
+#endif
+#ifndef NSK_EDITFILECODE
+# define NSK_EDITFILECODE   101
+#endif
+
+#define LFLAG  3   /* short "ls -l" type listing */
+
+static int   zi_long   OF((__GPRO__ zusz_t *pEndprev, int error_in_archive));
+static int   zi_short  OF((__GPRO));
+static void  zi_showMacTypeCreator
+                       OF((__GPRO__ uch *ebfield));
+static char *zi_time   OF((__GPRO__ ZCONST ulg *datetimez,
+                           ZCONST time_t *modtimez, char *d_t_str));
+
+
+/**********************************************/
+/*  Strings used in zipinfo.c (ZipInfo half)  */
+/**********************************************/
+
+static ZCONST char nullStr[] = "";
+static ZCONST char PlurSufx[] = "s";
+
+static ZCONST char Far ZipInfHeader2[] =
+  "Zip file size: %s bytes, number of entries: %s\n";
+static ZCONST char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n";
+static ZCONST char Far LineSeparators[] = "-------------------------------\n\n";
+static ZCONST char Far ZipFSizeVerbose[] = "\
+  Zip archive file size:               %s (%sh)\n";
+static ZCONST char Far ActOffsetCentDir[] = "\
+  Actual end-cent-dir record offset:   %s (%sh)\n\
+  Expected end-cent-dir record offset: %s (%sh)\n\
+  (based on the length of the central directory and its expected offset)\n\n";
+static ZCONST char Far SinglePartArchive1[] = "\
+  This zipfile constitutes the sole disk of a single-part archive; its\n\
+  central directory contains %s %s.\n\
+  The central directory is %s (%sh) bytes long,\n";
+static ZCONST char Far SinglePartArchive2[] = "\
+  and its (expected) offset in bytes from the beginning of the zipfile\n\
+  is %s (%sh).\n\n";
+static ZCONST char Far MultiPartArchive1[] = "\
+  This zipfile constitutes disk %lu of a multi-part archive.  The central\n\
+  directory starts on disk %lu at an offset within that archive part\n";
+static ZCONST char Far MultiPartArchive2[] = "\
+  of %s (%sh) bytes.  The entire\n\
+  central directory is %s (%sh) bytes long.\n";
+static ZCONST char Far MultiPartArchive3[] = "\
+  %s of the archive entries %s contained within this zipfile volume,\n\
+  out of a total of %s %s.\n\n";
+
+static ZCONST char Far CentralDirEntry[] =
+  "\nCentral directory entry #%lu:\n---------------------------\n\n";
+static ZCONST char Far ZipfileStats[] =
+  "%lu file%s, %s bytes uncompressed, %s bytes compressed:  %s%d.%d%%\n";
+
+/* zi_long() strings */
+static ZCONST char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT";
+static ZCONST char Far OS_Amiga[] = "Amiga";
+static ZCONST char Far OS_VMS[] = "VMS";
+static ZCONST char Far OS_Unix[] = "Unix";
+static ZCONST char Far OS_VMCMS[] = "VM/CMS";
+static ZCONST char Far OS_AtariST[] = "Atari ST";
+static ZCONST char Far OS_HPFS[] = "OS/2 or NT HPFS";
+static ZCONST char Far OS_Macintosh[] = "Macintosh HFS";
+static ZCONST char Far OS_ZSystem[] = "Z-System";
+static ZCONST char Far OS_CPM[] = "CP/M";
+static ZCONST char Far OS_TOPS20[] = "TOPS-20";
+static ZCONST char Far OS_NTFS[] = "NTFS";
+static ZCONST char Far OS_QDOS[] = "SMS/QDOS";
+static ZCONST char Far OS_Acorn[] = "Acorn RISC OS";
+static ZCONST char Far OS_MVS[] = "MVS";
+static ZCONST char Far OS_VFAT[] = "Win32 VFAT";
+static ZCONST char Far OS_AtheOS[] = "AtheOS";
+static ZCONST char Far OS_BeOS[] = "BeOS";
+static ZCONST char Far OS_Tandem[] = "Tandem NSK";
+static ZCONST char Far OS_Theos[] = "Theos";
+static ZCONST char Far OS_MacDarwin[] = "Mac OS/X (Darwin)";
+#ifdef OLD_THEOS_EXTRA
+  static ZCONST char Far OS_TheosOld[] = "Theos (Old)";
+#endif /* OLD_THEOS_EXTRA */
+
+static ZCONST char Far MthdNone[] = "none (stored)";
+static ZCONST char Far MthdShrunk[] = "shrunk";
+static ZCONST char Far MthdRedF1[] = "reduced (factor 1)";
+static ZCONST char Far MthdRedF2[] = "reduced (factor 2)";
+static ZCONST char Far MthdRedF3[] = "reduced (factor 3)";
+static ZCONST char Far MthdRedF4[] = "reduced (factor 4)";
+static ZCONST char Far MthdImplode[] = "imploded";
+static ZCONST char Far MthdToken[] = "tokenized";
+static ZCONST char Far MthdDeflate[] = "deflated";
+static ZCONST char Far MthdDeflat64[] = "deflated (enhanced-64k)";
+static ZCONST char Far MthdDCLImplode[] = "imploded (PK DCL)";
+static ZCONST char Far MthdBZip2[] = "bzipped";
+static ZCONST char Far MthdLZMA[] = "LZMA-ed";
+static ZCONST char Far MthdTerse[] = "tersed (IBM)";
+static ZCONST char Far MthdLZ77[] = "LZ77-compressed (IBM)";
+static ZCONST char Far MthdWavPack[] = "WavPacked";
+static ZCONST char Far MthdPPMd[] = "PPMd-ed";
+
+static ZCONST char Far DeflNorm[] = "normal";
+static ZCONST char Far DeflMax[] = "maximum";
+static ZCONST char Far DeflFast[] = "fast";
+static ZCONST char Far DeflSFast[] = "superfast";
+
+static ZCONST char Far ExtraBytesPreceding[] =
+  "  There are an extra %s bytes preceding this file.\n\n";
+
+static ZCONST char Far UnknownNo[] = "unknown (%d)";
+
+#ifdef ZIP64_SUPPORT
+  static ZCONST char Far LocalHeaderOffset[] =
+    "\n  offset of local header from start of archive:   %s\n\
+                                                  (%sh) bytes\n";
+#else
+  static ZCONST char Far LocalHeaderOffset[] =
+    "\n  offset of local header from start of archive:   %s (%sh) bytes\n";
+#endif
+static ZCONST char Far HostOS[] =
+  "  file system or operating system of origin:      %s\n";
+static ZCONST char Far EncodeSWVer[] =
+  "  version of encoding software:                   %u.%u\n";
+static ZCONST char Far MinOSCompReq[] =
+  "  minimum file system compatibility required:     %s\n";
+static ZCONST char Far MinSWVerReq[] =
+  "  minimum software version required to extract:   %u.%u\n";
+static ZCONST char Far CompressMethod[] =
+  "  compression method:                             %s\n";
+static ZCONST char Far SlideWindowSizeImplode[] =
+  "  size of sliding dictionary (implosion):         %cK\n";
+static ZCONST char Far ShannonFanoTrees[] =
+  "  number of Shannon-Fano trees (implosion):       %c\n";
+static ZCONST char Far CompressSubtype[] =
+  "  compression sub-type (deflation):               %s\n";
+static ZCONST char Far FileSecurity[] =
+  "  file security status:                           %sencrypted\n";
+static ZCONST char Far ExtendedLocalHdr[] =
+  "  extended local header:                          %s\n";
+static ZCONST char Far FileModDate[] =
+  "  file last modified on (DOS date/time):          %s\n";
+#ifdef USE_EF_UT_TIME
+  static ZCONST char Far UT_FileModDate[] =
+    "  file last modified on (UT extra field modtime): %s %s\n";
+  static ZCONST char Far LocalTime[] = "local";
+#ifndef NO_GMTIME
+  static ZCONST char Far GMTime[] = "UTC";
+#endif
+#endif /* USE_EF_UT_TIME */
+static ZCONST char Far CRC32Value[] =
+  "  32-bit CRC value (hex):                         %.8lx\n";
+static ZCONST char Far CompressedFileSize[] =
+  "  compressed size:                                %s bytes\n";
+static ZCONST char Far UncompressedFileSize[] =
+  "  uncompressed size:                              %s bytes\n";
+static ZCONST char Far FilenameLength[] =
+  "  length of filename:                             %u characters\n";
+static ZCONST char Far ExtraFieldLength[] =
+  "  length of extra field:                          %u bytes\n";
+static ZCONST char Far FileCommentLength[] =
+  "  length of file comment:                         %u characters\n";
+static ZCONST char Far FileDiskNum[] =
+  "  disk number on which file begins:               disk %lu\n";
+static ZCONST char Far ApparentFileType[] =
+  "  apparent file type:                             %s\n";
+static ZCONST char Far VMSFileAttributes[] =
+  "  VMS file attributes (%06o octal):             %s\n";
+static ZCONST char Far AmigaFileAttributes[] =
+  "  Amiga file attributes (%06o octal):           %s\n";
+static ZCONST char Far UnixFileAttributes[] =
+  "  Unix file attributes (%06o octal):            %s\n";
+static ZCONST char Far NonMSDOSFileAttributes[] =
+  "  non-MSDOS external file attributes:             %06lX hex\n";
+static ZCONST char Far MSDOSFileAttributes[] =
+  "  MS-DOS file attributes (%02X hex):                none\n";
+static ZCONST char Far MSDOSFileAttributesRO[] =
+  "  MS-DOS file attributes (%02X hex):                read-only\n";
+static ZCONST char Far MSDOSFileAttributesAlpha[] =
+  "  MS-DOS file attributes (%02X hex):                %s%s%s%s%s%s%s%s\n";
+static ZCONST char Far TheosFileAttributes[] =
+  "  Theos file attributes (%04X hex):               %s\n";
+
+static ZCONST char Far TheosFTypLib[] = "Library     ";
+static ZCONST char Far TheosFTypDir[] = "Directory   ";
+static ZCONST char Far TheosFTypReg[] = "Sequential  ";
+static ZCONST char Far TheosFTypRel[] = "Direct      ";
+static ZCONST char Far TheosFTypKey[] = "Keyed       ";
+static ZCONST char Far TheosFTypInd[] = "Indexed     ";
+static ZCONST char Far TheosFTypR16[] = " 86 program ";
+static ZCONST char Far TheosFTypP16[] = "286 program ";
+static ZCONST char Far TheosFTypP32[] = "386 program ";
+static ZCONST char Far TheosFTypUkn[] = "???         ";
+
+static ZCONST char Far ExtraFieldTrunc[] = "\n\
+  error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\
+         space %u; block length has been truncated.\n";
+static ZCONST char Far ExtraFields[] = "\n\
+  The central-directory extra field contains:";
+static ZCONST char Far ExtraFieldType[] = "\n\
+  - A subfield with ID 0x%04x (%s) and %u data bytes";
+static ZCONST char Far efPKSZ64[] = "PKWARE 64-bit sizes";
+static ZCONST char Far efAV[] = "PKWARE AV";
+static ZCONST char Far efOS2[] = "OS/2";
+static ZCONST char Far efPKVMS[] = "PKWARE VMS";
+static ZCONST char Far efPKWin32[] = "PKWARE Win32";
+static ZCONST char Far efPKUnix[] = "PKWARE Unix";
+static ZCONST char Far efIZVMS[] = "Info-ZIP VMS";
+static ZCONST char Far efIZUnix[] = "old Info-ZIP Unix/OS2/NT";
+static ZCONST char Far efIZUnix2[] = "Unix UID/GID (16-bit)";
+static ZCONST char Far efIZUnix3[] = "Unix UID/GID (any size)";
+static ZCONST char Far efTime[] = "universal time";
+static ZCONST char Far efU8Path[] = "UTF8 path name";
+static ZCONST char Far efU8Commnt[] = "UTF8 entry comment";
+static ZCONST char Far efJLMac[] = "old Info-ZIP Macintosh";
+static ZCONST char Far efMac3[] = "new Info-ZIP Macintosh";
+static ZCONST char Far efZipIt[] = "ZipIt Macintosh";
+static ZCONST char Far efSmartZip[] = "SmartZip Macintosh";
+static ZCONST char Far efZipIt2[] = "ZipIt Macintosh (short)";
+static ZCONST char Far efVMCMS[] = "VM/CMS";
+static ZCONST char Far efMVS[] = "MVS";
+static ZCONST char Far efACL[] = "OS/2 ACL";
+static ZCONST char Far efNTSD[] = "Security Descriptor";
+static ZCONST char Far efAtheOS[] = "AtheOS";
+static ZCONST char Far efBeOS[] = "BeOS";
+static ZCONST char Far efQDOS[] = "SMS/QDOS";
+static ZCONST char Far efAOSVS[] = "AOS/VS";
+static ZCONST char Far efSpark[] = "Acorn SparkFS";
+static ZCONST char Far efMD5[] = "Fred Kantor MD5";
+static ZCONST char Far efASiUnix[] = "ASi Unix";
+static ZCONST char Far efTandem[] = "Tandem NSK";
+static ZCONST char Far efTheos[] = "Theos";
+static ZCONST char Far efUnknown[] = "unknown";
+
+static ZCONST char Far OS2EAs[] = ".\n\
+    The local extra field has %lu bytes of OS/2 extended attributes.\n\
+    (May not match OS/2 \"dir\" amount due to storage method)";
+static ZCONST char Far izVMSdata[] = ".  The extra\n\
+    field is %s and has %u bytes of VMS %s information%s";
+static ZCONST char Far izVMSstored[] = "stored";
+static ZCONST char Far izVMSrleenc[] = "run-length encoded";
+static ZCONST char Far izVMSdeflat[] = "deflated";
+static ZCONST char Far izVMScunknw[] = "compressed(?)";
+static ZCONST char Far *izVMScomp[4] =
+  {izVMSstored, izVMSrleenc, izVMSdeflat, izVMScunknw};
+static ZCONST char Far ACLdata[] = ".\n\
+    The local extra field has %lu bytes of access control list information";
+static ZCONST char Far NTSDData[] = ".\n\
+    The local extra field has %lu bytes of NT security descriptor data";
+static ZCONST char Far UTdata[] = ".\n\
+    The local extra field has UTC/GMT %s time%s";
+static ZCONST char Far UTmodification[] = "modification";
+static ZCONST char Far UTaccess[] = "access";
+static ZCONST char Far UTcreation[] = "creation";
+static ZCONST char Far U8PthCmnComplete[] = ".\n\
+    The UTF8 data of the extra field (V%u, ASCII name CRC `%.8lx') are:\n   ";
+static ZCONST char Far U8PthCmnF24[] = ". The first\n\
+    24 UTF8 bytes in the extra field (V%u, ASCII name CRC `%.8lx') are:\n   ";
+static ZCONST char Far ZipItFname[] = ".\n\
+    The Mac long filename is %s";
+static ZCONST char Far Mac3data[] = ".\n\
+    The local extra field has %lu bytes of %scompressed Macintosh\n\
+    finder attributes";
+ /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */
+static ZCONST char Far MacOSdata[] = ".\n\
+    The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'";
+static ZCONST char Far MacOSdata1[] = ".\n\
+    The associated file has type code `0x%lx' and creator code `0x%lx'";
+static ZCONST char Far MacOSJLEEflags[] = ".\n    File is marked as %s";
+static ZCONST char Far MacOS_RF[] = "Resource-fork";
+static ZCONST char Far MacOS_DF[] = "Data-fork";
+static ZCONST char Far MacOSMAC3flags[] = ".\n\
+    File is marked as %s, File Dates are in %d Bit";
+static ZCONST char Far AtheOSdata[] = ".\n\
+    The local extra field has %lu bytes of %scompressed AtheOS file attributes";
+static ZCONST char Far BeOSdata[] = ".\n\
+    The local extra field has %lu bytes of %scompressed BeOS file attributes";
+ /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */
+static ZCONST char Far QDOSdata[] = ".\n\
+    The QDOS extra field subtype is `%c%c%c%c'";
+static ZCONST char Far AOSVSdata[] = ".\n\
+    The AOS/VS extra field revision is %d.%d";
+static ZCONST char Far TandemUnstr[] = "Unstructured";
+static ZCONST char Far TandemRel[]   = "Relative";
+static ZCONST char Far TandemEntry[] = "Entry Sequenced";
+static ZCONST char Far TandemKey[]   = "Key Sequenced";
+static ZCONST char Far TandemEdit[]  = "Edit";
+static ZCONST char Far TandemObj[]  = "Object";
+static ZCONST char Far *TandemFileformat[6] =
+  {TandemUnstr, TandemRel, TandemEntry, TandemKey, TandemEdit, TandemObj};
+static ZCONST char Far Tandemdata[] = ".\n\
+    The file was originally a Tandem %s file, with file code %u";
+static ZCONST char Far MD5data[] = ".\n\
+    The 128-bit MD5 signature is %s";
+#ifdef CMS_MVS
+   static ZCONST char Far VmMvsExtraField[] = ".\n\
+    The stored file open mode (FLDATA TYPE) is \"%s\"";
+   static ZCONST char Far VmMvsInvalid[] = "[invalid]";
+#endif /* CMS_MVS */
+
+static ZCONST char Far First20[] = ".  The first\n    20 are:  ";
+static ZCONST char Far ColonIndent[] = ":\n   ";
+static ZCONST char Far efFormat[] = " %02x";
+
+static ZCONST char Far lExtraFieldType[] = "\n\
+  There %s a local extra field with ID 0x%04x (%s) and\n\
+  %u data bytes (%s).\n";
+static ZCONST char Far efIZuid[] =
+  "GMT modification/access times and Unix UID/GID";
+static ZCONST char Far efIZnouid[] = "GMT modification/access times only";
+
+
+static ZCONST char Far NoFileComment[] = "\n  There is no file comment.\n";
+static ZCONST char Far FileCommBegin[] = "\n\
+------------------------- file comment begins ----------------------------\n";
+static ZCONST char Far FileCommEnd[] = "\
+-------------------------- file comment ends -----------------------------\n";
+
+/* zi_time() strings */
+static ZCONST char Far BogusFmt[] = "%03d";
+static ZCONST char Far shtYMDHMTime[] = "%02u-%s-%02u %02u:%02u";
+static ZCONST char Far lngYMDHMSTime[] = "%u %s %u %02u:%02u:%02u";
+static ZCONST char Far DecimalTime[] = "%04u%02u%02u.%02u%02u%02u";
+#ifdef USE_EF_UT_TIME
+  static ZCONST char Far lngYMDHMSTimeError[] = "???? ??? ?? ??:??:??";
+#endif
+
+
+
+
+
+#ifndef WINDLL
+
+/************************/
+/*  Function zi_opts()  */
+/************************/
+
+int zi_opts(__G__ pargc, pargv)
+    int *pargc;
+    char ***pargv;
+    __GDEF
+{
+    char   **argv, *s;
+    int    argc, c, error=FALSE, negative=0;
+    int    hflag_slmv=TRUE, hflag_2=FALSE;  /* diff options => diff defaults */
+    int    tflag_slm=TRUE, tflag_2v=FALSE;
+    int    explicit_h=FALSE, explicit_t=FALSE;
+
+#ifdef UNIX
+    extern char OEM_CP[MAX_CP_NAME];
+    extern char ISO_CP[MAX_CP_NAME];
+#endif
+
+#ifdef MACOS
+    uO.lflag = LFLAG;         /* reset default on each call */
+#endif
+    G.extract_flag = FALSE;   /* zipinfo does not extract to disk */
+    argc = *pargc;
+    argv = *pargv;
+
+    while (--argc > 0 && (*++argv)[0] == '-') {
+        s = argv[0] + 1;
+        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
+            switch (c) {
+                case '-':
+                    ++negative;
+                    break;
+                case '1':      /* shortest listing:  JUST filenames */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 1;
+                    break;
+                case '2':      /* just filenames, plus headers if specified */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 2;
+                    break;
+#ifndef CMS_MVS
+                case ('C'):    /* -C:  match filenames case-insensitively */
+                    if (negative)
+                        uO.C_flag = FALSE, negative = 0;
+                    else
+                        uO.C_flag = TRUE;
+                    break;
+#endif /* !CMS_MVS */
+                case 'h':      /* header line */
+                    if (negative)
+                        hflag_2 = hflag_slmv = FALSE, negative = 0;
+                    else {
+                        hflag_2 = hflag_slmv = explicit_h = TRUE;
+                        if (uO.lflag == -1)
+                            uO.lflag = 0;
+                    }
+                    break;
+#ifdef UNIX
+    			case ('I'):
+                    if (negative) {
+                        Info(slide, 0x401, ((char *)slide,
+                          "error:  encodings can't be negated"));
+                        return(PK_PARAM);
+    				} else {
+    					if(*s) { /* Handle the -Icharset case */
+    						/* Assume that charsets can't start with a dash to spot arguments misuse */
+    						if(*s == '-') { 
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+                ISO_CP[MAX_CP_NAME - 1] = '\0';
+    					} else { /* -I charset */
+    						++argv;
+    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						s = *argv;
+    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+                ISO_CP[MAX_CP_NAME - 1] = '\0';
+    					}
+    					while(*(++s)); /* No params straight after charset name */
+    				}
+    				break;
+#endif /* ?UNIX */
+                case 'l':      /* longer form of "ls -l" type listing */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 5;
+                    break;
+                case 'm':      /* medium form of "ls -l" type listing */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 4;
+                    break;
+#ifdef MORE
+                case 'M':      /* send output through built-in "more" */
+                    if (negative)
+                        G.M_flag = FALSE, negative = 0;
+                    else
+                        G.M_flag = TRUE;
+                    break;
+#endif
+#ifdef UNIX
+    			case ('O'):
+                    if (negative) {
+                        Info(slide, 0x401, ((char *)slide,
+                          "error:  encodings can't be negated"));
+                        return(PK_PARAM);
+    				} else {
+    					if(*s) { /* Handle the -Ocharset case */
+    						/* Assume that charsets can't start with a dash to spot arguments misuse */
+    						if(*s == '-') { 
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -I argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+                OEM_CP[MAX_CP_NAME - 1] = '\0';
+    					} else { /* -O charset */
+    						++argv;
+    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+    	                        Info(slide, 0x401, ((char *)slide,
+        		                  "error:  a valid character encoding should follow the -O argument"));
+    	                        return(PK_PARAM); 
+    						}
+    						s = *argv;
+    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+                OEM_CP[MAX_CP_NAME - 1] = '\0';
+    					}
+    					while(*(++s)); /* No params straight after charset name */
+    				}
+    				break;
+#endif /* ?UNIX */
+                case 's':      /* default:  shorter "ls -l" type listing */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 3;
+                    break;
+                case 't':      /* totals line */
+                    if (negative)
+                        tflag_2v = tflag_slm = FALSE, negative = 0;
+                    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, negative = 0;
+                    else
+                        uO.T_flag = TRUE;
+                    break;
+#ifdef UNICODE_SUPPORT
+                case ('U'):    /* escape UTF-8, or disable UTF-8 support */
+                    if (negative) {
+                        uO.U_flag = MAX(uO.U_flag-negative,0);
+                        negative = 0;
+                    } else
+                        uO.U_flag++;
+                    break;
+#endif /* UNICODE_SUPPORT */
+                case 'v':      /* turbo-verbose listing */
+                    if (negative)
+                        uO.lflag = -2, negative = 0;
+                    else
+                        uO.lflag = 10;
+                    break;
+#ifdef WILD_STOP_AT_DIR
+                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
+                    if (negative)
+                        uO.W_flag = FALSE, negative = 0;
+                    else
+                        uO.W_flag = TRUE;
+                    break;
+#endif /* WILD_STOP_AT_DIR */
+                case 'z':      /* print zipfile comment */
+                    if (negative)
+                        uO.zflag = negative = 0;
+                    else
+                        uO.zflag = 1;
+                    break;
+                case 'Z':      /* ZipInfo mode:  ignore */
+                    break;
+                default:
+                    error = TRUE;
+                    break;
+            }
+        }
+    }
+    if ((argc-- == 0) || error) {
+        *pargc = argc;
+        *pargv = argv;
+        return USAGE(error);
+    }
+
+#ifdef MORE
+    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func useless */
+        G.M_flag = 0;
+#endif
+
+    /* if no listing options given (or all negated), or if only -h/-t given
+     * with individual files specified, use default listing format */
+    if ((uO.lflag < 0) || ((argc > 0) && (uO.lflag == 0)))
+        uO.lflag = LFLAG;
+
+    /* set header and totals flags to default or specified values */
+    switch (uO.lflag) {
+        case 0:   /* 0:  can only occur if either -t or -h explicitly given; */
+        case 2:   /*  therefore set both flags equal to normally false value */
+            uO.hflag = hflag_2;
+            uO.tflag = tflag_2v;
+            break;
+        case 1:   /* only filenames, *always* */
+            uO.hflag = FALSE;
+            uO.tflag = FALSE;
+            uO.zflag = FALSE;
+            break;
+        case 3:
+        case 4:
+        case 5:
+            uO.hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
+            uO.tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
+            break;
+        case 10:
+            uO.hflag = hflag_slmv;
+            uO.tflag = tflag_2v;
+            break;
+    }
+
+    *pargc = argc;
+    *pargv = argv;
+    return 0;
+
+} /* end function zi_opts() */
+
+#endif /* !WINDLL */
+
+
+
+
+
+/*******************************/
+/*  Function zi_end_central()  */
+/*******************************/
+
+void zi_end_central(__G)
+    __GDEF
+{
+/*---------------------------------------------------------------------------
+    Print out various interesting things about the zipfile.
+  ---------------------------------------------------------------------------*/
+
+    if (uO.lflag > 9) {
+        /* verbose format */
+        Info(slide, 0, ((char *)slide, LoadFarString(EndCentDirRec)));
+        Info(slide, 0, ((char *)slide, LoadFarString(LineSeparators)));
+
+        Info(slide, 0, ((char *)slide, LoadFarString(ZipFSizeVerbose),
+          FmZofft(G.ziplen, "11", NULL),
+          FmZofft(G.ziplen, FZOFFT_HEX_DOT_WID, "X")));
+        Info(slide, 0, ((char *)slide, LoadFarString(ActOffsetCentDir),
+          FmZofft(G.real_ecrec_offset, "11", "u"),
+          FmZofft(G.real_ecrec_offset, FZOFFT_HEX_DOT_WID, "X"),
+          FmZofft(G.expect_ecrec_offset, "11", "u"),
+          FmZofft(G.expect_ecrec_offset, FZOFFT_HEX_DOT_WID, "X")));
+
+        if (G.ecrec.number_this_disk == 0) {
+            Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive1),
+              FmZofft(G.ecrec.total_entries_central_dir, NULL, "u"),
+              (G.ecrec.total_entries_central_dir == 1)? "entry" : "entries",
+              FmZofft(G.ecrec.size_central_directory, NULL, "u"),
+              FmZofft(G.ecrec.size_central_directory,
+                      FZOFFT_HEX_DOT_WID, "X")));
+            Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive2),
+              FmZofft(G.ecrec.offset_start_central_directory, NULL, "u"),
+              FmZofft(G.ecrec.offset_start_central_directory,
+                      FZOFFT_HEX_DOT_WID, "X")));
+        } else {
+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive1),
+              (ulg)(G.ecrec.number_this_disk + 1),
+              (ulg)(G.ecrec.num_disk_start_cdir + 1)));
+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive2),
+              FmZofft(G.ecrec.offset_start_central_directory, NULL, "u"),
+              FmZofft(G.ecrec.offset_start_central_directory,
+                      FZOFFT_HEX_DOT_WID, "X"),
+              FmZofft(G.ecrec.size_central_directory, NULL, "u"),
+              FmZofft(G.ecrec.size_central_directory,
+                      FZOFFT_HEX_DOT_WID, "X")));
+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive3),
+              FmZofft(G.ecrec.num_entries_centrl_dir_ths_disk, NULL, "u"),
+              (G.ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are",
+              FmZofft(G.ecrec.total_entries_central_dir, NULL, "u"),
+              (G.ecrec.total_entries_central_dir == 1) ? "entry" : "entries"));
+        }
+    }
+    else if (uO.hflag) {
+        /* print zip file size and number of contained entries: */
+        Info(slide, 0, ((char *)slide, LoadFarString(ZipInfHeader2),
+          FmZofft(G.ziplen, NULL, NULL),
+          FmZofft(G.ecrec.total_entries_central_dir, NULL, "u")));
+    }
+
+} /* end function zi_end_central() */
+
+
+
+
+
+/************************/
+/*  Function zipinfo()  */
+/************************/
+
+int zipinfo(__G)   /* return PK-type error code */
+    __GDEF
+{
+    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+    int *fn_matched=NULL, *xn_matched=NULL;
+    ulg j, members=0L;
+    zusz_t tot_csize=0L, tot_ucsize=0L;
+    zusz_t endprev;   /* buffers end of previous entry for zi_long()'s check
+                       *  of extra bytes */
+
+
+/*---------------------------------------------------------------------------
+    Malloc space for check on unmatched filespecs (no big deal if one or both
+    are NULL).
+  ---------------------------------------------------------------------------*/
+
+    if (G.filespecs > 0  &&
+        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != NULL)
+        for (j = 0;  j < G.filespecs;  ++j)
+            fn_matched[j] = FALSE;
+
+    if (G.xfilespecs > 0  &&
+        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != NULL)
+        for (j = 0;  j < G.xfilespecs;  ++j)
+            xn_matched[j] = FALSE;
+
+/*---------------------------------------------------------------------------
+    Set file pointer to start of central directory, then loop through cen-
+    tral directory entries.  Check that directory-entry signature bytes are
+    actually there (just a precaution), then process the entry.  We know
+    the entire central directory is on this disk:  we wouldn't have any of
+    this information unless the end-of-central-directory record was on this
+    disk, and we wouldn't have gotten to this routine unless this is also
+    the disk on which the central directory starts.  In practice, this had
+    better be the *only* disk in the archive, but maybe someday we'll add
+    multi-disk support.
+  ---------------------------------------------------------------------------*/
+
+    uO.L_flag = FALSE;      /* zipinfo mode: never convert name to lowercase */
+    G.pInfo = G.info;       /* (re-)initialize, (just to make sure) */
+    G.pInfo->textmode = 0;  /* so one can read on screen (is this ever used?) */
+
+    /* reset endprev for new zipfile; account for multi-part archives (?) */
+    endprev = (G.crec.relative_offset_local_header == 4L)? 4L : 0L;
+
+
+    for (j = 1L;; j++) {
+        if (readbuf(__G__ G.sig, 4) == 0) {
+            error_in_archive = PK_EOF;
+            break;
+        }
+        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
+             *    number of entries as stored in the end_central record?
+             */
+            if (((j - 1) &
+                 (ulg)(G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+                == (ulg)G.ecrec.total_entries_central_dir)
+            {
+                /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
+                 * number of directory entries -> probably, the regular
+                 * end of the central directory has been reached
+                 */
+                break;
+            } else {
+                Info(slide, 0x401,
+                     ((char *)slide, LoadFarString(CentSigMsg), j));
+                Info(slide, 0x401,
+                     ((char *)slide,"%s", LoadFarString(ReportMsg)));
+                error_in_archive = PK_BADERR;   /* sig not found */
+                break;
+            }
+        }
+        /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
+        if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
+            error_in_archive = error;   /* only PK_EOF defined */
+            break;
+        }
+
+        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+             PK_COOL)
+        {
+          if (error > error_in_archive)
+              error_in_archive = error;
+          if (error > PK_WARN)        /* fatal */
+              break;
+        }
+
+        if (!G.process_all_files) {   /* check if specified on command line */
+            unsigned i;
+
+            if (G.filespecs == 0)
+                do_this_file = TRUE;
+            else {  /* check if this entry matches an `include' argument */
+                do_this_file = FALSE;
+                for (i = 0; i < G.filespecs; i++)
+                    if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+                        do_this_file = TRUE;
+                        if (fn_matched)
+                            fn_matched[i] = TRUE;
+                        break;       /* found match, so stop looping */
+                    }
+            }
+            if (do_this_file) {  /* check if this is an excluded file */
+                for (i = 0; i < G.xfilespecs; i++)
+                    if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+                        do_this_file = FALSE;  /* ^-- ignore case in match */
+                        if (xn_matched)
+                            xn_matched[i] = TRUE;
+                        break;
+                    }
+            }
+        }
+
+    /*-----------------------------------------------------------------------
+        If current file was specified on command line, or if no names were
+        specified, do the listing for this file.  Otherwise, get rid of the
+        file comment and go back for the next file.
+      -----------------------------------------------------------------------*/
+
+        if (G.process_all_files || do_this_file) {
+
+            /* Read the extra field, if any.  The extra field info is required
+             * for resolving the Zip64 sizes/offsets and may be used in more
+             * analysis of the entry below.
+             */
+            if ((error = do_string(__G__ G.crec.extra_field_length,
+                                   EXTRA_FIELD)) != 0)
+            {
+                if (G.extra_field != NULL) {
+                    free(G.extra_field);
+                    G.extra_field = NULL;
+                }
+                error_in_archive = error;
+                /* The premature return in case of a "fatal" error (PK_EOF) is
+                 * delayed until we analyze the extra field contents.
+                 * This allows us to display all the other info that has been
+                 * successfully read in.
+                 */
+            }
+
+            switch (uO.lflag) {
+                case 1:
+                case 2:
+                    fnprint(__G);
+                    SKIP_(G.crec.file_comment_length)
+                    break;
+
+                case 3:
+                case 4:
+                case 5:
+                    if ((error = zi_short(__G)) != PK_COOL) {
+                        error_in_archive = error;   /* might be warning */
+                    }
+                    break;
+
+                case 10:
+                    Info(slide, 0, ((char *)slide,
+                      LoadFarString(CentralDirEntry), j));
+                    if ((error = zi_long(__G__ &endprev,
+                                         error_in_archive)) != PK_COOL) {
+                        error_in_archive = error;   /* might be warning */
+                    }
+                    break;
+
+                default:
+                    SKIP_(G.crec.file_comment_length)
+                    break;
+
+            } /* end switch (lflag) */
+            if (error > PK_WARN)        /* fatal */
+                break;
+
+            tot_csize += G.crec.csize;
+            tot_ucsize += G.crec.ucsize;
+            if (G.crec.general_purpose_bit_flag & 1)
+                tot_csize -= 12;   /* don't count encryption header */
+            ++members;
+
+#ifdef DLL
+            if ((G.statreportcb != NULL) &&
+                (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
+                                  G.filename, (zvoid *)&G.crec.ucsize)) {
+                /* cancel operation by user request */
+                error_in_archive = IZ_CTRLC;
+                break;
+            }
+#endif
+#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
+            UserStop();
+#endif
+
+        } else {        /* not listing this file */
+            SKIP_(G.crec.extra_field_length)
+            SKIP_(G.crec.file_comment_length)
+            if (endprev != 0) endprev = 0;
+
+        } /* end if (list member?) */
+
+    } /* end for-loop (j: member files) */
+
+/*---------------------------------------------------------------------------
+    Check that we actually found requested files; if so, print totals.
+  ---------------------------------------------------------------------------*/
+
+    if ((error_in_archive <= PK_WARN) && uO.tflag) {
+        char *sgn = "";
+        int cfactor = ratio(tot_ucsize, tot_csize);
+
+        if (cfactor < 0) {
+            sgn = "-";
+            cfactor = -cfactor;
+        }
+        Info(slide, 0, ((char *)slide, LoadFarString(ZipfileStats),
+          members, (members==1L)? nullStr:PlurSufx,
+          FmZofft(tot_ucsize, NULL, "u"),
+          FmZofft(tot_csize, NULL, "u"),
+          sgn, cfactor/10, cfactor%10));
+    }
+
+/*---------------------------------------------------------------------------
+    Check for unmatched filespecs on command line and print warning if any
+    found.
+  ---------------------------------------------------------------------------*/
+
+    if (fn_matched) {
+        if (error_in_archive <= PK_WARN)
+            for (j = 0;  j < G.filespecs;  ++j)
+                if (!fn_matched[j])
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(FilenameNotMatched), G.pfnames[j]));
+        free((zvoid *)fn_matched);
+    }
+    if (xn_matched) {
+        if (error_in_archive <= PK_WARN)
+            for (j = 0;  j < G.xfilespecs;  ++j)
+                if (!xn_matched[j])
+                    Info(slide, 0x401, ((char *)slide,
+                      LoadFarString(ExclFilenameNotMatched), G.pxnames[j]));
+        free((zvoid *)xn_matched);
+    }
+
+
+    /* Skip the following checks in case of a premature listing break. */
+    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 */
+            Info(slide, 0x401, 
+                 ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+            error_in_archive = PK_WARN;   /* didn't find sig */
+        }
+
+        /* Set specific return code when no files have been found. */
+        if (members == 0L && error_in_archive <= PK_WARN)
+            error_in_archive = PK_FIND;
+
+        if (uO.lflag >= 10)
+            (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+    }
+
+    return error_in_archive;
+
+} /* end function zipinfo() */
+
+
+
+
+
+/************************/
+/*  Function zi_long()  */
+/************************/
+
+static int zi_long(__G__ pEndprev, error_in_archive)
+    /* return PK-type error code */
+    __GDEF
+    zusz_t *pEndprev;                /* for zi_long() check of extra bytes */
+    int error_in_archive;            /* may signal premature return */
+{
+#ifdef USE_EF_UT_TIME
+    iztimes z_utime;
+#endif
+    int  error;
+    unsigned  hostnum, hostver, extnum, extver, methid, methnum, xattr;
+    char workspace[12], attribs[22];
+    ZCONST char *varmsg_str;
+    char unkn[16];
+    static ZCONST char Far *os[NUM_HOSTS] = {
+        OS_FAT, OS_Amiga, OS_VMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS,
+        OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS,
+        OS_Acorn, OS_VFAT, OS_MVS, OS_BeOS, OS_Tandem, OS_Theos, OS_MacDarwin,
+        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+        OS_AtheOS
+    };
+    static ZCONST char Far *method[NUM_METHODS] = {
+        MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4,
+        MthdImplode, MthdToken, MthdDeflate, MthdDeflat64, MthdDCLImplode,
+        MthdBZip2, MthdLZMA, MthdTerse, MthdLZ77, MthdWavPack, MthdPPMd
+    };
+    static ZCONST char Far *dtypelng[4] = {
+        DeflNorm, DeflMax, DeflFast, DeflSFast
+    };
+
+
+/*---------------------------------------------------------------------------
+    Check whether there's any extra space inside the zipfile.  If *pEndprev is
+    zero, it's probably a signal that OS/2 extra fields are involved (with
+    unknown compressed size).  We won't worry about prepended junk here...
+  ---------------------------------------------------------------------------*/
+
+    if (G.crec.relative_offset_local_header != *pEndprev && *pEndprev > 0L) {
+        /*  GRR DEBUG
+        Info(slide, 0, ((char *)slide,
+          "  [crec.relative_offset_local_header = %lu, endprev = %lu]\n",
+          G.crec.relative_offset_local_header, *pEndprev));
+         */
+        Info(slide, 0, ((char *)slide, LoadFarString(ExtraBytesPreceding),
+          FmZofft((G.crec.relative_offset_local_header - (*pEndprev)),
+          NULL, NULL)));
+    }
+
+    /* calculate endprev for next time around (problem:  extra fields may
+     * differ in length between local and central-directory records) */
+    *pEndprev = G.crec.relative_offset_local_header + (4L + LREC_SIZE) +
+      G.crec.filename_length + G.crec.extra_field_length + G.crec.csize;
+
+/*---------------------------------------------------------------------------
+    Print out various interesting things about the compressed file.
+  ---------------------------------------------------------------------------*/
+
+    hostnum = (unsigned)(G.pInfo->hostnum);
+    hostver = (unsigned)(G.pInfo->hostver);
+    extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
+    extver = (unsigned)G.crec.version_needed_to_extract[0];
+    methid = (unsigned)G.crec.compression_method;
+    methnum = find_compr_idx(G.crec.compression_method);
+
+    (*G.message)((zvoid *)&G, (uch *)"  ", 2L, 0);  fnprint(__G);
+
+    Info(slide, 0, ((char *)slide, LoadFarString(LocalHeaderOffset),
+      FmZofft(G.crec.relative_offset_local_header, NULL, "u"),
+      FmZofft(G.crec.relative_offset_local_header, FZOFFT_HEX_DOT_WID, "X")));
+
+    if (hostnum >= NUM_HOSTS) {
+        sprintf(unkn, LoadFarString(UnknownNo),
+                (int)G.crec.version_made_by[1]);
+        varmsg_str = unkn;
+    } else {
+        varmsg_str = LoadFarStringSmall(os[hostnum]);
+#ifdef OLD_THEOS_EXTRA
+        if (hostnum == FS_VFAT_ && hostver == 20) {
+            /* entry made by old non-official THEOS port zip archive */
+            varmsg_str = LoadFarStringSmall(OS_TheosOld);
+        }
+#endif /* OLD_THEOS_EXTRA */
+    }
+    Info(slide, 0, ((char *)slide, LoadFarString(HostOS), varmsg_str));
+    Info(slide, 0, ((char *)slide, LoadFarString(EncodeSWVer), hostver/10,
+      hostver%10));
+
+    if ((extnum >= NUM_HOSTS) || (os[extnum] == NULL)) {
+        sprintf(unkn, LoadFarString(UnknownNo),
+                (int)G.crec.version_needed_to_extract[1]);
+        varmsg_str = unkn;
+    } else {
+        varmsg_str = LoadFarStringSmall(os[extnum]);
+    }
+    Info(slide, 0, ((char *)slide, LoadFarString(MinOSCompReq), varmsg_str));
+    Info(slide, 0, ((char *)slide, LoadFarString(MinSWVerReq), extver/10,
+      extver%10));
+
+    if (methnum >= NUM_METHODS) {
+        sprintf(unkn, LoadFarString(UnknownNo), G.crec.compression_method);
+        varmsg_str = unkn;
+    } else {
+        varmsg_str = LoadFarStringSmall(method[methnum]);
+    }
+    Info(slide, 0, ((char *)slide, LoadFarString(CompressMethod), varmsg_str));
+    if (methid == IMPLODED) {
+        Info(slide, 0, ((char *)slide, LoadFarString(SlideWindowSizeImplode),
+          (G.crec.general_purpose_bit_flag & 2)? '8' : '4'));
+        Info(slide, 0, ((char *)slide, LoadFarString(ShannonFanoTrees),
+          (G.crec.general_purpose_bit_flag & 4)? '3' : '2'));
+    } else if (methid == DEFLATED || methid == ENHDEFLATED) {
+        ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+
+        Info(slide, 0, ((char *)slide, LoadFarString(CompressSubtype),
+          LoadFarStringSmall(dtypelng[dnum])));
+    }
+
+    Info(slide, 0, ((char *)slide, LoadFarString(FileSecurity),
+      (G.crec.general_purpose_bit_flag & 1) ? nullStr : "not "));
+    Info(slide, 0, ((char *)slide, LoadFarString(ExtendedLocalHdr),
+      (G.crec.general_purpose_bit_flag & 8) ? "yes" : "no"));
+    /* print upper 3 bits for amusement? */
+
+    /* For printing of date & time, a "char d_t_buf[21]" is required.
+     * To save stack space, we reuse the "char attribs[22]" buffer which
+     * is not used yet.
+     */
+#   define d_t_buf attribs
+
+    zi_time(__G__ &G.crec.last_mod_dos_datetime, NULL, d_t_buf);
+    Info(slide, 0, ((char *)slide, LoadFarString(FileModDate), d_t_buf));
+#ifdef USE_EF_UT_TIME
+    if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+        G.tz_is_valid &&
+#endif
+        (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+                          G.crec.last_mod_dos_datetime, &z_utime, NULL)
+         & EB_UT_FL_MTIME))
+    {
+        TIMET_TO_NATIVE(z_utime.mtime)   /* NOP unless MSC 7.0 or Macintosh */
+        d_t_buf[0] = (char)0;               /* signal "show local time" */
+        zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
+        Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
+          d_t_buf, LoadFarStringSmall(LocalTime)));
+#ifndef NO_GMTIME
+        d_t_buf[0] = (char)1;           /* signal "show UTC (GMT) time" */
+        zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
+        Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
+          d_t_buf, LoadFarStringSmall(GMTime)));
+#endif /* !NO_GMTIME */
+    }
+#endif /* USE_EF_UT_TIME */
+
+    Info(slide, 0, ((char *)slide, LoadFarString(CRC32Value), G.crec.crc32));
+    Info(slide, 0, ((char *)slide, LoadFarString(CompressedFileSize),
+      FmZofft(G.crec.csize, NULL, "u")));
+    Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize),
+      FmZofft(G.crec.ucsize, NULL, "u")));
+    Info(slide, 0, ((char *)slide, LoadFarString(FilenameLength),
+      G.crec.filename_length));
+    Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldLength),
+      G.crec.extra_field_length));
+    Info(slide, 0, ((char *)slide, LoadFarString(FileCommentLength),
+      G.crec.file_comment_length));
+    Info(slide, 0, ((char *)slide, LoadFarString(FileDiskNum),
+      (ulg)(G.crec.disk_number_start + 1)));
+    Info(slide, 0, ((char *)slide, LoadFarString(ApparentFileType),
+      (G.crec.internal_file_attributes & 1)? "text"
+         : (G.crec.internal_file_attributes & 2)? "ebcdic"
+              : "binary"));             /* changed to accept EBCDIC */
+#ifdef ATARI
+    printf("  external file attributes (hex):                   %.8lx\n",
+      G.crec.external_file_attributes);
+#endif
+    xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
+    if (hostnum == VMS_) {
+        char   *p=attribs, *q=attribs+1;
+        int    i, j, k;
+
+        for (k = 0;  k < 12;  ++k)
+            workspace[k] = 0;
+        if (xattr & VMS_IRUSR)
+            workspace[0] = 'R';
+        if (xattr & VMS_IWUSR) {
+            workspace[1] = 'W';
+            workspace[3] = 'D';
+        }
+        if (xattr & VMS_IXUSR)
+            workspace[2] = 'E';
+        if (xattr & VMS_IRGRP)
+            workspace[4] = 'R';
+        if (xattr & VMS_IWGRP) {
+            workspace[5] = 'W';
+            workspace[7] = 'D';
+        }
+        if (xattr & VMS_IXGRP)
+            workspace[6] = 'E';
+        if (xattr & VMS_IROTH)
+            workspace[8] = 'R';
+        if (xattr & VMS_IWOTH) {
+            workspace[9] = 'W';
+            workspace[11] = 'D';
+        }
+        if (xattr & VMS_IXOTH)
+            workspace[10] = 'E';
+
+        *p++ = '(';
+        for (k = j = 0;  j < 3;  ++j) {    /* loop over groups of permissions */
+            for (i = 0;  i < 4;  ++i, ++k)  /* loop over perms within a group */
+                if (workspace[k])
+                    *p++ = workspace[k];
+            *p++ = ',';                       /* group separator */
+            if (j == 0)
+                while ((*p++ = *q++) != ',')
+                    ;                         /* system, owner perms are same */
+        }
+        *p-- = '\0';
+        *p = ')';   /* overwrite last comma */
+        Info(slide, 0, ((char *)slide, LoadFarString(VMSFileAttributes), xattr,
+          attribs));
+
+    } else if (hostnum == AMIGA_) {
+        switch (xattr & AMI_IFMT) {
+            case AMI_IFDIR:  attribs[0] = 'd';  break;
+            case AMI_IFREG:  attribs[0] = '-';  break;
+            default:         attribs[0] = '?';  break;
+        }
+        attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
+        attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
+        attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
+        attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
+        attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
+        attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
+        attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
+        attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
+        attribs[9] = 0;   /* better dlm the string */
+        Info(slide, 0, ((char *)slide, LoadFarString(AmigaFileAttributes),
+          xattr, attribs));
+
+    } else if (hostnum == THEOS_) {
+        ZCONST char Far *fpFtyp;
+
+        switch (xattr & THS_IFMT) {
+            case THS_IFLIB:  fpFtyp = TheosFTypLib;  break;
+            case THS_IFDIR:  fpFtyp = TheosFTypDir;  break;
+            case THS_IFREG:  fpFtyp = TheosFTypReg;  break;
+            case THS_IFREL:  fpFtyp = TheosFTypRel;  break;
+            case THS_IFKEY:  fpFtyp = TheosFTypKey;  break;
+            case THS_IFIND:  fpFtyp = TheosFTypInd;  break;
+            case THS_IFR16:  fpFtyp = TheosFTypR16;  break;
+            case THS_IFP16:  fpFtyp = TheosFTypP16;  break;
+            case THS_IFP32:  fpFtyp = TheosFTypP32;  break;
+            default:         fpFtyp = TheosFTypUkn;  break;
+        }
+        strcpy(attribs, LoadFarStringSmall(fpFtyp));
+        attribs[12] = (xattr & THS_INHID) ? '.' : 'H';
+        attribs[13] = (xattr & THS_IMODF) ? '.' : 'M';
+        attribs[14] = (xattr & THS_IWOTH) ? '.' : 'W';
+        attribs[15] = (xattr & THS_IROTH) ? '.' : 'R';
+        attribs[16] = (xattr & THS_IEUSR) ? '.' : 'E';
+        attribs[17] = (xattr & THS_IXUSR) ? '.' : 'X';
+        attribs[18] = (xattr & THS_IWUSR) ? '.' : 'W';
+        attribs[19] = (xattr & THS_IRUSR) ? '.' : 'R';
+        attribs[20] = 0;
+        Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
+          xattr, attribs));
+
+#ifdef OLD_THEOS_EXTRA
+    } else if (hostnum == FS_VFAT_ && hostver == 20) {
+        /* process old non-official THEOS port zip archive */
+        ZCONST char Far *fpFtyp;
+
+        switch (xattr & _THS_IFMT) {
+            case _THS_IFLIB:  fpFtyp = TheosFTypLib;  break;
+            case _THS_IFDIR:  fpFtyp = TheosFTypDir;  break;
+            case _THS_IFREG:  fpFtyp = TheosFTypReg;  break;
+            case _THS_IODRC:  fpFtyp = TheosFTypRel;  break;
+            case _THS_IOKEY:  fpFtyp = TheosFTypKey;  break;
+            case _THS_IOIND:  fpFtyp = TheosFTypInd;  break;
+            case _THS_IOPRG:  fpFtyp = TheosFTypR16;  break;
+            case _THS_IO286:  fpFtyp = TheosFTypP16;  break;
+            case _THS_IO386:  fpFtyp = TheosFTypP32;  break;
+            default:         fpFtyp = TheosFTypUkn;  break;
+        }
+        strcpy(attribs, LoadFarStringSmall(fpFtyp));
+        attribs[12] = (xattr & _THS_HIDDN) ? 'H' : '.';
+        attribs[13] = (xattr & _THS_IXOTH) ? '.' : 'X';
+        attribs[14] = (xattr & _THS_IWOTH) ? '.' : 'W';
+        attribs[15] = (xattr & _THS_IROTH) ? '.' : 'R';
+        attribs[16] = (xattr & _THS_IEUSR) ? '.' : 'E';
+        attribs[17] = (xattr & _THS_IXUSR) ? '.' : 'X';
+        attribs[18] = (xattr & _THS_IWUSR) ? '.' : 'W';
+        attribs[19] = (xattr & _THS_IRUSR) ? '.' : 'R';
+        attribs[20] = 0;
+        Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
+          xattr, attribs));
+#endif /* OLD_THEOS_EXTRA */
+
+    } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) &&
+               (hostnum != FS_NTFS_) && (hostnum != FS_VFAT_) &&
+               (hostnum != ACORN_) &&
+               (hostnum != VM_CMS_) && (hostnum != MVS_))
+    {                                 /* assume Unix-like */
+        switch ((unsigned)(xattr & UNX_IFMT)) {
+            case (unsigned)UNX_IFDIR:   attribs[0] = 'd';  break;
+            case (unsigned)UNX_IFREG:   attribs[0] = '-';  break;
+            case (unsigned)UNX_IFLNK:   attribs[0] = 'l';  break;
+            case (unsigned)UNX_IFBLK:   attribs[0] = 'b';  break;
+            case (unsigned)UNX_IFCHR:   attribs[0] = 'c';  break;
+            case (unsigned)UNX_IFIFO:   attribs[0] = 'p';  break;
+            case (unsigned)UNX_IFSOCK:  attribs[0] = 's';  break;
+            default:          attribs[0] = '?';  break;
+        }
+        attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
+        attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
+        attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
+
+        attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
+        attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
+        attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
+
+        if (xattr & UNX_IXUSR)
+            attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
+        else
+            attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';   /* S = undefined */
+        if (xattr & UNX_IXGRP)
+            attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';   /* == UNX_ENFMT */
+        else
+            attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
+        if (xattr & UNX_IXOTH)
+            attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';   /* "sticky bit" */
+        else
+            attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';   /* T = undefined */
+        attribs[10] = 0;
+
+        Info(slide, 0, ((char *)slide, LoadFarString(UnixFileAttributes), xattr,
+          attribs));
+
+    } else {
+        Info(slide, 0, ((char *)slide, LoadFarString(NonMSDOSFileAttributes),
+            G.crec.external_file_attributes >> 8));
+
+    } /* endif (hostnum: external attributes format) */
+
+    if ((xattr=(unsigned)(G.crec.external_file_attributes & 0xFF)) == 0)
+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributes),
+          xattr));
+    else if (xattr == 1)
+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesRO),
+          xattr));
+    else
+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesAlpha),
+          xattr, (xattr&1)? "rdo " : nullStr,
+          (xattr&2)? "hid " : nullStr,
+          (xattr&4)? "sys " : nullStr,
+          (xattr&8)? "lab " : nullStr,
+          (xattr&16)? "dir " : nullStr,
+          (xattr&32)? "arc " : nullStr,
+          (xattr&64)? "lnk " : nullStr,
+          (xattr&128)? "exe" : nullStr));
+
+/*---------------------------------------------------------------------------
+    Analyze the extra field, if any, and print the file comment, if any (the
+    filename has already been printed, above).  That finishes up this file
+    entry...
+  ---------------------------------------------------------------------------*/
+
+    if (G.crec.extra_field_length > 0) {
+        uch *ef_ptr = G.extra_field;
+        ush ef_len = G.crec.extra_field_length;
+        ush eb_id, eb_datalen;
+        ZCONST char Far *ef_fieldname;
+
+        if (error_in_archive > PK_WARN)   /* fatal:  can't continue */
+            /* delayed "fatal error" return from extra field reading */
+            return error_in_archive;
+        if (G.extra_field == (uch *)NULL)
+            return PK_ERR;   /* not consistent with crec length */
+
+        Info(slide, 0, ((char *)slide, LoadFarString(ExtraFields)));
+
+        while (ef_len >= EB_HEADSIZE) {
+            eb_id = makeword(&ef_ptr[EB_ID]);
+            eb_datalen = makeword(&ef_ptr[EB_LEN]);
+            ef_ptr += EB_HEADSIZE;
+            ef_len -= EB_HEADSIZE;
+
+            if (eb_datalen > (ush)ef_len) {
+                Info(slide, 0x421, ((char *)slide,
+                  LoadFarString(ExtraFieldTrunc), eb_id, eb_datalen, ef_len));
+                eb_datalen = ef_len;
+            }
+
+            switch (eb_id) {
+                case EF_PKSZ64:
+                    ef_fieldname = efPKSZ64;
+                    if ((G.crec.relative_offset_local_header
+                         & (~(zusz_t)0xFFFFFFFFL)) != 0) {
+                        /* Subtract the size of the 64bit local offset from
+                           the local e.f. size, local Z64 e.f. block has no
+                           offset; when only local offset present, the entire
+                           local PKSZ64 block is missing. */
+                        *pEndprev -= (eb_datalen == 8 ? 12 : 8);
+                    }
+                    break;
+                case EF_AV:
+                    ef_fieldname = efAV;
+                    break;
+                case EF_OS2:
+                    ef_fieldname = efOS2;
+                    break;
+                case EF_ACL:
+                    ef_fieldname = efACL;
+                    break;
+                case EF_NTSD:
+                    ef_fieldname = efNTSD;
+                    break;
+                case EF_PKVMS:
+                    ef_fieldname = efPKVMS;
+                    break;
+                case EF_IZVMS:
+                    ef_fieldname = efIZVMS;
+                    break;
+                case EF_PKW32:
+                    ef_fieldname = efPKWin32;
+                    break;
+                case EF_PKUNIX:
+                    ef_fieldname = efPKUnix;
+                    break;
+                case EF_IZUNIX:
+                    ef_fieldname = efIZUnix;
+                    if (hostnum == UNIX_ && *pEndprev > 0L)
+                        *pEndprev += 4L;  /* also have UID/GID in local copy */
+                    break;
+                case EF_IZUNIX2:
+                    ef_fieldname = efIZUnix2;
+                    if (*pEndprev > 0L)
+                        *pEndprev += 4L;  /* 4 byte UID/GID in local copy */
+                    break;
+                case EF_IZUNIX3:
+                    ef_fieldname = efIZUnix3;
+#if 0
+                    if (*pEndprev > 0L)
+                        *pEndprev += 4L;  /* 4 byte UID/GID in local copy */
+#endif
+                    break;
+                case EF_TIME:
+                    ef_fieldname = efTime;
+                    break;
+                case EF_UNIPATH:
+                    ef_fieldname = efU8Path;
+                    break;
+                case EF_UNICOMNT:
+                    ef_fieldname = efU8Commnt;
+                    break;
+                case EF_MAC3:
+                    ef_fieldname = efMac3;
+                    break;
+                case EF_JLMAC:
+                    ef_fieldname = efJLMac;
+                    break;
+                case EF_ZIPIT:
+                    ef_fieldname = efZipIt;
+                    break;
+                case EF_ZIPIT2:
+                    ef_fieldname = efZipIt2;
+                    break;
+                case EF_VMCMS:
+                    ef_fieldname = efVMCMS;
+                    break;
+                case EF_MVS:
+                    ef_fieldname = efMVS;
+                    break;
+                case EF_ATHEOS:
+                    ef_fieldname = efAtheOS;
+                    break;
+                case EF_BEOS:
+                    ef_fieldname = efBeOS;
+                    break;
+                case EF_QDOS:
+                    ef_fieldname = efQDOS;
+                    break;
+                case EF_AOSVS:
+                    ef_fieldname = efAOSVS;
+                    break;
+                case EF_SPARK:   /* from RISC OS */
+                    ef_fieldname = efSpark;
+                    break;
+                case EF_MD5:
+                    ef_fieldname = efMD5;
+                    break;
+                case EF_ASIUNIX:
+                    ef_fieldname = efASiUnix;
+                    break;
+                case EF_TANDEM:
+                    ef_fieldname = efTandem;
+                    break;
+                case EF_SMARTZIP:
+                    ef_fieldname = efSmartZip;
+                    break;
+                case EF_THEOS:
+#ifdef OLD_THEOS_EXTRA
+                case EF_THEOSO:
+#endif
+                    ef_fieldname = efTheos;
+                    break;
+                default:
+                    ef_fieldname = efUnknown;
+                    break;
+            }
+            Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldType),
+                 eb_id, LoadFarStringSmall(ef_fieldname), eb_datalen));
+
+            /* additional, field-specific information: */
+            switch (eb_id) {
+                case EF_OS2:
+                case EF_ACL:
+                    if (eb_datalen >= EB_OS2_HLEN) {
+                        if (eb_id == EF_OS2)
+                            ef_fieldname = OS2EAs;
+                        else
+                            ef_fieldname = ACLdata;
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(ef_fieldname), makelong(ef_ptr)));
+                        *pEndprev = 0L;   /* no clue about csize of local */
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_NTSD:
+                    if (eb_datalen >= EB_NTSD_C_LEN) {
+                        Info(slide, 0, ((char *)slide, LoadFarString(NTSDData),
+                          makelong(ef_ptr)));
+                        *pEndprev = 0L;   /* no clue about csize of local */
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_IZVMS:
+                    if (eb_datalen >= 8) {
+                        char *p, q[8];
+                        unsigned compr = makeword(ef_ptr+EB_IZVMS_FLGS)
+                                        & EB_IZVMS_BCMASK;
+
+                        *q = '\0';
+                        if (compr > 3)
+                            compr = 3;
+                        switch (makelong(ef_ptr)) {
+                            case 0x42414656: /* "VFAB" */
+                                p = "FAB"; break;
+                            case 0x4C4C4156: /* "VALL" */
+                                p = "XABALL"; break;
+                            case 0x43484656: /* "VFHC" */
+                                p = "XABFHC"; break;
+                            case 0x54414456: /* "VDAT" */
+                                p = "XABDAT"; break;
+                            case 0x54445256: /* "VRDT" */
+                                p = "XABRDT"; break;
+                            case 0x4F525056: /* "VPRO" */
+                                p = "XABPRO"; break;
+                            case 0x59454B56: /* "VKEY" */
+                                p = "XABKEY"; break;
+                            case 0x56534D56: /* "VMSV" */
+                                p = "version";
+                                if (eb_datalen >= 16) {
+                                    /* put termitation first, for A_TO_N() */
+                                    q[7] = '\0';
+                                    q[0] = ' ';
+                                    q[1] = '(';
+                                    strncpy(q+2,
+                                            (char *)ef_ptr+EB_IZVMS_HLEN, 4);
+                                    A_TO_N(q+2);
+                                    q[6] = ')';
+                                }
+                                break;
+                            default:
+                                p = "unknown";
+                        }
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(izVMSdata),
+                          LoadFarStringSmall(izVMScomp[compr]),
+                          makeword(ef_ptr+EB_IZVMS_UCSIZ), p, q));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_TIME:
+                    if (eb_datalen > 0) {
+                        char types[80];
+                        int num = 0, len;
+
+                        *types = '\0';
+                        if (*ef_ptr & 1) {
+                            strcpy(types, LoadFarString(UTmodification));
+                            ++num;
+                        }
+                        if (*ef_ptr & 2) {
+                            len = strlen(types);
+                            if (num)
+                                types[len++] = '/';
+                            strcpy(types+len, LoadFarString(UTaccess));
+                            ++num;
+                            if (*pEndprev > 0L)
+                                *pEndprev += 4L;
+                        }
+                        if (*ef_ptr & 4) {
+                            len = strlen(types);
+                            if (num)
+                                types[len++] = '/';
+                            strcpy(types+len, LoadFarString(UTcreation));
+                            ++num;
+                            if (*pEndprev > 0L)
+                                *pEndprev += 4L;
+                        }
+                        if (num > 0)
+                            Info(slide, 0, ((char *)slide,
+                              LoadFarString(UTdata), types,
+                              num == 1? nullStr : PlurSufx));
+                    }
+                    break;
+                case EF_UNIPATH:
+                case EF_UNICOMNT:
+                    if (eb_datalen >= 5) {
+                        unsigned i, n;
+                        ulg name_crc = makelong(ef_ptr+1);
+
+                        if (eb_datalen <= 29) {
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(U8PthCmnComplete),
+                                 (unsigned)ef_ptr[0], name_crc));
+                            n = eb_datalen;
+                        } else {
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(U8PthCmnF24),
+                                 (unsigned)ef_ptr[0], name_crc));
+                            n = 29;
+                        }
+                        for (i = 5;  i < n;  ++i)
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(efFormat), ef_ptr[i]));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_MAC3:
+                    if (eb_datalen >= EB_MAC3_HLEN) {
+                        ulg eb_uc = makelong(ef_ptr);
+                        unsigned mac3_flgs = makeword(ef_ptr+EB_FLGS_OFFS);
+                        unsigned eb_is_uc = mac3_flgs & EB_M3_FL_UNCMPR;
+
+                        Info(slide, 0, ((char *)slide, LoadFarString(Mac3data),
+                          eb_uc, eb_is_uc ? "un" : nullStr));
+                        if (eb_is_uc) {
+                            if (*pEndprev > 0L)
+                                *pEndprev += makelong(ef_ptr);
+                        } else {
+                            *pEndprev = 0L; /* no clue about csize of local */
+                        }
+
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(MacOSMAC3flags),
+                          LoadFarStringSmall(mac3_flgs & EB_M3_FL_DATFRK ?
+                                             MacOS_DF : MacOS_RF),
+                          (mac3_flgs & EB_M3_FL_TIME64 ? 64 : 32)));
+                        zi_showMacTypeCreator(__G__ &ef_ptr[6]);
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_ZIPIT2:
+                    if (eb_datalen >= 5 &&
+                        makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
+
+                        if (eb_datalen >= 12) {
+                            zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+                        }
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_ZIPIT:
+                    if (eb_datalen >= 5 &&
+                        makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
+                        unsigned fnlen = ef_ptr[4];
+
+                        if ((unsigned)eb_datalen >= fnlen + (5 + 8)) {
+                            uch nullchar = ef_ptr[fnlen+5];
+
+                            ef_ptr[fnlen+5] = '\0'; /* terminate filename */
+                            A_TO_N(ef_ptr+5);
+                            Info(slide, 0, ((char *)slide,
+                              LoadFarString(ZipItFname), (char *)ef_ptr+5));
+                            ef_ptr[fnlen+5] = nullchar;
+                            zi_showMacTypeCreator(__G__ &ef_ptr[fnlen+5]);
+                        }
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_JLMAC:
+                    if (eb_datalen >= 40 &&
+                        makelong(ef_ptr) == 0x45454C4A /* "JLEE" */)
+                    {
+                        zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(MacOSJLEEflags),
+                          LoadFarStringSmall(ef_ptr[31] & 1 ?
+                                             MacOS_DF : MacOS_RF)));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_SMARTZIP:
+                    if ((eb_datalen == EB_SMARTZIP_HLEN) &&
+                        makelong(ef_ptr) == 0x70695A64 /* "dZip" */) {
+                        char filenameBuf[32];
+                        zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+                        memcpy(filenameBuf, &ef_ptr[33], 31);
+                        filenameBuf[ef_ptr[32]] = '\0';
+                        A_TO_N(filenameBuf);
+                        Info(slide, 0, ((char *)slide,
+                             LoadFarString(ZipItFname), filenameBuf));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+#ifdef CMS_MVS
+                case EF_VMCMS:
+                case EF_MVS:
+                    {
+                        char type[100];
+
+                        Info(slide, 0, ((char *)slide,
+                             LoadFarString(VmMvsExtraField),
+                             (getVMMVSexfield(type, ef_ptr-EB_HEADSIZE,
+                             (unsigned)eb_datalen) > 0)?
+                             type : LoadFarStringSmall(VmMvsInvalid)));
+                    }
+                    break;
+#endif /* CMS_MVS */
+                case EF_ATHEOS:
+                case EF_BEOS:
+                    if (eb_datalen >= EB_BEOS_HLEN) {
+                        ulg eb_uc = makelong(ef_ptr);
+                        unsigned eb_is_uc =
+                          *(ef_ptr+EB_FLGS_OFFS) & EB_BE_FL_UNCMPR;
+
+                        if (eb_id == EF_ATHEOS)
+                            ef_fieldname = AtheOSdata;
+                        else
+                            ef_fieldname = BeOSdata;
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(ef_fieldname),
+                          eb_uc, eb_is_uc ? "un" : nullStr));
+                        if (eb_is_uc) {
+                            if (*pEndprev > 0L)
+                                *pEndprev += makelong(ef_ptr);
+                        } else {
+                            *pEndprev = 0L; /* no clue about csize of local */
+                        }
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_QDOS:
+                    if (eb_datalen >= 4) {
+                        Info(slide, 0, ((char *)slide, LoadFarString(QDOSdata),
+                          ef_ptr[0], ef_ptr[1], ef_ptr[2], ef_ptr[3]));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_AOSVS:
+                    if (eb_datalen >= 5) {
+                        Info(slide, 0, ((char *)slide, LoadFarString(AOSVSdata),
+                          ((int)(uch)ef_ptr[4])/10, ((int)(uch)ef_ptr[4])%10));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_TANDEM:
+                    if (eb_datalen == 20) {
+                        unsigned type, code;
+
+                        type = (ef_ptr[18] & 0x60) >> 5;
+                        code = makeword(ef_ptr);
+                        /* Arrg..., Tandem e.f. uses BigEndian byte-order */
+                        code = ((code << 8) & 0xff00) | ((code >> 8) & 0x00ff);
+                        if (type == NSK_UNSTRUCTURED) {
+                            if (code == NSK_EDITFILECODE)
+                                type = 4;
+                            else if (code == NSK_OBJECTFILECODE)
+                                type = 5;
+                        }
+                        Info(slide, 0, ((char *)slide,
+                          LoadFarString(Tandemdata),
+                          LoadFarStringSmall(TandemFileformat[type]),
+                          code));
+                    } else {
+                        goto ef_default_display;
+                    }
+                    break;
+                case EF_MD5:
+                    if (eb_datalen >= 19) {
+                        char md5[33];
+                        int i;
+
+                        for (i = 0;  i < 16;  ++i)
+                            sprintf(&md5[i<<1], "%02x", ef_ptr[15-i]);
+                        md5[32] = '\0';
+                        Info(slide, 0, ((char *)slide, LoadFarString(MD5data),
+                          md5));
+                        break;
+                    }   /* else: fall through !! */
+                default:
+ef_default_display:
+                    if (eb_datalen > 0) {
+                        unsigned i, n;
+
+                        if (eb_datalen <= 24) {
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(ColonIndent)));
+                            n = eb_datalen;
+                        } else {
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(First20)));
+                            n = 20;
+                        }
+                        for (i = 0;  i < n;  ++i)
+                            Info(slide, 0, ((char *)slide,
+                                 LoadFarString(efFormat), ef_ptr[i]));
+                    }
+                    break;
+            }
+            (*G.message)((zvoid *)&G, (uch *)".", 1L, 0);
+
+            ef_ptr += eb_datalen;
+            ef_len -= eb_datalen;
+        }
+        (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+    }
+
+    /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */
+    if ((xattr = (unsigned)((G.crec.external_file_attributes & 0xC000) >> 12))
+        & 8)
+    {
+        if (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)
+        {
+            Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
+              "is", EF_IZUNIX, LoadFarStringSmall(efIZUnix),
+              (unsigned)(xattr&12), (xattr&4)? efIZuid : efIZnouid));
+            if (*pEndprev > 0L)
+                *pEndprev += (ulg)(xattr&12);
+        }
+        else if (hostnum == FS_FAT_ && !(xattr&4))
+            Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
+              "may be", EF_IZUNIX, LoadFarStringSmall(efIZUnix), 8,
+              efIZnouid));
+    }
+
+    if (!G.crec.file_comment_length)
+        Info(slide, 0, ((char *)slide, LoadFarString(NoFileComment)));
+    else {
+        Info(slide, 0, ((char *)slide, LoadFarString(FileCommBegin)));
+        if ((error = do_string(__G__ G.crec.file_comment_length, DISPL_8)) !=
+            PK_COOL)
+        {
+            error_in_archive = error;   /* might be warning */
+            if (error > PK_WARN)   /* fatal */
+                return error;
+        }
+        Info(slide, 0, ((char *)slide, LoadFarString(FileCommEnd)));
+    }
+
+    return error_in_archive;
+
+} /* end function zi_long() */
+
+
+
+
+
+/*************************/
+/*  Function zi_short()  */
+/*************************/
+
+static int zi_short(__G)   /* return PK-type error code */
+    __GDEF
+{
+#ifdef USE_EF_UT_TIME
+    iztimes     z_utime;
+    time_t      *z_modtim;
+#endif
+    int         k, error, error_in_archive=PK_COOL;
+    unsigned    hostnum, hostver, methid, methnum, xattr;
+    char        *p, workspace[12], attribs[17];
+    char        methbuf[5];
+    static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
+    static ZCONST char Far os[NUM_HOSTS+1][4] = {
+        "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
+        "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk",
+        "ths", "osx", "???", "???", "???", "???", "???", "???", "???",
+        "???", "???", "???", "ath", "???"
+    };
+#ifdef OLD_THEOS_EXTRA
+    static ZCONST char Far os_TheosOld[] = "tho";
+#endif
+    static ZCONST char Far method[NUM_METHODS+1][5] = {
+        "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn",
+        "def#", "d64#", "dcli", "bzp2", "lzma", "ters", "lz77", "wavp",
+        "ppmd", "u###"
+    };
+
+
+/*---------------------------------------------------------------------------
+    Print out various interesting things about the compressed file.
+  ---------------------------------------------------------------------------*/
+
+    methid = (unsigned)(G.crec.compression_method);
+    methnum = find_compr_idx(G.crec.compression_method);
+    hostnum = (unsigned)(G.pInfo->hostnum);
+    hostver = (unsigned)(G.pInfo->hostver);
+/*
+    extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
+    extver = (unsigned)G.crec.version_needed_to_extract[0];
+ */
+
+    zfstrcpy(methbuf, method[methnum]);
+    if (methid == IMPLODED) {
+        methbuf[1] = (char)((G.crec.general_purpose_bit_flag & 2)? '8' : '4');
+        methbuf[3] = (char)((G.crec.general_purpose_bit_flag & 4)? '3' : '2');
+    } else if (methid == DEFLATED || methid == ENHDEFLATED) {
+        ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+        methbuf[3] = dtype[dnum];
+    } else if (methnum >= NUM_METHODS) {   /* unknown */
+        /* 2016-12-05 SMS.
+         * https://launchpad.net/bugs/1643750
+         * 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);
+        }
+
+    }
+
+    for (k = 0;  k < 15;  ++k)
+        attribs[k] = ' ';
+    attribs[15] = 0;
+
+    xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
+    switch (hostnum) {
+        case VMS_:
+            {   int    i, j;
+
+                for (k = 0;  k < 12;  ++k)
+                    workspace[k] = 0;
+                if (xattr & VMS_IRUSR)
+                    workspace[0] = 'R';
+                if (xattr & VMS_IWUSR) {
+                    workspace[1] = 'W';
+                    workspace[3] = 'D';
+                }
+                if (xattr & VMS_IXUSR)
+                    workspace[2] = 'E';
+                if (xattr & VMS_IRGRP)
+                    workspace[4] = 'R';
+                if (xattr & VMS_IWGRP) {
+                    workspace[5] = 'W';
+                    workspace[7] = 'D';
+                }
+                if (xattr & VMS_IXGRP)
+                  workspace[6] = 'E';
+                if (xattr & VMS_IROTH)
+                    workspace[8] = 'R';
+                if (xattr & VMS_IWOTH) {
+                    workspace[9] = 'W';
+                    workspace[11] = 'D';
+                }
+                if (xattr & VMS_IXOTH)
+                    workspace[10] = 'E';
+
+                p = attribs;
+                for (k = j = 0;  j < 3;  ++j) {     /* groups of permissions */
+                    for (i = 0;  i < 4;  ++i, ++k)  /* perms within a group */
+                        if (workspace[k])
+                            *p++ = workspace[k];
+                    *p++ = ',';                     /* group separator */
+                }
+                *--p = ' ';   /* overwrite last comma */
+                if ((p - attribs) < 12)
+                    sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+            }
+            break;
+
+        case AMIGA_:
+            switch (xattr & AMI_IFMT) {
+                case AMI_IFDIR:  attribs[0] = 'd';  break;
+                case AMI_IFREG:  attribs[0] = '-';  break;
+                default:         attribs[0] = '?';  break;
+            }
+            attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
+            attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
+            attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
+            attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
+            attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
+            attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
+            attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
+            attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+            break;
+
+        case THEOS_:
+            switch (xattr & THS_IFMT) {
+                case THS_IFLIB: *attribs = 'L'; break;
+                case THS_IFDIR: *attribs = 'D'; break;
+                case THS_IFCHR: *attribs = 'C'; break;
+                case THS_IFREG: *attribs = 'S'; break;
+                case THS_IFREL: *attribs = 'R'; break;
+                case THS_IFKEY: *attribs = 'K'; break;
+                case THS_IFIND: *attribs = 'I'; break;
+                case THS_IFR16: *attribs = 'P'; break;
+                case THS_IFP16: *attribs = '2'; break;
+                case THS_IFP32: *attribs = '3'; break;
+                default:        *attribs = '?'; break;
+            }
+            attribs[1] = (xattr & THS_INHID) ? '.' : 'H';
+            attribs[2] = (xattr & THS_IMODF) ? '.' : 'M';
+            attribs[3] = (xattr & THS_IWOTH) ? '.' : 'W';
+            attribs[4] = (xattr & THS_IROTH) ? '.' : 'R';
+            attribs[5] = (xattr & THS_IEUSR) ? '.' : 'E';
+            attribs[6] = (xattr & THS_IXUSR) ? '.' : 'X';
+            attribs[7] = (xattr & THS_IWUSR) ? '.' : 'W';
+            attribs[8] = (xattr & THS_IRUSR) ? '.' : 'R';
+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+            break;
+
+        case FS_VFAT_:
+#ifdef OLD_THEOS_EXTRA
+            if (hostver == 20) {
+                switch (xattr & _THS_IFMT) {
+                    case _THS_IFLIB: *attribs = 'L'; break;
+                    case _THS_IFDIR: *attribs = 'd'; break;
+                    case _THS_IFCHR: *attribs = 'c'; break;
+                    case _THS_IFREG: *attribs = 'S'; break;
+                    case _THS_IODRC: *attribs = 'D'; break;
+                    case _THS_IOKEY: *attribs = 'K'; break;
+                    case _THS_IOIND: *attribs = 'I'; break;
+                    case _THS_IOPRG: *attribs = 'P'; break;
+                    case _THS_IO286: *attribs = '2'; break;
+                    case _THS_IO386: *attribs = '3'; break;
+                    default:         *attribs = '?'; break;
+                }
+                attribs[1] = (xattr & _THS_HIDDN) ? 'H' : '.';
+                attribs[2] = (xattr & _THS_IXOTH) ? '.' : 'X';
+                attribs[3] = (xattr & _THS_IWOTH) ? '.' : 'W';
+                attribs[4] = (xattr & _THS_IROTH) ? '.' : 'R';
+                attribs[5] = (xattr & _THS_IEUSR) ? '.' : 'E';
+                attribs[6] = (xattr & _THS_IXUSR) ? '.' : 'X';
+                attribs[7] = (xattr & _THS_IWUSR) ? '.' : 'W';
+                attribs[8] = (xattr & _THS_IRUSR) ? '.' : 'R';
+                sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+                break;
+            } /* else: fall through! */
+#endif /* OLD_THEOS_EXTRA */
+
+        case FS_FAT_:
+        case FS_HPFS_:
+        case FS_NTFS_:
+        case VM_CMS_:
+        case MVS_:
+        case ACORN_:
+            if (hostnum != FS_FAT_ ||
+                (unsigned)(xattr & 0700) !=
+                 ((unsigned)0400 |
+                  ((unsigned)!(G.crec.external_file_attributes & 1) << 7) |
+                  ((unsigned)(G.crec.external_file_attributes & 0x10) << 2))
+               )
+            {
+                xattr = (unsigned)(G.crec.external_file_attributes & 0xFF);
+                sprintf(attribs, ".r.-...     %u.%u", hostver/10, hostver%10);
+                attribs[2] = (xattr & 0x01)? '-' : 'w';
+                attribs[5] = (xattr & 0x02)? 'h' : '-';
+                attribs[6] = (xattr & 0x04)? 's' : '-';
+                attribs[4] = (xattr & 0x20)? 'a' : '-';
+                if (xattr & 0x10) {
+                    attribs[0] = 'd';
+                    attribs[3] = 'x';
+                } else
+                    attribs[0] = '-';
+                if (IS_VOLID(xattr))
+                    attribs[0] = 'V';
+                else if ((p = MBSRCHR(G.filename, '.')) != (char *)NULL) {
+                    ++p;
+                    if (STRNICMP(p, "com", 3) == 0 ||
+                        STRNICMP(p, "exe", 3) == 0 ||
+                        STRNICMP(p, "btm", 3) == 0 ||
+                        STRNICMP(p, "cmd", 3) == 0 ||
+                        STRNICMP(p, "bat", 3) == 0)
+                        attribs[3] = 'x';
+                }
+                break;
+            } /* else: fall through! */
+
+        default:   /* assume Unix-like */
+            switch ((unsigned)(xattr & UNX_IFMT)) {
+                case (unsigned)UNX_IFDIR:   attribs[0] = 'd';  break;
+                case (unsigned)UNX_IFREG:   attribs[0] = '-';  break;
+                case (unsigned)UNX_IFLNK:   attribs[0] = 'l';  break;
+                case (unsigned)UNX_IFBLK:   attribs[0] = 'b';  break;
+                case (unsigned)UNX_IFCHR:   attribs[0] = 'c';  break;
+                case (unsigned)UNX_IFIFO:   attribs[0] = 'p';  break;
+                case (unsigned)UNX_IFSOCK:  attribs[0] = 's';  break;
+                default:          attribs[0] = '?';  break;
+            }
+            attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
+            attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
+            attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
+            attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
+            attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
+            attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
+
+            if (xattr & UNX_IXUSR)
+                attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
+            else
+                attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';  /* S==undefined */
+            if (xattr & UNX_IXGRP)
+                attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';  /* == UNX_ENFMT */
+            else
+                /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';  real 4.3BSD */
+                attribs[6] = (xattr & UNX_ISGID)? 'S' : '-';  /* SunOS 4.1.x */
+            if (xattr & UNX_IXOTH)
+                attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';  /* "sticky bit" */
+            else
+                attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';  /* T==undefined */
+
+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+            break;
+
+    } /* end switch (hostnum: external attributes format) */
+
+#ifdef OLD_THEOS_EXTRA
+    Info(slide, 0, ((char *)slide, "%s %s %s ", attribs,
+      LoadFarStringSmall(((hostnum == FS_VFAT_ && hostver == 20) ?
+                          os_TheosOld :
+                          os[hostnum])),
+      FmZofft(G.crec.ucsize, "8", "u")));
+#else
+    Info(slide, 0, ((char *)slide, "%s %s %s ", attribs,
+      LoadFarStringSmall(os[hostnum]),
+      FmZofft(G.crec.ucsize, "8", "u")));
+#endif
+    Info(slide, 0, ((char *)slide, "%c",
+      (G.crec.general_purpose_bit_flag & 1)?
+      ((G.crec.internal_file_attributes & 1)? 'T' : 'B') :  /* encrypted */
+      ((G.crec.internal_file_attributes & 1)? 't' : 'b'))); /* plaintext */
+    k = (G.crec.extra_field_length ||
+         /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */
+         ((G.crec.external_file_attributes & 0x8000) &&
+          (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)));
+    Info(slide, 0, ((char *)slide, "%c", k?
+      ((G.crec.general_purpose_bit_flag & 8)? 'X' : 'x') :  /* extra field */
+      ((G.crec.general_purpose_bit_flag & 8)? 'l' : '-'))); /* no extra field */
+      /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */
+
+    if (uO.lflag == 4) {
+        zusz_t csiz = G.crec.csize;
+
+        if (G.crec.general_purpose_bit_flag & 1)
+            csiz -= 12;    /* if encrypted, don't count encryption header */
+        Info(slide, 0, ((char *)slide, "%3d%%",
+          (ratio(G.crec.ucsize,csiz)+5)/10));
+    } else if (uO.lflag == 5)
+        Info(slide, 0, ((char *)slide, " %s",
+          FmZofft(G.crec.csize, "8", "u")));
+
+    /* For printing of date & time, a "char d_t_buf[16]" is required.
+     * To save stack space, we reuse the "char attribs[16]" buffer whose
+     * content is no longer needed.
+     */
+#   define d_t_buf attribs
+#ifdef USE_EF_UT_TIME
+    z_modtim = G.extra_field &&
+#ifdef IZ_CHECK_TZ
+               G.tz_is_valid &&
+#endif
+               (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+                                 G.crec.last_mod_dos_datetime, &z_utime, NULL)
+                & EB_UT_FL_MTIME)
+              ? &z_utime.mtime : NULL;
+    TIMET_TO_NATIVE(z_utime.mtime)     /* NOP unless MSC 7.0 or Macintosh */
+    d_t_buf[0] = (char)0;              /* signal "show local time" */
+#else
+#   define z_modtim NULL
+#endif
+    Info(slide, 0, ((char *)slide, " %s %s ", methbuf,
+      zi_time(__G__ &G.crec.last_mod_dos_datetime, z_modtim, d_t_buf)));
+    fnprint(__G);
+
+/*---------------------------------------------------------------------------
+    Skip the file comment, if any (the filename has already been printed,
+    above).  That finishes up this file entry...
+  ---------------------------------------------------------------------------*/
+
+    SKIP_(G.crec.file_comment_length)
+
+    return error_in_archive;
+
+} /* end function zi_short() */
+
+
+
+
+
+/**************************************/
+/*  Function zi_showMacTypeCreator()  */
+/**************************************/
+
+static void zi_showMacTypeCreator(__G__ ebfield)
+    __GDEF
+    uch *ebfield;
+{
+    /* not every Type / Creator character is printable */
+    if (isprint(native(ebfield[0])) && isprint(native(ebfield[1])) &&
+        isprint(native(ebfield[2])) && isprint(native(ebfield[3])) &&
+        isprint(native(ebfield[4])) && isprint(native(ebfield[5])) &&
+        isprint(native(ebfield[6])) && isprint(native(ebfield[7]))) {
+       Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata),
+            native(ebfield[0]), native(ebfield[1]),
+            native(ebfield[2]), native(ebfield[3]),
+            native(ebfield[4]), native(ebfield[5]),
+            native(ebfield[6]), native(ebfield[7])));
+    } else {
+       Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata1),
+            (((ulg)ebfield[0]) << 24) +
+            (((ulg)ebfield[1]) << 16) +
+            (((ulg)ebfield[2]) << 8)  +
+            ((ulg)ebfield[3]),
+            (((ulg)ebfield[4]) << 24) +
+            (((ulg)ebfield[5]) << 16) +
+            (((ulg)ebfield[6]) << 8)  +
+            ((ulg)ebfield[7])));
+    }
+} /* end function zi_showMacTypeCreator() */
+
+
+
+
+
+/************************/
+/*  Function zi_time()  */
+/************************/
+
+static char *zi_time(__G__ datetimez, modtimez, d_t_str)
+    __GDEF
+    ZCONST ulg *datetimez;
+    ZCONST time_t *modtimez;
+    char *d_t_str;
+{
+    unsigned yr, mo, dy, hh, mm, ss;
+    char monthbuf[4];
+    ZCONST char *monthstr;
+    static ZCONST char Far month[12][4] = {
+        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    };
+#ifdef USE_EF_UT_TIME
+    struct tm *t;
+#endif
+
+
+
+/*---------------------------------------------------------------------------
+    Convert the file-modification date and time info to a string of the form
+    "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending
+    on values of lflag and T_flag.  If using Unix-time extra fields, convert
+    to local time or not, depending on value of first character in d_t_str[].
+  ---------------------------------------------------------------------------*/
+
+#ifdef USE_EF_UT_TIME
+    if (modtimez != NULL) {
+#ifndef NO_GMTIME
+        /* check for our secret message from above... */
+        t = (d_t_str[0] == (char)1)? gmtime(modtimez) : localtime(modtimez);
+#else
+        t = localtime(modtimez);
+#endif
+        if (uO.lflag > 9 && t == (struct tm *)NULL)
+            /* time conversion error in verbose listing format,
+             * return string with '?' instead of data
+             */
+            return (strcpy(d_t_str, LoadFarString(lngYMDHMSTimeError)));
+    } else
+        t = (struct tm *)NULL;
+    if (t != (struct tm *)NULL) {
+        mo = (unsigned)(t->tm_mon + 1);
+        dy = (unsigned)(t->tm_mday);
+        yr = (unsigned)(t->tm_year);
+
+        hh = (unsigned)(t->tm_hour);
+        mm = (unsigned)(t->tm_min);
+        ss = (unsigned)(t->tm_sec);
+    } else
+#endif /* USE_EF_UT_TIME */
+    {
+        yr = ((unsigned)(*datetimez >> 25) & 0x7f) + 80;
+        mo = ((unsigned)(*datetimez >> 21) & 0x0f);
+        dy = ((unsigned)(*datetimez >> 16) & 0x1f);
+
+        hh = (((unsigned)*datetimez >> 11) & 0x1f);
+        mm = (((unsigned)*datetimez >> 5) & 0x3f);
+        ss = (((unsigned)*datetimez << 1) & 0x3e);
+    }
+
+    if (mo == 0 || mo > 12) {
+        sprintf(monthbuf, LoadFarString(BogusFmt), mo);
+        monthstr = monthbuf;
+    } else
+        monthstr = LoadFarStringSmall(month[mo-1]);
+
+    if (uO.lflag > 9)   /* verbose listing format */
+        sprintf(d_t_str, LoadFarString(lngYMDHMSTime), yr+1900, monthstr, dy,
+          hh, mm, ss);
+    else if (uO.T_flag)
+        sprintf(d_t_str, LoadFarString(DecimalTime), yr+1900, mo, dy,
+          hh, mm, ss);
+    else   /* was:  if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
+        sprintf(d_t_str, LoadFarString(shtYMDHMTime), yr%100, monthstr, dy,
+          hh, mm);
+
+    return d_t_str;
+
+} /* end function zi_time() */
+
+#endif /* !NO_ZIPINFO */
Index: unzip/create-6.0-slackware-patch/unzip60-new
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new	(nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new	(revision 5)

Property changes on: unzip/create-6.0-slackware-patch/unzip60-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch
===================================================================
--- unzip/create-6.0-slackware-patch	(nonexistent)
+++ unzip/create-6.0-slackware-patch	(revision 5)

Property changes on: unzip/create-6.0-slackware-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/patches/README
===================================================================
--- unzip/patches/README	(nonexistent)
+++ unzip/patches/README	(revision 5)
@@ -0,0 +1,59 @@
+
+/* begin *
+
+   Patches from Slackware:
+   ======================
+
+     Various patches:
+     ---------------
+       unzip-6.0-bzip2-configure.patch.gz
+       unzip-6.0-exec-shield.patch.gz
+       unzip-6.0-close.patch.gz
+       unzip-6.0-attribs-overflow.patch.gz
+
+     RH specific:
+     -----------
+       unzip-6.0-manpage-fix.patch.gz
+       unzip-6.0-fix-recmatch.patch.gz
+       unzip-6.0-symlink.patch.gz
+       unzip-6.0-caseinsensitive.patch.gz
+       unzip-6.0-format-secure.patch.gz
+       unzip-6.0-valgrind.patch.gz
+       unzip-6.0-x-option.patch.gz
+       unzip-6.0-overflow.patch.gz
+       unzip-6.0-cve-2014-8139.patch.gz
+       unzip-6.0-cve-2014-8140.patch.gz
+       unzip-6.0-cve-2014-8141.patch.gz
+       unzip-6.0-overflow-long-fsize.patch.gz
+       unzip-6.0-heap-overflow-infloop.patch.gz
+       unzip-6.0-alt-iconv-utf8.patch.gz
+       unzip-6.0-alt-iconv-utf8-print.patch.gz
+       0001-Fix-CVE-2016-9844-rhbz-1404283.patch.gz
+       unzip-6.0-timestamp.patch.gz
+       unzip-6.0-cve-2018-1000035-heap-based-overflow.patch.gz
+       unzip-6.0-cve-2018-18384.patch.gz
+       unzip-6.0-COVSCAN-fix-unterminated-string.patch.gz
+
+     Arch Linux:
+     -----------
+       unzip-6.0_CVE-2021-4217.patch
+       28-cve-2022-0529-and-cve-2022-0530.patch
+
+     Changed files:
+     =============
+       unzip60/crc_i386.S
+       unzip60/crypt.c
+       unzip60/extract.c
+       unzip60/fileio.c
+       unzip60/list.c
+       unzip60/man/unzip.1
+       unzip60/match.c
+       unzip60/process.c
+       unzip60/unix/configure
+       unzip60/unix/unix.c
+       unzip60/unix/unxcfg.h
+       unzip60/unzip.c
+       unzip60/unzpriv.h
+       unzip60/zipinfo.c
+
+ * end */
Index: unzip/patches
===================================================================
--- unzip/patches	(nonexistent)
+++ unzip/patches	(revision 5)

Property changes on: unzip/patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip
===================================================================
--- unzip	(nonexistent)
+++ unzip	(revision 5)

Property changes on: unzip
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/Makefile
===================================================================
--- zip/Makefile	(nonexistent)
+++ zip/Makefile	(revision 5)
@@ -0,0 +1,65 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/infozip/zip30
+
+versions    = 30
+pkgname     = zip
+suffix      = tar.gz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname), $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+patches     = $(CURDIR)/patches/zip-3.0-curdir.patch
+patches    += $(CURDIR)/patches/zip-3.0-exec-shield.patch
+patches    += $(CURDIR)/patches/zip-3.0-format-security.patch
+patches    += $(CURDIR)/patches/zip-3.0-man-pages.patch
+patches    += $(CURDIR)/patches/zip-3.0-zipnote.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-3.0-curdir-patch          ; ./create.patch.sh ) ; \
+	 ( cd create-3.0-exec-shield-patch     ; ./create.patch.sh ) ; \
+	 ( cd create-3.0-format-security-patch ; ./create.patch.sh ) ; \
+	 ( cd create-3.0-man-pages-patch       ; ./create.patch.sh ) ; \
+	 ( cd create-3.0-zipnote-patch         ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: zip/create-3.0-curdir-patch/create.patch.sh
===================================================================
--- zip/create-3.0-curdir-patch/create.patch.sh	(nonexistent)
+++ zip/create-3.0-curdir-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr  zip${version}-orig  zip${version} > zip-${VERSION}-curdir.patch
+
+mv zip-${VERSION}-curdir.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig

Property changes on: zip/create-3.0-curdir-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-curdir-patch/file.list
===================================================================
--- zip/create-3.0-curdir-patch/file.list	(nonexistent)
+++ zip/create-3.0-curdir-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+zip30/util.c
Index: zip/create-3.0-curdir-patch/zip30-new/util.c
===================================================================
--- zip/create-3.0-curdir-patch/zip30-new/util.c	(nonexistent)
+++ zip/create-3.0-curdir-patch/zip30-new/util.c	(revision 5)
@@ -0,0 +1,1452 @@
+/*
+  util.c
+
+  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+/*
+ *  util.c by Mark Adler.
+ */
+#define __UTIL_C
+
+#include "zip.h"
+#include "ebcdic.h"
+#include <ctype.h>
+
+#ifdef MSDOS16
+#  include <dos.h>
+#endif
+
+#ifdef NO_MKTIME
+#  ifndef IZ_MKTIME_ONLY
+#    define IZ_MKTIME_ONLY      /* only mktime() related code is pulled in */
+#  endif
+#  include "timezone.c"
+#endif
+
+uch upper[256], lower[256];
+/* Country-dependent case map table */
+
+
+#ifndef UTIL /* UTIL picks out namecmp code (all utils) */
+
+/* RISC OS uses # as its single-character wildcard */
+#ifdef RISCOS
+#  define WILDCHR_SINGLE '#'
+#  define WILDCHR_MULTI  '*'
+#  define DIRSEP_CHR '.'
+#endif
+
+#ifdef VMS
+#  define WILDCHR_SINGLE '%'
+#  define WILDCHR_MULTI  '*'
+#  define DIRSEP_CHR '.'
+#endif
+
+#ifndef WILDCHR_SINGLE
+#  define WILDCHR_SINGLE '?'
+#endif
+#ifndef WILDCHR_MULTI
+#  define WILDCHR_MULTI '*'
+#endif
+#ifndef DIRSEP_CHR
+#  define DIRSEP_CHR '/'
+#endif
+
+/* Local functions */
+local int recmatch OF((ZCONST char *, ZCONST char *, int));
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+  local long recmatchw OF((ZCONST wchar_t *, ZCONST wchar_t *, int));
+#endif
+local int count_args OF((char *s));
+
+#ifdef MSDOS16
+  local unsigned ident OF((unsigned chr));
+#endif
+
+#ifndef HAVE_FSEEKABLE
+
+/* 2004-11-12 SMS.
+   Changed to use z*o() functions, and ftell() test from >= 0 to != -1.
+   This solves problems with negative 32-bit offsets, even on small-file
+   products.
+*/
+int fseekable( fp)
+FILE *fp;
+{
+    zoff_t x;
+
+    return (fp == NULL ||
+     ((zfseeko( fp, ((zoff_t) -1), SEEK_CUR) == 0) &&   /* Seek ok. */
+     ((x = zftello( fp)) != ((zoff_t) -1)) &&           /* Tell ok. */
+     (zfseeko( fp, ((zoff_t) 1), SEEK_CUR) == 0) &&     /* Seek ok. */
+     (zftello( fp) == x+ 1)));                          /* Tells agree. */
+}
+#endif /* HAVE_FSEEKABLE */
+
+
+char *isshexp(p)
+char *p;                /* candidate sh expression */
+/* If p is a sh expression, a pointer to the first special character is
+   returned.  Otherwise, NULL is returned. */
+{
+  for (; *p; INCSTR(p))
+    if (*p == '\\' && *(p+1))
+      p++;
+#ifdef VMS
+    else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI)
+#else /* !VMS */
+    else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI || *p == '[')
+#endif /* ?VMS */
+      return p;
+  return NULL;
+}
+
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+wchar_t *isshexpw(pw)
+  wchar_t *pw;          /* candidate sh expression */
+/* If pw is a sh expression, a pointer to the first special character is
+   returned.  Otherwise, NULL is returned. */
+{
+  for (; *pw; pw++)
+    if (*pw == (wchar_t)'\\' && *(pw+1))
+      pw++;
+    else if (*pw == (wchar_t)WILDCHR_SINGLE || *pw == (wchar_t)WILDCHR_MULTI ||
+             *pw == (wchar_t)'[')
+      return pw;
+  return NULL;
+}
+
+# endif
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+local long recmatchw(pw, sw, cs)
+ZCONST wchar_t *pw;     /* sh pattern to match */
+ZCONST wchar_t *sw;     /* string to match it to */
+int cs;                 /* flag: force case-sensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+   they match, and 0 or 2 if they don't or if there is a syntax error in the
+   pattern.  This routine recurses on itself no deeper than the number of
+   characters in the pattern. */
+{
+  long c;               /* pattern char or start of range in [-] loop */
+  /* Get first character, the pattern for new recmatch calls follows */
+
+  c = (long)*(pw++);
+
+  /* If that was the end of the pattern, match if string empty too */
+  if (c == 0)
+    return *sw == 0;
+
+  /* '?' matches any character (but not an empty string) */
+  if ((wchar_t)c == (wchar_t)WILDCHR_SINGLE) {
+    if (wild_stop_at_dir)
+      return (*sw && *sw != (wchar_t)DIRSEP_CHR) ? recmatchw(pw, sw + 1, cs) : 0;
+    else
+      return *sw ? recmatchw(pw, sw + 1, cs) : 0;
+  }
+
+  /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+  if (!no_wild && (wchar_t)c == (wchar_t)WILDCHR_MULTI)
+  {
+    if (wild_stop_at_dir) {
+      /* Check for an immediately following WILDCHR_MULTI */
+      if (*pw != (wchar_t)WILDCHR_MULTI) {
+        /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+        for (; *sw && *sw != (wchar_t)DIRSEP_CHR; sw++)
+          if ((c = recmatchw(pw, sw, cs)) != 0)
+            return c;
+        /* end of pattern: matched if at end of string, else continue */
+        if (*pw == 0)
+          return (*sw == 0);
+        /* continue to match if at DIRSEP_CHR in pattern, else give up */
+        return (*pw == (wchar_t)DIRSEP_CHR || (*pw == (wchar_t)'\\' &&
+                pw[1] == (wchar_t)DIRSEP_CHR))
+               ? recmatchw(pw, sw, cs) : 2;
+      }
+      /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+      pw++;        /* move p past the second WILDCHR_MULTI */
+      /* continue with the normal non-WILD_STOP_AT_DIR code */
+    } /* wild_stop_at_dir */
+
+    /* Not wild_stop_at_dir */
+    if (*pw == 0)
+      return 1;
+    if (!isshexpw((wchar_t *)pw))
+    {
+      /* optimization for rest of pattern being a literal string */
+
+      /* optimization to handle patterns like *.txt */
+      /* if the first char in the pattern is '*' and there */
+      /* are no other shell expression chars, i.e. a literal string */
+      /* then just compare the literal string at the end */
+
+      ZCONST wchar_t *swrest;
+
+      swrest = sw + (wcslen(sw) - wcslen(pw));
+      if (swrest - sw < 0)
+        /* remaining literal string from pattern is longer than rest of
+           test string, there can't be a match
+         */
+        return 0;
+      else
+        /* compare the remaining literal pattern string with the last bytes
+           of the test string to check for a match */
+        return ((cs ? wcscmp(pw, swrest) : _wcsicmp(pw, swrest)) == 0);
+    }
+    else
+    {
+      /* pattern contains more wildcards, continue with recursion... */
+      for (; *sw; sw++)
+        if ((c = recmatchw(pw, sw, cs)) != 0)
+          return c;
+      return 2;           /* 2 means give up--shmatch will return false */
+    }
+  }
+
+  /* Parse and process the list of characters and ranges in brackets */
+  if (!no_wild && allow_regex && (wchar_t)c == '[')
+  {
+    int e;              /* flag true if next char to be taken literally */
+    ZCONST wchar_t *qw; /* pointer to end of [-] group */
+    int r;              /* flag true to match anything but the range */
+
+    if (*sw == 0)                        /* need a character to match */
+      return 0;
+    pw += (r = (*pw == (wchar_t)'!' || *pw == (wchar_t)'^')); /* see if reverse */
+    for (qw = pw, e = 0; *qw; qw++)         /* find closing bracket */
+      if (e)
+        e = 0;
+      else
+        if (*qw == (wchar_t)'\\')
+          e = 1;
+        else if (*qw == (wchar_t)']')
+          break;
+    if (*qw != (wchar_t)']')                      /* nothing matches if bad syntax */
+      return 0;
+    for (c = 0, e = *pw == (wchar_t)'-'; pw < qw; pw++)      /* go through the list */
+    {
+      if (e == 0 && *pw == (wchar_t)'\\')         /* set escape flag if \ */
+        e = 1;
+      else if (e == 0 && *pw == (wchar_t)'-')     /* set start of range if - */
+        c = *(pw-1);
+      else
+      {
+        wchar_t cc = (cs ? *sw : towupper(*sw));
+        wchar_t uc = (wchar_t) c;
+
+        if (*(pw+1) != (wchar_t)'-')
+          for (uc = uc ? uc : *pw; cc <= *pw; uc++)
+            /* compare range */
+            if ((cs ? uc : towupper(uc)) == cc)
+              return r ? 0 : recmatchw(qw + 1, sw + 1, cs);
+        c = e = 0;                      /* clear range, escape flags */
+      }
+    }
+    return r ? recmatchw(qw + 1, sw + 1, cs) : 0;
+                                        /* bracket match failed */
+  }
+
+  /* If escape ('\'), just compare next character */
+  if (!no_wild && (wchar_t)c == (wchar_t)'\\')
+    if ((c = *pw++) == '\0')            /* if \ at end, then syntax error */
+      return 0;
+
+  /* Just a character--compare it */
+  return (cs ? (wchar_t)c == *sw : towupper((wchar_t)c) == towupper(*sw)) ?
+          recmatchw(pw, sw + 1, cs) : 0;
+}
+
+# endif
+#endif
+
+
+local int recmatch(p, s, cs)
+ZCONST char *p;         /* sh pattern to match */
+ZCONST char *s;         /* string to match it to */
+int cs;                 /* flag: force case-sensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+   they match, and 0 or 2 if they don't or if there is a syntax error in the
+   pattern.  This routine recurses on itself no deeper than the number of
+   characters in the pattern. */
+{
+  int c;                /* pattern char or start of range in [-] loop */
+  /* Get first character, the pattern for new recmatch calls follows */
+
+  /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+     See 21 July 2006 mail.
+     It only applies when p is pointing to a doublebyte character and
+     things like / and wildcards are not doublebyte.  This probably
+     should not be needed. */
+
+#ifdef _MBCS
+  if (CLEN(p) == 2) {
+    if (CLEN(s) == 2) {
+      return (*p == *s && *(p+1) == *(s+1)) ?
+        recmatch(p + 2, s + 2, cs) : 0;
+    } else {
+      return 0;
+    }
+  }
+#endif /* ?_MBCS */
+
+  c = *POSTINCSTR(p);
+
+  /* If that was the end of the pattern, match if string empty too */
+  if (c == 0)
+    return *s == 0;
+
+  /* '?' (or '%' or '#') matches any character (but not an empty string) */
+  if (c == WILDCHR_SINGLE) {
+    if (wild_stop_at_dir)
+      return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
+    else
+      return *s ? recmatch(p, s + CLEN(s), cs) : 0;
+  }
+
+  /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+#ifdef AMIGA
+  if (!no_wild && c == '#' && *p == '?')            /* "#?" is Amiga-ese for "*" */
+    c = WILDCHR_MULTI, p++;
+#endif /* AMIGA */
+  if (!no_wild && c == WILDCHR_MULTI)
+  {
+    if (wild_stop_at_dir) {
+      /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+      if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+        c = WILDCHR_MULTI, p++;
+      if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+      if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+        /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+        for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+          if ((c = recmatch(p, s, cs)) != 0)
+            return c;
+        /* end of pattern: matched if at end of string, else continue */
+        if (*p == 0)
+          return (*s == 0);
+        /* continue to match if at DIRSEP_CHR in pattern, else give up */
+        return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+               ? recmatch(p, s, cs) : 2;
+      }
+      /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+      p++;        /* move p past the second WILDCHR_MULTI */
+      /* continue with the normal non-WILD_STOP_AT_DIR code */
+    } /* wild_stop_at_dir */
+
+    /* Not wild_stop_at_dir */
+    if (*p == 0)
+      return 1;
+    if (!isshexp((char *)p))
+    {
+      /* optimization for rest of pattern being a literal string */
+
+      /* optimization to handle patterns like *.txt */
+      /* if the first char in the pattern is '*' and there */
+      /* are no other shell expression chars, i.e. a literal string */
+      /* then just compare the literal string at the end */
+
+      ZCONST char *srest;
+
+      srest = s + (strlen(s) - strlen(p));
+      if (srest - s < 0)
+        /* remaining literal string from pattern is longer than rest of
+           test string, there can't be a match
+         */
+        return 0;
+      else
+        /* compare the remaining literal pattern string with the last bytes
+           of the test string to check for a match */
+#ifdef _MBCS
+      {
+        ZCONST char *q = s;
+
+        /* MBCS-aware code must not scan backwards into a string from
+         * the end.
+         * So, we have to move forward by character from our well-known
+         * character position s in the test string until we have advanced
+         * to the srest position.
+         */
+        while (q < srest)
+          INCSTR(q);
+        /* In case the byte *srest is a trailing byte of a multibyte
+         * character, we have actually advanced past the position (srest).
+         * For this case, the match has failed!
+         */
+        if (q != srest)
+          return 0;
+        return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
+      }
+#else /* !_MBCS */
+        return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+#endif /* ?_MBCS */
+    }
+    else
+    {
+      /* pattern contains more wildcards, continue with recursion... */
+      for (; *s; INCSTR(s))
+        if ((c = recmatch(p, s, cs)) != 0)
+          return c;
+      return 2;           /* 2 means give up--shmatch will return false */
+    }
+  }
+
+#ifndef VMS             /* No bracket matching in VMS */
+  /* Parse and process the list of characters and ranges in brackets */
+  if (!no_wild && allow_regex && c == '[')
+  {
+    int e;              /* flag true if next char to be taken literally */
+    ZCONST char *q;     /* pointer to end of [-] group */
+    int r;              /* flag true to match anything but the range */
+
+    if (*s == 0)                        /* need a character to match */
+      return 0;
+    p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+    for (q = p, e = 0; *q; q++)         /* find closing bracket */
+      if (e)
+        e = 0;
+      else
+        if (*q == '\\')
+          e = 1;
+        else if (*q == ']')
+          break;
+    if (*q != ']')                      /* nothing matches if bad syntax */
+      return 0;
+    for (c = 0, e = *p == '-'; p < q; p++)      /* go through the list */
+    {
+      if (e == 0 && *p == '\\')         /* set escape flag if \ */
+        e = 1;
+      else if (e == 0 && *p == '-')     /* set start of range if - */
+        c = *(p-1);
+      else
+      {
+        uch cc = (cs ? (uch)*s : case_map((uch)*s));
+        uch uc = (uch) c;
+        if (*(p+1) != '-')
+          for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+            /* compare range */
+            if ((cs ? uc : case_map(uc)) == cc)
+              return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
+        c = e = 0;                      /* clear range, escape flags */
+      }
+    }
+    return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
+                                        /* bracket match failed */
+  }
+#endif /* !VMS */
+
+  /* If escape ('\'), just compare next character */
+  if (!no_wild && c == '\\')
+    if ((c = *p++) == '\0')             /* if \ at end, then syntax error */
+      return 0;
+
+#ifdef VMS
+  /* 2005-11-06 SMS.
+     Handle "..." wildcard in p with "." or "]" in s.
+  */
+  if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+   ((*s == '.') || (*s == ']')))
+  {
+    /* Match "...]" with "]".  Continue after "]" in both. */
+    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+    /* Else, look for a reduced match in s, until "]" in or end of s. */
+    for (; *s && (*s != ']'); INCSTR(s))
+      if (*s == '.')
+        /* If reduced match, then continue after "..." in p, "." in s. */
+        if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
+          return (int)c;
+
+    /* Match "...]" with "]".  Continue after "]" in both. */
+    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+    /* No reduced match.  Quit. */
+    return 2;
+  }
+
+#endif /* def VMS */
+
+  /* Just a character--compare it */
+  return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
+          recmatch(p, s + CLEN(s), cs) : 0;
+}
+
+
+int shmatch(p, s, cs)
+ZCONST char *p;         /* sh pattern to match */
+ZCONST char *s;         /* string to match it to */
+int cs;                 /* force case-sensitive match if TRUE */
+/* Compare the sh pattern p with the string s and return true if they match,
+   false if they don't or if there is a syntax error in the pattern. */
+{
+  while (s[0] == '.' && s[1] == '/') 
+    s += 2;                /* strip redundant leading "./" sections */
+  return recmatch(p, s, cs) == 1;
+}
+
+
+#if defined(DOS) || defined(WIN32)
+
+#ifdef UNICODE_SUPPORT
+
+int dosmatchw(pw, sw, cs)
+ZCONST wchar_t *pw;     /* dos pattern to match    */
+ZCONST wchar_t *sw;     /* string to match it to   */
+int cs;                 /* force case-sensitive match if TRUE */
+/* Treat filenames without periods as having an implicit trailing period */
+{
+  wchar_t *sw1;         /* revised string to match */
+  int r;                /* result */
+
+  if (wcschr(pw, (wchar_t)'.') && !wcschr(sw, (wchar_t)'.') &&
+      ((sw1 = (wchar_t *)malloc((wcslen(sw) + 2) * sizeof(wchar_t))) != NULL))
+  {
+    wcscpy(sw1, sw);
+    wcscat(sw1, L".");
+  }
+  else
+  {
+    /* will usually be OK */
+    sw1 = (wchar_t *)sw;
+  }
+
+  r = recmatchw(pw, sw1, cs) == 1;
+  if (sw != sw1)
+    free((zvoid *)sw1);
+  return r == 1;
+}
+
+#endif
+
+/* XXX  also suitable for OS2?  Atari?  Human68K?  TOPS-20?? */
+
+int dosmatch(p, s, cs)
+ZCONST char *p;         /* dos pattern to match    */
+ZCONST char *s;         /* string to match it to   */
+int cs;                 /* force case-sensitive match if TRUE */
+/* Treat filenames without periods as having an implicit trailing period */
+{
+  char *s1;             /* revised string to match */
+  int r;                /* result */
+
+  if (strchr(p, '.') && !strchr(s, '.') &&
+      ((s1 = malloc(strlen(s) + 2)) != NULL))
+  {
+    strcpy(s1, s);
+    strcat(s1, ".");
+  }
+  else
+  {
+    /* will usually be OK */
+    s1 = (char *)s;
+  }
+
+  r = recmatch(p, s1, cs) == 1;
+  if (s != s1)
+    free((zvoid *)s1);
+  return r == 1;
+}
+
+#endif /* DOS || WIN32 */
+
+zvoid far **search(b, a, n, cmp)
+ZCONST zvoid *b;        /* pointer to value to search for */
+ZCONST zvoid far **a;   /* table of pointers to values, sorted */
+extent n;               /* number of pointers in a[] */
+int (*cmp) OF((ZCONST zvoid *, ZCONST zvoid far *)); /* comparison function */
+
+/* Search for b in the pointer list a[0..n-1] using the compare function
+   cmp(b, c) where c is an element of a[i] and cmp() returns negative if
+   *b < *c, zero if *b == *c, or positive if *b > *c.  If *b is found,
+   search returns a pointer to the entry in a[], else search() returns
+   NULL.  The nature and size of *b and *c (they can be different) are
+   left up to the cmp() function.  A binary search is used, and it is
+   assumed that the list is sorted in ascending order. */
+{
+  ZCONST zvoid far **i; /* pointer to midpoint of current range */
+  ZCONST zvoid far **l; /* pointer to lower end of current range */
+  int r;                /* result of (*cmp)() call */
+  ZCONST zvoid far **u; /* pointer to upper end of current range */
+
+  l = (ZCONST zvoid far **)a;  u = l + (n-1);
+  while (u >= l) {
+    i = l + ((unsigned)(u - l) >> 1);
+    if ((r = (*cmp)(b, (ZCONST char far *)*(struct zlist far **)i)) < 0)
+      u = i - 1;
+    else if (r > 0)
+      l = i + 1;
+    else
+      return (zvoid far **)i;
+  }
+  return NULL;          /* If b were in list, it would belong at l */
+}
+
+#endif /* !UTIL */
+
+#ifdef MSDOS16
+
+local unsigned ident(unsigned chr)
+{
+   return chr; /* in al */
+}
+
+void init_upper()
+{
+  static struct country {
+    uch ignore[18];
+    int (far *casemap)(int);
+    uch filler[16];
+  } country_info;
+
+  struct country far *info = &country_info;
+  union REGS regs;
+  struct SREGS sregs;
+  unsigned int c;
+
+  regs.x.ax = 0x3800; /* get country info */
+  regs.x.dx = FP_OFF(info);
+  sregs.ds  = FP_SEG(info);
+  intdosx(&regs, &regs, &sregs);
+  for (c = 0; c < 128; c++) {
+    upper[c] = (uch) toupper(c);
+    lower[c] = (uch) c;
+  }
+  for (; c < sizeof(upper); c++) {
+    upper[c] = (uch) (*country_info.casemap)(ident(c));
+    /* ident() required because casemap takes its parameter in al */
+    lower[c] = (uch) c;
+  }
+  for (c = 0; c < sizeof(upper); c++ ) {
+    unsigned int u = upper[c];
+    if (u != c && lower[u] == (uch) u) {
+      lower[u] = (uch)c;
+    }
+  }
+  for (c = 'A'; c <= 'Z'; c++) {
+    lower[c] = (uch) (c - 'A' + 'a');
+  }
+}
+#else /* !MSDOS16 */
+#  ifndef OS2
+
+void init_upper()
+{
+  unsigned int c;
+#if defined(ATARI) || defined(CMS_MVS)
+#include <ctype.h>
+/* this should be valid for all other platforms too.   (HD 11/11/95) */
+  for (c = 0; c< sizeof(upper); c++) {
+    upper[c] = islower(c) ? toupper(c) : c;
+    lower[c] = isupper(c) ? tolower(c) : c;
+  }
+#else
+  for (c = 0; c < sizeof(upper); c++) upper[c] = lower[c] = (uch)c;
+  for (c = 'a'; c <= 'z';        c++) upper[c] = (uch)(c - 'a' + 'A');
+  for (c = 'A'; c <= 'Z';        c++) lower[c] = (uch)(c - 'A' + 'a');
+#endif
+}
+#  endif /* !OS2 */
+
+#endif /* ?MSDOS16 */
+
+int namecmp(string1, string2)
+  ZCONST char *string1, *string2;
+/* Compare the two strings ignoring case, and correctly taking into
+ * account national language characters. For operating systems with
+ * case sensitive file names, this function is equivalent to strcmp.
+ */
+{
+  int d;
+
+  for (;;)
+  {
+    d = (int) (uch) case_map(*string1)
+      - (int) (uch) case_map(*string2);
+
+    if (d || *string1 == 0 || *string2 == 0)
+      return d;
+
+    string1++;
+    string2++;
+  }
+}
+
+#ifdef EBCDIC
+char *strtoasc(char *str1, ZCONST char *str2)
+{
+  char *old;
+  old = str1;
+  while (*str1++ = (char)ascii[(uch)(*str2++)]);
+  return old;
+}
+
+char *strtoebc(char *str1, ZCONST char *str2)
+{
+  char *old;
+  old = str1;
+  while (*str1++ = (char)ebcdic[(uch)(*str2++)]);
+  return old;
+}
+
+char *memtoasc(char *mem1, ZCONST char *mem2, unsigned len)
+{
+  char *old;
+  old = mem1;
+  while (len--)
+     *mem1++ = (char)ascii[(uch)(*mem2++)];
+  return old;
+}
+
+char *memtoebc(char *mem1, ZCONST char *mem2, unsigned len)
+{
+  char *old;
+  old = mem1;
+  while (len--)
+     *mem1++ = (char)ebcdic[(uch)(*mem2++)];
+  return old;
+}
+#endif /* EBCDIC */
+
+#ifdef IZ_ISO2OEM_ARRAY
+char *str_iso_to_oem(dst, src)
+  ZCONST char *src;
+  char *dst;
+{
+  char *dest_start = dst;
+  while (*dst++ = (char)iso2oem[(uch)(*src++)]);
+  return dest_start;
+}
+#endif
+
+#ifdef IZ_OEM2ISO_ARRAY
+char *str_oem_to_iso(dst, src)
+  ZCONST char *src;
+  char *dst;
+{
+  char *dest_start = dst;
+  while (*dst++ = (char)oem2iso[(uch)(*src++)]);
+  return dest_start;
+}
+#endif
+
+
+
+/* DBCS support for Info-ZIP's zip  (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ * This code is public domain!   Date: 1998/12/20
+ */
+#ifdef _MBCS
+
+char *___tmp_ptr;
+
+int lastchar(ptr)
+    ZCONST char *ptr;
+{
+    ZCONST char *oldptr = ptr;
+    while(*ptr != '\0'){
+        oldptr = ptr;
+        INCSTR(ptr);
+    }
+    return (int)(unsigned)*oldptr;
+}
+
+unsigned char *zmbschr(str, c)
+    ZCONST unsigned char *str;
+    unsigned int c;
+{
+    while(*str != '\0'){
+        if (*str == c) {return (unsigned char *)str;}
+        INCSTR(str);
+    }
+    return NULL;
+}
+
+unsigned char *zmbsrchr(str, c)
+    ZCONST unsigned char *str;
+    unsigned int c;
+{
+    unsigned char *match = NULL;
+    while(*str != '\0'){
+        if (*str == c) {match = (unsigned char*)str;}
+        INCSTR(str);
+    }
+    return match;
+}
+#endif /* _MBCS */
+
+
+
+#ifndef UTIL
+
+/*****************************************************************
+ | envargs - add default options from environment to command line
+ |----------------------------------------------------------------
+ | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
+ | This program is in the public domain.
+ |----------------------------------------------------------------
+ | Minor program notes:
+ |  1. Yes, the indirection is a tad complex
+ |  2. Parenthesis were added where not needed in some cases
+ |     to make the action of the code less obscure.
+ ****************************************************************/
+
+void envargs(Pargc, Pargv, envstr, envstr2)
+    int *Pargc;
+    char ***Pargv;
+    char *envstr;
+    char *envstr2;
+{
+    char *envptr;                     /* value returned by getenv */
+    char *bufptr;                     /* copy of env info */
+    int argc;                         /* internal arg count */
+    register int ch;                  /* spare temp value */
+    char **argv;                      /* internal arg vector */
+    char **argvect;                   /* copy of vector address */
+
+    /* see if anything in the environment */
+    envptr = getenv(envstr);
+    if (envptr != NULL)                                /* usual var */
+        while (isspace((uch)*envptr))      /* we must discard leading spaces */
+            envptr++;
+    if (envptr == NULL || *envptr == '\0')
+        if ((envptr = getenv(envstr2)) != NULL)                 /* alternate */
+            while (isspace((uch)*envptr))
+                envptr++;
+    if (envptr == NULL || *envptr == '\0')
+        return;
+
+    /* count the args so we can allocate room for them */
+    argc = count_args(envptr);
+    bufptr = malloc(1 + strlen(envptr));
+    if (bufptr == NULL)
+        ziperr(ZE_MEM, "Can't get memory for arguments");
+    strcpy(bufptr, envptr);
+
+    /* allocate a vector large enough for all args */
+    argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
+    if (argv == NULL) {
+        free(bufptr);
+        ziperr(ZE_MEM, "Can't get memory for arguments");
+    }
+    argvect = argv;
+
+    /* copy the program name first, that's always true */
+    *(argv++) = *((*Pargv)++);
+
+    /* copy the environment args first, may be changed */
+    do {
+#if defined(AMIGA) || defined(UNIX)
+        if (*bufptr == '"') {
+            char *argstart = ++bufptr;
+            *(argv++) = argstart;
+            for (ch = *bufptr; ch != '\0' && ch != '\"';
+                 ch = *PREINCSTR(bufptr))
+                if (ch == '\\' && bufptr[1] != '\0')
+                    ++bufptr;               /* skip to char after backslash */
+            if (ch != '\0')                       /* overwrite trailing '"' */
+                *(bufptr++) = '\0';
+
+            /* remove escape characters */
+            while ((argstart = MBSCHR(argstart, '\\')) != NULL) {
+                strcpy(argstart, argstart + 1);
+                if (*argstart)
+                    ++argstart;
+            }
+        } else {
+            *(argv++) = bufptr;
+            while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+            if (ch != '\0') *(bufptr++) = '\0';
+        }
+#else
+#  ifdef WIN32
+        /* We do not support backslash-quoting of quotes in quoted */
+        /* strings under Win32, because backslashes are directory  */
+        /* separators and double quotes are illegal in filenames.  */
+        if (*bufptr == '"') {
+            *(argv++) = ++bufptr;
+            while ((ch = *bufptr) != '\0' && ch != '\"') INCSTR(bufptr);
+            if (ch != '\0') *(bufptr++) = '\0';
+        } else {
+            *(argv++) = bufptr;
+            while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+            if (ch != '\0') *(bufptr++) = '\0';
+        }
+#  else
+        *(argv++) = bufptr;
+        while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+        if (ch != '\0') *(bufptr++) = '\0';
+#  endif
+#endif /* ?(AMIGA || UNIX) */
+        while ((ch = *bufptr) != '\0' && isspace((uch)ch)) INCSTR(bufptr);
+    } while (ch);
+
+    /* now save old argc and copy in the old args */
+    argc += *Pargc;
+    while (--(*Pargc)) *(argv++) = *((*Pargv)++);
+
+    /* finally, add a NULL after the last arg, like UNIX */
+    *argv = NULL;
+
+    /* save the values and return */
+    *Pargv = argvect;
+    *Pargc = argc;
+}
+
+local int count_args(s)
+char *s;
+{
+    int count = 0;
+    char ch;
+
+    do {
+        /* count and skip args */
+        ++count;
+#if defined(AMIGA) || defined(UNIX)
+        if (*s == '\"') {
+            for (ch = *PREINCSTR(s); ch != '\0' && ch != '\"';
+                 ch = *PREINCSTR(s))
+                if (ch == '\\' && s[1] != '\0')
+                    INCSTR(s);
+            if (*s) INCSTR(s);  /* trailing quote */
+        } else
+            while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+#else
+#  ifdef WIN32
+        if (*s == '\"') {
+            ++s;                /* leading quote */
+            while ((ch = *s) != '\0' && ch != '\"') INCSTR(s);
+            if (*s) INCSTR(s);  /* trailing quote */
+        } else
+            while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+#  else
+        while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+#  endif
+#endif /* ?(AMIGA || UNIX) */
+        while ((ch = *s) != '\0' && isspace((uch)ch)) INCSTR(s);
+    } while (ch);
+
+    return(count);
+}
+
+
+
+/* Extended argument processing -- by Rich Wales
+ * This function currently deals only with the MKS shell, but could be
+ * extended later to understand other conventions.
+ *
+ * void expand_args(int *argcp, char ***argvp)
+ *
+ *    Substitutes the extended command line argument list produced by
+ *    the MKS Korn Shell in place of the command line info from DOS.
+ *
+ *    The MKS shell gets around DOS's 128-byte limit on the length of
+ *    a command line by passing the "real" command line in the envi-
+ *    ronment.  The "real" arguments are flagged by prepending a tilde
+ *    (~) to each one.
+ *
+ *    This "expand_args" routine creates a new argument list by scanning
+ *    the environment from the beginning, looking for strings begin-
+ *    ning with a tilde character.  The new list replaces the original
+ *    "argv" (pointed to by "argvp"), and the number of arguments
+ *    in the new list replaces the original "argc" (pointed to by
+ *    "argcp").
+ */
+void expand_args(argcp, argvp)
+      int *argcp;
+      char ***argvp;
+{
+#ifdef DOS
+
+/* Do NEVER include (re)definiton of `environ' variable with any version
+   of MSC or BORLAND/Turbo C. These compilers supply an incompatible
+   definition in <stdlib.h>.  */
+#if defined(__GO32__) || defined(__EMX__)
+      extern char **environ;          /* environment */
+#endif /* __GO32__ || __EMX__ */
+      char        **envp;             /* pointer into environment */
+      char        **newargv;          /* new argument list */
+      char        **argp;             /* pointer into new arg list */
+      int           newargc;          /* new argument count */
+
+      /* sanity check */
+      if (environ == NULL
+          || argcp == NULL
+          || argvp == NULL || *argvp == NULL)
+              return;
+      /* find out how many environment arguments there are */
+      for (envp = environ, newargc = 0;
+           *envp != NULL && (*envp)[0] == '~';
+           envp++, newargc++) ;
+      if (newargc == 0)
+              return;                 /* no environment arguments */
+      /* set up new argument list */
+      newargv = (char **) malloc(sizeof(char **) * (newargc+1));
+      if (newargv == NULL)
+              return;                 /* malloc failed */
+      for (argp = newargv, envp = environ;
+           *envp != NULL && (*envp)[0] == '~';
+           *argp++ = &(*envp++)[1]) ;
+      *argp = NULL;                   /* null-terminate the list */
+      /* substitute new argument list in place of old one */
+      *argcp = newargc;
+      *argvp = newargv;
+#else /* !DOS */
+      if (argcp || argvp) return;
+#endif /* ?DOS */
+}
+
+
+/* Fast routine for detection of plain text
+ * (ASCII or an ASCII-compatible extension such as ISO-8859, UTF-8, etc.)
+ * Author: Cosmin Truta.
+ * See "proginfo/txtvsbin.txt" for more information.
+ *
+ * This function returns the same result as set_file_type() in "trees.c".
+ * Unlike in set_file_type(), however, the speed depends on the buffer size,
+ * so the optimal implementation is different.
+ */
+int is_text_buf(buf_ptr, buf_size)
+    ZCONST char *buf_ptr;
+    unsigned buf_size;
+{
+    int result = 0;
+    unsigned i;
+    unsigned char c;
+
+    for (i = 0; i < buf_size; ++i)
+    {
+        c = (unsigned char)buf_ptr[i];
+        if (c >= 32)    /* speed up the loop by checking this first */
+            result = 1; /* white-listed character found; keep looping */
+        else            /* speed up the loop by inlining the following check */
+        if ((c <= 6) || (c >= 14 && c <= 25) || (c >= 28 && c <= 31))
+            return 0;   /* black-listed character found; stop */
+    }
+
+    return result;
+}
+
+#endif /* UTIL */
+
+
+#ifdef DEBUGNAMES
+#undef free
+int Free(x)
+void *x;
+{
+    if (x == (void *) 0xdeadbeef)
+        exit(-1);
+    free(x);
+    return 0;
+}
+
+int printnames()
+{
+     struct zlist far *z;
+
+     for (z = zfiles; z != NULL; z = z->nxt)
+           fprintf(mesg, "%s %s %s %p %p %p %08x %08x %08x\n",
+                            z->name, z->zname, z->iname,
+                            z->name, z->zname, z->iname,
+                            *((int *) z->name), *((int *) z->zname),
+                            *((int *) z->iname));
+     return 0;
+}
+
+#endif /* DEBUGNAMES */
+
+
+/* Below is used to format zoff_t values, which can be either long or long long
+   depending on if LARGE FILES are supported.  Function provided by SMS.
+   10/17/04 EG */
+
+/* 2004-12-01 SMS.
+ * Brought in fancy fzofft() from UnZip.
+ */
+
+/* This implementation assumes that no more than FZOFF_NUM values will be
+   needed in any printf using it.  */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set.
+   This version renamed from fzofft because of name conflict in unzip
+   when combined in WiZ. */
+
+/* 2004-12-19 SMS.
+ * I still claim than the smart move would have been to disable one or
+ * the other instance with #if for Wiz.  But fine.  We'll change the
+ * name.
+ */
+
+/* This is likely not thread safe.  Needs to be done without static storage.
+   12/29/04 EG */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set. */
+
+#define FZOFFT_NUM 4            /* Number of chambers. */
+#define FZOFFT_LEN 24           /* Number of characters/chamber. */
+
+
+/* Format a zoff_t value in a cylindrical buffer set. */
+
+char *zip_fzofft( val, pre, post)
+  zoff_t val;
+  char *pre;
+  char *post;
+{
+    /* Storage cylinder. */
+    static char fzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+    static int fzofft_index = 0;
+
+    /* Temporary format string storage. */
+    static char fmt[ 16] = "%";
+
+    /* Assemble the format string. */
+    fmt[ 1] = '\0';             /* Start after initial "%". */
+    if (pre == FZOFFT_HEX_WID)  /* Special hex width. */
+    {
+        strcat( fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+    {
+        strcat( fmt, ".");
+        strcat( fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre != NULL)       /* Caller's prefix (width). */
+    {
+        strcat( fmt, pre);
+    }
+
+    strcat( fmt, FZOFFT_FMT);   /* Long or long-long or whatever. */
+
+    if (post == NULL)
+        strcat( fmt, "d");      /* Default radix = decimal. */
+    else
+        strcat( fmt, post);     /* Caller's radix. */
+
+    /* Advance the cylinder. */
+    fzofft_index = (fzofft_index+ 1)% FZOFFT_NUM;
+
+    /* Write into the current chamber. */
+    sprintf( fzofft_buf[ fzofft_index], fmt, val);
+
+    /* Return a pointer to this chamber. */
+    return fzofft_buf[ fzofft_index];
+}
+
+
+/* Format a uzoff_t value in a cylindrical buffer set. */
+/* Added to support uzoff_t type.  12/29/04 */
+
+char *zip_fuzofft( val, pre, post)
+  uzoff_t val;
+  char *pre;
+  char *post;
+{
+    /* Storage cylinder. */
+    static char fuzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+    static int fuzofft_index = 0;
+
+    /* Temporary format string storage. */
+    static char fmt[ 16] = "%";
+
+    /* Assemble the format string. */
+    fmt[ 1] = '\0';             /* Start after initial "%". */
+    if (pre == FZOFFT_HEX_WID)  /* Special hex width. */
+    {
+        strcat( fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+    {
+        strcat( fmt, ".");
+        strcat( fmt, FZOFFT_HEX_WID_VALUE);
+    }
+    else if (pre != NULL)       /* Caller's prefix (width). */
+    {
+        strcat( fmt, pre);
+    }
+
+    strcat( fmt, FZOFFT_FMT);   /* Long or long-long or whatever. */
+
+    if (post == NULL)
+        strcat( fmt, "u");      /* Default radix = decimal. */
+    else
+        strcat( fmt, post);     /* Caller's radix. */
+
+    /* Advance the cylinder. */
+    fuzofft_index = (fuzofft_index+ 1)% FZOFFT_NUM;
+
+    /* Write into the current chamber. */
+    sprintf( fuzofft_buf[ fuzofft_index], fmt, val);
+
+    /* Return a pointer to this chamber. */
+    return fuzofft_buf[ fuzofft_index];
+}
+
+
+/* Display number to mesg stream
+   5/15/05 EG */
+
+int DisplayNumString(file, i)
+  FILE *file;
+  uzoff_t i;
+{
+  char tempstrg[100];
+  int j;
+  char *s = tempstrg;
+
+  WriteNumString(i, tempstrg);
+  /* skip spaces */
+  for (j = 0; j < 3; j++) {
+    if (*s != ' ') break;
+    s++;
+  }
+  fprintf(file, "%s", s);
+
+  return 0;
+}
+
+/* Read numbers with trailing size multiplier (like 10M) and return number.
+   10/30/04 EG */
+
+uzoff_t ReadNumString( numstring )
+  char *numstring;
+{
+  zoff_t num = 0;
+  char multchar = ' ';
+  int i;
+  uzoff_t mult = 1;
+
+  /* check if valid number (currently no negatives) */
+  if (numstring == NULL) {
+    zipwarn("Unable to read empty number in ReadNumString", "");
+    return (uzoff_t)-1;
+  }
+  if (numstring[0] < '0' || numstring[0] > '9') {
+    zipwarn("Unable to read number (must start with digit): ", numstring);
+    return (uzoff_t)-1;
+  }
+  if (strlen(numstring) > 8) {
+    zipwarn("Number too long to read (8 characters max): ", numstring);
+    return (uzoff_t)-1;
+  }
+
+  /* get the number part */
+  num = atoi(numstring);
+
+  /* find trailing multiplier */
+  for (i = 0; numstring[i] && isdigit(numstring[i]); i++) ;
+
+  /* return if no multiplier */
+  if (numstring[i] == '\0') {
+    return (uzoff_t)num;
+  }
+
+  /* nothing follows multiplier */
+  if (numstring[i + 1]) {
+    return (uzoff_t)-1;
+  }
+
+  /* get multiplier */
+  multchar = toupper(numstring[i]);
+
+  if (multchar == 'K') {
+    mult <<= 10;
+  } else if (multchar == 'M') {
+    mult <<= 20;
+  } else if (multchar == 'G') {
+    mult <<= 30;
+#ifdef LARGE_FILE_SUPPORT
+  } else if (multchar == 'T') {
+    mult <<= 40;
+#endif
+  } else {
+    return (uzoff_t)-1;
+  }
+
+  return (uzoff_t)num * mult;
+}
+
+
+/* Write the number as a string with a multiplier (like 10M) to outstring.
+   Always writes no more than 3 digits followed maybe by a multiplier and
+   returns the characters written or -1 if error.
+   10/30/04 EG */
+
+int WriteNumString( num, outstring )
+  uzoff_t num;
+  char *outstring;
+{
+  int mult;
+  int written = 0;
+  int i;
+  int j;
+  char digits[4];
+  int dig;
+
+  *outstring = '\0';
+
+  /* shift number 1 K until less than 10000 */
+  for (mult = 0; num >= 10240; mult++) {
+    num >>= 10;
+  }
+
+  /* write digits as "    0" */
+  for (i = 1; i < 4; i++) {
+    digits[i] = ' ';
+  }
+  digits[0] = '0';
+
+  if (num >= 1000) {
+    i = 3;
+    num *= 10;
+    num >>= 10;
+    mult++;
+    digits[0] = (char) (num % 10) + '0';
+    digits[1] = '.';
+    digits[2] = (char) (num / 10) + '0';
+  } else {
+    for (i = 0; num; i++) {
+      dig = (int) (num % 10);
+      num /= 10;
+      digits[i] = dig + '0';
+    }
+  }
+  if (i == 0) i = 1;
+  for (j = i; j > 0; j--) {
+    *outstring = digits[j - 1];
+    outstring++;
+    written++;
+  }
+
+  /* output multiplier */
+  if (mult == 0) {
+  } else if (mult == 1) {
+    *outstring = 'K';
+    outstring++;
+    written++;
+  } else if (mult == 2) {
+    *outstring = 'M';
+    outstring++;
+    written++;
+  } else if (mult == 3) {
+    *outstring = 'G';
+    outstring++;
+    written++;
+  } else if (mult == 4) {
+    *outstring = 'T';
+    outstring++;
+    written++;
+  } else {
+    *outstring = '?';
+    outstring++;
+    written++;
+  }
+
+  *outstring = '\0';
+
+  return written;
+}
+
+
+#if 0 /* not used anywhere, should get removed by next release... */
+
+/* Apply the Adler-16 checksum to a set of bytes.
+ * Use this function as you would use crc32():
+ * - First call this function by passing a NULL pointer instead of buf
+ *   OR initialize the checksum register with ADLERVAL_INITIAL.
+ * - Iteratively call this function for each buffer fragment.
+ * This function returns the updated checksum.
+ *
+ * IN assertion: chksum is a valid Adler-16 checksum:
+ *    (chksum & 0xffU) < ADLER16_BASE && ((chksum >> 8) & 0xffU) < ADLER16_BASE
+ *
+ * Author: Cosmin Truta.
+ * See "proginfo/adler16.txt" for more information.
+ */
+
+#define ADLER16_BASE 251        /* The largest prime smaller than 256 */
+
+unsigned int adler16(chksum, buf, len)
+    unsigned int chksum;
+    ZCONST uch *buf;
+    extent len;
+{
+    unsigned int sum1 = chksum & 0xff;
+    unsigned int sum2 = (chksum >> 8) & 0xff;
+    extent i;
+
+    Assert((sum1 < ADLER16_BASE) && (sum2 < ADLER16_BASE),
+           "adler16: invalid checksum");
+
+    if (buf == NULL)
+        return 1;
+
+    for (i = 0; i < len; ++i)
+    {
+        sum1 += buf[i];
+        if (sum1 >= ADLER16_BASE) /* this is faster than modulo ADLER16_BASE */
+            sum1 -= ADLER16_BASE;
+        sum2 += sum1;
+        if (sum2 >= ADLER16_BASE) /* ditto */
+            sum2 -= ADLER16_BASE;
+    }
+
+    return (sum2 << 8) | sum1;
+}
+
+#endif /* 0, not used anywhere */
+
+
+/* returns true if abbrev is abbreviation for matchstring */
+int abbrevmatch (matchstring, abbrev, case_sensitive, minmatch)
+  char *matchstring;
+  char *abbrev;
+  int case_sensitive;
+  int minmatch;
+{
+  int cnt = 0;
+  char *m;
+  char *a;
+
+  m = matchstring;
+  a = abbrev;
+
+  for (; *m && *a; m++, a++) {
+    cnt++;
+    if (case_sensitive) {
+      if (*m != *a) {
+        /* mismatch */
+        return 0;
+      }
+    } else {
+      if (toupper(*m) != toupper(*a)) {
+        /* mismatch */
+        return 0;
+      }
+    }
+  }
+  if (cnt < minmatch) {
+    /* not big enough string */
+    return 0;
+  }
+  if (*a != '\0') {
+    /* abbreviation longer than match string */
+    return 0;
+  }
+  /* either abbreviation or match */
+  return 1;
+}
Index: zip/create-3.0-curdir-patch/zip30-new
===================================================================
--- zip/create-3.0-curdir-patch/zip30-new	(nonexistent)
+++ zip/create-3.0-curdir-patch/zip30-new	(revision 5)

Property changes on: zip/create-3.0-curdir-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-curdir-patch
===================================================================
--- zip/create-3.0-curdir-patch	(nonexistent)
+++ zip/create-3.0-curdir-patch	(revision 5)

Property changes on: zip/create-3.0-curdir-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-exec-shield-patch/create.patch.sh
===================================================================
--- zip/create-3.0-exec-shield-patch/create.patch.sh	(nonexistent)
+++ zip/create-3.0-exec-shield-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr  zip${version}-orig  zip${version} > zip-${VERSION}-exec-shield.patch
+
+mv zip-${VERSION}-exec-shield.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig

Property changes on: zip/create-3.0-exec-shield-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-exec-shield-patch/file.list
===================================================================
--- zip/create-3.0-exec-shield-patch/file.list	(nonexistent)
+++ zip/create-3.0-exec-shield-patch/file.list	(revision 5)
@@ -0,0 +1,2 @@
+zip30/crc_i386.S
+zip30/match.S
Index: zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S	(nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S	(revision 5)
@@ -0,0 +1,307 @@
+/*
+  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 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
+*/
+/*
+ * crc_i386.S, optimized CRC calculation function for Zip and UnZip,
+ * created by Paul Kienitz and Christian Spieler.  Last revised 07 Jan 2007.
+ *
+ * GRR 961110:  incorporated Scott Field optimizations from win32/crc_i386.asm
+ *              => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
+ *
+ * SPC 970402:  revised for Rodney Brown's optimizations (32-bit-wide
+ *              aligned reads for most of the data from buffer), can be
+ *              disabled by defining the macro NO_32_BIT_LOADS
+ *
+ * SPC 971012:  added Rodney Brown's additional tweaks for 32-bit-optimized
+ *              CPUs (like the Pentium Pro, Pentium II, and probably some
+ *              Pentium clones). This optimization is controlled by the
+ *              preprocessor switch "__686" and is disabled by default.
+ *              (This default is based on the assumption that most users
+ *              do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * COS 050116:  Enabled the 686 build by default, because there are hardly any
+ *              pre-686 CPUs in serious use nowadays. (See SPC 970402 above.)
+ *
+ * SPC 060103:  Updated code to incorporate newer optimizations found in zlib.
+ *
+ * SPC 070107:  Added conditional switch to deactivate crc32() compilation.
+ *
+ * FLAT memory model assumed.  Calling interface:
+ *   - args are pushed onto the stack from right to left,
+ *   - return value is given in the EAX register,
+ *   - all other registers (with exception of EFLAGS) are preserved. (With
+ *     GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
+ *     them nevertheless adds only 4 single byte instructions.)
+ *
+ * This source generates the function
+ * ulg crc32(ulg crc, ZCONST uch *buf, extent len).
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ */
+
+/* This file is NOT used in conjunction with zlib, or when only creation of
+ * the basic CRC_32_Table (for other purpose) is requested.
+ */
+#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+#  define _crc32            crc32
+#  define _get_crc_table    get_crc_table
+#endif
+/* Use 16-byte alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+#  define ALIGNMENT .align 4,0x90
+#endif
+
+#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
+
+/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to use the C version,
+ * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
+ */
+
+                .file   "crc_i386.S"
+
+#if !defined(PRE_686) && !defined(__686)
+   /* Optimize for Pentium Pro and compatible CPUs by default. */
+#  define __686
+#endif
+
+#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
+#  undef USE_STACKFRAME
+#else
+   /* The default is to use standard stack frame entry, because it
+    * results in smaller code!
+    */
+#  ifndef USE_STD_STACKFRAME
+#    define USE_STD_STACKFRAME
+#  endif
+#endif
+
+#ifdef USE_STD_STACKFRAME
+#  define _STD_ENTRY    pushl   %ebp ; movl   %esp,%ebp
+#  define arg1  8(%ebp)
+#  define arg2  12(%ebp)
+#  define arg3  16(%ebp)
+#  define _STD_LEAVE    popl    %ebp
+#else /* !USE_STD_STACKFRAME */
+#  define _STD_ENTRY
+#  define arg1  24(%esp)
+#  define arg2  28(%esp)
+#  define arg3  32(%esp)
+#  define _STD_LEAVE
+#endif /* ?USE_STD_STACKFRAME */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ *   eax  : crc value "c"
+ *   esi  : pointer to next data byte (or lword) "buf++"
+ * registers read:
+ *   edi  : pointer to base of crc_table array
+ * scratch registers:
+ *   ebx  : index into crc_table array
+ *          (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686   /* optimize for 386, 486, Pentium */
+#define Do_CRC          /* c = (c >> 8) ^ table[c & 0xFF] */\
+                movb    %al, %bl                ;/* tmp = c & 0xFF  */\
+                shrl    $8, %eax                ;/* c = (c >> 8)    */\
+                xorl    (%edi, %ebx, 4), %eax   ;/* c ^= table[tmp] */
+#else   /* __686 : optimize for Pentium Pro and compatible CPUs */
+#define Do_CRC          /* c = (c >> 8) ^ table[c & 0xFF] */\
+                movzbl  %al, %ebx               ;/* tmp = c & 0xFF  */\
+                shrl    $8, %eax                ;/* c = (c >> 8)    */\
+                xorl    (%edi, %ebx, 4), %eax   ;/* c ^=table[tmp]  */
+#endif  /* ?__686 */
+
+#define Do_CRC_byte             /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+                xorb    (%esi), %al     ;/* c ^= *buf  */\
+                incl    %esi            ;/* buf++      */\
+                Do_CRC
+
+#define Do_CRC_byteof(ofs)      /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+                xorb    ofs(%esi), %al  ;/* c ^= *buf  */\
+                incl    %esi            ;/* buf++      */\
+                Do_CRC
+
+#ifndef  NO_32_BIT_LOADS
+# ifdef IZ_CRCOPTIM_UNFOLDTBL
+   /* the edx register is needed in crc calculation */
+#  define SavLen arg3
+#  define UpdCRC_lword \
+                movzbl  %al, %ebx               ; \
+                movl    3072(%edi,%ebx,4), %edx ; \
+                movzbl  %ah, %ebx               ; \
+                shrl    $16, %eax               ; \
+                xor     2048(%edi,%ebx,4), %edx ; \
+                movzbl  %al, %ebx               ; \
+                shrl    $8,%eax                 ; \
+                xorl    1024(%edi,%ebx,4), %edx ; \
+                movl    (%edi,%eax,4), %eax     ; \
+                xorl    %edx,%eax               ;
+#  define UpdCRC_lword_sh(dwPtrIncr) \
+                movzbl  %al, %ebx               ; \
+                movl    3072(%edi,%ebx,4), %edx ; \
+                movzbl  %ah, %ebx               ; \
+                shrl    $16, %eax               ; \
+                xor     2048(%edi,%ebx,4), %edx ; \
+                movzbl  %al, %ebx               ; \
+                addl    $4*(dwPtrIncr), %esi    ;/* ((ulg *)buf)+=dwPtrIncr */\
+                shrl    $8,%eax                 ; \
+                xorl    1024(%edi,%ebx,4), %edx ; \
+                movl    (%edi,%eax,4),%eax      ; \
+                xorl    %edx,%eax               ;
+# else /* !IZ_CRCOPTIM_UNFOLDTBL */
+   /* the edx register is not needed anywhere else */
+#  define SavLen %edx
+#  define UpdCRC_lword \
+                Do_CRC \
+                Do_CRC \
+                Do_CRC \
+                Do_CRC
+#  define UpdCRC_lword_sh(dwPtrIncr) \
+                Do_CRC \
+                Do_CRC \
+                addl    $4*(dwPtrIncr), %esi    ;/* ((ulg *)buf)++   */\
+                Do_CRC \
+                Do_CRC
+# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+#define Do_CRC_lword \
+                xorl    (%esi), %eax           ;/* c ^= *(ulg *)buf */\
+                UpdCRC_lword_sh(1)              /* ... ((ulg *)buf)++ */
+#define Do_CRC_4lword \
+                xorl    (%esi), %eax           ;/* c ^= *(ulg *)buf */\
+                UpdCRC_lword \
+                xorl    4(%esi), %eax          ;/* c ^= *((ulg *)buf+1) */\
+                UpdCRC_lword \
+                xorl    8(%esi), %eax          ;/* c ^= *((ulg *)buf+2) */\
+                UpdCRC_lword \
+                xorl    12(%esi), %eax         ;/* c ^= *((ulg *)buf]+3 */\
+                UpdCRC_lword_sh(4)              /* ... ((ulg *)buf)+=4 */
+#endif  /* !NO_32_BIT_LOADS */
+
+
+                .text
+
+                .globl  _crc32
+
+_crc32:                         /* ulg crc32(ulg crc, uch *buf, extent len) */
+                _STD_ENTRY
+                pushl   %edi
+                pushl   %esi
+                pushl   %ebx
+                pushl   %edx
+                pushl   %ecx
+
+                movl    arg2, %esi           /* 2nd arg: uch *buf            */
+                subl    %eax, %eax           /* > if (!buf)                  */
+                testl   %esi, %esi           /* >   return 0;                */
+                jz      .L_fine              /* > else {                     */
+                call    _get_crc_table
+                movl    %eax, %edi
+                movl    arg1, %eax           /* 1st arg: ulg crc             */
+#ifndef __686
+                subl    %ebx, %ebx           /* ebx=0; bl usable as dword    */
+#endif
+                movl    arg3, %ecx           /* 3rd arg: extent len          */
+                notl    %eax                 /* >   c = ~crc;                */
+
+                testl   %ecx, %ecx
+#ifndef  NO_UNROLLED_LOOPS
+                jz      .L_bail
+#  ifndef  NO_32_BIT_LOADS
+                /* Assert now have positive length */
+.L_align_loop:
+                testl   $3, %esi        /* Align buf on lword boundary */
+                jz      .L_aligned_now
+                Do_CRC_byte
+                decl    %ecx
+                jnz     .L_align_loop
+.L_aligned_now:
+#  endif  /* !NO_32_BIT_LOADS */
+                movl    %ecx, SavLen         /* save current value of len */
+                shrl    $4, %ecx             /* ecx = len / 16   */
+                jz      .L_No_Sixteens
+/*  align loop head at start of 486 internal cache line !! */
+                ALIGNMENT
+.L_Next_Sixteen:
+#  ifndef NO_32_BIT_LOADS
+                 Do_CRC_4lword
+#  else   /* NO_32_BIT_LOADS */
+                 Do_CRC_byteof(0)
+                 Do_CRC_byteof(1)
+                 Do_CRC_byteof(2)
+                 Do_CRC_byteof(3)
+                 Do_CRC_byteof(4)
+                 Do_CRC_byteof(5)
+                 Do_CRC_byteof(6)
+                 Do_CRC_byteof(7)
+                 Do_CRC_byteof(8)
+                 Do_CRC_byteof(9)
+                 Do_CRC_byteof(10)
+                 Do_CRC_byteof(11)
+                 Do_CRC_byteof(12)
+                 Do_CRC_byteof(13)
+                 Do_CRC_byteof(14)
+                 Do_CRC_byteof(15)
+                 addl    $16,%esi        ;/* buf += 16 */
+#  endif  /* ?NO_32_BIT_LOADS */
+                decl    %ecx
+                jnz     .L_Next_Sixteen
+
+.L_No_Sixteens:
+                movl    SavLen, %ecx
+                andl    $15, %ecx         /* ecx = len % 16   */
+# ifndef NO_32_BIT_LOADS
+                shrl    $2,%ecx           /* ecx = len / 4    */
+                jz      .L_No_Fours
+.L_Next_Four:
+                Do_CRC_lword
+                decl    %ecx
+                jnz     .L_Next_Four
+.L_No_Fours:
+                movl    SavLen,%ecx
+                andl    $3,%ecx          /* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
+#endif /* !NO_UNROLLED_LOOPS */
+                jz      .L_bail          /* > if (len)                       */
+/* align loop head at start of 486 internal cache line !! */
+                ALIGNMENT
+.L_loupe:                                /* >   do {                         */
+                 Do_CRC_byte             /*       c = CRC32(c,*buf++,crctab);*/
+                decl    %ecx             /* >   } while (--len);             */
+                jnz     .L_loupe
+
+.L_bail:                                 /* > }                              */
+                notl    %eax             /* > return ~c;                     */
+.L_fine:
+                popl    %ecx
+                popl    %edx
+                popl    %ebx
+                popl    %esi
+                popl    %edi
+                _STD_LEAVE
+                ret
+
+#else
+ error: this asm version is for 386 only
+#endif /* i386 || _i386 || _I386 || __i386 */
+
+#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: zip/create-3.0-exec-shield-patch/zip30-new/match.S
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new/match.S	(nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new/match.S	(revision 5)
@@ -0,0 +1,410 @@
+/*
+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2004-May-22 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.info-zip.org/pub/infozip/license.html
+*/
+
+/*
+ * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel.
+ * The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
+ * with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
+ * Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
+ * Kristoffer Eriksson <ske@pkmab.se>
+ */
+
+/* This file is NOT used in conjunction with zlib. */
+#ifndef USE_ZLIB
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+#  define _prev             prev
+#  define _window           window
+#  define _match_start      match_start
+#  define _prev_length      prev_length
+#  define _good_match       good_match
+#  define _nice_match       nice_match
+#  define _strstart         strstart
+#  define _max_chain_length max_chain_length
+
+#  define _match_init       match_init
+#  define _longest_match    longest_match
+#endif
+
+#ifdef DYN_ALLOC
+  error: DYN_ALLOC not yet supported in match.s
+#endif
+
+/* Use 16-bytes alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-bytes alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+#  define ALIGNMENT 4
+#endif
+
+
+#ifndef WSIZE
+# define WSIZE          32768
+#endif
+#define MIN_MATCH       3
+#define MAX_MATCH       258
+#define MIN_LOOKAHEAD   (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_DIST        (WSIZE - MIN_LOOKAHEAD)
+
+#if defined(i386) || defined(_I386) || defined(_i386) || defined(__i386)
+
+/* This version is for 386 Unix or OS/2 in 32 bit mode.
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to force the C version,
+ * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
+ * If you have reduced WSIZE in (g)zip.h, then make sure this is
+ * assembled with an equivalent -DWSIZE=<whatever>.
+ * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
+ */
+
+        .file   "match.S"
+
+        .globl  _match_init
+        .globl  _longest_match
+
+        .text
+
+_match_init:
+        ret
+
+/*-----------------------------------------------------------------------
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+
+        .align  ALIGNMENT
+
+_longest_match: /* int longest_match(cur_match) */
+
+#define cur_match   20(%esp)
+     /* return address */               /* esp+16 */
+        push    %ebp                    /* esp+12 */
+        push    %edi                    /* esp+8  */
+        push    %esi                    /* esp+4  */
+        push    %ebx                    /* esp    */
+
+/*
+ *      match        equ esi
+ *      scan         equ edi
+ *      chain_length equ ebp
+ *      best_len     equ ebx
+ *      limit        equ edx
+ */
+        mov     cur_match,%esi
+        mov     _strstart,%edx
+        mov     _max_chain_length,%ebp /* chain_length = max_chain_length */
+        mov     %edx,%edi
+        sub     $(MAX_DIST),%edx       /* limit = strstart-MAX_DIST */
+        cld                            /* string ops increment si and di */
+        jae     limit_ok
+        sub     %edx,%edx              /* limit = NIL */
+limit_ok:
+        add     $2+_window,%edi        /* edi = offset(window+strstart+2) */
+        mov     _prev_length,%ebx      /* best_len = prev_length */
+        movw    -2(%edi),%cx           /* cx = scan[0..1] */
+        movw    -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
+        cmp     _good_match,%ebx       /* do we have a good match already? */
+        jb      do_scan
+        shr     $2,%ebp                /* chain_length >>= 2 */
+        jmp     do_scan
+
+        .align  ALIGNMENT
+long_loop:
+/* at this point, edi == scan+2, esi == cur_match */
+        movw    -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
+        movw     -2(%edi),%cx           /* cx = scan[0..1] */
+short_loop:
+/*
+ * at this point, di == scan+2, si == cur_match,
+ * ax = scan[best_len-1..best_len] and cx = scan[0..1]
+ */
+        and     $(WSIZE-1), %esi
+        dec     %ebp                    /* --chain_length */
+        movw    _prev(,%esi,2),%si      /* cur_match = prev[cur_match] */
+                                        /* top word of esi is still 0 */
+        jz      the_end
+        cmp     %edx,%esi               /* cur_match <= limit ? */
+        jbe     the_end
+do_scan:
+        cmpw    _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
+        jne     short_loop
+        cmpw    _window(%esi),%cx       /* check min_match_length match */
+        jne     short_loop
+
+        add     $2+_window,%esi         /* si = match */
+        mov     $((MAX_MATCH>>1)-1),%ecx/* scan for at most MAX_MATCH bytes */
+        mov     %edi,%eax               /* ax = scan+2 */
+        repe;   cmpsw                   /* loop until mismatch */
+        je      maxmatch                /* match of length MAX_MATCH? */
+mismatch:
+        movb    -2(%edi),%cl        /* mismatch on first or second byte? */
+        xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
+        subb    -2(%esi),%cl        /* cl = 0 if first bytes equal */
+        sub     %edi,%eax           /* eax = len */
+        sub     $2+_window,%esi     /* esi = cur_match + len */
+        sub     %eax,%esi           /* esi = cur_match */
+        subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
+        adc     $0,%eax             /* eax = carry ? len+1 : len */
+        cmp     %ebx,%eax           /* len > best_len ? */
+        jle     long_loop
+        mov     %esi,_match_start       /* match_start = cur_match */
+        mov     %eax,%ebx               /* ebx = best_len = len */
+#ifdef FULL_SEARCH
+        cmp     $(MAX_MATCH),%eax       /* len >= MAX_MATCH ? */
+#else
+        cmp     _nice_match,%eax        /* len >= nice_match ? */
+#endif
+        jl      long_loop
+the_end:
+        mov     %ebx,%eax               /* result = eax = best_len */
+        pop     %ebx
+        pop     %esi
+        pop     %edi
+        pop     %ebp
+        ret
+        .align  ALIGNMENT
+maxmatch:
+        cmpsb
+        jmp     mismatch
+
+#else /* !(i386 || _I386 || _i386 || __i386) */
+
+/* ======================== 680x0 version ================================= */
+
+#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
+#  ifndef mc68000
+#    define mc68000
+#  endif
+#endif
+
+#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
+#  ifndef mc68020
+#    define mc68020
+#  endif
+#endif
+
+#if defined(mc68020) || defined(mc68000)
+
+#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
+#  define UNALIGNED_OK
+#endif
+
+#ifdef sysV68  /* Try Motorola Delta style */
+
+#  define GLOBAL(symbol)        global  symbol
+#  define TEXT                  text
+#  define FILE(filename)        file    filename
+#  define invert_maybe(src,dst) dst,src
+#  define imm(data)             &data
+#  define reg(register)         %register
+
+#  define addl                  add.l
+#  define addql                 addq.l
+#  define blos                  blo.b
+#  define bhis                  bhi.b
+#  define bras                  bra.b
+#  define clrl                  clr.l
+#  define cmpmb                 cmpm.b
+#  define cmpw                  cmp.w
+#  define cmpl                  cmp.l
+#  define lslw                  lsl.w
+#  define lsrl                  lsr.l
+#  define movel                 move.l
+#  define movew                 move.w
+#  define moveb                 move.b
+#  define moveml                movem.l
+#  define subl                  sub.l
+#  define subw                  sub.w
+#  define subql                 subq.l
+
+#  define IndBase(bd,An)        (bd,An)
+#  define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
+#  define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
+#  define predec(An)            -(An)
+#  define postinc(An)           (An)+
+
+#else /* default style (Sun 3, NeXT, Amiga, Atari) */
+
+#  define GLOBAL(symbol)        .globl  symbol
+#  define TEXT                  .text
+#  define FILE(filename)        .even
+#  define invert_maybe(src,dst) src,dst
+#  if defined(sun) || defined(mc68k)
+#    define imm(data)           #data
+#  else
+#    define imm(data)           \#data
+#  endif
+#  define reg(register)         register
+
+#  define blos                  bcss
+#  if defined(sun) || defined(mc68k)
+#    define movel               movl
+#    define movew               movw
+#    define moveb               movb
+#  endif
+#  define IndBase(bd,An)        An@(bd)
+#  define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l)
+#  define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w)
+#  define predec(An)            An@-
+#  define postinc(An)           An@+
+
+#endif  /* styles */
+
+#define Best_Len        reg(d0)         /* unsigned */
+#define Cur_Match       reg(d1)         /* Ipos */
+#define Loop_Counter    reg(d2)         /* int */
+#define Scan_Start      reg(d3)         /* unsigned short */
+#define Scan_End        reg(d4)         /* unsigned short */
+#define Limit           reg(d5)         /* IPos */
+#define Chain_Length    reg(d6)         /* unsigned */
+#define Scan_Test       reg(d7)
+#define Scan            reg(a0)         /* *uch */
+#define Match           reg(a1)         /* *uch */
+#define Prev_Address    reg(a2)         /* *Pos */
+#define Scan_Ini        reg(a3)         /* *uch */
+#define Match_Ini       reg(a4)         /* *uch */
+#define Stack_Pointer   reg(sp)
+
+        GLOBAL  (_match_init)
+        GLOBAL  (_longest_match)
+
+        TEXT
+
+        FILE    ("match.S")
+
+_match_init:
+        rts
+
+/*-----------------------------------------------------------------------
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+
+/* int longest_match (cur_match) */
+
+#ifdef UNALIGNED_OK
+#  define pushreg       15928           /* d2-d6/a2-a4 */
+#  define popreg        7292
+#else
+#  define pushreg       16184           /* d2-d7/a2-a4 */
+#  define popreg        7420
+#endif
+
+_longest_match:
+        movel   IndBase(4,Stack_Pointer),Cur_Match
+        moveml  imm(pushreg),predec(Stack_Pointer)
+        movel   _max_chain_length,Chain_Length
+        movel   _prev_length,Best_Len
+        movel   imm(_prev),Prev_Address
+        movel   imm(_window+MIN_MATCH),Match_Ini
+        movel   _strstart,Limit
+        movel   Match_Ini,Scan_Ini
+        addl    Limit,Scan_Ini
+        subw    imm(MAX_DIST),Limit
+        bhis    L__limit_ok
+        clrl    Limit
+L__limit_ok:
+        cmpl    invert_maybe(_good_match,Best_Len)
+        blos    L__length_ok
+        lsrl    imm(2),Chain_Length
+L__length_ok:
+        subql   imm(1),Chain_Length
+#ifdef UNALIGNED_OK
+        movew   IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+        movew   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+#else
+        moveb   IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+        lslw    imm(8),Scan_Start
+        moveb   IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start
+        moveb   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+        lslw    imm(8),Scan_End
+        moveb   IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+#endif
+        bras    L__do_scan
+
+L__long_loop:
+#ifdef UNALIGNED_OK
+        movew   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+#else
+        moveb   IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+        lslw    imm(8),Scan_End
+        moveb   IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+#endif
+
+L__short_loop:
+        lslw    imm(1),Cur_Match
+        movew   IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match
+        cmpw    invert_maybe(Limit,Cur_Match)
+        dbls    Chain_Length,L__do_scan
+        bras    L__return
+
+L__do_scan:
+        movel   Match_Ini,Match
+        addl    Cur_Match,Match
+#ifdef UNALIGNED_OK
+        cmpw    invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End)
+        bne     L__short_loop
+        cmpw    invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start)
+        bne     L__short_loop
+#else
+        moveb   IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test
+        lslw    imm(8),Scan_Test
+        moveb   IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test
+        cmpw    invert_maybe(Scan_Test,Scan_End)
+        bne     L__short_loop
+        moveb   IndBase(-MIN_MATCH,Match),Scan_Test
+        lslw    imm(8),Scan_Test
+        moveb   IndBase(-MIN_MATCH+1,Match),Scan_Test
+        cmpw    invert_maybe(Scan_Test,Scan_Start)
+        bne     L__short_loop
+#endif
+
+        movew   imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter
+        movel   Scan_Ini,Scan
+L__scan_loop:
+        cmpmb   postinc(Match),postinc(Scan)
+        dbne    Loop_Counter,L__scan_loop
+
+        subl    Scan_Ini,Scan
+        addql   imm(MIN_MATCH-1),Scan
+        cmpl    invert_maybe(Best_Len,Scan)
+        bls     L__short_loop
+        movel   Scan,Best_Len
+        movel   Cur_Match,_match_start
+#ifdef FULL_SEARCH
+        cmpl    invert_maybe(imm(MAX_MATCH),Best_Len)
+#else
+        cmpl    invert_maybe(_nice_match,Best_Len)
+#endif
+        blos    L__long_loop
+L__return:
+        moveml  postinc(Stack_Pointer),imm(popreg)
+        rts
+
+#else
+ error: this asm version is for 386 or 680x0 only
+#endif /* mc68000 || mc68020 */
+#endif /* i386 || _I386 || _i386 || __i386  */
+
+#endif /* !USE_ZLIB */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: zip/create-3.0-exec-shield-patch/zip30-new
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new	(nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new	(revision 5)

Property changes on: zip/create-3.0-exec-shield-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-exec-shield-patch
===================================================================
--- zip/create-3.0-exec-shield-patch	(nonexistent)
+++ zip/create-3.0-exec-shield-patch	(revision 5)

Property changes on: zip/create-3.0-exec-shield-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-format-security-patch/create.patch.sh
===================================================================
--- zip/create-3.0-format-security-patch/create.patch.sh	(nonexistent)
+++ zip/create-3.0-format-security-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr  zip${version}-orig  zip${version} > zip-${VERSION}-format-security.patch
+
+mv zip-${VERSION}-format-security.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig

Property changes on: zip/create-3.0-format-security-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-format-security-patch/file.list
===================================================================
--- zip/create-3.0-format-security-patch/file.list	(nonexistent)
+++ zip/create-3.0-format-security-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+zip30/zip.c
Index: zip/create-3.0-format-security-patch/zip30-new/zip.c
===================================================================
--- zip/create-3.0-format-security-patch/zip30-new/zip.c	(nonexistent)
+++ zip/create-3.0-format-security-patch/zip30-new/zip.c	(revision 5)
@@ -0,0 +1,6018 @@
+/*
+  zip.c - Zip 3
+
+  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+/*
+ *  zip.c by Mark Adler.
+ */
+#define __ZIP_C
+
+#include "zip.h"
+#include <time.h>       /* for tzset() declaration */
+#if defined(WIN32) || defined(WINDLL)
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+#endif
+#ifdef WINDLL
+#  include <setjmp.h>
+#  include "windll/windll.h"
+#endif
+#define DEFCPYRT        /* main module: enable copyright string defines! */
+#include "revision.h"
+#include "crc32.h"
+#include "crypt.h"
+#include "ttyio.h"
+#include <ctype.h>
+#include <errno.h>
+#ifdef VMS
+#  include <stsdef.h>
+#  include "vms/vmsmunch.h"
+#  include "vms/vms.h"
+#endif
+
+#ifdef MACOS
+#  include "macglob.h"
+   extern MacZipGlobals MacZip;
+   extern int error_level;
+#endif
+
+#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
+#  include <process.h>
+#  if (!defined(P_WAIT) && defined(_P_WAIT))
+#    define P_WAIT _P_WAIT
+#  endif
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef UNICODE_TEST
+# ifdef WIN32
+#  include <direct.h>
+# endif
+#endif
+
+#ifdef BZIP2_SUPPORT
+  /* If IZ_BZIP2 is defined as the location of the bzip2 files then
+     assume the location has been added to include path.  For Unix
+     this is done by the configure script. */
+  /* Also do not need path for bzip2 include if OS includes support
+     for bzip2 library. */
+# include "bzlib.h"
+#endif
+
+#define MAXCOM 256      /* Maximum one-line comment size */
+
+
+/* Local option flags */
+#ifndef DELETE
+#define DELETE  0
+#endif
+#define ADD     1
+#define UPDATE  2
+#define FRESHEN 3
+#define ARCHIVE 4
+local int action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
+local int comadd = 0;   /* 1=add comments for new files */
+local int zipedit = 0;  /* 1=edit zip comment and all file comments */
+local int latest = 0;   /* 1=set zip file time to time of latest file */
+local int test = 0;     /* 1=test zip file with unzip -t */
+local char *unzip_path = NULL; /* where to find unzip */
+local int tempdir = 0;  /* 1=use temp directory (-b) */
+local int junk_sfx = 0; /* 1=junk the sfx prefix */
+#if defined(AMIGA) || defined(MACOS)
+local int filenotes = 0; /* 1=take comments from AmigaDOS/MACOS filenotes */
+#endif
+
+#ifdef EBCDIC
+int aflag = __EBCDIC;   /* Convert EBCDIC to ASCII or stay EBCDIC ? */
+#endif
+#ifdef CMS_MVS
+int bflag = 0;          /* Use text mode as default */
+#endif
+
+#ifdef QDOS
+char _version[] = VERSION;
+#endif
+
+#ifdef WINDLL
+jmp_buf zipdll_error_return;
+#ifdef ZIP64_SUPPORT
+  unsigned long low, high; /* returning 64 bit values for systems without an _int64 */
+  uzoff_t filesize64;
+#endif
+#endif
+
+#if CRYPT
+/* Pointer to crc_table, needed in crypt.c */
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ZCONST ulg near *crc_32_tab;
+# else
+ZCONST uLongf *crc_32_tab;
+# endif
+#endif /* CRYPT */
+
+/* Local functions */
+
+local void freeup  OF((void));
+local int  finish  OF((int));
+#if (!defined(MACOS) && !defined(WINDLL))
+local void handler OF((int));
+local void license OF((void));
+#ifndef VMSCLI
+local void help    OF((void));
+local void help_extended OF((void));
+#endif /* !VMSCLI */
+#endif /* !MACOS && !WINDLL */
+
+/* prereading of arguments is not supported in new command
+   line interpreter get_option() so read filters as arguments
+   are processed and convert to expected array later */
+local int add_filter OF((int flag, char *pattern));
+local int filterlist_to_patterns OF((void));
+/* not used
+ local int get_filters OF((int argc, char **argv));
+*/
+
+/* list to store file arguments */
+local long add_name OF((char *filearg));
+
+
+local int DisplayRunningStats OF((void));
+local int BlankRunningStats OF((void));
+
+#if !defined(WINDLL)
+local void version_info OF((void));
+# if !defined(MACOS)
+local void zipstdout OF((void));
+# endif /* !MACOS */
+local int check_unzip_version OF((char *unzippath));
+local void check_zipfile OF((char *zipname, char *zippath));
+#endif /* !WINDLL */
+
+/* structure used by add_filter to store filters */
+struct filterlist_struct {
+  char flag;
+  char *pattern;
+  struct filterlist_struct *next;
+};
+struct filterlist_struct *filterlist = NULL;  /* start of list */
+struct filterlist_struct *lastfilter = NULL;  /* last filter in list */
+
+/* structure used by add_filearg to store file arguments */
+struct filelist_struct {
+  char *name;
+  struct filelist_struct *next;
+};
+long filearg_count = 0;
+struct filelist_struct *filelist = NULL;  /* start of list */
+struct filelist_struct *lastfile = NULL;  /* last file in list */
+
+local void freeup()
+/* Free all allocations in the 'found' list, the 'zfiles' list and
+   the 'patterns' list. */
+{
+  struct flist far *f;  /* steps through found list */
+  struct zlist far *z;  /* pointer to next entry in zfiles list */
+
+  for (f = found; f != NULL; f = fexpel(f))
+    ;
+  while (zfiles != NULL)
+  {
+    z = zfiles->nxt;
+    if (zfiles->zname && zfiles->zname != zfiles->name)
+      free((zvoid *)(zfiles->zname));
+    if (zfiles->name)
+      free((zvoid *)(zfiles->name));
+    if (zfiles->iname)
+      free((zvoid *)(zfiles->iname));
+    if (zfiles->cext && zfiles->cextra && zfiles->cextra != zfiles->extra)
+      free((zvoid *)(zfiles->cextra));
+    if (zfiles->ext && zfiles->extra)
+      free((zvoid *)(zfiles->extra));
+    if (zfiles->com && zfiles->comment)
+      free((zvoid *)(zfiles->comment));
+    if (zfiles->oname)
+      free((zvoid *)(zfiles->oname));
+#ifdef UNICODE_SUPPORT
+    if (zfiles->uname)
+      free((zvoid *)(zfiles->uname));
+    if (zfiles->zuname)
+      free((zvoid *)(zfiles->zuname));
+    if (zfiles->ouname)
+      free((zvoid *)(zfiles->ouname));
+# ifdef WIN32
+    if (zfiles->namew)
+      free((zvoid *)(zfiles->namew));
+    if (zfiles->inamew)
+      free((zvoid *)(zfiles->inamew));
+    if (zfiles->znamew)
+      free((zvoid *)(zfiles->znamew));
+# endif
+#endif
+    farfree((zvoid far *)zfiles);
+    zfiles = z;
+    zcount--;
+  }
+
+  if (patterns != NULL) {
+    while (pcount-- > 0) {
+      if (patterns[pcount].zname != NULL)
+        free((zvoid *)(patterns[pcount].zname));
+    }
+    free((zvoid *)patterns);
+    patterns = NULL;
+  }
+
+  /* close logfile */
+  if (logfile) {
+    fclose(logfile);
+  }
+}
+
+local int finish(e)
+int e;                  /* exit code */
+/* Process -o and -m options (if specified), free up malloc'ed stuff, and
+   exit with the code e. */
+{
+  int r;                /* return value from trash() */
+  ulg t;                /* latest time in zip file */
+  struct zlist far *z;  /* pointer into zfile list */
+
+  /* If latest, set time to zip file to latest file in zip file */
+  if (latest && zipfile && strcmp(zipfile, "-"))
+  {
+    diag("changing time of zip file to time of latest file in it");
+    /* find latest time in zip file */
+    if (zfiles == NULL)
+       zipwarn("zip file is empty, can't make it as old as latest entry", "");
+    else {
+      t = 0;
+      for (z = zfiles; z != NULL; z = z->nxt)
+        /* Ignore directories in time comparisons */
+#ifdef USE_EF_UT_TIME
+        if (z->iname[z->nam-1] != (char)0x2f)   /* ascii '/' */
+        {
+          iztimes z_utim;
+          ulg z_tim;
+
+          z_tim = ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+                   unix2dostime(&z_utim.mtime) : z->tim);
+          if (t < z_tim)
+            t = z_tim;
+        }
+#else /* !USE_EF_UT_TIME */
+        if (z->iname[z->nam-1] != (char)0x2f    /* ascii '/' */
+            && t < z->tim)
+          t = z->tim;
+#endif /* ?USE_EF_UT_TIME */
+      /* set modified time of zip file to that time */
+      if (t != 0)
+        stamp(zipfile, t);
+      else
+        zipwarn(
+         "zip file has only directories, can't make it as old as latest entry",
+         "");
+    }
+  }
+  if (tempath != NULL)
+  {
+    free((zvoid *)tempath);
+    tempath = NULL;
+  }
+  if (zipfile != NULL)
+  {
+    free((zvoid *)zipfile);
+    zipfile = NULL;
+  }
+  if (in_file != NULL)
+  {
+    fclose(in_file);
+    in_file = NULL;
+  }
+  if (in_path != NULL)
+  {
+    free((zvoid *)in_path);
+    in_path = NULL;
+  }
+  if (out_path != NULL)
+  {
+    free((zvoid *)out_path);
+    out_path = NULL;
+  }
+  if (zcomment != NULL)
+  {
+    free((zvoid *)zcomment);
+    zcomment = NULL;
+  }
+
+
+  /* If dispose, delete all files in the zfiles list that are marked */
+  if (dispose)
+  {
+    diag("deleting files that were added to zip file");
+    if ((r = trash()) != ZE_OK)
+      ZIPERR(r, "was deleting moved files and directories");
+  }
+
+
+  /* Done! */
+  freeup();
+  return e;
+}
+
+void ziperr(c, h)
+int c;                  /* error code from the ZE_ class */
+ZCONST char *h;         /* message about how it happened */
+/* Issue a message for the error, clean up files and memory, and exit. */
+{
+#ifndef WINDLL
+#ifndef MACOS
+  static int error_level = 0;
+#endif
+
+  if (error_level++ > 0)
+     /* avoid recursive ziperr() printouts (his should never happen) */
+     EXIT(ZE_LOGIC);  /* ziperr recursion is an internal logic error! */
+#endif /* !WINDLL */
+
+  if (mesg_line_started) {
+    fprintf(mesg, "\n");
+    mesg_line_started = 0;
+  }
+  if (logfile && logfile_line_started) {
+    fprintf(logfile, "\n");
+    logfile_line_started = 0;
+  }
+  if (h != NULL) {
+    if (PERR(c))
+      fprintf(mesg, "zip I/O error: %s", strerror(errno));
+      /* perror("zip I/O error"); */
+    fflush(mesg);
+    fprintf(mesg, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+#ifdef DOS
+    check_for_windows("Zip");
+#endif
+    if (logfile) {
+      if (PERR(c))
+        fprintf(logfile, "zip I/O error: %s\n", strerror(errno));
+      fprintf(logfile, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+      logfile_line_started = 0;
+    }
+  }
+  if (tempzip != NULL)
+  {
+    if (tempzip != zipfile) {
+      if (current_local_file)
+        fclose(current_local_file);
+      if (y != current_local_file && y != NULL)
+        fclose(y);
+#ifndef DEBUG
+      destroy(tempzip);
+#endif
+      free((zvoid *)tempzip);
+    } else {
+      /* -g option, attempt to restore the old file */
+
+      /* zip64 support 09/05/2003 R.Nausedat */
+      uzoff_t k = 0;                        /* keep count for end header */
+      uzoff_t cb = cenbeg;                  /* get start of central */
+
+      struct zlist far *z;  /* steps through zfiles linked list */
+
+      fprintf(mesg, "attempting to restore %s to its previous state\n",
+         zipfile);
+      if (logfile)
+        fprintf(logfile, "attempting to restore %s to its previous state\n",
+           zipfile);
+
+      zfseeko(y, cenbeg, SEEK_SET);
+
+      tempzn = cenbeg;
+      for (z = zfiles; z != NULL; z = z->nxt)
+      {
+        putcentral(z);
+        tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+        k++;
+      }
+      putend(k, tempzn - cb, cb, zcomlen, zcomment);
+      fclose(y);
+      y = NULL;
+    }
+  }
+
+  if (key != NULL) {
+    free((zvoid *)key);
+    key = NULL;
+  }
+  if (tempath != NULL) {
+    free((zvoid *)tempath);
+    tempath = NULL;
+  }
+  if (zipfile != NULL) {
+    free((zvoid *)zipfile);
+    zipfile = NULL;
+  }
+  if (out_path != NULL) {
+    free((zvoid *)out_path);
+    out_path = NULL;
+  }
+  if (zcomment != NULL) {
+    free((zvoid *)zcomment);
+    zcomment = NULL;
+  }
+
+  freeup();
+#ifndef WINDLL
+  EXIT(c);
+#else
+  longjmp(zipdll_error_return, c);
+#endif
+}
+
+
+void error(h)
+  ZCONST char *h;
+/* Internal error, should never happen */
+{
+  ziperr(ZE_LOGIC, h);
+}
+
+#if (!defined(MACOS) && !defined(WINDLL))
+local void handler(s)
+int s;                  /* signal number (ignored) */
+/* Upon getting a user interrupt, turn echo back on for tty and abort
+   cleanly using ziperr(). */
+{
+#if defined(AMIGA) && defined(__SASC)
+   _abort();
+#else
+#if !defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS)
+  echon();
+  putc('\n', mesg);
+#endif /* !MSDOS */
+#endif /* AMIGA && __SASC */
+  ziperr(ZE_ABORT, "aborting");
+  s++;                                  /* keep some compilers happy */
+}
+#endif /* !MACOS && !WINDLL */
+
+void zipmessage_nl(a, nl)
+ZCONST char *a;     /* message string to output */
+int nl;             /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+   If nl true, print and add new line.  If logfile is
+   open then also write message to log file. */
+{
+  if (noisy) {
+    if (a && strlen(a)) {
+      fprintf(mesg, "%s", a);
+      mesg_line_started = 1;
+    }
+    if (nl) {
+      if (mesg_line_started) {
+        fprintf(mesg, "\n");
+        mesg_line_started = 0;
+      }
+    } else if (a && strlen(a)) {
+      mesg_line_started = 1;
+    }
+    fflush(mesg);
+  }
+  if (logfile) {
+    if (a && strlen(a)) {
+      fprintf(logfile, "%s", a);
+      logfile_line_started = 1;
+    }
+    if (nl) {
+      if (logfile_line_started) {
+        fprintf(logfile, "\n");
+        logfile_line_started = 0;
+      }
+    } else if (a && strlen(a)) {
+      logfile_line_started = 1;
+    }
+    fflush(logfile);
+  }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b;     /* message strings juxtaposed in output */
+/* Print a message to mesg and flush.  Also write to log file if
+   open.  Write new line first if current line has output already. */
+{
+  if (noisy) {
+    if (mesg_line_started)
+      fprintf(mesg, "\n");
+    fprintf(mesg, "%s%s\n", a, b);
+    mesg_line_started = 0;
+    fflush(mesg);
+  }
+  if (logfile) {
+    if (logfile_line_started)
+      fprintf(logfile, "\n");
+    fprintf(logfile, "%s%s\n", a, b);
+    logfile_line_started = 0;
+    fflush(logfile);
+  }
+}
+
+void zipwarn(a, b)
+ZCONST char *a, *b;     /* message strings juxtaposed in output */
+/* Print a warning message to mesg (usually stderr) and return. */
+{
+  if (noisy) {
+    if (mesg_line_started)
+      fprintf(mesg, "\n");
+    fprintf(mesg, "\tzip warning: %s%s\n", a, b);
+    mesg_line_started = 0;
+    fflush(mesg);
+  }
+  if (logfile) {
+    if (logfile_line_started)
+      fprintf(logfile, "\n");
+    fprintf(logfile, "\tzip warning: %s%s\n", a, b);
+    logfile_line_started = 0;
+    fflush(logfile);
+  }
+}
+
+#ifndef WINDLL
+local void license()
+/* Print license information to stdout. */
+{
+  extent i;             /* counter for copyright array */
+
+  for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
+    puts(swlicense[i]);
+}
+
+#ifdef VMSCLI
+void help()
+#else
+local void help()
+#endif
+/* Print help (along with license info) to stdout. */
+{
+  extent i;             /* counter for help array */
+
+  /* help array */
+  static ZCONST char *text[] = {
+#ifdef VMS
+"Zip %s (%s). Usage: zip == \"$ disk:[dir]zip.exe\"",
+#else
+"Zip %s (%s). Usage:",
+#endif
+#ifdef MACOS
+"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+"  The default action is to add or replace zipfile entries from list.",
+" ",
+"  -f   freshen: only changed files  -u   update: only changed or new files",
+"  -d   delete entries in zipfile    -m   move into zipfile (delete OS files)",
+"  -r   recurse into directories     -j   junk (don't record) directory names",
+"  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)",
+"  -1   compress faster              -9   compress better",
+"  -q   quiet operation              -v   verbose operation/print version info",
+"  -c   add one-line comments        -z   add zipfile comment",
+"                                    -o   make zipfile as old as latest entry",
+"  -F   fix zipfile (-FF try harder) -D   do not add directory entries",
+"  -T   test zipfile integrity       -X   eXclude eXtra file attributes",
+#  if CRYPT
+"  -e   encrypt                      -n   don't compress these suffixes"
+#  else
+"  -h   show this help               -n   don't compress these suffixes"
+#  endif
+," -h2  show more help",
+"  Macintosh specific:",
+"  -jj  record Fullpath (+ Volname)  -N store finder-comments as comments",
+"  -df  zip only datafork of a file  -S include finder invisible/system files"
+#else /* !MACOS */
+#ifdef VM_CMS
+"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+#else  /* !VM_CMS */
+"zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+#endif /* ?VM_CMS */
+"  The default action is to add or replace zipfile entries from list, which",
+"  can include the special name - to compress standard input.",
+"  If zipfile and list are omitted, zip compresses stdin to stdout.",
+"  -f   freshen: only changed files  -u   update: only changed or new files",
+"  -d   delete entries in zipfile    -m   move into zipfile (delete OS files)",
+"  -r   recurse into directories     -j   junk (don't record) directory names",
+#ifdef THEOS
+"  -0   store only                   -l   convert CR to CR LF (-ll CR LF to CR)",
+#else
+"  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)",
+#endif
+"  -1   compress faster              -9   compress better",
+"  -q   quiet operation              -v   verbose operation/print version info",
+"  -c   add one-line comments        -z   add zipfile comment",
+"  -@   read names from stdin        -o   make zipfile as old as latest entry",
+"  -x   exclude the following names  -i   include only the following names",
+#ifdef EBCDIC
+#ifdef CMS_MVS
+"  -a   translate to ASCII           -B   force binary read (text is default)",
+#else  /* !CMS_MVS */
+"  -a   translate to ASCII",
+#endif /* ?CMS_MVS */
+#endif /* EBCDIC */
+#ifdef TANDEM
+"                                    -Bn  set Enscribe formatting options",
+#endif
+"  -F   fix zipfile (-FF try harder) -D   do not add directory entries",
+"  -A   adjust self-extracting exe   -J   junk zipfile prefix (unzipsfx)",
+"  -T   test zipfile integrity       -X   eXclude eXtra file attributes",
+#ifdef VMS
+"  -C   preserve case of file names  -C-  down-case all file names",
+"  -C2  preserve case of ODS2 names  -C2- down-case ODS2 file names* (*=default)",
+"  -C5  preserve case of ODS5 names* -C5- down-case ODS5 file names",
+"  -V   save VMS file attributes (-VV also save allocated blocks past EOF)",
+"  -w   store file version numbers\
+   -ww  store file version numbers as \".nnn\"",
+#endif /* def VMS */
+#ifdef NTSD_EAS
+"  -!   use privileges (if granted) to obtain all aspects of WinNT security",
+#endif /* NTSD_EAS */
+#ifdef OS2
+"  -E   use the .LONGNAME Extended attribute (if found) as filename",
+#endif /* OS2 */
+#ifdef S_IFLNK
+"  -y   store symbolic links as the link instead of the referenced file",
+#endif /* !S_IFLNK */
+/*
+"  -R   PKZIP recursion (see manual)",
+*/
+#if defined(MSDOS) || defined(OS2)
+"  -$   include volume label         -S   include system and hidden files",
+#endif
+#ifdef AMIGA
+#  if CRYPT
+"  -N   store filenotes as comments  -e   encrypt",
+"  -h   show this help               -n   don't compress these suffixes"
+#  else
+"  -N   store filenotes as comments  -n   don't compress these suffixes"
+#  endif
+#else /* !AMIGA */
+#  if CRYPT
+"  -e   encrypt                      -n   don't compress these suffixes"
+#  else
+"  -h   show this help               -n   don't compress these suffixes"
+#  endif
+#endif /* ?AMIGA */
+#ifdef RISCOS
+,"  -h2  show more help               -I   don't scan thru Image files"
+#else
+,"  -h2  show more help"
+#endif
+#endif /* ?MACOS */
+#ifdef VMS
+,"  (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND)"
+#endif /* def VMS */
+,"  "
+  };
+
+  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+  {
+    printf(copyright[i], "zip");
+    putchar('\n');
+  }
+  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+  {
+    printf(text[i], VERSION, REVDATE);
+    putchar('\n');
+  }
+}
+
+#ifdef VMSCLI
+void help_extended()
+#else
+local void help_extended()
+#endif
+/* Print extended help to stdout. */
+{
+  extent i;             /* counter for help array */
+
+  /* help array */
+  static ZCONST char *text[] = {
+"",
+"Extended Help for Zip",
+"",
+"See the Zip Manual for more detailed help",
+"",
+"",
+"Zip stores files in zip archives.  The default action is to add or replace",
+"zipfile entries.",
+"",
+"Basic command line:",
+"  zip options archive_name file file ...",
+"",
+"Some examples:",
+"  Add file.txt to z.zip (create z if needed):      zip z file.txt",
+"  Zip all files in current dir:                    zip z *",
+"  Zip files in current dir and subdirs also:       zip -r z .",
+"",
+"Basic modes:",
+" External modes (selects files from file system):",
+"        add      - add new files/update existing files in archive (default)",
+"  -u    update   - add new files/update existing files only if later date",
+"  -f    freshen  - update existing files only (no files added)",
+"  -FS   filesync - update if date or size changed, delete if no OS match",
+" Internal modes (selects entries in archive):",
+"  -d    delete   - delete files from archive (see below)",
+"  -U    copy     - select files in archive to copy (use with --out)",
+"",
+"Basic options:",
+"  -r        recurse into directories (see Recursion below)",
+"  -m        after archive created, delete original files (move into archive)",
+"  -j        junk directory names (store just file names)",
+"  -q        quiet operation",
+"  -v        verbose operation (just \"zip -v\" shows version information)",
+"  -c        prompt for one-line comment for each entry",
+"  -z        prompt for comment for archive (end with just \".\" line or EOF)",
+"  -@        read names to zip from stdin (one path per line)",
+"  -o        make zipfile as old as latest entry",
+"",
+"",
+"Syntax:",
+"  The full command line syntax is:",
+"",
+"    zip [-shortopts ...] [--longopt ...] [zipfile [path path ...]] [-xi list]",
+"",
+"  Any number of short option and long option arguments are allowed",
+"  (within limits) as well as any number of path arguments for files",
+"  to zip up.  If zipfile exists, the archive is read in.  If zipfile",
+"  is \"-\", stream to stdout.  If any path is \"-\", zip stdin.",
+"",
+"Options and Values:",
+"  For short options that take values, use -ovalue or -o value or -o=value",
+"  For long option values, use either --longoption=value or --longoption value",
+"  For example:",
+"    zip -ds 10 --temp-dir=path zipfile path1 path2 --exclude pattern pattern",
+"  Avoid -ovalue (no space between) to avoid confusion",
+"  In particular, be aware of 2-character options.  For example:",
+"    -d -s is (delete, split size) while -ds is (dot size)",
+"  Usually better to break short options across multiple arguments by function",
+"    zip -r -dbdcds 10m -lilalf logfile archive input_directory -ll",
+"",
+"  All args after just \"--\" arg are read verbatim as paths and not options.",
+"    zip zipfile path path ... -- verbatimpath verbatimpath ...",
+"  Use -nw to also disable wildcards, so paths are read literally:",
+"    zip zipfile -nw -- \"-leadingdashpath\" \"a[path].c\" \"path*withwildcard\"",
+"  You may still have to escape or quote arguments to avoid shell expansion",
+"",
+"Wildcards:",
+"  Internally zip supports the following wildcards:",
+"    ?       (or %% or #, depending on OS) matches any single character",
+"    *       matches any number of characters, including zero",
+"    [list]  matches char in list (regex), can do range [ac-f], all but [!bf]",
+"  If port supports [], must escape [ as [[] or use -nw to turn off wildcards",
+"  For shells that expand wildcards, escape (\\* or \"*\") so zip can recurse",
+"    zip zipfile -r . -i \"*.h\"",
+"",
+"  Normally * crosses dir bounds in path, e.g. 'a*b' can match 'ac/db'.  If",
+"   -ws option used, * does not cross dir bounds but ** does",
+"",
+"  For DOS and Windows, [list] is now disabled unless the new option",
+"  -RE       enable [list] (regular expression) matching",
+"  is used to avoid problems with file paths containing \"[\" and \"]\":",
+"    zip files_ending_with_number -RE foo[0-9].c",
+"",
+"Include and Exclude:",
+"  -i pattern pattern ...   include files that match a pattern",
+"  -x pattern pattern ...   exclude files 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.",
+"    zip -x pattern pattern @ zipfile path path ...",
+"",
+"Case matching:",
+"  On most OS the case of patterns must match the case in the archive, unless",
+"  the -ic option is used.",
+"  -ic       ignore case of archive entries",
+"  This option not available on case-sensitive file systems.  On others, case",
+"  ignored when matching files on file system but matching against archive",
+"  entries remains case sensitive for modes -f (freshen), -U (archive copy),",
+"  and -d (delete) because archive paths are always case sensitive.  With",
+"  -ic, all matching ignores case, but it's then possible multiple archive",
+"  entries that differ only in case will match.",
+"",
+"End Of Line Translation (text files only):",
+"  -l        change CR or LF (depending on OS) line end to CR LF (Unix->Win)",
+"  -ll       change CR LF to CR or LF (depending on OS) line end (Win->Unix)",
+"  If first buffer read from file contains binary the translation is skipped",
+"",
+"Recursion:",
+"  -r        recurse paths, include files in subdirs:  zip -r a path path ...",
+"  -R        recurse current dir and match patterns:   zip -R a ptn ptn ...",
+"  Use -i and -x with either to include or exclude paths",
+"  Path root in archive starts at current dir, so if /a/b/c/file and",
+"   current dir is /a/b, 'zip -r archive .' puts c/file in archive",
+"",
+"Date filtering:",
+"  -t date   exclude before (include files modified on this date and later)",
+"  -tt date  include before (include files modified before date)",
+"  Can use both at same time to set a date range",
+"  Dates are mmddyyyy or yyyy-mm-dd",
+"",
+"Deletion, File Sync:",
+"  -d        delete files",
+"  Delete archive entries matching internal archive paths in list",
+"    zip archive -d pattern pattern ...",
+"  Can use -t and -tt to select files in archive, but NOT -x or -i, so",
+"    zip archive -d \"*\" -t 2005-12-27",
+"  deletes all files from archive.zip with date of 27 Dec 2005 and later",
+"  Note the * (escape as \"*\" on Unix) to select all files in archive",
+"",
+"  -FS       file sync",
+"  Similar to update, but files updated if date or size of entry does not",
+"  match file on OS.  Also deletes entry from archive if no matching file",
+"  on OS.",
+"    zip archive_to_update -FS -r dir_used_before",
+"  Result generally same as creating new archive, but unchanged entries",
+"  are copied instead of being read and compressed so can be faster.",
+"      WARNING:  -FS deletes entries so make backup copy of archive first",
+"",
+"Compression:",
+"  -0        store files (no compression)",
+"  -1 to -9  compress fastest to compress best (default is 6)",
+"  -Z cm     set compression method to cm:",
+"              store   - store without compression, same as option -0",
+"              deflate - original zip deflate, same as -1 to -9 (default)",
+"            if bzip2 is enabled:",
+"              bzip2 - use bzip2 compression (need modern unzip)",
+"",
+"Encryption:",
+"  -e        use standard (weak) PKZip 2.0 encryption, prompt for password",
+"  -P pswd   use standard encryption, password is pswd",
+"",
+"Splits (archives created as a set of split files):",
+"  -s ssize  create split archive with splits of size ssize, where ssize nm",
+"              n number and m multiplier (kmgt, default m), 100k -> 100 kB",
+"  -sp       pause after each split closed to allow changing disks",
+"      WARNING:  Archives created with -sp use data descriptors and should",
+"                work with most unzips but may not work with some",
+"  -sb       ring bell when pause",
+"  -sv       be verbose about creating splits",
+"      Split archives CANNOT be updated, but see --out and Copy Mode below",
+"",
+"Using --out (output to new archive):",
+"  --out oa  output to new archive oa",
+"  Instead of updating input archive, create new output archive oa.",
+"  Result is same as without --out but in new archive.  Input archive",
+"  unchanged.",
+"      WARNING:  --out ALWAYS overwrites any existing output file",
+"  For example, to create new_archive like old_archive but add newfile1",
+"  and newfile2:",
+"    zip old_archive newfile1 newfile2 --out new_archive",
+"  Cannot update split archive, so use --out to out new archive:",
+"    zip in_split_archive newfile1 newfile2 --out out_split_archive",
+"  If input is split, output will default to same split size",
+"  Use -s=0 or -s- to turn off splitting to convert split to single file:",
+"    zip in_split_archive -s 0 --out out_single_file_archive",
+"      WARNING:  If overwriting old split archive but need less splits,",
+"                old splits not overwritten are not needed but remain",
+"",
+"Copy Mode (copying from archive to archive):",
+"  -U        (also --copy) select entries in archive to copy (reverse delete)",
+"  Copy Mode copies entries from old to new archive with --out and is used by",
+"  zip when either no input files on command line or -U (--copy) used.",
+"    zip inarchive --copy pattern pattern ... --out outarchive",
+"  To copy only files matching *.c into new archive, excluding foo.c:",
+"    zip old_archive --copy \"*.c\" --out new_archive -x foo.c",
+"  If no input files and --out, copy all entries in old archive:",
+"    zip old_archive --out new_archive",
+"",
+"Streaming and FIFOs:",
+"  prog1 | zip -ll z -      zip output of prog1 to zipfile z, converting CR LF",
+"  zip - -R \"*.c\" | prog2   zip *.c files in current dir and stream to prog2 ",
+"  prog1 | zip | prog2      zip in pipe with no in or out acts like zip - -",
+"  If Zip is Zip64 enabled, streaming stdin creates Zip64 archives by default",
+"   that need PKZip 4.5 unzipper like UnZip 6.0",
+"  WARNING:  Some archives created with streaming use data descriptors and",
+"            should work with most unzips but may not work with some",
+"  Can use -fz- to turn off Zip64 if input not large (< 4 GB):",
+"    prog_with_small_output | zip archive -fz-",
+"",
+"  Zip now can read Unix FIFO (named pipes).  Off by default to prevent zip",
+"  from stopping unexpectedly on unfed pipe, use -FI to enable:",
+"    zip -FI archive fifo",
+"",
+"Dots, counts:",
+"  -db       display running count of bytes processed and bytes to go",
+"              (uncompressed size, except delete and copy show stored size)",
+"  -dc       display running count of entries done and entries to go",
+"  -dd       display dots every 10 MB (or dot size) while processing files",
+"  -dg       display dots globally for archive instead of for each file",
+"    zip -qdgds 10m   will turn off most output except dots every 10 MB",
+"  -ds siz   each dot is siz processed where siz is nm as splits (0 no dots)",
+"  -du       display original uncompressed size for each entry as added",
+"  -dv       display volume (disk) number in format in_disk>out_disk",
+"  Dot size is approximate, especially for dot sizes less than 1 MB",
+"  Dot options don't apply to Scanning files dots (dot/2sec) (-q turns off)",
+"",
+"Logging:",
+"  -lf path  open file at path as logfile (overwrite existing file)",
+"  -la       append to existing logfile",
+"  -li       include info messages (default just warnings and errors)",
+"",
+"Testing archives:",
+"  -T        test completed temp archive with unzip before updating archive",
+"  -TT cmd   use command cmd instead of 'unzip -tqq' to test archive",
+"             On Unix, to use unzip in current directory, could use:",
+"               zip archive file1 file2 -T -TT \"./unzip -tqq\"",
+"             In cmd, {} replaced by temp archive path, else temp appended.",
+"             The return code is checked for success (0 on Unix)",
+"",
+"Fixing archives:",
+"  -F        attempt to fix a mostly intact archive (try this first)",
+"  -FF       try to salvage what can (may get more but less reliable)",
+"  Fix options copy entries from potentially bad archive to new archive.",
+"  -F tries to read archive normally and copy only intact entries, while",
+"  -FF tries to salvage what can and may result in incomplete entries.",
+"  Must use --out option to specify output archive:",
+"    zip -F bad.zip --out fixed.zip",
+"  Use -v (verbose) with -FF to see details:",
+"    zip reallybad.zip -FF -v --out fixed.zip",
+"  Currently neither option fixes bad entries, as from text mode ftp get.",
+"",
+"Difference mode:",
+"  -DF       (also --dif) only include files that have changed or are",
+"             new as compared to the input archive",
+"  Difference mode can be used to create incremental backups.  For example:",
+"    zip --dif full_backup.zip -r somedir --out diff.zip",
+"  will store all new files, as well as any files in full_backup.zip where",
+"  either file time or size have changed from that in full_backup.zip,",
+"  in new diff.zip.  Output archive not excluded automatically if exists,",
+"  so either use -x to exclude it or put outside what is being zipped.",
+"",
+"DOS Archive bit (Windows only):",
+"  -AS       include only files with the DOS Archive bit set",
+"  -AC       after archive created, clear archive bit of included files",
+"      WARNING: Once the archive bits are cleared they are cleared",
+"               Use -T to test the archive before the bits are cleared",
+"               Can also use -sf to save file list before zipping files",
+"",
+"Show files:",
+"  -sf       show files to operate on and exit (-sf- logfile only)",
+"  -su       as -sf but show escaped UTF-8 Unicode names also if exist",
+"  -sU       as -sf but show escaped UTF-8 Unicode names instead",
+"  Any character not in the current locale is escaped as #Uxxxx, where x",
+"  is hex digit, if 16-bit code is sufficient, or #Lxxxxxx if 24-bits",
+"  are needed.  If add -UN=e, Zip escapes all non-ASCII characters.",
+"",
+"Unicode:",
+"  If compiled with Unicode support, Zip stores UTF-8 path of entries.",
+"  This is backward compatible.  Unicode paths allow better conversion",
+"  of entry names between different character sets.",
+"",
+"  New Unicode extra field includes checksum to verify Unicode path",
+"  goes with standard path for that entry (as utilities like ZipNote",
+"  can rename entries).  If these do not match, use below options to",
+"  set what Zip does:",
+"      -UN=Quit     - if mismatch, exit with error",
+"      -UN=Warn     - if mismatch, warn, ignore UTF-8 (default)",
+"      -UN=Ignore   - if mismatch, quietly ignore UTF-8",
+"      -UN=No       - ignore any UTF-8 paths, use standard paths for all",
+"  An exception to -UN=N are entries with new UTF-8 bit set (instead",
+"  of using extra fields).  These are always handled as Unicode.",
+"",
+"  Normally Zip escapes all chars outside current char set, but leaves",
+"  as is supported chars, which may not be OK in path names.  -UN=Escape",
+"  escapes any character not ASCII:",
+"    zip -sU -UN=e archive",
+"  Can use either normal path or escaped Unicode path on command line",
+"  to match files in archive.",
+"",
+"  Zip now stores UTF-8 in entry path and comment fields on systems",
+"  where UTF-8 char set is default, such as most modern Unix, and",
+"  and on other systems in new extra fields with escaped versions in",
+"  entry path and comment fields for backward compatibility.",
+"  Option -UN=UTF8 will force storing UTF-8 in entry path and comment",
+"  fields:",
+"      -UN=UTF8     - store UTF-8 in entry path and comment fields",
+"  This option can be useful for multi-byte char sets on Windows where",
+"  escaped paths and comments can be too long to be valid as the UTF-8",
+"  versions tend to be shorter.",
+"",
+"  Only UTF-8 comments on UTF-8 native systems supported.  UTF-8 comments",
+"  for other systems planned in next release.",
+"",
+"Self extractor:",
+"  -A        Adjust offsets - a self extractor is created by prepending",
+"             the extractor executable to archive, but internal offsets",
+"             are then off.  Use -A to fix offsets.",
+"  -J        Junk sfx - removes prepended extractor executable from",
+"             self extractor, leaving a plain zip archive.",
+"",
+"More option highlights (see manual for additional options and details):",
+"  -b dir    when creating or updating archive, create the temp archive in",
+"             dir, which allows using seekable temp file when writing to a",
+"             write once CD, such archives compatible with more unzips",
+"             (could require additional file copy if on another device)",
+"  -MM       input patterns must match at least one file and matched files",
+"             must be readable or exit with OPEN error and abort archive",
+"             (without -MM, both are warnings only, and if unreadable files",
+"             are skipped OPEN error (18) returned after archive created)",
+"  -nw       no wildcards (wildcards are like any other character)",
+"  -sc       show command line arguments as processed and exit",
+"  -sd       show debugging as Zip does each step",
+"  -so       show all available options on this system",
+"  -X        default=strip old extra fields, -X- keep old, -X strip most",
+"  -ws       wildcards don't span directory boundaries in paths",
+""
+  };
+
+  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+  {
+    printf("%s", text[i]);
+    putchar('\n');
+  }
+#ifdef DOS
+  check_for_windows("Zip");
+#endif
+}
+
+/*
+ * XXX version_info() in a separate file
+ */
+local void version_info()
+/* Print verbose info about program version and compile time options
+   to stdout. */
+{
+  extent i;             /* counter in text arrays */
+  char *envptr;
+
+  /* Bzip2 option string storage (with version). */
+
+#ifdef BZIP2_SUPPORT
+  static char bz_opt_ver[81];
+  static char bz_opt_ver2[81];
+  static char bz_opt_ver3[81];
+#endif
+
+  /* Options info array */
+  static ZCONST char *comp_opts[] = {
+#ifdef ASM_CRC
+    "ASM_CRC",
+#endif
+#ifdef ASMV
+    "ASMV",
+#endif
+#ifdef DYN_ALLOC
+    "DYN_ALLOC",
+#endif
+#ifdef MMAP
+    "MMAP",
+#endif
+#ifdef BIG_MEM
+    "BIG_MEM",
+#endif
+#ifdef MEDIUM_MEM
+    "MEDIUM_MEM",
+#endif
+#ifdef SMALL_MEM
+    "SMALL_MEM",
+#endif
+#ifdef DEBUG
+    "DEBUG",
+#endif
+#ifdef USE_EF_UT_TIME
+    "USE_EF_UT_TIME       (store Universal Time)",
+#endif
+#ifdef NTSD_EAS
+    "NTSD_EAS             (store NT Security Descriptor)",
+#endif
+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+    "NO_W32TIMES_IZFIX",
+#endif
+#ifdef VMS
+#ifdef VMSCLI
+    "VMSCLI",
+#endif
+#ifdef VMS_IM_EXTRA
+    "VMS_IM_EXTRA",
+#endif
+#ifdef VMS_PK_EXTRA
+    "VMS_PK_EXTRA",
+#endif
+#endif /* VMS */
+#ifdef WILD_STOP_AT_DIR
+    "WILD_STOP_AT_DIR     (wildcards do not cross directory boundaries)",
+#endif
+#ifdef WIN32_OEM
+    "WIN32_OEM            (store file paths on Windows as OEM)",
+#endif
+#ifdef BZIP2_SUPPORT
+    bz_opt_ver,
+    bz_opt_ver2,
+    bz_opt_ver3,
+#endif
+#ifdef S_IFLNK
+# ifdef VMS
+    "SYMLINK_SUPPORT      (symbolic links supported, if C RTL permits)",
+# else
+    "SYMLINK_SUPPORT      (symbolic links supported)",
+# endif
+#endif
+#ifdef LARGE_FILE_SUPPORT
+# ifdef USING_DEFAULT_LARGE_FILE_SUPPORT
+    "LARGE_FILE_SUPPORT (default settings)",
+# else
+    "LARGE_FILE_SUPPORT   (can read and write large files on file system)",
+# endif
+#endif
+#ifdef ZIP64_SUPPORT
+    "ZIP64_SUPPORT        (use Zip64 to store large files in archives)",
+#endif
+#ifdef UNICODE_SUPPORT
+    "UNICODE_SUPPORT      (store and read UTF-8 Unicode paths)",
+#endif
+
+#ifdef UNIX
+    "STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field)",
+# ifdef UIDGID_NOT_16BIT
+    "UIDGID_NOT_16BIT     (old Unix 16-bit UID/GID extra field not used)",
+# else
+    "UIDGID_16BIT         (old Unix 16-bit UID/GID extra field also used)",
+# endif
+#endif
+
+#if CRYPT && defined(PASSWD_FROM_STDIN)
+    "PASSWD_FROM_STDIN",
+#endif /* CRYPT & PASSWD_FROM_STDIN */
+    NULL
+  };
+
+  static ZCONST char *zipenv_names[] = {
+#ifndef VMS
+#  ifndef RISCOS
+    "ZIP"
+#  else /* RISCOS */
+    "Zip$Options"
+#  endif /* ?RISCOS */
+#else /* VMS */
+    "ZIP_OPTS"
+#endif /* ?VMS */
+    ,"ZIPOPT"
+#ifdef AZTEC_C
+    ,     /* extremely lame compiler bug workaround */
+#endif
+#ifndef __RSXNT__
+# ifdef __EMX__
+    ,"EMX"
+    ,"EMXOPT"
+# endif
+# if (defined(__GO32__) && (!defined(__DJGPP__) || __DJGPP__ < 2))
+    ,"GO32"
+    ,"GO32TMP"
+# endif
+# if (defined(__DJGPP__) && __DJGPP__ >= 2)
+    ,"TMPDIR"
+# endif
+#endif /* !__RSXNT__ */
+#ifdef RISCOS
+    ,"Zip$Exts"
+#endif
+  };
+
+  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+  {
+    printf(copyright[i], "zip");
+    putchar('\n');
+  }
+
+  for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
+  {
+    printf(versinfolines[i], "Zip", VERSION, REVDATE);
+    putchar('\n');
+  }
+
+  version_local();
+
+  puts("Zip special compilation options:");
+#if WSIZE != 0x8000
+  printf("\tWSIZE=%u\n", WSIZE);
+#endif
+
+  /* Fill in bzip2 version.  (32-char limit valid as of bzip 1.0.3.) */
+#ifdef BZIP2_SUPPORT
+  sprintf( bz_opt_ver,
+   "BZIP2_SUPPORT        (bzip2 library version %.32s)", BZ2_bzlibVersion());
+  sprintf( bz_opt_ver2,
+   "    bzip2 code and library copyright (c) Julian R Seward");
+  sprintf( bz_opt_ver3,
+   "    (See the bzip2 license for terms of use)");
+#endif
+
+  for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
+  {
+    printf("\t%s\n",comp_opts[i]);
+  }
+#ifdef USE_ZLIB
+  if (strcmp(ZLIB_VERSION, zlibVersion()) == 0)
+    printf("\tUSE_ZLIB [zlib version %s]\n", ZLIB_VERSION);
+  else
+    printf("\tUSE_ZLIB [compiled with version %s, using version %s]\n",
+      ZLIB_VERSION, zlibVersion());
+  i++;  /* zlib use means there IS at least one compilation option */
+#endif
+#if CRYPT
+  printf("\t[encryption, version %d.%d%s of %s] (modified for Zip 3)\n\n",
+            CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
+  for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++)
+  {
+    printf("%s", cryptnote[i]);
+    putchar('\n');
+  }
+  ++i;  /* crypt support means there IS at least one compilation option */
+#endif /* CRYPT */
+  if (i == 0)
+      puts("\t[none]");
+
+  puts("\nZip environment options:");
+  for (i = 0; i < sizeof(zipenv_names)/sizeof(char *); i++)
+  {
+    envptr = getenv(zipenv_names[i]);
+    printf("%16s:  %s\n", zipenv_names[i],
+           ((envptr == (char *)NULL || *envptr == 0) ? "[none]" : envptr));
+  }
+#ifdef DOS
+  check_for_windows("Zip");
+#endif
+}
+#endif /* !WINDLL */
+
+
+#ifndef PROCNAME
+/* Default to case-sensitive matching of archive entries for the modes
+   that specifically operate on archive entries, as this archive may
+   have come from a system that allows paths in the archive to differ
+   only by case.  Except for adding ARCHIVE (copy mode), this is how it
+   was done before.  Note that some case-insensitive ports (WIN32, VMS)
+   define their own PROCNAME() in their respective osdep.h that use the
+   filter_match_case flag set to FALSE by the -ic option to enable
+   case-insensitive archive entry mathing. */
+#  define PROCNAME(n) procname(n, (action == ARCHIVE || action == DELETE \
+                                   || action == FRESHEN) \
+                                  && filter_match_case)
+#endif /* PROCNAME */
+
+#ifndef WINDLL
+#ifndef MACOS
+local void zipstdout()
+/* setup for writing zip file on stdout */
+{
+  mesg = stderr;
+  if (isatty(1))
+    ziperr(ZE_PARMS, "cannot write zip file to terminal");
+  if ((zipfile = malloc(4)) == NULL)
+    ziperr(ZE_MEM, "was processing arguments");
+  strcpy(zipfile, "-");
+  /*
+  if ((r = readzipfile()) != ZE_OK)
+    ziperr(r, zipfile);
+  */
+}
+#endif /* !MACOS */
+
+local int check_unzip_version(unzippath)
+  char *unzippath;
+{
+#ifdef ZIP64_SUPPORT
+  /* Here is where we need to check for the version of unzip the user
+   * has.  If creating a Zip64 archive need UnZip 6 or may fail.
+   */
+    char cmd[4004];
+    FILE *unzip_out = NULL;
+    char buf[1001];
+    float UnZip_Version = 0.0;
+
+    cmd[0] = '\0';
+    strncat(cmd, unzippath, 4000);
+    strcat(cmd, " -v");
+
+    if ((unzip_out = popen(cmd, "r")) == NULL) {
+      perror("unzip pipe error");
+    } else {
+      if (fgets(buf, 1000, unzip_out) == NULL) {
+        zipwarn("failed to get information from UnZip", "");
+      } else {
+        /* the first line should start with the version */
+        if (sscanf(buf, "UnZip %f ", &UnZip_Version) < 1) {
+          zipwarn("unexpected output of UnZip -v", "");
+        } else {
+          /* printf("UnZip %f\n", UnZip_Version); */
+
+          while (fgets(buf, 1000, unzip_out)) {
+          }
+        }
+      }
+      pclose(unzip_out);
+    }
+    if (UnZip_Version < 6.0 && zip64_archive) {
+      sprintf(buf, "Found UnZip version %4.2f", UnZip_Version);
+      zipwarn(buf, "");
+      zipwarn("Need UnZip 6.00 or later to test this Zip64 archive", "");
+      return 0;
+    }
+#endif
+  return 1;
+}
+
+local void check_zipfile(zipname, zippath)
+  char *zipname;
+  char *zippath;
+  /* Invoke unzip -t on the given zip file */
+{
+#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
+  int status, len;
+  char *path, *p;
+  char *zipnam;
+
+  if ((zipnam = (char *)malloc(strlen(zipname) + 3)) == NULL)
+    ziperr(ZE_MEM, "was creating unzip zipnam");
+
+# ifdef MSDOS
+  /* Add quotes for MSDOS.  8/11/04 */
+  strcpy(zipnam, "\"");    /* accept spaces in name and path */
+  strcat(zipnam, zipname);
+  strcat(zipnam, "\"");
+# else
+  strcpy(zipnam, zipname);
+# endif
+
+  if (unzip_path) {
+    /* if user gave us the unzip to use go with it */
+    char *here;
+    int len;
+    char *cmd;
+
+    /* Replace first {} with archive name.  If no {} append name to string. */
+    here = strstr(unzip_path, "{}");
+
+    if ((cmd = (char *)malloc(strlen(unzip_path) + strlen(zipnam) + 3)) == NULL)
+      ziperr(ZE_MEM, "was creating unzip cmd");
+
+    if (here) {
+      /* have {} so replace with temp name */
+      len = here - unzip_path;
+      strcpy(cmd, unzip_path);
+      cmd[len] = '\0';
+      strcat(cmd, " ");
+      strcat(cmd, zipnam);
+      strcat(cmd, " ");
+      strcat(cmd, here + 2);
+    } else {
+      /* No {} so append temp name to end */
+      strcpy(cmd, unzip_path);
+      strcat(cmd, " ");
+      strcat(cmd, zipnam);
+    }
+
+    status = system(cmd);
+
+    free(unzip_path);
+    unzip_path = NULL;
+    free(cmd);
+  } else {
+    /* Here is where we need to check for the version of unzip the user
+     * has.  If creating a Zip64 archive need UnZip 6 or may fail.
+     */
+    if (check_unzip_version("unzip") == 0)
+      ZIPERR(ZE_TEST, zipfile);
+
+    status = spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
+                     zipnam, NULL);
+# ifdef __human68k__
+    if (status == -1)
+      perror("unzip");
+# else
+/*
+ * unzip isn't in PATH range, assume an absolute path to zip in argv[0]
+ * and hope that unzip is in the same directory.
+ */
+    if (status == -1) {
+      p = MBSRCHR(zippath, '\\');
+      path = MBSRCHR((p == NULL ? zippath : p), '/');
+      if (path != NULL)
+        p = path;
+      if (p != NULL) {
+        len = (int)(p - zippath) + 1;
+        if ((path = malloc(len + sizeof("unzip.exe"))) == NULL)
+          ziperr(ZE_MEM, "was creating unzip path");
+        memcpy(path, zippath, len);
+        strcpy(&path[len], "unzip.exe");
+
+        if (check_unzip_version(path) == 0)
+          ZIPERR(ZE_TEST, zipfile);
+
+        status = spawnlp(P_WAIT, path, "unzip", verbose ? "-t" : "-tqq",
+                        zipnam, NULL);
+        free(path);
+      }
+      if (status == -1)
+        perror("unzip");
+    }
+  }
+# endif /* ?__human68k__ */
+  free(zipnam);
+  if (status != 0) {
+
+#else /* (MSDOS && !__GO32__) || __human68k__ */
+  char *cmd;
+  int result;
+
+  /* Tell picky compilers to shut up about unused variables */
+  zippath = zippath;
+
+  if (unzip_path) {
+    /* user gave us a path to some unzip (may not be UnZip) */
+    char *here;
+    int len;
+
+    /* Replace first {} with archive name.  If no {} append name to string. */
+    here = strstr(unzip_path, "{}");
+
+    if ((cmd = malloc(strlen(unzip_path) + strlen(zipname) + 3)) == NULL) {
+      ziperr(ZE_MEM, "building command string for testing archive");
+    }
+
+    if (here) {
+      /* have {} so replace with temp name */
+      len = here - unzip_path;
+      strcpy(cmd, unzip_path);
+      cmd[len] = '\0';
+      strcat(cmd, " ");
+# ifdef UNIX
+      strcat(cmd, "'");    /* accept space or $ in name */
+      strcat(cmd, zipname);
+      strcat(cmd, "'");
+# else
+      strcat(cmd, zipname);
+# endif
+      strcat(cmd, " ");
+      strcat(cmd, here + 2);
+    } else {
+      /* No {} so append temp name to end */
+      strcpy(cmd, unzip_path);
+      strcat(cmd, " ");
+# ifdef UNIX
+      strcat(cmd, "'");    /* accept space or $ in name */
+      strcat(cmd, zipname);
+      strcat(cmd, "'");
+# else
+      strcat(cmd, zipname);
+# endif
+    }
+    free(unzip_path);
+    unzip_path = NULL;
+
+  } else {
+    if ((cmd = malloc(20 + strlen(zipname))) == NULL) {
+      ziperr(ZE_MEM, "building command string for testing archive");
+    }
+
+    strcpy(cmd, "unzip -t ");
+# ifdef QDOS
+    strcat(cmd, "-Q4 ");
+# endif
+    if (!verbose) strcat(cmd, "-qq ");
+    if (check_unzip_version("unzip") == 0)
+      ZIPERR(ZE_TEST, zipfile);
+
+# ifdef UNIX
+    strcat(cmd, "'");    /* accept space or $ in name */
+    strcat(cmd, zipname);
+    strcat(cmd, "'");
+# else
+    strcat(cmd, zipname);
+# endif
+  }
+
+  result = system(cmd);
+# ifdef VMS
+  /* Convert success severity to 0, others to non-zero. */
+  result = ((result & STS$M_SEVERITY) != STS$M_SUCCESS);
+# endif /* def VMS */
+  free(cmd);
+  cmd = NULL;
+  if (result) {
+#endif /* ?((MSDOS && !__GO32__) || __human68k__) */
+
+    fprintf(mesg, "test of %s FAILED\n", zipfile);
+    ziperr(ZE_TEST, "original files unmodified");
+  }
+  if (noisy) {
+    fprintf(mesg, "test of %s OK\n", zipfile);
+    fflush(mesg);
+  }
+  if (logfile) {
+    fprintf(logfile, "test of %s OK\n", zipfile);
+    fflush(logfile);
+  }
+}
+#endif /* !WINDLL */
+
+/* get_filters() is replaced by the following
+local int get_filters(argc, argv)
+*/
+
+/* The filter patterns for options -x, -i, and -R are
+   returned by get_option() one at a time, so use a linked
+   list to store until all args are processed.  Then convert
+   to array for processing.
+ */
+
+/* add a filter to the linked list */
+local int add_filter(flag, pattern)
+  int flag;
+  char *pattern;
+{
+  char *iname, *p = NULL;
+  FILE *fp;
+  struct filterlist_struct *filter = NULL;
+
+  /* should never happen */
+  if (flag != 'R' && flag != 'x' && flag != 'i') {
+    ZIPERR(ZE_LOGIC, "bad flag to add_filter");
+  }
+  if (pattern == NULL) {
+    ZIPERR(ZE_LOGIC, "null pattern to add_filter");
+  }
+
+  if (pattern[0] == '@') {
+    /* read file with 1 pattern per line */
+    if (pattern[1] == '\0') {
+      ZIPERR(ZE_PARMS, "missing file after @");
+    }
+    fp = fopen(pattern + 1, "r");
+    if (fp == NULL) {
+      sprintf(errbuf, "%c pattern file '%s'", flag, pattern);
+      ZIPERR(ZE_OPEN, errbuf);
+    }
+    while ((p = getnam(fp)) != NULL) {
+      if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+        ZIPERR(ZE_MEM, "adding filter");
+      }
+      if (filterlist == NULL) {
+        /* first filter */
+        filterlist = filter;         /* start of list */
+        lastfilter = filter;
+      } else {
+        lastfilter->next = filter;   /* link to last filter in list */
+        lastfilter = filter;
+      }
+      iname = ex2in(p, 0, (int *)NULL);
+      free(p);
+      if (iname != NULL) {
+        lastfilter->pattern = in2ex(iname);
+        free(iname);
+      } else {
+        lastfilter->pattern = NULL;
+      }
+      lastfilter->flag = flag;
+      pcount++;
+      lastfilter->next = NULL;
+    }
+    fclose(fp);
+  } else {
+    /* single pattern */
+    if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+      ZIPERR(ZE_MEM, "adding filter");
+    }
+    if (filterlist == NULL) {
+      /* first pattern */
+      filterlist = filter;         /* start of list */
+      lastfilter = filter;
+    } else {
+      lastfilter->next = filter;   /* link to last filter in list */
+      lastfilter = filter;
+    }
+    iname = ex2in(pattern, 0, (int *)NULL);
+    if (iname != NULL) {
+       lastfilter->pattern = in2ex(iname);
+       free(iname);
+    } else {
+      lastfilter->pattern = NULL;
+    }
+    lastfilter->flag = flag;
+    pcount++;
+    lastfilter->next = NULL;
+  }
+
+  return pcount;
+}
+
+/* convert list to patterns array */
+local int filterlist_to_patterns()
+{
+  unsigned i;
+  struct filterlist_struct *next = NULL;
+
+  if (pcount == 0) {
+    patterns = NULL;
+    return 0;
+  }
+  if ((patterns = (struct plist *) malloc((pcount + 1) * sizeof(struct plist)))
+      == NULL) {
+    ZIPERR(ZE_MEM, "was creating pattern list");
+  }
+
+  for (i = 0; i < pcount && filterlist != NULL; i++) {
+    switch (filterlist->flag) {
+      case 'i':
+        icount++;
+        break;
+      case 'R':
+        Rcount++;
+        break;
+    }
+    patterns[i].select = filterlist->flag;
+    patterns[i].zname = filterlist->pattern;
+    next = filterlist->next;
+    free(filterlist);
+    filterlist = next;
+  }
+
+  return pcount;
+}
+
+
+/* add a file argument to linked list */
+local long add_name(filearg)
+  char *filearg;
+{
+  char *name = NULL;
+  struct filelist_struct *fileentry = NULL;
+
+  if ((fileentry = (struct filelist_struct *) malloc(sizeof(struct filelist_struct))) == NULL) {
+    ZIPERR(ZE_MEM, "adding file");
+  }
+  if ((name = malloc(strlen(filearg) + 1)) == NULL) {
+    ZIPERR(ZE_MEM, "adding file");
+  }
+  strcpy(name, filearg);
+  fileentry->next = NULL;
+  fileentry->name = name;
+  if (filelist == NULL) {
+    /* first file argument */
+    filelist = fileentry;         /* start of list */
+    lastfile = fileentry;
+  } else {
+    lastfile->next = fileentry;   /* link to last filter in list */
+    lastfile = fileentry;
+  }
+  filearg_count++;
+
+  return filearg_count;
+}
+
+
+/* Running Stats
+   10/30/04 */
+
+local int DisplayRunningStats()
+{
+  char tempstrg[100];
+
+  if (mesg_line_started) {
+    fprintf(mesg, "\n");
+    mesg_line_started = 0;
+  }
+  if (logfile_line_started) {
+    fprintf(logfile, "\n");
+    logfile_line_started = 0;
+  }
+  if (display_volume) {
+    if (noisy) {
+      fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+      logfile_line_started = 1;
+    }
+  }
+  if (display_counts) {
+    if (noisy) {
+      fprintf(mesg, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+      logfile_line_started = 1;
+    }
+  }
+  if (display_bytes) {
+    /* since file sizes can change as we go, use bytes_so_far from
+       initial scan so all adds up */
+    WriteNumString(bytes_so_far, tempstrg);
+    if (noisy) {
+      fprintf(mesg, "[%4s", tempstrg);
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "[%4s", tempstrg);
+      logfile_line_started = 1;
+    }
+    if (bytes_total >= bytes_so_far) {
+      WriteNumString(bytes_total - bytes_so_far, tempstrg);
+      if (noisy)
+        fprintf(mesg, "/%4s] ", tempstrg);
+      if (logall)
+        fprintf(logfile, "/%4s] ", tempstrg);
+    } else {
+      WriteNumString(bytes_so_far - bytes_total, tempstrg);
+      if (noisy)
+        fprintf(mesg, "-%4s] ", tempstrg);
+      if (logall)
+        fprintf(logfile, "-%4s] ", tempstrg);
+    }
+  }
+  if (noisy)
+      fflush(mesg);
+  if (logall)
+      fflush(logfile);
+
+  return 0;
+}
+
+local int BlankRunningStats()
+{
+  if (display_volume) {
+    if (noisy) {
+      fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+      logfile_line_started = 1;
+    }
+  }
+  if (display_counts) {
+    if (noisy) {
+      fprintf(mesg, "   /    ");
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "   /    ");
+      logfile_line_started = 1;
+    }
+  }
+  if (display_bytes) {
+    if (noisy) {
+      fprintf(mesg, "     /      ");
+      mesg_line_started = 1;
+    }
+    if (logall) {
+      fprintf(logfile, "     /      ");
+      logfile_line_started = 1;
+    }
+  }
+  if (noisy)
+      fflush(mesg);
+  if (logall)
+      fflush(logfile);
+
+  return 0;
+}
+
+#if CRYPT
+#ifndef WINDLL
+int encr_passwd(modeflag, pwbuf, size, zfn)
+int modeflag;
+char *pwbuf;
+int size;
+ZCONST char *zfn;
+{
+    char *prompt;
+
+    /* Tell picky compilers to shut up about unused variables */
+    zfn = zfn;
+
+    prompt = (modeflag == ZP_PW_VERIFY) ?
+              "Verify password: " : "Enter password: ";
+
+    if (getp(prompt, pwbuf, size) == NULL) {
+      ziperr(ZE_PARMS, "stderr is not a tty");
+    }
+    return IZ_PW_ENTERED;
+}
+#endif /* !WINDLL */
+#else /* !CRYPT */
+int encr_passwd(modeflag, pwbuf, size, zfn)
+int modeflag;
+char *pwbuf;
+int size;
+ZCONST char *zfn;
+{
+    /* Tell picky compilers to shut up about unused variables */
+    modeflag = modeflag; pwbuf = pwbuf; size = size; zfn = zfn;
+
+    return ZE_LOGIC;    /* This function should never be called! */
+}
+#endif /* CRYPT */
+
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+  char *temp_name;
+  char *out_path;
+{
+  int r;
+  /* Replace old zip file with new zip file, leaving only the new one */
+  if ((r = replace(out_path, temp_name)) != ZE_OK)
+  {
+    zipwarn("new zip file left as: ", temp_name);
+    free((zvoid *)tempzip);
+    tempzip = NULL;
+    ZIPERR(r, "was replacing split file");
+  }
+  if (zip_attributes) {
+    setfileattr(out_path, zip_attributes);
+  }
+  return ZE_OK;
+}
+
+
+int set_filetype(out_path)
+  char *out_path;
+{
+#ifdef __BEOS__
+  /* Set the filetype of the zipfile to "application/zip" */
+  setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+  /* Set the filetype of the zipfile to "application/x-zip" */
+  setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+  /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+  setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+  /* Set the filetype of the zipfile to &DDC */
+  setfiletype(out_path, 0xDDC);
+#endif
+  return ZE_OK;
+}
+
+
+/*
+  -------------------------------------------------------
+  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 argument).  To add an option to zip just add it
+  to this table and add a case in the main switch to handle
+  it.  If either shortopt or longopt not used set to "".
+
+   The fields:
+       shortopt     - short option name (1 or 2 chars)
+       longopt      - long option name
+       value_type   - see zip.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
+*/
+
+/* Most option IDs are set to the shortopt char.  For
+   multichar short options set to arbitrary unused constant. */
+#define o_AC            0x101
+#define o_AS            0x102
+#define o_C2            0x103
+#define o_C5            0x104
+#define o_db            0x105
+#define o_dc            0x106
+#define o_dd            0x107
+#define o_des           0x108
+#define o_df            0x109
+#define o_DF            0x110
+#define o_dg            0x111
+#define o_ds            0x112
+#define o_du            0x113
+#define o_dv            0x114
+#define o_FF            0x115
+#define o_FI            0x116
+#define o_FS            0x117
+#define o_h2            0x118
+#define o_ic            0x119
+#define o_jj            0x120
+#define o_la            0x121
+#define o_lf            0x122
+#define o_li            0x123
+#define o_ll            0x124
+#define o_mm            0x125
+#define o_MM            0x126
+#define o_nw            0x127
+#define o_RE            0x128
+#define o_sb            0x129
+#define o_sc            0x130
+#define o_sd            0x131
+#define o_sf            0x132
+#define o_so            0x133
+#define o_sp            0x134
+#define o_su            0x135
+#define o_sU            0x136
+#define o_sv            0x137
+#define o_tt            0x138
+#define o_TT            0x139
+#define o_UN            0x140
+#define o_ve            0x141
+#define o_VV            0x142
+#define o_ws            0x143
+#define o_ww            0x144
+#define o_z64           0x145
+#ifdef UNICODE_TEST
+#define o_sC            0x146
+#endif
+
+
+/* the below is mainly from the old main command line
+   switch with a few changes */
+struct option_struct far options[] = {
+  /* short longopt        value_type        negatable        ID    name */
+#ifdef EBCDIC
+    {"a",  "ascii",       o_NO_VALUE,       o_NOT_NEGATABLE, 'a',  "to ascii"},
+#endif /* EBCDIC */
+#ifdef CMS_MVS
+    {"B",  "binary",      o_NO_VALUE,       o_NOT_NEGATABLE, 'B',  "binary"},
+#endif /* CMS_MVS */
+#ifdef TANDEM
+    {"B",  "",            o_NUMBER_VALUE,   o_NOT_NEGATABLE, 'B',  "nsk"},
+#endif
+    {"0",  "store",       o_NO_VALUE,       o_NOT_NEGATABLE, '0',  "store"},
+    {"1",  "compress-1",  o_NO_VALUE,       o_NOT_NEGATABLE, '1',  "compress 1"},
+    {"2",  "compress-2",  o_NO_VALUE,       o_NOT_NEGATABLE, '2',  "compress 2"},
+    {"3",  "compress-3",  o_NO_VALUE,       o_NOT_NEGATABLE, '3',  "compress 3"},
+    {"4",  "compress-4",  o_NO_VALUE,       o_NOT_NEGATABLE, '4',  "compress 4"},
+    {"5",  "compress-5",  o_NO_VALUE,       o_NOT_NEGATABLE, '5',  "compress 5"},
+    {"6",  "compress-6",  o_NO_VALUE,       o_NOT_NEGATABLE, '6',  "compress 6"},
+    {"7",  "compress-7",  o_NO_VALUE,       o_NOT_NEGATABLE, '7',  "compress 7"},
+    {"8",  "compress-8",  o_NO_VALUE,       o_NOT_NEGATABLE, '8',  "compress 8"},
+    {"9",  "compress-9",  o_NO_VALUE,       o_NOT_NEGATABLE, '9',  "compress 9"},
+    {"A",  "adjust-sfx",  o_NO_VALUE,       o_NOT_NEGATABLE, 'A',  "adjust self extractor offsets"},
+#if defined(WIN32)
+    {"AC", "archive-clear", o_NO_VALUE,     o_NOT_NEGATABLE, o_AC, "clear DOS archive bit of included files"},
+    {"AS", "archive-set", o_NO_VALUE,       o_NOT_NEGATABLE, o_AS, "include only files with archive bit set"},
+#endif
+    {"b",  "temp-path",   o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b',  "dir to use for temp archive"},
+    {"c",  "entry-comments", o_NO_VALUE,    o_NOT_NEGATABLE, 'c',  "add comments for each entry"},
+#ifdef VMS
+    {"C",  "preserve-case", o_NO_VALUE,     o_NEGATABLE,     'C',  "Preserve (C-: down-) case all on VMS"},
+    {"C2", "preserve-case-2", o_NO_VALUE,   o_NEGATABLE,     o_C2, "Preserve (C2-: down-) case ODS2 on VMS"},
+    {"C5", "preserve-case-5", o_NO_VALUE,   o_NEGATABLE,     o_C5, "Preserve (C5-: down-) case ODS5 on VMS"},
+#endif /* VMS */
+    {"d",  "delete",      o_NO_VALUE,       o_NOT_NEGATABLE, 'd',  "delete entries from archive"},
+    {"db", "display-bytes", o_NO_VALUE,     o_NEGATABLE,     o_db, "display running bytes"},
+    {"dc", "display-counts", o_NO_VALUE,    o_NEGATABLE,     o_dc, "display running file count"},
+    {"dd", "display-dots", o_NO_VALUE,      o_NEGATABLE,     o_dd, "display dots as process each file"},
+    {"dg", "display-globaldots",o_NO_VALUE, o_NEGATABLE,     o_dg, "display dots for archive instead of files"},
+    {"ds", "dot-size",     o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_ds, "set progress dot size - default 10M bytes"},
+    {"du", "display-usize", o_NO_VALUE,     o_NEGATABLE,     o_du, "display uncompressed size in bytes"},
+    {"dv", "display-volume", o_NO_VALUE,    o_NEGATABLE,     o_dv, "display volume (disk) number"},
+#ifdef MACOS
+    {"df", "datafork",    o_NO_VALUE,       o_NOT_NEGATABLE, o_df, "save datafork"},
+#endif /* MACOS */
+    {"D",  "no-dir-entries", o_NO_VALUE,    o_NOT_NEGATABLE, 'D',  "no entries for dirs themselves (-x */)"},
+    {"DF", "difference-archive",o_NO_VALUE, o_NOT_NEGATABLE, o_DF, "create diff archive with changed/new files"},
+    {"e",  "encrypt",     o_NO_VALUE,       o_NOT_NEGATABLE, 'e',  "encrypt entries, ask for password"},
+#ifdef OS2
+    {"E",  "longnames",   o_NO_VALUE,       o_NOT_NEGATABLE, 'E',  "use OS2 longnames"},
+#endif
+    {"F",  "fix",         o_NO_VALUE,       o_NOT_NEGATABLE, 'F',  "fix mostly intact archive (try first)"},
+    {"FF", "fixfix",      o_NO_VALUE,       o_NOT_NEGATABLE, o_FF, "try harder to fix archive (not as reliable)"},
+    {"FI", "fifo",        o_NO_VALUE,       o_NEGATABLE,     o_FI, "read Unix FIFO (zip will wait on open pipe)"},
+    {"FS", "filesync",    o_NO_VALUE,       o_NOT_NEGATABLE, o_FS, "add/delete entries to make archive match OS"},
+    {"f",  "freshen",     o_NO_VALUE,       o_NOT_NEGATABLE, 'f',  "freshen existing archive entries"},
+    {"fd", "force-descriptors", o_NO_VALUE, o_NOT_NEGATABLE, o_des,"force data descriptors as if streaming"},
+#ifdef ZIP64_SUPPORT
+    {"fz", "force-zip64", o_NO_VALUE,       o_NEGATABLE,     o_z64,"force use of Zip64 format, negate prevents"},
+#endif
+    {"g",  "grow",        o_NO_VALUE,       o_NOT_NEGATABLE, 'g',  "grow existing archive instead of replace"},
+#ifndef WINDLL
+    {"h",  "help",        o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
+    {"H",  "",            o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
+    {"?",  "",            o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
+    {"h2", "more-help",   o_NO_VALUE,       o_NOT_NEGATABLE, o_h2, "extended help"},
+#endif /* !WINDLL */
+    {"i",  "include",     o_VALUE_LIST,     o_NOT_NEGATABLE, 'i',  "include only files matching patterns"},
+#if defined(VMS) || defined(WIN32)
+    {"ic", "ignore-case", o_NO_VALUE,       o_NEGATABLE,     o_ic, "ignore case when matching archive entries"},
+#endif
+#ifdef RISCOS
+    {"I",  "no-image",    o_NO_VALUE,       o_NOT_NEGATABLE, 'I',  "no image"},
+#endif
+    {"j",  "junk-paths",  o_NO_VALUE,       o_NOT_NEGATABLE, 'j',  "strip paths and just store file names"},
+#ifdef MACOS
+    {"jj", "absolute-path", o_NO_VALUE,     o_NOT_NEGATABLE, o_jj, "MAC absolute path"},
+#endif /* ?MACOS */
+    {"J",  "junk-sfx",    o_NO_VALUE,       o_NOT_NEGATABLE, 'J',  "strip self extractor from archive"},
+    {"k",  "DOS-names",   o_NO_VALUE,       o_NOT_NEGATABLE, 'k',  "force use of 8.3 DOS names"},
+    {"l",  "to-crlf",     o_NO_VALUE,       o_NOT_NEGATABLE, 'l',  "convert text file line ends - LF->CRLF"},
+    {"ll", "from-crlf",   o_NO_VALUE,       o_NOT_NEGATABLE, o_ll, "convert text file line ends - CRLF->LF"},
+    {"lf", "logfile-path",o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_lf, "log to log file at path (default overwrite)"},
+    {"la", "log-append",  o_NO_VALUE,       o_NEGATABLE,     o_la, "append to existing log file"},
+    {"li", "log-info",    o_NO_VALUE,       o_NEGATABLE,     o_li, "include informational messages in log"},
+#ifndef WINDLL
+    {"L",  "license",     o_NO_VALUE,       o_NOT_NEGATABLE, 'L',  "display license"},
+#endif
+    {"m",  "move",        o_NO_VALUE,       o_NOT_NEGATABLE, 'm',  "add files to archive then delete files"},
+    {"mm", "",            o_NO_VALUE,       o_NOT_NEGATABLE, o_mm, "not used"},
+    {"MM", "must-match",  o_NO_VALUE,       o_NOT_NEGATABLE, o_MM, "error if in file not matched/not readable"},
+    {"n",  "suffixes",    o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'n',  "suffixes to not compress: .gz:.zip"},
+    {"nw", "no-wild",     o_NO_VALUE,       o_NOT_NEGATABLE, o_nw, "no wildcards during add or update"},
+#if defined(AMIGA) || defined(MACOS)
+    {"N",  "notes",       o_NO_VALUE,       o_NOT_NEGATABLE, 'N',  "add notes as entry comments"},
+#endif
+    {"o",  "latest-time", o_NO_VALUE,       o_NOT_NEGATABLE, 'o',  "use latest entry time as archive time"},
+    {"O",  "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O',  "set out zipfile different than in zipfile"},
+    {"p",  "paths",       o_NO_VALUE,       o_NOT_NEGATABLE, 'p',  "store paths"},
+    {"P",  "password",    o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'P',  "encrypt entries, option value is password"},
+#if defined(QDOS) || defined(QLZIP)
+    {"Q",  "Q-flag",      o_NUMBER_VALUE,   o_NOT_NEGATABLE, 'Q',  "Q flag"},
+#endif
+    {"q",  "quiet",       o_NO_VALUE,       o_NOT_NEGATABLE, 'q',  "quiet"},
+    {"r",  "recurse-paths", o_NO_VALUE,     o_NOT_NEGATABLE, 'r',  "recurse down listed paths"},
+    {"R",  "recurse-patterns", o_NO_VALUE,  o_NOT_NEGATABLE, 'R',  "recurse current dir and match patterns"},
+    {"RE", "regex",       o_NO_VALUE,       o_NOT_NEGATABLE, o_RE, "allow [list] matching (regex)"},
+    {"s",  "split-size",  o_REQUIRED_VALUE, o_NOT_NEGATABLE, 's',  "do splits, set split size (-s=0 no splits)"},
+    {"sp", "split-pause", o_NO_VALUE,       o_NOT_NEGATABLE, o_sp, "pause while splitting to select destination"},
+    {"sv", "split-verbose", o_NO_VALUE,     o_NOT_NEGATABLE, o_sv, "be verbose about creating splits"},
+    {"sb", "split-bell",  o_NO_VALUE,       o_NOT_NEGATABLE, o_sb, "when pause for next split ring bell"},
+    {"sc", "show-command",o_NO_VALUE,       o_NOT_NEGATABLE, o_sc, "show command line"},
+#ifdef UNICODE_TEST
+    {"sC", "create-files",o_NO_VALUE,       o_NOT_NEGATABLE, o_sC, "create empty files using archive names"},
+#endif
+    {"sd", "show-debug",  o_NO_VALUE,       o_NOT_NEGATABLE, o_sd, "show debug"},
+    {"sf", "show-files",  o_NO_VALUE,       o_NEGATABLE,     o_sf, "show files to operate on and exit"},
+    {"so", "show-options",o_NO_VALUE,       o_NOT_NEGATABLE, o_so, "show options"},
+#ifdef UNICODE_SUPPORT
+    {"su", "show-unicode", o_NO_VALUE,      o_NEGATABLE,     o_su, "as -sf but also show escaped Unicode"},
+    {"sU", "show-just-unicode", o_NO_VALUE, o_NEGATABLE,     o_sU, "as -sf but only show escaped Unicode"},
+#endif
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
+    {"S",  "",            o_NO_VALUE,       o_NOT_NEGATABLE, 'S',  "include system and hidden"},
+#endif /* MSDOS || OS2 || WIN32 || ATARI */
+    {"t",  "from-date",   o_REQUIRED_VALUE, o_NOT_NEGATABLE, 't',  "exclude before date"},
+    {"tt", "before-date", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_tt, "include before date"},
+    {"T",  "test",        o_NO_VALUE,       o_NOT_NEGATABLE, 'T',  "test updates before replacing archive"},
+    {"TT", "unzip-command", o_REQUIRED_VALUE,o_NOT_NEGATABLE,o_TT, "unzip command to use, name is added to end"},
+    {"u",  "update",      o_NO_VALUE,       o_NOT_NEGATABLE, 'u',  "update existing entries and add new"},
+    {"U",  "copy-entries", o_NO_VALUE,      o_NOT_NEGATABLE, 'U',  "select from archive instead of file system"},
+#ifdef UNICODE_SUPPORT
+    {"UN", "unicode",     o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_UN, "UN=quit, warn, ignore, no, escape"},
+#endif
+    {"v",  "verbose",     o_NO_VALUE,       o_NOT_NEGATABLE, 'v',  "display additional information"},
+    {"",   "version",     o_NO_VALUE,       o_NOT_NEGATABLE, o_ve, "(if no other args) show version information"},
+#ifdef VMS
+    {"V",  "VMS-portable", o_NO_VALUE,      o_NOT_NEGATABLE, 'V',  "Store VMS attributes, portable file format"},
+    {"VV", "VMS-specific", o_NO_VALUE,      o_NOT_NEGATABLE, o_VV, "Store VMS attributes, VMS specific format"},
+    {"w",  "VMS-versions", o_NO_VALUE,      o_NOT_NEGATABLE, 'w',  "store VMS versions"},
+    {"ww", "VMS-dot-versions", o_NO_VALUE,  o_NOT_NEGATABLE, o_ww, "store VMS versions as \".nnn\""},
+#endif /* VMS */
+    {"ws", "wild-stop-dirs", o_NO_VALUE,    o_NOT_NEGATABLE, o_ws,  "* stops at /, ** includes any /"},
+    {"x",  "exclude",     o_VALUE_LIST,     o_NOT_NEGATABLE, 'x',  "exclude files matching patterns"},
+/*    {"X",  "no-extra",    o_NO_VALUE,       o_NOT_NEGATABLE, 'X',  "no extra"},
+*/
+    {"X",  "strip-extra", o_NO_VALUE,       o_NEGATABLE,     'X',  "-X- keep all ef, -X strip but critical ef"},
+#ifdef S_IFLNK
+    {"y",  "symlinks",    o_NO_VALUE,       o_NOT_NEGATABLE, 'y',  "store symbolic links"},
+#endif /* S_IFLNK */
+    {"z",  "archive-comment", o_NO_VALUE,   o_NOT_NEGATABLE, 'z',  "ask for archive comment"},
+    {"Z",  "compression-method", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'Z', "compression method"},
+#if defined(MSDOS) || defined(OS2)
+    {"$",  "volume-label", o_NO_VALUE,      o_NOT_NEGATABLE, '$',  "store volume label"},
+#endif
+#ifndef MACOS
+    {"@",  "names-stdin", o_NO_VALUE,       o_NOT_NEGATABLE, '@',  "get file names from stdin, one per line"},
+#endif /* !MACOS */
+#ifdef NTSD_EAS
+    {"!",  "use-privileges", o_NO_VALUE,    o_NOT_NEGATABLE, '!',  "use privileges"},
+#endif
+#ifdef RISCOS
+    {"/",  "exts-to-swap", o_REQUIRED_VALUE, o_NOT_NEGATABLE, '/',  "override Zip$Exts"},
+#endif
+    /* the end of the list */
+    {NULL, NULL,          o_NO_VALUE,       o_NOT_NEGATABLE, 0,    NULL} /* end has option_ID = 0 */
+  };
+
+
+
+#ifndef USE_ZIPMAIN
+int main(argc, argv)
+#else
+int zipmain(argc, argv)
+#endif
+int argc;               /* number of tokens in command line */
+char **argv;            /* command line tokens */
+/* Add, update, freshen, or delete zip entries in a zip file.  See the
+   command help in help() above. */
+{
+  int d;                /* true if just adding to a zip file */
+  char *e;              /* malloc'd comment buffer */
+  struct flist far *f;  /* steps through found linked list */
+  int i;                /* arg counter, root directory flag */
+  int kk;               /* next arg type (formerly another re-use of "k") */
+
+  /* zip64 support 09/05/2003 R.Nausedat */
+  uzoff_t c;            /* start of central directory */
+  uzoff_t t;            /* length of central directory */
+  zoff_t k;             /* marked counter, comment size, entry count */
+  uzoff_t n;            /* total of entry len's */
+
+  int o;                /* true if there were any ZE_OPEN errors */
+  char *p;              /* steps through option arguments */
+  char *pp;             /* temporary pointer */
+  int r;                /* temporary variable */
+  int s;                /* flag to read names from stdin */
+  uzoff_t csize;        /* compressed file size for stats */
+  uzoff_t usize;        /* uncompressed file size for stats */
+  ulg tf;               /* file time */
+  int first_listarg = 0;/* index of first arg of "process these files" list */
+  struct zlist far *v;  /* temporary variable */
+  struct zlist far * far *w;    /* pointer to last link in zfiles list */
+  FILE *x /*, *y */;    /* input and output zip files (y global) */
+  struct zlist far *z;  /* steps through zfiles linked list */
+  int bad_open_is_error = 0; /* if read fails, 0=warning, 1=error */
+#if 0
+  /* does not seem used */
+#ifdef WINDLL
+  int retcode;          /* return code for dll */
+#endif /* WINDLL */
+#endif
+#if (!defined(VMS) && !defined(CMS_MVS))
+  char *zipbuf;         /* stdio buffer for the zip file */
+#endif /* !VMS && !CMS_MVS */
+  FILE *comment_stream; /* set to stderr if anything is read from stdin */
+  int all_current;      /* used by File Sync to determine if all entries are current */
+
+  struct filelist_struct *filearg;
+
+/* used by get_option */
+  unsigned long option; /* option ID returned by get_option */
+  int argcnt = 0;       /* current argcnt in args */
+  int argnum = 0;       /* arg number */
+  int optchar = 0;      /* option state */
+  char *value = NULL;   /* non-option arg, option value or NULL */
+  int negated = 0;      /* 1 = option negated */
+  int fna = 0;          /* current first non-opt arg */
+  int optnum = 0;       /* index in table */
+
+  int show_options = 0; /* show options */
+  int show_what_doing = 0; /* show what doing */
+  int show_args = 0;    /* show command line */
+  int seen_doubledash = 0; /* seen -- argument */
+  int key_needed = 0;   /* prompt for encryption key */
+  int have_out = 0;     /* if set in_path and out_path different archive */
+#ifdef UNICODE_TEST
+  int create_files = 0;
+#endif
+
+  char **args = NULL;  /* could be wide argv */
+
+
+#ifdef THEOS
+  /* the argument expansion from the standard library is full of bugs */
+  /* use mine instead */
+  _setargv(&argc, &argv);
+  setlocale(LC_CTYPE, "I");
+#else
+  SETLOCALE(LC_CTYPE, "");
+#endif
+
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+  /* For Unix, set the locale to UTF-8.  Any UTF-8 locale is
+     OK and they should all be the same.  This allows seeing,
+     writing, and displaying (if the fonts are loaded) all
+     characters in UTF-8. */
+  {
+    char *loc;
+
+    /*
+      loc = setlocale(LC_CTYPE, NULL);
+      printf("  Initial language locale = '%s'\n", loc);
+    */
+
+    loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+    /*
+      printf("langinfo %s\n", nl_langinfo(CODESET));
+    */
+
+    if (loc != NULL) {
+      /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+      using_utf8 = 1;
+      /*
+        printf("  Locale set to %s\n", loc);
+      */
+    } else {
+      /*
+        printf("  Could not set Unicode UTF-8 locale\n");
+      */
+    }
+  }
+# endif
+#endif
+
+#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
+  {
+    extern void DebugMalloc(void);
+    atexit(DebugMalloc);
+  }
+#endif
+
+#ifdef QDOS
+  {
+    extern void QDOSexit(void);
+    atexit(QDOSexit);
+  }
+#endif
+
+#ifdef NLM
+  {
+    extern void NLMexit(void);
+    atexit(NLMexit);
+  }
+#endif
+
+#ifdef RISCOS
+  set_prefix();
+#endif
+
+#ifdef __human68k__
+  fflush(stderr);
+  setbuf(stderr, NULL);
+#endif
+
+/* Re-initialize global variables to make the zip dll re-entrant. It is
+ * possible that we could get away with not re-initializing all of these
+ * but better safe than sorry.
+ */
+#if defined(MACOS) || defined(WINDLL) || defined(USE_ZIPMAIN)
+  action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
+  comadd = 0;   /* 1=add comments for new files */
+  zipedit = 0;  /* 1=edit zip comment and all file comments */
+  latest = 0;   /* 1=set zip file time to time of latest file */
+  before = 0;   /* 0=ignore, else exclude files before this time */
+  after = 0;    /* 0=ignore, else exclude files newer than this time */
+  test = 0;     /* 1=test zip file with unzip -t */
+  unzip_path = NULL; /* where to look for unzip command path */
+  tempdir = 0;  /* 1=use temp directory (-b) */
+  junk_sfx = 0; /* 1=junk the sfx prefix */
+#if defined(AMIGA) || defined(MACOS)
+  filenotes = 0;/* 1=take comments from AmigaDOS/MACOS filenotes */
+#endif
+#ifndef USE_ZIPMAIN
+  zipstate = -1;
+#endif
+  tempzip = NULL;
+  fcount = 0;
+  recurse = 0;         /* 1=recurse into directories; 2=match filenames */
+  dispose = 0;         /* 1=remove files after put in zip file */
+  pathput = 1;         /* 1=store path with name */
+  method = BEST;       /* one of BEST, DEFLATE (only), or STORE (only) */
+  dosify = 0;          /* 1=make new entries look like MSDOS */
+  verbose = 0;         /* 1=report oddities in zip file structure */
+  fix = 0;             /* 1=fix the zip file */
+  adjust = 0;          /* 1=adjust offsets for sfx'd file (keep preamble) */
+  level = 6;           /* 0=fastest compression, 9=best compression */
+  translate_eol = 0;   /* Translate end-of-line LF -> CR LF */
+#if defined(OS2) || defined(WIN32)
+  use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
+#endif
+#ifdef NTSD_EAS
+  use_privileges = 0;     /* 1=use security privileges overrides */
+#endif
+  no_wild = 0;            /* 1 = wildcards are disabled */
+#ifdef WILD_STOP_AT_DIR
+   wild_stop_at_dir = 1;  /* default wildcards do not include / in matches */
+#else
+   wild_stop_at_dir = 0;  /* default wildcards do include / in matches */
+#endif
+
+  skip_this_disk = 0;
+  des_good = 0;           /* Good data descriptor found */
+  des_crc = 0;            /* Data descriptor CRC */
+  des_csize = 0;          /* Data descriptor csize */
+  des_usize = 0;          /* Data descriptor usize */
+
+  dot_size = 0;           /* buffers processed in deflate per dot, 0 = no dots */
+  dot_count = 0;          /* buffers seen, recyles at dot_size */
+
+  display_counts = 0;     /* display running file count */
+  display_bytes = 0;      /* display running bytes remaining */
+  display_globaldots = 0; /* display dots for archive instead of each file */
+  display_volume = 0;     /* display current input and output volume (disk) numbers */
+  display_usize = 0;      /* display uncompressed bytes */
+
+  files_so_far = 0;       /* files processed so far */
+  bad_files_so_far = 0;   /* bad files skipped so far */
+  files_total = 0;        /* files total to process */
+  bytes_so_far = 0;       /* bytes processed so far (from initial scan) */
+  good_bytes_so_far = 0;  /* good bytes read so far */
+  bad_bytes_so_far = 0;   /* bad bytes skipped so far */
+  bytes_total = 0;        /* total bytes to process (from initial scan) */
+
+  logall = 0;             /* 0 = warnings/errors, 1 = all */
+  logfile = NULL;         /* pointer to open logfile or NULL */
+  logfile_append = 0;     /* append to existing logfile */
+  logfile_path = NULL;    /* pointer to path of logfile */
+
+  hidden_files = 0;       /* process hidden and system files */
+  volume_label = 0;       /* add volume label */
+  dirnames = 1;           /* include directory entries by default */
+#if defined(WIN32)
+  only_archive_set = 0;   /* only include if DOS archive bit set */
+  clear_archive_bits = 0; /* clear DOS archive bit of included files */
+#endif
+  linkput = 0;            /* 1=store symbolic links as such */
+  noisy = 1;              /* 0=quiet operation */
+  extra_fields = 1;       /* 0=create minimum, 1=don't copy old, 2=keep old */
+
+  use_descriptors = 0;    /* 1=use data descriptors 12/29/04 */
+  zip_to_stdout = 0;      /* output zipfile to stdout 12/30/04 */
+  allow_empty_archive = 0;/* if no files, create empty archive anyway 12/28/05 */
+  copy_only = 0;          /* 1=copying archive entries only */
+
+  output_seekable = 1;    /* 1 = output seekable 3/13/05 EG */
+
+#ifdef ZIP64_SUPPORT      /* zip64 support 10/4/03 */
+  force_zip64 = -1;       /* if 1 force entries to be zip64 */
+                          /* mainly for streaming from stdin */
+  zip64_entry = 0;        /* current entry needs Zip64 */
+  zip64_archive = 0;      /* if 1 then at least 1 entry needs zip64 */
+#endif
+
+#ifdef UNICODE_SUPPORT
+  utf8_force = 0;         /* 1=force storing UTF-8 as standard per AppNote bit 11 */
+#endif
+
+  unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */
+  unicode_mismatch = 1;   /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+
+  scan_delay = 5;         /* seconds before display Scanning files message */
+  scan_dot_time = 2;      /* time in seconds between Scanning files dots */
+  scan_start = 0;         /* start of scan */
+  scan_last = 0;          /* time of last message */
+  scan_started = 0;       /* scan has started */
+  scan_count = 0;         /* Used for Scanning files ... message */
+
+  before = 0;             /* 0=ignore, else exclude files before this time */
+  after = 0;              /* 0=ignore, else exclude files newer than this time */
+
+  special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
+  key = NULL;             /* Scramble password if scrambling */
+  key_needed = 0;         /* Need scramble password */
+  tempath = NULL;         /* Path for temporary files */
+  patterns = NULL;        /* List of patterns to be matched */
+  pcount = 0;             /* number of patterns */
+  icount = 0;             /* number of include only patterns */
+  Rcount = 0;             /* number of -R include patterns */
+
+  found = NULL;           /* List of names found, or new found entry */
+  fnxt = &found;
+
+  /* used by get_option */
+  argcnt = 0;             /* size of args */
+  argnum = 0;             /* current arg number */
+  optchar = 0;            /* option state */
+  value = NULL;           /* non-option arg, option value or NULL */
+  negated = 0;            /* 1 = option negated */
+  fna = 0;                /* current first nonopt arg */
+  optnum = 0;             /* option index */
+
+  show_options = 0;       /* 1 = show options */
+  show_what_doing = 0;    /* 1 = show what zip doing */
+  show_args = 0;          /* 1 = show command line */
+  seen_doubledash = 0;    /* seen -- argument */
+
+  zipfile = NULL;         /* path of usual in and out zipfile */
+  tempzip = NULL;         /* name of temp file */
+  y = NULL;               /* output file now global so can change in splits */
+  in_file = NULL;         /* current input file for splits */
+  in_split_path = NULL;   /* current in split path */
+  in_path = NULL;         /* used by splits to track changing split locations */
+  out_path = NULL;        /* if set, use -O out_path as output */
+  have_out = 0;           /* if set, in_path and out_path not the same archive */
+
+  total_disks = 0;        /* total disks in archive */
+  current_in_disk = 0;    /* current read split disk */
+  current_in_offset = 0;  /* current offset in current read disk */
+  skip_current_disk = 0;  /* if != 0 and fix then skip entries on this disk */
+
+  zip64_eocd_disk = 0;    /* disk with Zip64 End Of Central Directory Record */
+  zip64_eocd_offset = 0;  /* offset for Zip64 EOCD Record */
+
+  current_local_disk = 0; /* disk with current local header */
+
+  current_disk = 0;           /* current disk number */
+  cd_start_disk = (ulg)-1;    /* central directory start disk */
+  cd_start_offset = 0;        /* offset of start of cd on cd start disk */
+  cd_entries_this_disk = 0;   /* cd entries this disk */
+  total_cd_entries = 0;       /* total cd entries in new/updated archive */
+
+  /* for split method 1 (keep split with local header open and update) */
+  current_local_tempname = NULL; /* name of temp file */
+  current_local_file = NULL;  /* file pointer for current local header */
+  current_local_offset = 0;   /* offset to start of current local header */
+
+  /* global */
+  bytes_this_split = 0;       /* bytes written to the current split */
+  read_split_archive = 0;     /* 1=scanzipf_reg detected spanning signature */
+  split_method = 0;           /* 0=no splits, 1=update LHs, 2=data descriptors */
+  split_size = 0;             /* how big each split should be */
+  split_bell = 0;             /* when pause for next split ring bell */
+  bytes_prev_splits = 0;      /* total bytes written to all splits before this */
+  bytes_this_entry = 0;       /* bytes written for this entry across all splits */
+  noisy_splits = 0;           /* be verbose about creating splits */
+  mesg_line_started = 0;      /* 1=started writing a line to mesg */
+  logfile_line_started = 0;   /* 1=started writing a line to logfile */
+
+  filelist = NULL;
+  filearg_count = 0;
+  allow_empty_archive = 0;    /* if no files, allow creation of empty archive anyway */
+  bad_open_is_error = 0;      /* if read fails, 0=warning, 1=error */
+  unicode_mismatch = 0;       /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+  show_files = 0;             /* show files to operate on and exit */
+  scan_delay = 5;             /* seconds before display Scanning files message */
+  scan_dot_time = 2;          /* time in seconds between Scanning files dots */
+  scan_started = 0;           /* space at start of scan has been displayed */
+  scan_last = 0;              /* Time last dot displayed for Scanning files message */
+  scan_start = 0;             /* Time scanning started for Scanning files message */
+#ifdef UNICODE_SUPPORT
+  use_wide_to_mb_default = 0;
+#endif
+  filter_match_case = 1;      /* default is to match case when matching archive entries */
+  allow_fifo = 0;             /* 1=allow reading Unix FIFOs, waiting if pipe open */
+
+#if !defined(MACOS) && !defined(USE_ZIPMAIN)
+  retcode = setjmp(zipdll_error_return);
+  if (retcode) {
+    return retcode;
+  }
+#endif /* !MACOS */
+#endif /* MACOS || WINDLL */
+
+#if !defined(ALLOW_REGEX) && (defined(MSDOS) || defined(WIN32))
+  allow_regex = 0;        /* 1 = allow [list] matching (regex) */
+#else
+  allow_regex = 1;
+#endif
+
+  mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
+  comment_stream = (FILE *)stdin;
+
+  init_upper();           /* build case map table */
+
+#ifdef LARGE_FILE_SUPPORT
+  /* test if we can support large files - 9/29/04 */
+  if (sizeof(zoff_t) < 8) {
+    ZIPERR(ZE_COMPERR, "LARGE_FILE_SUPPORT enabled but OS not supporting it");
+  }
+#endif
+  /* test if sizes are the same - 12/30/04 */
+  if (sizeof(uzoff_t) != sizeof(zoff_t)){
+    ZIPERR(ZE_COMPERR, "uzoff_t not same size as zoff_t");
+  }
+
+#if (defined(WIN32) && defined(USE_EF_UT_TIME))
+  /* For the Win32 environment, we may have to "prepare" the environment
+     prior to the tzset() call, to work around tzset() implementation bugs.
+   */
+  iz_w32_prepareTZenv();
+#endif
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+#  ifndef VALID_TIMEZONE
+#     define VALID_TIMEZONE(tmp) \
+             (((tmp = getenv("TZ")) != NULL) && (*tmp != '\0'))
+#  endif
+  zp_tz_is_valid = VALID_TIMEZONE(p);
+#if (defined(AMIGA) || defined(DOS))
+  if (!zp_tz_is_valid)
+    extra_fields = 0;     /* disable storing "UT" time stamps */
+#endif /* AMIGA || DOS */
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+/* For systems that do not have tzset() but supply this function using another
+   name (_tzset() or something similar), an appropiate "#define tzset ..."
+   should be added to the system specifc configuration section.  */
+#if (!defined(TOPS20) && !defined(VMS))
+#if (!defined(RISCOS) && !defined(MACOS) && !defined(QDOS))
+#if (!defined(BSD) && !defined(MTS) && !defined(CMS_MVS) && !defined(TANDEM))
+  tzset();
+#endif
+#endif
+#endif
+
+#ifdef VMSCLI
+  {
+      ulg status = vms_zip_cmdline(&argc, &argv);
+      if (!(status & 1))
+            return status;
+  }
+#endif /* VMSCLI */
+
+  /*    Substitutes the extended command line argument list produced by
+   *    the MKS Korn Shell in place of the command line info from DOS.
+   */
+
+  /* extract extended argument list from environment */
+  expand_args(&argc, &argv);
+
+#ifndef WINDLL
+  /* Process arguments */
+  diag("processing arguments");
+  /* First, check if just the help or version screen should be displayed */
+  if (argc == 1 && isatty(1))   /* no arguments, and output screen available */
+  {                             /* show help screen */
+# ifdef VMSCLI
+    VMSCLI_help();
+# else
+    help();
+# endif
+    EXIT(ZE_OK);
+  }
+  /* Check -v here as env arg can change argc.  Handle --version in main switch. */
+  else if (argc == 2 && strcmp(argv[1], "-v") == 0 &&
+           /* only "-v" as argument, and */
+           (isatty(1) || isatty(0)))
+           /* stdout or stdin is connected to console device */
+  {                             /* show diagnostic version info */
+    version_info();
+    EXIT(ZE_OK);
+  }
+# ifndef VMS
+#   ifndef RISCOS
+  envargs(&argc, &argv, "ZIPOPT", "ZIP");  /* get options from environment */
+#   else /* RISCOS */
+  envargs(&argc, &argv, "ZIPOPT", "Zip$Options");  /* get options from environment */
+  getRISCOSexts("Zip$Exts");        /* get the extensions to swap from environment */
+#   endif /* ? RISCOS */
+# else /* VMS */
+  envargs(&argc, &argv, "ZIPOPT", "ZIP_OPTS");  /* 4th arg for unzip compat. */
+# endif /* ?VMS */
+#endif /* !WINDLL */
+
+  zipfile = tempzip = NULL;
+  y = NULL;
+  d = 0;                        /* disallow adding to a zip file */
+#if (!defined(MACOS) && !defined(WINDLL) && !defined(NLM))
+  signal(SIGINT, handler);
+#ifdef SIGTERM                  /* AMIGADOS and others have no SIGTERM */
+  signal(SIGTERM, handler);
+#endif
+# if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
+   signal(SIGABRT, handler);
+# endif
+# ifdef SIGBREAK
+   signal(SIGBREAK, handler);
+# endif
+# ifdef SIGBUS
+   signal(SIGBUS, handler);
+# endif
+# ifdef SIGILL
+   signal(SIGILL, handler);
+# endif
+# ifdef SIGSEGV
+   signal(SIGSEGV, handler);
+# endif
+#endif /* !MACOS && !WINDLL && !NLM */
+#ifdef NLM
+  NLMsignals();
+#endif
+
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+  /* check if this Win32 OS has support for wide character calls */
+  has_win32_wide();
+#endif
+
+  /* make copy of args that can use with insert_arg() used by get_option() */
+  args = copy_args(argv, 0);
+
+  kk = 0;                       /* Next non-option argument type */
+  s = 0;                        /* set by -@ */
+
+  /*
+  -------------------------------------------
+  Process command line using get_option
+  -------------------------------------------
+
+  Each call to get_option() returns either a command
+  line option and possible value or a non-option argument.
+  Arguments are permuted so that all options (-r, -b temp)
+  are returned before non-option arguments (zipfile).
+  Returns 0 when nothing left to read.
+  */
+
+  /* set argnum = 0 on first call to init get_option */
+  argnum = 0;
+
+  /* get_option returns the option ID and updates parameters:
+         args    - usually same as argv if no argument file support
+         argcnt  - current argc for args
+         value   - char* to value (free() when done with it) or NULL if no value
+         negated - option was negated with trailing -
+  */
+
+  while ((option = get_option(&args, &argcnt, &argnum,
+                              &optchar, &value, &negated,
+                              &fna, &optnum, 0)))
+  {
+    switch (option)
+    {
+#ifdef EBCDIC
+      case 'a':
+        aflag = ASCII;
+        printf("Translating to ASCII...\n");
+        break;
+#endif /* EBCDIC */
+#ifdef CMS_MVS
+        case 'B':
+          bflag = 1;
+          printf("Using binary mode...\n");
+          break;
+#endif /* CMS_MVS */
+#ifdef TANDEM
+        case 'B':
+          nskformatopt(value);
+          free(value);
+          break;
+#endif
+
+        case '0':
+          method = STORE; level = 0; break;
+        case '1':  case '2':  case '3':  case '4':
+        case '5':  case '6':  case '7':  case '8':  case '9':
+          /* Set the compression efficacy */
+          level = (int)option - '0';  break;
+        case 'A':   /* Adjust unzipsfx'd zipfile:  adjust offsets only */
+          adjust = 1; break;
+#if defined(WIN32)
+        case o_AC:
+          clear_archive_bits = 1; break;
+        case o_AS:
+          /* Since some directories could be empty if no archive bits are
+             set for files in a directory, don't add directory entries (-D).
+             Just files with the archive bit set are added, including paths
+             (unless paths are excluded).  All major unzips should create
+             directories for the paths as needed. */
+          dirnames = 0;
+          only_archive_set = 1; break;
+#endif /* MSDOS || OS2 || WIN32 */
+        case 'b':   /* Specify path for temporary file */
+          tempdir = 1;
+          tempath = value;
+          break;
+        case 'c':   /* Add comments for new files in zip file */
+          comadd = 1;  break;
+
+        /* -C, -C2, and -C5 are with -V */
+
+        case 'd':   /* Delete files from zip file */
+          if (action != ADD) {
+            ZIPERR(ZE_PARMS, "specify just one action");
+          }
+          action = DELETE;
+          break;
+#ifdef MACOS
+        case o_df:
+          MacZip.DataForkOnly = true;
+          break;
+#endif /* MACOS */
+        case o_db:
+          if (negated)
+            display_bytes = 0;
+          else
+            display_bytes = 1;
+          break;
+        case o_dc:
+          if (negated)
+            display_counts = 0;
+          else
+            display_counts = 1;
+          break;
+        case o_dd:
+          /* display dots */
+          display_globaldots = 0;
+          if (negated) {
+            dot_count = 0;
+          } else {
+            /* set default dot size if dot_size not set (dot_count = 0) */
+            if (dot_count == 0)
+              /* default to 10 MB */
+              dot_size = 10 * 0x100000;
+            dot_count = -1;
+          }
+          break;
+        case o_dg:
+          /* display dots globally for archive instead of for each file */
+          if (negated) {
+            display_globaldots = 0;
+          } else {
+            display_globaldots = 1;
+            /* set default dot size if dot_size not set (dot_count = 0) */
+            if (dot_count == 0)
+              dot_size = 10 * 0x100000;
+            dot_count = -1;
+          }
+          break;
+        case o_ds:
+          /* input dot_size is now actual dot size to account for
+             different buffer sizes */
+          if (value == NULL)
+            dot_size = 10 * 0x100000;
+          else if (value[0] == '\0') {
+            /* default to 10 MB */
+            dot_size = 10 * 0x100000;
+            free(value);
+          } else {
+            dot_size = ReadNumString(value);
+            if (dot_size == (zoff_t)-1) {
+              sprintf(errbuf, "option -ds (--dot-size) has bad size:  '%s'",
+                      value);
+              free(value);
+              ZIPERR(ZE_PARMS, errbuf);
+            }
+            if (dot_size < 0x400) {
+              /* < 1 KB so there is no multiplier, assume MB */
+              dot_size *= 0x100000;
+
+            } else if (dot_size < 0x400L * 32) {
+              /* 1K <= dot_size < 32K */
+              sprintf(errbuf, "dot size must be at least 32 KB:  '%s'", value);
+              free(value);
+              ZIPERR(ZE_PARMS, errbuf);
+
+            } else {
+              /* 32K <= dot_size */
+            }
+            free(value);
+          }
+          dot_count = -1;
+          break;
+        case o_du:
+          if (negated)
+            display_usize = 0;
+          else
+            display_usize = 1;
+          break;
+        case o_dv:
+          if (negated)
+            display_volume = 0;
+          else
+            display_volume = 1;
+          break;
+        case 'D':   /* Do not add directory entries */
+          dirnames = 0; break;
+        case o_DF:  /* Create a difference archive */
+          diff_mode = 1;
+          allow_empty_archive = 1;
+          break;
+        case 'e':   /* Encrypt */
+#if !CRYPT
+          ZIPERR(ZE_PARMS, "encryption not supported");
+#else /* CRYPT */
+          if (key)
+            free(key);
+          key_needed = 1;
+#endif /* !CRYPT */
+          break;
+        case 'F':   /* fix the zip file */
+          fix = 1; break;
+        case o_FF:  /* try harder to fix file */
+          fix = 2; break;
+        case o_FI:
+          if (negated)
+            allow_fifo = 0;
+          else
+            allow_fifo = 1;
+          break;
+        case o_FS:  /* delete exiting entries in archive where there is
+                       no matching file on file system */
+          filesync = 1; break;
+        case 'f':   /* Freshen zip file--overwrite only */
+          if (action != ADD) {
+            ZIPERR(ZE_PARMS, "specify just one action");
+          }
+          action = FRESHEN;
+          break;
+        case 'g':   /* Allow appending to a zip file */
+          d = 1;  break;
+#ifndef WINDLL
+        case 'h': case 'H': case '?':  /* Help */
+#ifdef VMSCLI
+          VMSCLI_help();
+#else
+          help();
+#endif
+          RETURN(finish(ZE_OK));
+#endif /* !WINDLL */
+
+#ifndef WINDLL
+        case o_h2:  /* Extended Help */
+          help_extended();
+          RETURN(finish(ZE_OK));
+#endif /* !WINDLL */
+
+        /* -i is with -x */
+#if defined(VMS) || defined(WIN32)
+        case o_ic:  /* Ignore case (case-insensitive matching of archive entries) */
+          if (negated)
+            filter_match_case = 1;
+          else
+            filter_match_case = 0;
+          break;
+#endif
+#ifdef RISCOS
+        case 'I':   /* Don't scan through Image files */
+          scanimage = 0;
+          break;
+#endif
+#ifdef MACOS
+        case o_jj:   /* store absolute path including volname */
+            MacZip.StoreFullPath = true;
+            break;
+#endif /* ?MACOS */
+        case 'j':   /* Junk directory names */
+          pathput = 0;  break;
+        case 'J':   /* Junk sfx prefix */
+          junk_sfx = 1;  break;
+        case 'k':   /* Make entries using DOS names (k for Katz) */
+          dosify = 1;  break;
+        case 'l':   /* Translate end-of-line */
+          translate_eol = 1; break;
+        case o_ll:
+          translate_eol = 2; break;
+        case o_lf:
+          /* open a logfile */
+          /* allow multiple use of option but only last used */
+          if (logfile_path) {
+            free(logfile_path);
+          }
+          logfile_path = value;
+          break;
+        case o_la:
+          /* append to existing logfile */
+          if (negated)
+            logfile_append = 0;
+          else
+            logfile_append = 1;
+          break;
+        case o_li:
+          /* log all including informational messages */
+          if (negated)
+            logall = 0;
+          else
+            logall = 1;
+          break;
+#ifndef WINDLL
+        case 'L':   /* Show license */
+          license();
+          RETURN(finish(ZE_OK));
+#endif
+        case 'm':   /* Delete files added or updated in zip file */
+          dispose = 1;  break;
+        case o_mm:  /* To prevent use of -mm for -MM */
+          ZIPERR(ZE_PARMS, "-mm not supported, Must_Match is -MM");
+          dispose = 1;  break;
+        case o_MM:  /* Exit with error if input file can't be read */
+          bad_open_is_error = 1; break;
+        case 'n':   /* Don't compress files with a special suffix */
+          special = value;
+          /* special = NULL; */ /* will be set at next argument */
+          break;
+        case o_nw:  /* no wildcards - wildcards are handled like other characters */
+          no_wild = 1;
+          break;
+#if defined(AMIGA) || defined(MACOS)
+        case 'N':   /* Get zipfile comments from AmigaDOS/MACOS filenotes */
+          filenotes = 1; break;
+#endif
+        case 'o':   /* Set zip file time to time of latest file in it */
+          latest = 1;  break;
+        case 'O':   /* Set output file different than input archive */
+          out_path = ziptyp(value);
+          free(value);
+          have_out = 1;
+          break;
+        case 'p':   /* Store path with name */
+          break;            /* (do nothing as annoyance avoidance) */
+        case 'P':   /* password for encryption */
+          if (key != NULL) {
+            free(key);
+          }
+#if CRYPT
+          key = value;
+          key_needed = 0;
+#else
+          ZIPERR(ZE_PARMS, "encryption not supported");
+#endif /* CRYPT */
+          break;
+#if defined(QDOS) || defined(QLZIP)
+        case 'Q':
+          qlflag  = strtol(value, NULL, 10);
+       /* qlflag  = strtol((p+1), &p, 10); */
+       /* p--; */
+          if (qlflag == 0) qlflag = 4;
+          free(value);
+          break;
+#endif
+        case 'q':   /* Quiet operation */
+          noisy = 0;
+#ifdef MACOS
+          MacZip.MacZip_Noisy = false;
+#endif  /* MACOS */
+          if (verbose) verbose--;
+          break;
+        case 'r':   /* Recurse into subdirectories, match full path */
+          if (recurse == 2) {
+            ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+          }
+          recurse = 1;  break;
+        case 'R':   /* Recurse into subdirectories, match filename */
+          if (recurse == 1) {
+            ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+          }
+          recurse = 2;  break;
+
+        case o_RE:   /* Allow [list] matching (regex) */
+          allow_regex = 1; break;
+
+        case o_sc:  /* show command line args */
+          show_args = 1; break;
+#ifdef UNICODE_TEST
+        case o_sC:  /* create empty files from archive names */
+          create_files = 1;
+          show_files = 1; break;
+#endif
+        case o_sd:  /* show debugging */
+          show_what_doing = 1; break;
+        case o_sf:  /* show files to operate on */
+          if (!negated)
+            show_files = 1;
+          else
+            show_files = 2;
+          break;
+        case o_so:  /* show all options */
+          show_options = 1; break;
+#ifdef UNICODE_SUPPORT
+        case o_su:  /* -sf but also show Unicode if exists */
+          if (!negated)
+            show_files = 3;
+          else
+            show_files = 4;
+          break;
+        case o_sU:  /* -sf but only show Unicode if exists or normal if not */
+          if (!negated)
+            show_files = 5;
+          else
+            show_files = 6;
+          break;
+#endif
+
+        case 's':   /* enable split archives */
+          /* get the split size from value */
+          if (strcmp(value, "-") == 0) {
+            /* -s- do not allow splits */
+            split_method = -1;
+          } else {
+            split_size = ReadNumString(value);
+            if (split_size == (uzoff_t)-1) {
+              sprintf(errbuf, "bad split size:  '%s'", value);
+              ZIPERR(ZE_PARMS, errbuf);
+            }
+            if (split_size == 0) {
+              /* do not allow splits */
+              split_method = -1;
+            } else {
+              if (split_method == 0) {
+                split_method = 1;
+              }
+              if (split_size < 0x400) {
+                /* < 1 KB there is no multiplier, assume MB */
+                split_size *= 0x100000;
+              }
+              /* By setting the minimum split size to 64 KB we avoid
+                 not having enough room to write a header unsplit
+                 which is required */
+              if (split_size < 0x400L * 64) {
+                /* split_size < 64K */
+                sprintf(errbuf, "minimum split size is 64 KB:  '%s'", value);
+                free(value);
+                ZIPERR(ZE_PARMS, errbuf);
+              }
+            }
+          }
+          free(value);
+          break;
+        case o_sb:  /* when pause for next split ring bell */
+          split_bell = 1;
+          break;
+        case o_sp:  /* enable split select - pause splitting between splits */
+          use_descriptors = 1;
+          split_method = 2;
+          break;
+        case o_sv:  /* be verbose about creating splits */
+          noisy_splits = 1;
+          break;
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
+        case 'S':
+          hidden_files = 1; break;
+#endif /* MSDOS || OS2 || WIN32 || ATARI */
+#ifdef MACOS
+        case 'S':
+          MacZip.IncludeInvisible = true; break;
+#endif /* MACOS */
+        case 't':   /* Exclude files earlier than specified date */
+          {
+            int yyyy, mm, dd;       /* results of sscanf() */
+
+            /* Support ISO 8601 & American dates */
+            if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+                 sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+                mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+              ZIPERR(ZE_PARMS,
+                     "invalid date entered for -t option - use mmddyyyy or yyyy-mm-dd");
+            }
+            before = dostime(yyyy, mm, dd, 0, 0, 0);
+          }
+          free(value);
+          break;
+        case o_tt:  /* Exclude files at or after specified date */
+          {
+            int yyyy, mm, dd;       /* results of sscanf() */
+
+            /* Support ISO 8601 & American dates */
+            if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+                 sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+                mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+              ZIPERR(ZE_PARMS,
+                     "invalid date entered for -tt option - use mmddyyyy or yyyy-mm-dd");
+            }
+            after = dostime(yyyy, mm, dd, 0, 0, 0);
+          }
+          free(value);
+          break;
+        case 'T':   /* test zip file */
+          test = 1; break;
+        case o_TT:  /* command path to use instead of 'unzip -t ' */
+          if (unzip_path)
+            free(unzip_path);
+          unzip_path = value;
+          break;
+        case 'U':   /* Select archive entries to keep or operate on */
+          if (action != ADD) {
+            ZIPERR(ZE_PARMS, "specify just one action");
+          }
+          action = ARCHIVE;
+          break;
+#ifdef UNICODE_SUPPORT
+        case o_UN:   /* Unicode */
+          if (abbrevmatch("quit", value, 0, 1)) {
+            /* Unicode path mismatch is error */
+            unicode_mismatch = 0;
+          } else if (abbrevmatch("warn", value, 0, 1)) {
+            /* warn of mismatches and continue */
+            unicode_mismatch = 1;
+          } else if (abbrevmatch("ignore", value, 0, 1)) {
+            /* ignore mismatches and continue */
+            unicode_mismatch = 2;
+          } else if (abbrevmatch("no", value, 0, 1)) {
+            /* no use Unicode path */
+            unicode_mismatch = 3;
+          } else if (abbrevmatch("escape", value, 0, 1)) {
+            /* escape all non-ASCII characters */
+            unicode_escape_all = 1;
+
+          } else if (abbrevmatch("UTF8", value, 0, 1)) {
+            /* force storing UTF-8 as standard per AppNote bit 11 */
+            utf8_force = 1;
+
+          } else {
+            zipwarn("-UN must be Quit, Warn, Ignore, No, Escape, or UTF8: ", value);
+
+            free(value);
+            ZIPERR(ZE_PARMS, "-UN (unicode) bad value");
+          }
+          free(value);
+          break;
+#endif
+        case 'u':   /* Update zip file--overwrite only if newer */
+          if (action != ADD) {
+            ZIPERR(ZE_PARMS, "specify just one action");
+          }
+          action = UPDATE;
+          break;
+        case 'v':        /* Either display version information or */
+        case o_ve:       /* Mention oddities in zip file structure */
+          if (option == o_ve ||      /* --version */
+              (argcnt == 2 && strlen(args[1]) == 2)) { /* -v only */
+            /* display version */
+#ifndef WINDLL
+            version_info();
+#else
+            zipwarn("version information not supported for dll", "");
+#endif
+            RETURN(finish(ZE_OK));
+          } else {
+            noisy = 1;
+            verbose++;
+          }
+          break;
+#ifdef VMS
+        case 'C':  /* Preserve case (- = down-case) all. */
+          if (negated)
+          { /* Down-case all. */
+            if ((vms_case_2 > 0) || (vms_case_5 > 0))
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C-)");
+            }
+            vms_case_2 = -1;
+            vms_case_5 = -1;
+          }
+          else
+          { /* Not negated.  Preserve all. */
+            if ((vms_case_2 < 0) || (vms_case_5 < 0))
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C)");
+            }
+            vms_case_2 = 1;
+            vms_case_5 = 1;
+          }
+          break;
+        case o_C2:  /* Preserve case (- = down-case) ODS2. */
+          if (negated)
+          { /* Down-case ODS2. */
+            if (vms_case_2 > 0)
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C2-)");
+            }
+            vms_case_2 = -1;
+          }
+          else
+          { /* Not negated.  Preserve ODS2. */
+            if (vms_case_2 < 0)
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C2)");
+            }
+            vms_case_2 = 1;
+          }
+          break;
+        case o_C5:  /* Preserve case (- = down-case) ODS5. */
+          if (negated)
+          { /* Down-case ODS5. */
+            if (vms_case_5 > 0)
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C5-)");
+            }
+            vms_case_5 = -1;
+          }
+          else
+          { /* Not negated.  Preserve ODS5. */
+            if (vms_case_5 < 0)
+            {
+              ZIPERR( ZE_PARMS, "Conflicting case directives (-C5)");
+            }
+            vms_case_5 = 1;
+          }
+          break;
+        case 'V':   /* Store in VMS format.  (Record multiples.) */
+          vms_native = 1; break;
+          /* below does work with new parser but doesn't allow tracking
+             -VV separately, like adding a separate description */
+          /* vms_native++; break; */
+        case o_VV:  /* Store in VMS specific format */
+          vms_native = 2; break;
+        case 'w':   /* Append the VMS version number */
+          vmsver |= 1;  break;
+        case o_ww:   /* Append the VMS version number as ".nnn". */
+          vmsver |= 3;  break;
+#endif /* VMS */
+        case o_ws:  /* Wildcards do not include directory boundaries in matches */
+          wild_stop_at_dir = 1;
+          break;
+
+        case 'i':   /* Include only the following files */
+          /* if nothing matches include list then still create an empty archive */
+          allow_empty_archive = 1;
+        case 'x':   /* Exclude following files */
+          add_filter((int) option, value);
+          free(value);
+          break;
+#ifdef S_IFLNK
+        case 'y':   /* Store symbolic links as such */
+          linkput = 1;  break;
+#endif /* S_IFLNK */
+        case 'z':   /* Edit zip file comment */
+          zipedit = 1;  break;
+        case 'Z':   /* Compression method */
+          if (abbrevmatch("deflate", value, 0, 1)) {
+            /* deflate */
+            method = DEFLATE;
+          } else if (abbrevmatch("store", value, 0, 1)) {
+            /* store */
+            method = STORE;
+          } else if (abbrevmatch("bzip2", value, 0, 1)) {
+            /* bzip2 */
+#ifdef BZIP2_SUPPORT
+            method = BZIP2;
+#else
+            ZIPERR(ZE_COMPERR, "Compression method bzip2 not enabled");
+#endif
+          } else {
+#ifdef BZIP2_SUPPORT
+            zipwarn("valid compression methods are:  store, deflate, bzip2", "");
+#else
+            zipwarn("valid compression methods are:  store, deflate)", "");
+#endif
+            zipwarn("unknown compression method found:  ", value);
+            free(value);
+            ZIPERR(ZE_PARMS, "Option -Z (--compression-method):  unknown method");
+          }
+          free(value);
+          break;
+#if defined(MSDOS) || defined(OS2)
+        case '$':   /* Include volume label */
+          volume_label = 1; break;
+#endif
+#ifndef MACOS
+        case '@':   /* read file names from stdin */
+          comment_stream = NULL;
+          s = 1;          /* defer -@ until have zipfile name */
+          break;
+#endif /* !MACOS */
+        case 'X':
+          if (negated)
+            extra_fields = 2;
+          else
+            extra_fields = 0;
+          break;
+#ifdef OS2
+        case 'E':
+          /* use the .LONGNAME EA (if any) as the file's name. */
+          use_longname_ea = 1;
+          break;
+#endif
+#ifdef NTSD_EAS
+        case '!':
+          /* use security privilege overrides */
+          use_privileges = 1;
+          break;
+#endif
+#ifdef RISCOS
+        case '/':
+          exts2swap = value; /* override Zip$Exts */
+          break;
+#endif
+        case o_des:
+          use_descriptors = 1;
+          break;
+
+#ifdef ZIP64_SUPPORT
+        case o_z64:   /* Force creation of Zip64 entries */
+          if (negated) {
+            force_zip64 = 0;
+          } else {
+            force_zip64 = 1;
+          }
+          break;
+#endif
+
+        case o_NON_OPTION_ARG:
+          /* not an option */
+          /* no more options as permuting */
+          /* just dash also ends up here */
+
+          if (recurse != 2 && kk == 0 && patterns == NULL) {
+            /* have all filters so convert filterlist to patterns array
+               as PROCNAME needs patterns array */
+            filterlist_to_patterns();
+          }
+
+          /* "--" stops arg processing for remaining args */
+          /* ignore only first -- */
+          if (strcmp(value, "--") == 0 && seen_doubledash == 0) {
+            /* -- */
+            seen_doubledash = 1;
+            if (kk == 0) {
+              ZIPERR(ZE_PARMS, "can't use -- before archive name");
+            }
+
+            /* just ignore as just marks what follows as non-option arguments */
+
+          } else if (kk == 6) {
+            /* value is R pattern */
+            add_filter((int)'R', value);
+            free(value);
+            if (first_listarg == 0) {
+              first_listarg = argnum;
+            }
+          } else switch (kk)
+          {
+            case 0:
+              /* first non-option arg is zipfile name */
+#if (!defined(MACOS) && !defined(WINDLL))
+              if (strcmp(value, "-") == 0) {  /* output zipfile is dash */
+                /* just a dash */
+                zipstdout();
+              } else
+#endif /* !MACOS && !WINDLL */
+              {
+                /* name of zipfile */
+                if ((zipfile = ziptyp(value)) == NULL) {
+                  ZIPERR(ZE_MEM, "was processing arguments");
+                }
+                /* read zipfile if exists */
+                /*
+                if ((r = readzipfile()) != ZE_OK) {
+                  ZIPERR(r, zipfile);
+                }
+                */
+                free(value);
+              }
+              if (show_what_doing) {
+                fprintf(mesg, "sd: Zipfile name '%s'\n", zipfile);
+                fflush(mesg);
+              }
+              /* if in_path not set, use zipfile path as usual for input */
+              /* in_path is used as the base path to find splits */
+              if (in_path == NULL) {
+                if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+                  ZIPERR(ZE_MEM, "was processing arguments");
+                }
+                strcpy(in_path, zipfile);
+              }
+              /* if out_path not set, use zipfile path as usual for output */
+              /* out_path is where the output archive is written */
+              if (out_path == NULL) {
+                if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
+                  ZIPERR(ZE_MEM, "was processing arguments");
+                }
+                strcpy(out_path, zipfile);
+              }
+              kk = 3;
+              if (s)
+              {
+                /* do -@ and get names from stdin */
+                /* should be able to read names from
+                   stdin and output to stdout, but
+                   this was not allowed in old code.
+                   This check moved to kk = 3 case to fix. */
+                /* if (strcmp(zipfile, "-") == 0) {
+                  ZIPERR(ZE_PARMS, "can't use - and -@ together");
+                }
+                */
+                while ((pp = getnam(stdin)) != NULL)
+                {
+                  kk = 4;
+                  if (recurse == 2) {
+                    /* reading patterns from stdin */
+                    add_filter((int)'R', pp);
+                  } else {
+                    /* file argument now processed later */
+                    add_name(pp);
+                  }
+                  /*
+                  if ((r = PROCNAME(pp)) != ZE_OK) {
+                    if (r == ZE_MISS)
+                      zipwarn("name not matched: ", pp);
+                    else {
+                      ZIPERR(r, pp);
+                    }
+                  }
+                  */
+                  free(pp);
+                }
+                s = 0;
+              }
+              if (recurse == 2) {
+                /* rest are -R patterns */
+                kk = 6;
+              }
+              break;
+
+            case 3:  case 4:
+              /* no recurse and -r file names */
+              /* can't read filenames -@ and input - from stdin at
+                 same time */
+              if (s == 1 && strcmp(value, "-") == 0) {
+                ZIPERR(ZE_PARMS, "can't read input (-) and filenames (-@) both from stdin");
+              }
+              /* add name to list for later processing */
+              add_name(value);
+              /*
+              if ((r = PROCNAME(value)) != ZE_OK) {
+                if (r == ZE_MISS)
+                  zipwarn("name not matched: ", value);
+                else {
+                  ZIPERR(r, value);
+                }
+              }
+              */
+              if (kk == 3) {
+                first_listarg = argnum;
+                kk = 4;
+              }
+              break;
+
+            } /* switch kk */
+            break;
+
+        default:
+          /* should never get here as get_option will exit if not in table */
+          sprintf(errbuf, "no such option ID: %ld", option);
+          ZIPERR(ZE_PARMS, errbuf);
+
+     }  /* switch */
+  }
+
+
+  /* do processing of command line and one-time tasks */
+
+  /* Key not yet specified.  If needed, get/verify it now. */
+  if (key_needed) {
+    if ((key = malloc(IZ_PWLEN+1)) == NULL) {
+      ZIPERR(ZE_MEM, "was getting encryption password");
+    }
+    r = encr_passwd(ZP_PW_ENTER, key, IZ_PWLEN+1, zipfile);
+    if (r != IZ_PW_ENTERED) {
+      if (r < IZ_PW_ENTERED)
+        r = ZE_PARMS;
+      ZIPERR(r, "was getting encryption password");
+    }
+    if (*key == '\0') {
+      ZIPERR(ZE_PARMS, "zero length password not allowed");
+    }
+    if ((e = malloc(IZ_PWLEN+1)) == NULL) {
+      ZIPERR(ZE_MEM, "was verifying encryption password");
+    }
+    r = encr_passwd(ZP_PW_VERIFY, e, IZ_PWLEN+1, zipfile);
+    if (r != IZ_PW_ENTERED && r != IZ_PW_SKIPVERIFY) {
+      free((zvoid *)e);
+      if (r < ZE_OK) r = ZE_PARMS;
+      ZIPERR(r, "was verifying encryption password");
+    }
+    r = ((r == IZ_PW_SKIPVERIFY) ? 0 : strcmp(key, e));
+    free((zvoid *)e);
+    if (r) {
+      ZIPERR(ZE_PARMS, "password verification failed");
+    }
+  }
+  if (key) {
+    /* if -P "" could get here */
+    if (*key == '\0') {
+      ZIPERR(ZE_PARMS, "zero length password not allowed");
+    }
+  }
+
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Command line read\n");
+    fflush(mesg);
+  }
+
+  /* show command line args */
+  if (show_args) {
+    fprintf(mesg, "command line:\n");
+    for (i = 0; args[i]; i++) {
+      fprintf(mesg, "'%s'  ", args[i]);
+    }
+    fprintf(mesg, "\n");
+    ZIPERR(ZE_ABORT, "show command line");
+  }
+
+  /* show all options */
+  if (show_options) {
+    printf("available options:\n");
+    printf(" %-2s  %-18s %-4s %-3s %-30s\n", "sh", "long", "val", "neg", "description");
+    printf(" %-2s  %-18s %-4s %-3s %-30s\n", "--", "----", "---", "---", "-----------");
+    for (i = 0; options[i].option_ID; i++) {
+      printf(" %-2s  %-18s ", options[i].shortopt, options[i].longopt);
+      switch (options[i].value_type) {
+        case o_NO_VALUE:
+          printf("%-4s ", "");
+          break;
+        case o_REQUIRED_VALUE:
+          printf("%-4s ", "req");
+          break;
+        case o_OPTIONAL_VALUE:
+          printf("%-4s ", "opt");
+          break;
+        case o_VALUE_LIST:
+          printf("%-4s ", "list");
+          break;
+        case o_ONE_CHAR_VALUE:
+          printf("%-4s ", "char");
+          break;
+        case o_NUMBER_VALUE:
+          printf("%-4s ", "num");
+          break;
+        default:
+          printf("%-4s ", "unk");
+      }
+      switch (options[i].negatable) {
+        case o_NEGATABLE:
+          printf("%-3s ", "neg");
+          break;
+        case o_NOT_NEGATABLE:
+          printf("%-3s ", "");
+          break;
+        default:
+          printf("%-3s ", "unk");
+      }
+      if (options[i].name)
+        printf("%-30s\n", options[i].name);
+      else
+        printf("\n");
+    }
+    RETURN(finish(ZE_OK));
+  }
+
+
+  /* open log file */
+  if (logfile_path) {
+    char mode[10];
+    char *p;
+    char *lastp;
+
+    /* if no extension add .log */
+    p = logfile_path;
+    /* find last / */
+    lastp = NULL;
+    for (p = logfile_path; (p = MBSRCHR(p, '/')) != NULL; p++) {
+      lastp = p;
+    }
+    if (lastp == NULL)
+      lastp = logfile_path;
+    if (MBSRCHR(lastp, '.') == NULL) {
+      /* add .log */
+      if ((p = malloc(strlen(logfile_path) + 5)) == NULL) {
+        ZIPERR(ZE_MEM, "logpath");
+      }
+      strcpy(p, logfile_path);
+      strcat(p, ".log");
+      free(logfile_path);
+      logfile_path = p;
+    }
+
+    if (logfile_append) {
+      sprintf(mode, "a");
+    } else {
+      sprintf(mode, "w");
+    }
+    if ((logfile = zfopen(logfile_path, mode)) == NULL) {
+      sprintf(errbuf, "could not open logfile '%s'", logfile_path);
+      ZIPERR(ZE_PARMS, errbuf);
+    }
+    {
+      /* At top put start time and command line */
+
+      /* get current time */
+      struct tm *now;
+      time_t clocktime;
+
+      time(&clocktime);
+      now = localtime(&clocktime);
+
+      fprintf(logfile, "---------\n");
+      fprintf(logfile, "Zip log opened %s", asctime(now));
+      fprintf(logfile, "command line arguments:\n ");
+      for (i = 1; args[i]; i++) {
+        size_t j;
+        int has_space = 0;
+
+        for (j = 0; j < strlen(args[i]); j++) {
+          if (isspace(args[i][j])) {
+            has_space = 1;
+            break;
+          }
+        }
+        if (has_space)
+          fprintf(logfile, "\"%s\" ", args[i]);
+        else
+          fprintf(logfile, "%s ", args[i]);
+      }
+      fprintf(logfile, "\n\n");
+      fflush(logfile);
+    }
+  } else {
+    /* only set logall if logfile open */
+    logall = 0;
+  }
+
+
+  if (split_method && out_path) {
+    /* if splitting, the archive name must have .zip extension */
+    int plen = strlen(out_path);
+    char *out_path_ext;
+
+#ifdef VMS
+    /* On VMS, adjust plen (and out_path_ext) to avoid the file version. */
+    plen -= strlen( vms_file_version( out_path));
+#endif /* def VMS */
+    out_path_ext = out_path+ plen- 4;
+
+    if (plen < 4 ||
+        out_path_ext[0] != '.' ||
+        toupper(out_path_ext[1]) != 'Z' ||
+        toupper(out_path_ext[2]) != 'I' ||
+        toupper(out_path_ext[3]) != 'P') {
+      ZIPERR(ZE_PARMS, "archive name must end in .zip for splits");
+    }
+  }
+
+
+  if (verbose && (dot_size == 0) && (dot_count == 0)) {
+    /* now default to default 10 MB dot size */
+    dot_size = 10 * 0x100000;
+    /* show all dots as before if verbose set and dot_size not set (dot_count = 0) */
+    /* maybe should turn off dots in default verbose mode */
+    /* dot_size = -1; */
+  }
+
+  /* done getting -R filters so convert filterlist if not done */
+  if (pcount && patterns == NULL) {
+    filterlist_to_patterns();
+  }
+
+#if (defined(MSDOS) || defined(OS2)) && !defined(WIN32)
+  if ((kk == 3 || kk == 4) && volume_label == 1) {
+    /* read volume label */
+    PROCNAME(NULL);
+    kk = 4;
+  }
+#endif
+
+  if (have_out && kk == 3) {
+    copy_only = 1;
+    action = ARCHIVE;
+  }
+
+  if (have_out && namecmp(in_path, out_path) == 0) {
+    sprintf(errbuf, "--out path must be different than in path: %s", out_path);
+    ZIPERR(ZE_PARMS, errbuf);
+  }
+
+  if (fix && diff_mode) {
+    ZIPERR(ZE_PARMS, "can't use --diff (-DF) with fix (-F or -FF)");
+  }
+
+  if (action == ARCHIVE && !have_out && !show_files) {
+    ZIPERR(ZE_PARMS, "-U (--copy) requires -O (--out)");
+  }
+
+  if (fix && !have_out) {
+    zipwarn("fix options -F and -FF require --out:\n",
+            "                     zip -F indamagedarchive --out outfixedarchive");
+    ZIPERR(ZE_PARMS, "fix options require --out");
+  }
+
+  if (fix && !copy_only) {
+    ZIPERR(ZE_PARMS, "no other actions allowed when fixing archive (-F or -FF)");
+  }
+
+  if (!have_out && diff_mode) {
+    ZIPERR(ZE_PARMS, "-DF (--diff) requires -O (--out)");
+  }
+
+  if (diff_mode && (action == ARCHIVE || action == DELETE)) {
+    ZIPERR(ZE_PARMS, "can't use --diff (-DF) with -d or -U");
+  }
+
+  if (action != ARCHIVE && (recurse == 2 || pcount) && first_listarg == 0 &&
+      !filelist && (kk < 3 || (action != UPDATE && action != FRESHEN))) {
+    ZIPERR(ZE_PARMS, "nothing to select from");
+  }
+
+/*
+  -------------------------------------
+  end of new command line code
+  -------------------------------------
+*/
+
+#if (!defined(MACOS) && !defined(WINDLL))
+  if (kk < 3) {               /* zip used as filter */
+    zipstdout();
+    comment_stream = NULL;
+    if ((r = procname("-", 0)) != ZE_OK) {
+      if (r == ZE_MISS) {
+        if (bad_open_is_error) {
+          zipwarn("name not matched: ", "-");
+          ZIPERR(ZE_OPEN, "-");
+        } else {
+          zipwarn("name not matched: ", "-");
+        }
+      } else {
+        ZIPERR(r, "-");
+      }
+    }
+    kk = 4;
+    if (s) {
+      ZIPERR(ZE_PARMS, "can't use - and -@ together");
+    }
+  }
+#endif /* !MACOS && !WINDLL */
+
+  if (zipfile && !strcmp(zipfile, "-")) {
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Zipping to stdout\n");
+      fflush(mesg);
+    }
+    zip_to_stdout = 1;
+  }
+
+  /* Check option combinations */
+  if (special == NULL) {
+    ZIPERR(ZE_PARMS, "missing suffix list");
+  }
+  if (level == 9 || !strcmp(special, ";") || !strcmp(special, ":"))
+    special = NULL; /* compress everything */
+
+  if (action == DELETE && (method != BEST || dispose || recurse ||
+      key != NULL || comadd || zipedit)) {
+    zipwarn("invalid option(s) used with -d; ignored.","");
+    /* reset flags - needed? */
+    method  = BEST;
+    dispose = 0;
+    recurse = 0;
+    if (key != NULL) {
+      free((zvoid *)key);
+      key   = NULL;
+    }
+    comadd  = 0;
+    zipedit = 0;
+  }
+  if (action == ARCHIVE && (method != BEST || dispose || recurse ||
+      comadd || zipedit)) {
+    zipwarn("can't set method, move, recurse, or comments with copy mode.","");
+    /* reset flags - needed? */
+    method  = BEST;
+    dispose = 0;
+    recurse = 0;
+    comadd  = 0;
+    zipedit = 0;
+  }
+  if (linkput && dosify)
+    {
+      zipwarn("can't use -y with -k, -y ignored", "");
+      linkput = 0;
+    }
+  if (fix == 1 && adjust)
+    {
+      zipwarn("can't use -F with -A, -F ignored", "");
+      fix = 0;
+    }
+  if (fix == 2 && adjust)
+    {
+      zipwarn("can't use -FF with -A, -FF ignored", "");
+      fix = 0;
+    }
+  if (test && zip_to_stdout) {
+    test = 0;
+    zipwarn("can't use -T on stdout, -T ignored", "");
+  }
+  if (split_method && (fix || adjust)) {
+    ZIPERR(ZE_PARMS, "can't create split archive while fixing or adjusting\n");
+  }
+  if (split_method && (d || zip_to_stdout)) {
+    ZIPERR(ZE_PARMS, "can't create split archive with -d or -g or on stdout\n");
+  }
+  if ((action != ADD || d) && filesync) {
+    ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g with filesync -FS\n");
+  }
+  if ((action != ADD || d) && zip_to_stdout) {
+    ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g on stdout\n");
+  }
+#if defined(EBCDIC)  && !defined(OS390)
+  if (aflag==ASCII && !translate_eol) {
+    /* Translation to ASCII implies EOL translation!
+     * (on OS390, consistent EOL translation is controlled separately)
+     * The default translation mode is "UNIX" mode (single LF terminators).
+     */
+    translate_eol = 2;
+  }
+#endif
+#ifdef CMS_MVS
+  if (aflag==ASCII && bflag)
+    ZIPERR(ZE_PARMS, "can't use -a with -B");
+#endif
+#ifdef VMS
+  if (!extra_fields && vms_native)
+    {
+      zipwarn("can't use -V with -X, -V ignored", "");
+      vms_native = 0;
+    }
+  if (vms_native && translate_eol)
+    ZIPERR(ZE_PARMS, "can't use -V with -l or -ll");
+#endif
+
+  if (noisy) {
+    if (fix == 1)
+      zipmessage("Fix archive (-F) - assume mostly intact archive", "");
+    else if (fix == 2)
+      zipmessage("Fix archive (-FF) - salvage what can", "");
+  }
+
+  /* Read old archive */
+
+  /* Now read the zip file here instead of when doing args above */
+  /* Only read the central directory and build zlist */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Reading archive\n");
+    fflush(mesg);
+  }
+
+
+
+
+  /* If -FF we do it all here */
+  if (fix == 2) {
+
+    /* Open zip file and temporary output file */
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Open zip file and create temp file (-FF)\n");
+      fflush(mesg);
+    }
+    diag("opening zip file and creating temporary zip file");
+    x = NULL;
+    tempzn = 0;
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Creating new zip file (-FF)\n");
+      fflush(mesg);
+    }
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+    {
+      int yd;
+      int i;
+
+      /* use mkstemp to avoid race condition and compiler warning */
+
+      if (tempath != NULL)
+      {
+        /* if -b used to set temp file dir use that for split temp */
+        if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+          ZIPERR(ZE_MEM, "allocating temp filename");
+        }
+        strcpy(tempzip, tempath);
+        if (lastchar(tempzip) != '/')
+          strcat(tempzip, "/");
+      }
+      else
+      {
+        /* create path by stripping name and appending template */
+        if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+        ZIPERR(ZE_MEM, "allocating temp filename");
+        }
+        strcpy(tempzip, zipfile);
+        for(i = strlen(tempzip); i > 0; i--) {
+          if (tempzip[i - 1] == '/')
+            break;
+        }
+        tempzip[i] = '\0';
+      }
+      strcat(tempzip, "ziXXXXXX");
+
+      if ((yd = mkstemp(tempzip)) == EOF) {
+        ZIPERR(ZE_TEMP, tempzip);
+      }
+      if ((y = fdopen(yd, FOPW_TMP)) == NULL) {
+        ZIPERR(ZE_TEMP, tempzip);
+      }
+    }
+#else
+    if ((tempzip = tempname(zipfile)) == NULL) {
+      ZIPERR(ZE_MEM, "allocating temp filename");
+    }
+    if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
+      ZIPERR(ZE_TEMP, tempzip);
+    }
+#endif
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+    /* Use large buffer to speed up stdio: */
+#if (defined(_IOFBF) || !defined(BUFSIZ))
+    zipbuf = (char *)malloc(ZBSZ);
+#else
+    zipbuf = (char *)malloc(BUFSIZ);
+#endif
+    if (zipbuf == NULL) {
+      ZIPERR(ZE_MEM, tempzip);
+    }
+# ifdef _IOFBF
+    setvbuf(y, zipbuf, _IOFBF, ZBSZ);
+# else
+    setbuf(y, zipbuf);
+# endif /* _IOBUF */
+#endif /* !VMS  && !CMS_MVS */
+
+
+    if ((r = readzipfile()) != ZE_OK) {
+      ZIPERR(r, zipfile);
+    }
+
+    /* Write central directory and end header to temporary zip */
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Writing central directory (-FF)\n");
+      fflush(mesg);
+    }
+    diag("writing central directory");
+    k = 0;                        /* keep count for end header */
+    c = tempzn;                   /* get start of central */
+    n = t = 0;
+    for (z = zfiles; z != NULL; z = z->nxt)
+    {
+      if ((r = putcentral(z)) != ZE_OK) {
+        ZIPERR(r, tempzip);
+      }
+      tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+      n += z->len;
+      t += z->siz;
+      k++;
+    }
+    if (zcount == 0)
+      zipwarn("zip file empty", "");
+    t = tempzn - c;               /* compute length of central */
+    diag("writing end of central directory");
+    if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
+      ZIPERR(r, tempzip);
+    }
+    if (fclose(y)) {
+      ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
+    }
+    if (in_file != NULL) {
+      fclose(in_file);
+      in_file = NULL;
+    }
+
+    /* Replace old zip file with new zip file, leaving only the new one */
+    if (strcmp(zipfile, "-") && !d)
+    {
+      diag("replacing old zip file with new zip file");
+      if ((r = replace(out_path, tempzip)) != ZE_OK)
+      {
+        zipwarn("new zip file left as: ", tempzip);
+        free((zvoid *)tempzip);
+        tempzip = NULL;
+        ZIPERR(r, "was replacing the original zip file");
+      }
+      free((zvoid *)tempzip);
+    }
+    tempzip = NULL;
+    if (zip_attributes && strcmp(zipfile, "-")) {
+      setfileattr(out_path, zip_attributes);
+#ifdef VMS
+      /* If the zip file existed previously, restore its record format: */
+      if (x != NULL)
+        (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
+#endif
+    }
+
+    set_filetype(out_path);
+
+    /* finish logfile (it gets closed in freeup() called by finish()) */
+    if (logfile) {
+        struct tm *now;
+        time_t clocktime;
+
+        fprintf(logfile, "\nTotal %ld entries (", files_total);
+        DisplayNumString(logfile, bytes_total);
+        fprintf(logfile, " bytes)");
+
+        /* get current time */
+        time(&clocktime);
+        now = localtime(&clocktime);
+        fprintf(logfile, "\nDone %s", asctime(now));
+        fflush(logfile);
+    }
+
+    RETURN(finish(ZE_OK));
+  }
+
+
+
+  /* read zipfile if exists */
+  if ((r = readzipfile()) != ZE_OK) {
+    ZIPERR(r, zipfile);
+  }
+
+#ifndef UTIL
+  if (split_method == -1) {
+    split_method = 0;
+  } else if (!fix && split_method == 0 && total_disks > 1) {
+    /* if input archive is multi-disk and splitting has not been
+       enabled or disabled (split_method == -1), then automatically
+       set split size to same as first input split */
+    zoff_t size = 0;
+
+    in_split_path = get_in_split_path(in_path, 0);
+
+    if (filetime(in_split_path, NULL, &size, NULL) == 0) {
+      zipwarn("Could not get info for input split: ", in_split_path);
+      return ZE_OPEN;
+    }
+    split_method = 1;
+    split_size = (uzoff_t) size;
+
+    free(in_split_path);
+    in_split_path = NULL;
+  }
+
+  if (noisy_splits && split_size > 0)
+    zipmessage("splitsize = ", zip_fuzofft(split_size, NULL, NULL));
+#endif
+
+  /* so disk display starts at 1, will be updated when entries are read */
+  current_in_disk = 0;
+
+  /* no input zipfile and showing contents */
+  if (!zipfile_exists && show_files && (kk == 3 || action == ARCHIVE)) {
+    ZIPERR(ZE_OPEN, zipfile);
+  }
+
+  if (zcount == 0 && (action != ADD || d)) {
+    zipwarn(zipfile, " not found or empty");
+  }
+
+  if (have_out && kk == 3) {
+    /* no input paths so assume copy mode and match everything if --out */
+    for (z = zfiles; z != NULL; z = z->nxt) {
+      z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+    }
+  }
+
+  /* Scan for new files */
+
+  /* Process file arguments from command line */
+  if (filelist) {
+    if (action == ARCHIVE) {
+      /* find in archive */
+      if (show_what_doing) {
+        fprintf(mesg, "sd: Scanning archive entries\n");
+        fflush(mesg);
+      }
+      for (; filelist; ) {
+        if ((r = proc_archive_name(filelist->name, filter_match_case)) != ZE_OK) {
+          if (r == ZE_MISS) {
+            char *n = NULL;
+#ifdef WIN32
+            /* Win9x console always uses OEM character coding, and
+               WinNT console is set to OEM charset by default, too */
+            if ((n = malloc(strlen(filelist->name) + 1)) == NULL)
+              ZIPERR(ZE_MEM, "name not matched error");
+            INTERN_TO_OEM(filelist->name, n);
+#else
+            n = filelist->name;
+#endif
+            zipwarn("not in archive: ", n);
+#ifdef WIN32
+            free(n);
+#endif
+          }
+          else {
+            ZIPERR(r, filelist->name);
+          }
+        }
+        free(filelist->name);
+        filearg = filelist;
+        filelist = filelist->next;
+        free(filearg);
+      }
+    } else {
+      /* try find matching files on OS first then try find entries in archive */
+      if (show_what_doing) {
+        fprintf(mesg, "sd: Scanning files\n");
+        fflush(mesg);
+      }
+      for (; filelist; ) {
+        if ((r = PROCNAME(filelist->name)) != ZE_OK) {
+          if (r == ZE_MISS) {
+            if (bad_open_is_error) {
+              zipwarn("name not matched: ", filelist->name);
+              ZIPERR(ZE_OPEN, filelist->name);
+            } else {
+              zipwarn("name not matched: ", filelist->name);
+            }
+          } else {
+            ZIPERR(r, filelist->name);
+          }
+        }
+        free(filelist->name);
+        filearg = filelist;
+        filelist = filelist->next;
+        free(filearg);
+      }
+    }
+  }
+
+  /* recurse from current directory for -R */
+  if (recurse == 2) {
+#ifdef AMIGA
+    if ((r = PROCNAME("")) != ZE_OK)
+#else
+    if ((r = PROCNAME(".")) != ZE_OK)
+#endif
+    {
+      if (r == ZE_MISS) {
+        if (bad_open_is_error) {
+          zipwarn("name not matched: ", "current directory for -R");
+          ZIPERR(ZE_OPEN, "-R");
+        } else {
+          zipwarn("name not matched: ", "current directory for -R");
+        }
+      } else {
+        ZIPERR(r, "-R");
+      }
+    }
+  }
+
+
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Applying filters\n");
+    fflush(mesg);
+  }
+  /* Clean up selections ("3 <= kk <= 5" now) */
+  if (kk != 4 && first_listarg == 0 &&
+      (action == UPDATE || action == FRESHEN)) {
+    /* if -u or -f with no args, do all, but, when present, apply filters */
+    for (z = zfiles; z != NULL; z = z->nxt) {
+      z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+#ifdef DOS
+      if (z->mark) z->dosflag = 1;      /* force DOS attribs for incl. names */
+#endif
+    }
+  }
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Checking dups\n");
+    fflush(mesg);
+  }
+  if ((r = check_dup()) != ZE_OK) {     /* remove duplicates in found list */
+    if (r == ZE_PARMS) {
+      ZIPERR(r, "cannot repeat names in zip file");
+    }
+    else {
+      ZIPERR(r, "was processing list of files");
+    }
+  }
+
+  if (zcount)
+    free((zvoid *)zsort);
+
+
+/*
+ * XXX make some kind of mktemppath() function for each OS.
+ */
+
+#ifndef VM_CMS
+/* For CMS, leave tempath NULL.  A-disk will be used as default. */
+  /* If -b not specified, make temporary path the same as the zip file */
+#if defined(MSDOS) || defined(__human68k__) || defined(AMIGA)
+  if (tempath == NULL && ((p = MBSRCHR(zipfile, '/')) != NULL ||
+#  ifdef MSDOS
+                          (p = MBSRCHR(zipfile, '\\')) != NULL ||
+#  endif /* MSDOS */
+                          (p = MBSRCHR(zipfile, ':')) != NULL))
+  {
+    if (*p == ':')
+      p++;
+#else
+#ifdef RISCOS
+  if (tempath == NULL && (p = MBSRCHR(zipfile, '.')) != NULL)
+  {
+#else
+#ifdef QDOS
+  if (tempath == NULL && (p = LastDir(zipfile)) != NULL)
+  {
+#else
+  if (tempath == NULL && (p = MBSRCHR(zipfile, '/')) != NULL)
+  {
+#endif /* QDOS */
+#endif /* RISCOS */
+#endif /* MSDOS || __human68k__ || AMIGA */
+    if ((tempath = (char *)malloc((int)(p - zipfile) + 1)) == NULL) {
+      ZIPERR(ZE_MEM, "was processing arguments");
+    }
+    r = *p;  *p = 0;
+    strcpy(tempath, zipfile);
+    *p = (char)r;
+  }
+#endif /* VM_CMS */
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+  if (!zp_tz_is_valid) {
+    zipwarn("TZ environment variable not found, cannot use UTC times!!","");
+  }
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+  /* For each marked entry, if not deleting, check if it exists, and if
+     updating or freshening, compare date with entry in old zip file.
+     Unmark if it doesn't exist or is too old, else update marked count. */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Scanning files to update\n");
+    fflush(mesg);
+  }
+#ifdef MACOS
+  PrintStatProgress("Getting file information ...");
+#endif
+  diag("stating marked entries");
+  k = 0;                        /* Initialize marked count */
+  scan_started = 0;
+  scan_count = 0;
+  all_current = 1;
+  for (z = zfiles; z != NULL; z = z->nxt) {
+    /* if already displayed Scanning files in newname() then continue dots */
+    if (noisy && scan_last) {
+      scan_count++;
+      if (scan_count % 100 == 0) {
+        time_t current = time(NULL);
+
+        if (current - scan_last > scan_dot_time) {
+          if (scan_started == 0) {
+            scan_started = 1;
+            fprintf(mesg, " ");
+            fflush(mesg);
+          }
+          scan_last = current;
+          fprintf(mesg, ".");
+          fflush(mesg);
+        }
+      }
+    }
+    z->current = 0;
+    if (!(z->mark)) {
+      /* if something excluded run through the list to catch deletions */
+      all_current = 0;
+    }
+    if (z->mark) {
+#ifdef USE_EF_UT_TIME
+      iztimes f_utim, z_utim;
+      ulg z_tim;
+#endif /* USE_EF_UT_TIME */
+      Trace((stderr, "zip diagnostics: marked file=%s\n", z->oname));
+
+      csize = z->siz;
+      usize = z->len;
+      if (action == DELETE) {
+        /* only delete files in date range */
+#ifdef USE_EF_UT_TIME
+        z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+                unix2dostime(&z_utim.mtime) : z->tim;
+#else /* !USE_EF_UT_TIME */
+#       define z_tim  z->tim
+#endif /* ?USE_EF_UT_TIME */
+        if (z_tim < before || (after && z_tim >= after)) {
+          /* include in archive */
+          z->mark = 0;
+        } else {
+          /* delete file */
+          files_total++;
+          /* ignore len in old archive and update to current size */
+          z->len = usize;
+          if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+            bytes_total += csize;
+          k++;
+        }
+      } else if (action == ARCHIVE) {
+        /* only keep files in date range */
+#ifdef USE_EF_UT_TIME
+        z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+                unix2dostime(&z_utim.mtime) : z->tim;
+#else /* !USE_EF_UT_TIME */
+#       define z_tim  z->tim
+#endif /* ?USE_EF_UT_TIME */
+        if (z_tim < before || (after && z_tim >= after)) {
+          /* exclude from archive */
+          z->mark = 0;
+        } else {
+          /* keep file */
+          files_total++;
+          /* ignore len in old archive and update to current size */
+          z->len = usize;
+          if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+            bytes_total += csize;
+          k++;
+        }
+      } else {
+        int isdirname = 0;
+
+        if (z->name && (z->name)[strlen(z->name) - 1] == '/') {
+          isdirname = 1;
+        }
+
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+        if (!no_win32_wide) {
+          if (z->namew == NULL) {
+            if (z->uname != NULL)
+              z->namew = utf8_to_wchar_string(z->uname);
+            else
+              z->namew = local_to_wchar_string(z->name);
+          }
+        }
+# endif
+
+#ifdef USE_EF_UT_TIME
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+        if (!no_win32_wide)
+          tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+        else
+          tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# else
+        tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# endif
+#else /* !USE_EF_UT_TIME */
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+        if (!no_win32_wide)
+          tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+        else
+          tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# else
+        tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# endif
+#endif /* ?USE_EF_UT_TIME */
+        if (tf == 0)
+          /* entry that is not on OS */
+          all_current = 0;
+        if (tf == 0 ||
+            tf < before || (after && tf >= after) ||
+            ((action == UPDATE || action == FRESHEN) &&
+#ifdef USE_EF_UT_TIME
+             ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+              f_utim.mtime <= ROUNDED_TIME(z_utim.mtime) : tf <= z->tim)
+#else /* !USE_EF_UT_TIME */
+             tf <= z->tim
+#endif /* ?USE_EF_UT_TIME */
+           ))
+        {
+          z->mark = comadd ? 2 : 0;
+          z->trash = tf && tf >= before &&
+                     (after ==0 || tf < after);   /* delete if -um or -fm */
+          if (verbose)
+            fprintf(mesg, "zip diagnostic: %s %s\n", z->oname,
+                   z->trash ? "up to date" : "missing or early");
+          if (logfile)
+            fprintf(logfile, "zip diagnostic: %s %s\n", z->oname,
+                   z->trash ? "up to date" : "missing or early");
+        }
+        else if (diff_mode && tf == z->tim &&
+                 ((isdirname && (zoff_t)usize == -1) || (usize == z->len))) {
+          /* if in diff mode only include if file time or size changed */
+          /* usize is -1 for directories */
+          z->mark = 0;
+        }
+        else {
+          /* usize is -1 for directories and -2 for devices */
+          if (tf == z->tim &&
+              ((z->len == 0 && (zoff_t)usize == -1)
+               || usize == z->len)) {
+            /* FileSync uses the current flag */
+            /* Consider an entry current if file time is the same
+               and entry size is 0 and a directory on the OS
+               or the entry size matches the OS size */
+            z->current = 1;
+          } else {
+            all_current = 0;
+          }
+          files_total++;
+          if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+            /* ignore len in old archive and update to current size */
+            z->len = usize;
+          else
+            z->len = 0;
+          if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+            bytes_total += usize;
+          k++;
+        }
+      }
+    }
+  }
+
+  /* Remove entries from found list that do not exist or are too old */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: fcount = %u\n", (unsigned)fcount);
+    fflush(mesg);
+  }
+
+  diag("stating new entries");
+  scan_count = 0;
+  scan_started = 0;
+  Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
+  for (f = found; f != NULL;) {
+    Trace((stderr, "zip diagnostic: new file=%s\n", f->oname));
+
+    if (noisy) {
+      /* if updating archive and update was quick, scanning for new files
+         can still take a long time */
+      if (!zip_to_stdout && scan_last == 0 && scan_count % 100 == 0) {
+        time_t current = time(NULL);
+
+        if (current - scan_start > scan_delay) {
+          fprintf(mesg, "Scanning files ");
+          fflush(mesg);
+          mesg_line_started = 1;
+          scan_last = current;
+        }
+      }
+      /* if already displayed Scanning files in newname() or above then continue dots */
+      if (scan_last) {
+        scan_count++;
+        if (scan_count % 100 == 0) {
+          time_t current = time(NULL);
+
+          if (current - scan_last > scan_dot_time) {
+            if (scan_started == 0) {
+              scan_started = 1;
+              fprintf(mesg, " ");
+              fflush(mesg);
+            }
+            scan_last = current;
+            fprintf(mesg, ".");
+            fflush(mesg);
+          }
+        }
+      }
+    }
+    tf = 0;
+    if (action != DELETE && action != FRESHEN) {
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+      if (!no_win32_wide)
+        tf = filetimew(f->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+      else
+        tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#else
+      tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#endif
+    }
+
+    if (action == DELETE || action == FRESHEN ||
+        tf == 0 ||
+        tf < before || (after && tf >= after) ||
+        (namecmp(f->zname, zipfile) == 0 && !zip_to_stdout)
+       )
+      f = fexpel(f);
+    else {
+      /* ??? */
+      files_total++;
+      f->usize = 0;
+      if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2) {
+        bytes_total += usize;
+        f->usize = usize;
+      }
+      f = f->nxt;
+    }
+  }
+  if (mesg_line_started) {
+    fprintf(mesg, "\n");
+    mesg_line_started = 0;
+  }
+#ifdef MACOS
+  PrintStatProgress("done");
+#endif
+
+  if (show_files) {
+    uzoff_t count = 0;
+    uzoff_t bytes = 0;
+
+    if (noisy) {
+      fflush(mesg);
+    }
+
+    if (noisy && (show_files == 1 || show_files == 3 || show_files == 5)) {
+      /* sf, su, sU */
+      if (mesg_line_started) {
+        fprintf(mesg, "\n");
+        mesg_line_started = 0;
+      }
+      if (kk == 3)
+        /* -sf alone */
+        fprintf(mesg, "Archive contains:\n");
+      else if (action == DELETE)
+        fprintf(mesg, "Would Delete:\n");
+      else if (action == FRESHEN)
+        fprintf(mesg, "Would Freshen:\n");
+      else if (action == ARCHIVE)
+        fprintf(mesg, "Would Copy:\n");
+      else
+        fprintf(mesg, "Would Add/Update:\n");
+      fflush(mesg);
+    }
+
+    if (logfile) {
+      if (logfile_line_started) {
+        fprintf(logfile, "\n");
+        logfile_line_started = 0;
+      }
+      if (kk == 3)
+        /* -sf alone */
+        fprintf(logfile, "Archive contains:\n");
+      else if (action == DELETE)
+        fprintf(logfile, "Would Delete:\n");
+      else if (action == FRESHEN)
+        fprintf(logfile, "Would Freshen:\n");
+      else if (action == ARCHIVE)
+        fprintf(logfile, "Would Copy:\n");
+      else
+        fprintf(logfile, "Would Add/Update:\n");
+      fflush(logfile);
+    }
+
+    for (z = zfiles; z != NULL; z = z->nxt) {
+      if (z->mark || kk == 3) {
+        count++;
+        if ((zoff_t)z->len > 0)
+          bytes += z->len;
+        if (noisy && (show_files == 1 || show_files == 3))
+          /* sf, su */
+          fprintf(mesg, "  %s\n", z->oname);
+        if (logfile && !(show_files == 5 || show_files == 6))
+          /* not sU or sU- show normal name in log */
+          fprintf(logfile, "  %s\n", z->oname);
+
+#ifdef UNICODE_TEST
+        if (create_files) {
+          int r;
+          int dir = 0;
+          FILE *f;
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+          char *fn = NULL;
+          wchar_t *fnw = NULL;
+
+          if (!no_win32_wide) {
+            if ((fnw = malloc((wcslen(z->znamew) + 120) * sizeof(wchar_t))) == NULL)
+              ZIPERR(ZE_MEM, "sC");
+            wcscpy(fnw, L"testdir/");
+            wcscat(fnw, z->znamew);
+            if (fnw[wcslen(fnw) - 1] == '/')
+              dir = 1;
+            if (dir)
+              r = _wmkdir(fnw);
+            else
+              f = _wfopen(fnw, L"w");
+          } else {
+            if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+              ZIPERR(ZE_MEM, "sC");
+            strcpy(fn, "testdir/");
+            strcat(fn, z->zname);
+            if (fn[strlen(fn) - 1] == '/')
+              dir = 1;
+            if (dir)
+              r = mkdir(fn);
+            else
+              f = fopen(fn, "w");
+          }
+#else
+          char *fn = NULL;
+          if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+            ZIPERR(ZE_MEM, "sC");
+          strcpy(fn, "testdir/");
+          if (z->uname)
+            strcat(fn, z->uname);
+          else
+            strcat(fn, z->zname);
+
+          if (fn[strlen(fn) - 1] == '/')
+            dir = 1;
+          if (dir)
+            r = mkdir(fn, 0777);
+          else
+            f = fopen(fn, "w");
+#endif
+          if (dir) {
+            if (r) {
+              if (errno != 17) {
+                printf(" - could not create directory testdir/%s\n", z->oname);
+                perror("    dir");
+              }
+            } else {
+              printf(" - created directory testdir/%s\n", z->oname);
+            }
+          } else {
+            if (f == NULL) {
+              printf(" - could not open testdir/%s\n", z->oname);
+              perror("    file");
+            } else {
+              fclose(f);
+              printf(" - created testdir/%s\n", z->oname);
+              if (z->uname)
+                printf("   u - created testdir/%s\n", z->uname);
+            }
+          }
+        }
+#endif
+#ifdef UNICODE_SUPPORT
+        if (show_files == 3 || show_files == 4) {
+          /* su, su- */
+          /* Include escaped Unicode name if exists under standard name */
+          if (z->ouname) {
+            if (noisy && show_files == 3)
+              fprintf(mesg, "     Escaped Unicode:  %s\n", z->ouname);
+            if (logfile)
+              fprintf(logfile, "     Escaped Unicode:  %s\n", z->ouname);
+          }
+        }
+        if (show_files == 5 || show_files == 6) {
+          /* sU, sU- */
+          /* Display only escaped Unicode name if exists or standard name */
+          if (z->ouname) {
+            /* Unicode name */
+            if (noisy && show_files == 5) {
+              fprintf(mesg, "  %s\n", z->ouname);
+            }
+            if (logfile) {
+              fprintf(logfile, "  %s\n", z->ouname);
+            }
+          } else {
+            /* No Unicode name so use standard name */
+            if (noisy && show_files == 5) {
+              fprintf(mesg, "  %s\n", z->oname);
+            }
+            if (logfile) {
+              fprintf(logfile, "  %s\n", z->oname);
+            }
+          }
+        }
+#endif
+      }
+    }
+    for (f = found; f != NULL; f = f->nxt) {
+      count++;
+      if ((zoff_t)f->usize > 0)
+        bytes += f->usize;
+#ifdef UNICODE_SUPPORT
+      if (unicode_escape_all) {
+        char *escaped_unicode;
+        escaped_unicode = local_to_escape_string(f->zname);
+        if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+          /* sf, su, sU */
+          fprintf(mesg, "  %s\n", escaped_unicode);
+        if (logfile)
+          fprintf(logfile, "  %s\n", escaped_unicode);
+        free(escaped_unicode);
+      } else {
+#endif
+        if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+          /* sf, su, sU */
+          fprintf(mesg, "  %s\n", f->oname);
+        if (logfile)
+          fprintf(logfile, "  %s\n", f->oname);
+#ifdef UNICODE_SUPPORT
+      }
+#endif
+    }
+    if (noisy || logfile == NULL)
+      fprintf(mesg, "Total %s entries (%s bytes)\n",
+                                          zip_fuzofft(count, NULL, NULL),
+                                          zip_fuzofft(bytes, NULL, NULL));
+    if (logfile)
+      fprintf(logfile, "Total %s entries (%s bytes)\n",
+                                          zip_fuzofft(count, NULL, NULL),
+                                          zip_fuzofft(bytes, NULL, NULL));
+    RETURN(finish(ZE_OK));
+  }
+
+  /* Make sure there's something left to do */
+  if (k == 0 && found == NULL && !diff_mode &&
+      !(zfiles == NULL && allow_empty_archive) &&
+      !(zfiles != NULL &&
+        (latest || fix || adjust || junk_sfx || comadd || zipedit))) {
+    if (test && (zfiles != NULL || zipbeg != 0)) {
+#ifndef WINDLL
+      check_zipfile(zipfile, argv[0]);
+#endif
+      RETURN(finish(ZE_OK));
+    }
+    if (action == UPDATE || action == FRESHEN) {
+      RETURN(finish(ZE_NONE));
+    }
+    else if (zfiles == NULL && (latest || fix || adjust || junk_sfx)) {
+      ZIPERR(ZE_NAME, zipfile);
+    }
+#ifndef WINDLL
+    else if (recurse && (pcount == 0) && (first_listarg > 0)) {
+#ifdef VMS
+      strcpy(errbuf, "try: zip \"");
+      for (i = 1; i < (first_listarg - 1); i++)
+        strcat(strcat(errbuf, args[i]), "\" ");
+      strcat(strcat(errbuf, args[i]), " *.* -i");
+#else /* !VMS */
+      strcpy(errbuf, "try: zip");
+      for (i = 1; i < first_listarg; i++)
+        strcat(strcat(errbuf, " "), args[i]);
+#  ifdef AMIGA
+      strcat(errbuf, " \"\" -i");
+#  else
+      strcat(errbuf, " . -i");
+#  endif
+#endif /* ?VMS */
+      for (i = first_listarg; i < argc; i++)
+        strcat(strcat(errbuf, " "), args[i]);
+      ZIPERR(ZE_NONE, errbuf);
+    }
+    else {
+      ZIPERR(ZE_NONE, zipfile);
+    }
+#endif /* !WINDLL */
+  }
+
+  if (filesync && all_current && fcount == 0) {
+    zipmessage("Archive is current", "");
+    RETURN(finish(ZE_OK));
+  }
+
+  d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
+
+#if CRYPT
+  /* Initialize the crc_32_tab pointer, when encryption was requested. */
+  if (key != NULL) {
+    crc_32_tab = get_crc_table();
+#ifdef EBCDIC
+    /* convert encryption key to ASCII (ISO variant for 8-bit ASCII chars) */
+    strtoasc(key, key);
+#endif /* EBCDIC */
+  }
+#endif /* CRYPT */
+
+  /* Just ignore the spanning signature if a multi-disk archive */
+  if (zfiles && total_disks != 1 && zipbeg == 4) {
+    zipbeg = 0;
+  }
+
+  /* Before we get carried away, make sure zip file is writeable. This
+   * has the undesired side effect of leaving one empty junk file on a WORM,
+   * so when the zipfile does not exist already and when -b is specified,
+   * the writability check is made in replace().
+   */
+  if (strcmp(zipfile, "-"))
+  {
+    if (tempdir && zfiles == NULL && zipbeg == 0) {
+      zip_attributes = 0;
+    } else {
+      x = (have_out || (zfiles == NULL && zipbeg == 0)) ? zfopen(out_path, FOPW) :
+                                                          zfopen(out_path, FOPM);
+      /* Note: FOPW and FOPM expand to several parameters for VMS */
+      if (x == NULL) {
+        ZIPERR(ZE_CREAT, out_path);
+      }
+      fclose(x);
+      zip_attributes = getfileattr(out_path);
+      if (zfiles == NULL && zipbeg == 0)
+        destroy(out_path);
+    }
+  }
+  else
+    zip_attributes = 0;
+
+  /* Throw away the garbage in front of the zip file for -J */
+  if (junk_sfx) zipbeg = 0;
+
+  /* Open zip file and temporary output file */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Open zip file and create temp file\n");
+    fflush(mesg);
+  }
+  diag("opening zip file and creating temporary zip file");
+  x = NULL;
+  tempzn = 0;
+  if (strcmp(zipfile, "-") == 0)
+  {
+#ifdef MSDOS
+    /* It is nonsense to emit the binary data stream of a zipfile to
+     * the (text mode) console.  This case should already have been caught
+     * in a call to zipstdout() far above.  Therefore, if the following
+     * failsafe check detects a console attached to stdout, zip is stopped
+     * with an "internal logic error"!  */
+    if (isatty(fileno(stdout)))
+      ZIPERR(ZE_LOGIC, "tried to write binary zipfile data to console!");
+    /* Set stdout mode to binary for MSDOS systems */
+#  ifdef __HIGHC__
+    setmode(stdout, _BINARY);
+#  else
+    setmode(fileno(stdout), O_BINARY);
+#  endif
+    y = zfdopen(fileno(stdout), FOPW);
+#else
+    y = stdout;
+#endif
+    /* tempzip must be malloced so a later free won't barf */
+    tempzip = malloc(4);
+    if (tempzip == NULL) {
+      ZIPERR(ZE_MEM, "allocating temp filename");
+    }
+    strcpy(tempzip, "-");
+  }
+  else if (d) /* d true if just appending (-g) */
+  {
+    if (total_disks > 1) {
+      ZIPERR(ZE_PARMS, "cannot grow split archive");
+    }
+    if ((y = zfopen(zipfile, FOPM)) == NULL) {
+      ZIPERR(ZE_NAME, zipfile);
+    }
+    tempzip = zipfile;
+    /*
+    tempzf = y;
+    */
+
+    if (zfseeko(y, cenbeg, SEEK_SET)) {
+      ZIPERR(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
+    }
+    bytes_this_split = cenbeg;
+    tempzn = cenbeg;
+  }
+  else
+  {
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Creating new zip file\n");
+      fflush(mesg);
+    }
+    /* See if there is something at beginning of disk 1 to copy.
+       If not, do nothing as zipcopy() will open files to read
+       as needed. */
+    if (zipbeg) {
+      in_split_path = get_in_split_path(in_path, 0);
+
+      while ((in_file = zfopen(in_split_path, FOPR_EX)) == NULL) {
+        /* could not open split */
+
+        /* Ask for directory with split.  Updates in_path */
+        if (ask_for_split_read_path(0) != ZE_OK) {
+          ZIPERR(ZE_ABORT, "could not open archive to read");
+        }
+        free(in_split_path);
+        in_split_path = get_in_split_path(in_path, 1);
+      }
+    }
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+    {
+      int yd;
+      int i;
+
+      /* use mkstemp to avoid race condition and compiler warning */
+
+      if (tempath != NULL)
+      {
+        /* if -b used to set temp file dir use that for split temp */
+        if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+          ZIPERR(ZE_MEM, "allocating temp filename");
+        }
+        strcpy(tempzip, tempath);
+        if (lastchar(tempzip) != '/')
+          strcat(tempzip, "/");
+      }
+      else
+      {
+        /* create path by stripping name and appending template */
+        if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+        ZIPERR(ZE_MEM, "allocating temp filename");
+        }
+        strcpy(tempzip, zipfile);
+        for(i = strlen(tempzip); i > 0; i--) {
+          if (tempzip[i - 1] == '/')
+            break;
+        }
+        tempzip[i] = '\0';
+      }
+      strcat(tempzip, "ziXXXXXX");
+
+      if ((yd = mkstemp(tempzip)) == EOF) {
+        ZIPERR(ZE_TEMP, tempzip);
+      }
+      if ((y = fdopen(yd, FOPW_TMP)) == NULL) {
+        ZIPERR(ZE_TEMP, tempzip);
+      }
+    }
+#else
+    if ((tempzip = tempname(zipfile)) == NULL) {
+      ZIPERR(ZE_MEM, "allocating temp filename");
+    }
+    if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
+      ZIPERR(ZE_TEMP, tempzip);
+    }
+#endif
+  }
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+  /* Use large buffer to speed up stdio: */
+#if (defined(_IOFBF) || !defined(BUFSIZ))
+  zipbuf = (char *)malloc(ZBSZ);
+#else
+  zipbuf = (char *)malloc(BUFSIZ);
+#endif
+  if (zipbuf == NULL) {
+    ZIPERR(ZE_MEM, tempzip);
+  }
+# ifdef _IOFBF
+  setvbuf(y, zipbuf, _IOFBF, ZBSZ);
+# else
+  setbuf(y, zipbuf);
+# endif /* _IOBUF */
+#endif /* !VMS  && !CMS_MVS */
+
+  /* If not seekable set some flags 3/14/05 EG */
+  output_seekable = 1;
+  if (!is_seekable(y)) {
+    output_seekable = 0;
+    use_descriptors = 1;
+  }
+
+  /* Not needed.  Only need Zip64 when input file is larger than 2 GB or reading
+     stdin and writing stdout.  This is set in putlocal() for each file. */
+#if 0
+  /* If using descriptors and Zip64 enabled force Zip64 3/13/05 EG */
+# ifdef ZIP64_SUPPORT
+  if (use_descriptors && force_zip64 != 0) {
+    force_zip64 = 1;
+  }
+# endif
+#endif
+
+  /* if archive exists, not streaming and not deleting or growing, copy
+     any bytes at beginning */
+  if (strcmp(zipfile, "-") != 0 && !d)  /* this must go *after* set[v]buf */
+  {
+    /* copy anything before archive */
+    if (in_file && zipbeg && (r = bfcopy(zipbeg)) != ZE_OK) {
+      ZIPERR(r, r == ZE_TEMP ? tempzip : zipfile);
+    }
+    if (in_file) {
+      fclose(in_file);
+      in_file = NULL;
+      free(in_split_path);
+    }
+    tempzn = zipbeg;
+    if (split_method) {
+      /* add spanning signature */
+      if (show_what_doing) {
+        fprintf(mesg, "sd: Adding spanning/splitting signature at top of archive\n");
+        fflush(mesg);
+      }
+      /* write the spanning signature at the top of the archive */
+      errbuf[0] = 0x50 /*'P' except for EBCDIC*/;
+      errbuf[1] = 0x4b /*'K' except for EBCDIC*/;
+      errbuf[2] = 7;
+      errbuf[3] = 8;
+      bfwrite(errbuf, 1, 4, BFWRITE_DATA);
+      /* tempzn updated below */
+      tempzn += 4;
+    }
+  }
+
+  o = 0;                                /* no ZE_OPEN errors yet */
+
+
+  /* Process zip file, updating marked files */
+#ifdef DEBUG
+  if (zfiles != NULL)
+    diag("going through old zip file");
+#endif
+  if (zfiles != NULL && show_what_doing) {
+    fprintf(mesg, "sd: Going through old zip file\n");
+    fflush(mesg);
+  }
+  w = &zfiles;
+  while ((z = *w) != NULL) {
+    if (z->mark == 1)
+    {
+      uzoff_t len;
+      if ((zoff_t)z->len == -1)
+        /* device */
+        len = 0;
+      else
+        len = z->len;
+
+      /* if not deleting, zip it up */
+      if (action != ARCHIVE && action != DELETE)
+      {
+        struct zlist far *localz; /* local header */
+
+        if (verbose || !(filesync && z->current))
+          DisplayRunningStats();
+        if (noisy)
+        {
+          if (action == FRESHEN) {
+            fprintf(mesg, "freshening: %s", z->oname);
+            mesg_line_started = 1;
+            fflush(mesg);
+          } else if (filesync && z->current) {
+            if (verbose) {
+              fprintf(mesg, "      ok: %s", z->oname);
+              mesg_line_started = 1;
+              fflush(mesg);
+            }
+          } else if (!(filesync && z->current)) {
+            fprintf(mesg, "updating: %s", z->oname);
+            mesg_line_started = 1;
+            fflush(mesg);
+          }
+        }
+        if (logall)
+        {
+          if (action == FRESHEN) {
+            fprintf(logfile, "freshening: %s", z->oname);
+            logfile_line_started = 1;
+            fflush(logfile);
+          } else if (filesync && z->current) {
+            if (verbose) {
+              fprintf(logfile, " current: %s", z->oname);
+              logfile_line_started = 1;
+              fflush(logfile);
+            }
+          } else {
+            fprintf(logfile, "updating: %s", z->oname);
+            logfile_line_started = 1;
+            fflush(logfile);
+          }
+        }
+
+        /* Get local header flags and extra fields */
+        if (readlocal(&localz, z) != ZE_OK) {
+          zipwarn("could not read local entry information: ", z->oname);
+          z->lflg = z->flg;
+          z->ext = 0;
+        } else {
+          z->lflg = localz->lflg;
+          z->ext = localz->ext;
+          z->extra = localz->extra;
+          if (localz->nam) free(localz->iname);
+          if (localz->nam) free(localz->name);
+#ifdef UNICODE_SUPPORT
+          if (localz->uname) free(localz->uname);
+#endif
+          free(localz);
+        }
+
+        if (!(filesync && z->current) &&
+             (r = zipup(z)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
+        {
+          zipmessage_nl("", 1);
+          /*
+          if (noisy)
+          {
+            if (mesg_line_started) {
+#if (!defined(MACOS) && !defined(WINDLL))
+              putc('\n', mesg);
+              fflush(mesg);
+#else
+              fprintf(stdout, "\n");
+              fflush(stdout);
+#endif
+              mesg_line_started = 0;
+            }
+          }
+          if (logall) {
+            if (logfile_line_started) {
+              fprintf(logfile, "\n");
+              logfile_line_started = 0;
+              fflush(logfile);
+            }
+          }
+          */
+          sprintf(errbuf, "was zipping %s", z->name);
+          ZIPERR(r, errbuf);
+        }
+        if (filesync && z->current)
+        {
+          /* if filesync if entry matches OS just copy */
+          if ((r = zipcopy(z)) != ZE_OK)
+          {
+            sprintf(errbuf, "was copying %s", z->oname);
+            ZIPERR(r, errbuf);
+          }
+          zipmessage_nl("", 1);
+          /*
+          if (noisy)
+          {
+            if (mesg_line_started) {
+#if (!defined(MACOS) && !defined(WINDLL))
+              putc('\n', mesg);
+              fflush(mesg);
+#else
+              fprintf(stdout, "\n");
+              fflush(stdout);
+#endif
+              mesg_line_started = 0;
+            }
+          }
+          if (logall) {
+            if (logfile_line_started) {
+              fprintf(logfile, "\n");
+              logfile_line_started = 0;
+              fflush(logfile);
+            }
+          }
+          */
+        }
+        if (r == ZE_OPEN || r == ZE_MISS)
+        {
+          o = 1;
+          zipmessage_nl("", 1);
+          /*
+          if (noisy)
+          {
+#if (!defined(MACOS) && !defined(WINDLL))
+            putc('\n', mesg);
+            fflush(mesg);
+#else
+            fprintf(stdout, "\n");
+#endif
+            mesg_line_started = 0;
+          }
+          if (logall) {
+            fprintf(logfile, "\n");
+            logfile_line_started = 0;
+            fflush(logfile);
+          }
+          */
+          if (r == ZE_OPEN) {
+            perror(z->oname);
+            zipwarn("could not open for reading: ", z->oname);
+            if (bad_open_is_error) {
+              sprintf(errbuf, "was zipping %s", z->name);
+              ZIPERR(r, errbuf);
+            }
+          } else {
+            zipwarn("file and directory with the same name: ", z->oname);
+          }
+          zipwarn("will just copy entry over: ", z->oname);
+          if ((r = zipcopy(z)) != ZE_OK)
+          {
+            sprintf(errbuf, "was copying %s", z->oname);
+            ZIPERR(r, errbuf);
+          }
+          z->mark = 0;
+        }
+        files_so_far++;
+        good_bytes_so_far += z->len;
+        bytes_so_far += len;
+        w = &z->nxt;
+      }
+      else if (action == ARCHIVE)
+      {
+#ifdef DEBUG
+        zoff_t here = zftello(y);
+#endif
+
+        DisplayRunningStats();
+        if (skip_this_disk - 1 != z->dsk)
+          /* moved to another disk so start copying again */
+          skip_this_disk = 0;
+        if (skip_this_disk - 1 == z->dsk) {
+          /* skipping this disk */
+          if (noisy) {
+            fprintf(mesg, " skipping: %s", z->oname);
+            mesg_line_started = 1;
+            fflush(mesg);
+          }
+          if (logall) {
+            fprintf(logfile, " skipping: %s", z->oname);
+            logfile_line_started = 1;
+            fflush(logfile);
+          }
+        } else {
+          /* copying this entry */
+          if (noisy) {
+            fprintf(mesg, " copying: %s", z->oname);
+            if (display_usize) {
+              fprintf(mesg, " (");
+              DisplayNumString(mesg, z->len );
+              fprintf(mesg, ")");
+            }
+            mesg_line_started = 1;
+            fflush(mesg);
+          }
+          if (logall)
+          {
+            fprintf(logfile, " copying: %s", z->oname);
+            if (display_usize) {
+              fprintf(logfile, " (");
+              DisplayNumString(logfile, z->len );
+              fprintf(logfile, ")");
+            }
+            logfile_line_started = 1;
+            fflush(logfile);
+          }
+        }
+
+        if (skip_this_disk - 1 == z->dsk)
+          /* skip entries on this disk */
+          z->mark = 0;
+        else if ((r = zipcopy(z)) != ZE_OK)
+        {
+          if (r == ZE_ABORT) {
+            ZIPERR(r, "user requested abort");
+          } else if (fix != 1) {
+            /* exit */
+            sprintf(errbuf, "was copying %s", z->oname);
+            zipwarn("(try -F to attempt to fix)", "");
+            ZIPERR(r, errbuf);
+          }
+          else /* if (r == ZE_FORM) */ {
+#ifdef DEBUG
+            zoff_t here = zftello(y);
+#endif
+
+            /* seek back in output to start of this entry so can overwrite */
+            if (zfseeko(y, current_local_offset, SEEK_SET) != 0){
+              ZIPERR(r, "could not seek in output file");
+            }
+            zipwarn("bad - skipping: ", z->oname);
+#ifdef DEBUG
+            here = zftello(y);
+#endif
+            tempzn = current_local_offset;
+            bytes_this_split = current_local_offset;
+          }
+        }
+        if (skip_this_disk || !(fix == 1 && r != ZE_OK))
+        {
+          if (noisy && mesg_line_started) {
+            fprintf(mesg, "\n");
+            mesg_line_started = 0;
+            fflush(mesg);
+          }
+          if (logall && logfile_line_started) {
+            fprintf(logfile, "\n");
+            logfile_line_started = 0;
+            fflush(logfile);
+          }
+        }
+        /* input counts */
+        files_so_far++;
+        if (r != ZE_OK)
+          bad_bytes_so_far += z->siz;
+        else
+          good_bytes_so_far += z->siz;
+        bytes_so_far += z->siz;
+
+        if (r != ZE_OK && fix == 1) {
+          /* remove bad entry from list */
+          v = z->nxt;                     /* delete entry from list */
+          free((zvoid *)(z->iname));
+          free((zvoid *)(z->zname));
+          free(z->oname);
+#ifdef UNICODE_SUPPORT
+          if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+          if (z->ext)
+            /* don't have local extra until zipcopy reads it */
+            if (z->extra) free((zvoid *)(z->extra));
+          if (z->cext && z->cextra != z->extra)
+            free((zvoid *)(z->cextra));
+          if (z->com)
+            free((zvoid *)(z->comment));
+          farfree((zvoid far *)z);
+          *w = v;
+          zcount--;
+        } else {
+          w = &z->nxt;
+        }
+
+#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+        /* int64 support in caller */
+        if (lpZipUserFunctions->ServiceApplication64 != NULL)
+        {
+          if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+                    ZIPERR(ZE_ABORT, "User terminated operation");
+        }
+        else
+        {
+          /* no int64 support in caller */
+          filesize64 = z->siz;
+          low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+          high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+          if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+            if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+                      ZIPERR(ZE_ABORT, "User terminated operation");
+          }
+        }
+#else
+        if (lpZipUserFunctions->ServiceApplication != NULL) {
+          if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
+            ZIPERR(ZE_ABORT, "User terminated operation");
+        }
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+   each other, the Aztec Amiga compiler never sees the second endif!  WTF?? PK */
+#endif /* WINDLL */
+      }
+      else
+      {
+        DisplayRunningStats();
+        if (noisy)
+        {
+          fprintf(mesg, "deleting: %s", z->oname);
+          if (display_usize) {
+            fprintf(mesg, " (");
+            DisplayNumString(mesg, z->len );
+            fprintf(mesg, ")");
+          }
+          fflush(mesg);
+          fprintf(mesg, "\n");
+        }
+        if (logall)
+        {
+          fprintf(logfile, "deleting: %s", z->oname);
+          if (display_usize) {
+            fprintf(logfile, " (");
+            DisplayNumString(logfile, z->len );
+            fprintf(logfile, ")");
+          }
+          fprintf(logfile, "\n");
+          fflush(logfile);
+        }
+        files_so_far++;
+        good_bytes_so_far += z->siz;
+        bytes_so_far += z->siz;
+#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+        /* int64 support in caller */
+        if (lpZipUserFunctions->ServiceApplication64 != NULL)
+        {
+          if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+                    ZIPERR(ZE_ABORT, "User terminated operation");
+        }
+        else
+        {
+          /* no int64 support in caller */
+          filesize64 = z->siz;
+          low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+          high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+          if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+            if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+                      ZIPERR(ZE_ABORT, "User terminated operation");
+          }
+        }
+#else
+        if (lpZipUserFunctions->ServiceApplication != NULL) {
+          if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
+            ZIPERR(ZE_ABORT, "User terminated operation");
+        }
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+   each other, the Aztec Amiga compiler never sees the second endif!  WTF?? PK */
+#endif /* WINDLL */
+
+        v = z->nxt;                     /* delete entry from list */
+        free((zvoid *)(z->iname));
+        free((zvoid *)(z->zname));
+        free(z->oname);
+#ifdef UNICODE_SUPPORT
+        if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+        if (z->ext)
+          /* don't have local extra until zipcopy reads it */
+          if (z->extra) free((zvoid *)(z->extra));
+        if (z->cext && z->cextra != z->extra)
+          free((zvoid *)(z->cextra));
+        if (z->com)
+          free((zvoid *)(z->comment));
+        farfree((zvoid far *)z);
+        *w = v;
+        zcount--;
+      }
+    }
+    else
+    {
+      if (action == ARCHIVE) {
+        v = z->nxt;                     /* delete entry from list */
+        free((zvoid *)(z->iname));
+        free((zvoid *)(z->zname));
+        free(z->oname);
+#ifdef UNICODE_SUPPORT
+        if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+        if (z->ext)
+          /* don't have local extra until zipcopy reads it */
+          if (z->extra) free((zvoid *)(z->extra));
+        if (z->cext && z->cextra != z->extra)
+          free((zvoid *)(z->cextra));
+        if (z->com)
+          free((zvoid *)(z->comment));
+        farfree((zvoid far *)z);
+        *w = v;
+        zcount--;
+      }
+      else
+      {
+        if (filesync) {
+          /* Delete entries if don't match a file on OS */
+          BlankRunningStats();
+          if (noisy)
+          {
+            fprintf(mesg, "deleting: %s", z->oname);
+            if (display_usize) {
+              fprintf(mesg, " (");
+              DisplayNumString(mesg, z->len );
+              fprintf(mesg, ")");
+            }
+            fflush(mesg);
+            fprintf(mesg, "\n");
+            mesg_line_started = 0;
+          }
+          if (logall)
+          {
+            fprintf(logfile, "deleting: %s", z->oname);
+            if (display_usize) {
+              fprintf(logfile, " (");
+              DisplayNumString(logfile, z->len );
+              fprintf(logfile, ")");
+            }
+            fprintf(logfile, "\n");
+            fflush(logfile);
+            logfile_line_started = 0;
+          }
+        }
+        /* copy the original entry */
+        else if (!d && !diff_mode && (r = zipcopy(z)) != ZE_OK)
+        {
+          sprintf(errbuf, "was copying %s", z->oname);
+          ZIPERR(r, errbuf);
+        }
+        w = &z->nxt;
+      }
+    }
+  }
+
+
+  /* Process the edited found list, adding them to the zip file */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Zipping up new entries\n");
+    fflush(mesg);
+  }
+  diag("zipping up new entries, if any");
+  Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
+  for (f = found; f != NULL; f = fexpel(f))
+  {
+    uzoff_t len;
+    /* add a new zfiles entry and set the name */
+    if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+      ZIPERR(ZE_MEM, "was adding files to zip file");
+    }
+    z->nxt = NULL;
+    z->name = f->name;
+    f->name = NULL;
+#ifdef UNICODE_SUPPORT
+    z->uname = NULL;          /* UTF-8 name for extra field */
+    z->zuname = NULL;         /* externalized UTF-8 name for matching */
+    z->ouname = NULL;         /* display version of UTF-8 name with OEM */
+
+#if 0
+    /* New AppNote bit 11 allowing storing UTF-8 in path */
+    if (utf8_force && f->uname) {
+      if (f->iname)
+        free(f->iname);
+      if ((f->iname = malloc(strlen(f->uname) + 1)) == NULL)
+        ZIPERR(ZE_MEM, "Unicode bit 11");
+      strcpy(f->iname, f->uname);
+# ifdef WIN32
+      if (f->inamew)
+        free(f->inamew);
+      f->inamew = utf8_to_wchar_string(f->iname);
+# endif
+    }
+#endif
+
+    /* Only set z->uname if have a non-ASCII Unicode name */
+    /* The Unicode path extra field is created if z->uname is not NULL,
+       unless on a UTF-8 system, then instead of creating the extra field
+       set bit 11 in the General Purpose Bit Flag */
+    {
+      int is_ascii = 0;
+
+# ifdef WIN32
+      if (!no_win32_wide)
+        is_ascii = is_ascii_stringw(f->inamew);
+      else
+        is_ascii = is_ascii_string(f->uname);
+# else
+      is_ascii = is_ascii_string(f->uname);
+# endif
+
+      if (z->uname == NULL) {
+        if (!is_ascii)
+          z->uname = f->uname;
+        else
+          free(f->uname);
+      } else {
+        free(f->uname);
+      }
+    }
+    f->uname = NULL;
+
+#endif
+    z->iname = f->iname;
+    f->iname = NULL;
+    z->zname = f->zname;
+    f->zname = NULL;
+    z->oname = f->oname;
+    f->oname = NULL;
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+    z->namew = f->namew;
+    f->namew = NULL;
+    z->inamew = f->inamew;
+    f->inamew = NULL;
+    z->znamew = f->znamew;
+    f->znamew = NULL;
+#endif
+    z->ext = z->cext = z->com = 0;
+    z->extra = z->cextra = NULL;
+    z->mark = 1;
+    z->dosflag = f->dosflag;
+    /* zip it up */
+    DisplayRunningStats();
+    if (noisy)
+    {
+      fprintf(mesg, "  adding: %s", z->oname);
+      mesg_line_started = 1;
+      fflush(mesg);
+    }
+    if (logall)
+    {
+      fprintf(logfile, "  adding: %s", z->oname);
+      logfile_line_started = 1;
+      fflush(logfile);
+    }
+    /* initial scan */
+    len = f->usize;
+    if ((r = zipup(z)) != ZE_OK  && r != ZE_OPEN && r != ZE_MISS)
+    {
+      zipmessage_nl("", 1);
+      /*
+      if (noisy)
+      {
+#if (!defined(MACOS) && !defined(WINDLL))
+        putc('\n', mesg);
+        fflush(mesg);
+#else
+        fprintf(stdout, "\n");
+#endif
+        mesg_line_started = 0;
+        fflush(mesg);
+      }
+      if (logall) {
+        fprintf(logfile, "\n");
+        logfile_line_started = 0;
+        fflush(logfile);
+      }
+      */
+      sprintf(errbuf, "was zipping %s", z->oname);
+      ZIPERR(r, errbuf);
+    }
+    if (r == ZE_OPEN || r == ZE_MISS)
+    {
+      o = 1;
+      zipmessage_nl("", 1);
+      /*
+      if (noisy)
+      {
+#if (!defined(MACOS) && !defined(WINDLL))
+        putc('\n', mesg);
+        fflush(mesg);
+#else
+        fprintf(stdout, "\n");
+#endif
+        mesg_line_started = 0;
+        fflush(mesg);
+      }
+      if (logall) {
+        fprintf(logfile, "\n");
+        logfile_line_started = 0;
+        fflush(logfile);
+      }
+      */
+      if (r == ZE_OPEN) {
+        perror("zip warning");
+        if (logfile)
+          fprintf(logfile, "zip warning: %s\n", strerror(errno));
+        zipwarn("could not open for reading: ", z->oname);
+        if (bad_open_is_error) {
+          sprintf(errbuf, "was zipping %s", z->name);
+          ZIPERR(r, errbuf);
+        }
+      } else {
+        zipwarn("file and directory with the same name: ", z->oname);
+      }
+      files_so_far++;
+      bytes_so_far += len;
+      bad_files_so_far++;
+      bad_bytes_so_far += len;
+      free((zvoid *)(z->name));
+      free((zvoid *)(z->iname));
+      free((zvoid *)(z->zname));
+      free(z->oname);
+#ifdef UNICODE_SUPPORT
+      if (z->uname)
+        free(z->uname);
+# ifdef WIN32
+      if (z->namew)
+        free((zvoid *)(z->namew));
+      if (z->inamew)
+        free((zvoid *)(z->inamew));
+      if (z->znamew)
+        free((zvoid *)(z->znamew));
+# endif
+#endif
+      farfree((zvoid far *)z);
+    }
+    else
+    {
+      files_so_far++;
+      /* current size of file (just before reading) */
+      good_bytes_so_far += z->len;
+      /* size of file on initial scan */
+      bytes_so_far += len;
+      *w = z;
+      w = &z->nxt;
+      zcount++;
+    }
+  }
+  if (key != NULL)
+  {
+    free((zvoid *)key);
+    key = NULL;
+  }
+
+  /* final status 3/17/05 EG */
+  if (noisy && bad_files_so_far)
+  {
+    char tempstrg[100];
+
+    fprintf(mesg, "\nzip warning: Not all files were readable\n");
+    fprintf(mesg, "  files/entries read:  %lu", files_total - bad_files_so_far);
+    WriteNumString(good_bytes_so_far, tempstrg);
+    fprintf(mesg, " (%s bytes)", tempstrg);
+    fprintf(mesg, "  skipped:  %lu", bad_files_so_far);
+    WriteNumString(bad_bytes_so_far, tempstrg);
+    fprintf(mesg, " (%s bytes)\n", tempstrg);
+    fflush(mesg);
+  }
+  if (logfile && bad_files_so_far)
+  {
+    char tempstrg[100];
+
+    fprintf(logfile, "\nzip warning: Not all files were readable\n");
+    fprintf(logfile, "  files/entries read:  %lu", files_total - bad_files_so_far);
+    WriteNumString(good_bytes_so_far, tempstrg);
+    fprintf(logfile, " (%s bytes)", tempstrg);
+    fprintf(logfile, "  skipped:  %lu", bad_files_so_far);
+    WriteNumString(bad_bytes_so_far, tempstrg);
+    fprintf(logfile, " (%s bytes)", tempstrg);
+  }
+
+  /* Get one line comment for each new entry */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Get comment if any\n");
+    fflush(mesg);
+  }
+#if defined(AMIGA) || defined(MACOS)
+  if (comadd || filenotes)
+  {
+    if (comadd)
+#else
+  if (comadd)
+  {
+#endif
+    {
+      if (comment_stream == NULL) {
+#ifndef RISCOS
+        comment_stream = (FILE*)fdopen(fileno(stderr), "r");
+#else
+        comment_stream = stderr;
+#endif
+      }
+      if ((e = malloc(MAXCOM + 1)) == NULL) {
+        ZIPERR(ZE_MEM, "was reading comment lines");
+      }
+    }
+#ifdef __human68k__
+    setmode(fileno(comment_stream), O_TEXT);
+#endif
+#ifdef MACOS
+    if (noisy) fprintf(mesg, "\nStart commenting files ...\n");
+#endif
+    for (z = zfiles; z != NULL; z = z->nxt)
+      if (z->mark)
+#if defined(AMIGA) || defined(MACOS)
+        if (filenotes && (p = GetComment(z->zname)))
+        {
+          if (z->comment = malloc(k = strlen(p)+1))
+          {
+            z->com = k;
+            strcpy(z->comment, p);
+          }
+          else
+          {
+            free((zvoid *)e);
+            ZIPERR(ZE_MEM, "was reading filenotes");
+          }
+        }
+        else if (comadd)
+#endif /* AMIGA || MACOS */
+        {
+          if (noisy)
+            fprintf(mesg, "Enter comment for %s:\n", z->oname);
+          if (fgets(e, MAXCOM+1, comment_stream) != NULL)
+          {
+            if ((p = malloc((extent)(k = strlen(e))+1)) == NULL)
+            {
+              free((zvoid *)e);
+              ZIPERR(ZE_MEM, "was reading comment lines");
+            }
+            strcpy(p, e);
+            if (p[k-1] == '\n')
+              p[--k] = 0;
+            z->comment = p;
+            /* zip64 support 09/05/2003 R.Nausedat */
+            z->com = (extent)k;
+          }
+        }
+#ifdef MACOS
+    if (noisy) fprintf(mesg, "\n...done");
+#endif
+#if defined(AMIGA) || defined(MACOS)
+    if (comadd)
+      free((zvoid *)e);
+    GetComment(NULL);           /* makes it free its internal storage */
+#else
+    free((zvoid *)e);
+#endif
+  }
+
+  /* Get multi-line comment for the zip file */
+  if (zipedit)
+  {
+#ifndef WINDLL
+    if (comment_stream == NULL) {
+#ifndef RISCOS
+      comment_stream = (FILE*)fdopen(fileno(stderr), "r");
+#else
+      comment_stream = stderr;
+#endif
+    }
+    if ((e = malloc(MAXCOM + 1)) == NULL) {
+      ZIPERR(ZE_MEM, "was reading comment lines");
+    }
+    if (noisy && zcomlen)
+    {
+      fputs("current zip file comment is:\n", mesg);
+      fwrite(zcomment, 1, zcomlen, mesg);
+      if (zcomment[zcomlen-1] != '\n')
+        putc('\n', mesg);
+      free((zvoid *)zcomment);
+    }
+    if ((zcomment = malloc(1)) == NULL)
+      ZIPERR(ZE_MEM, "was setting comments to null");
+    zcomment[0] = '\0';
+    if (noisy)
+      fputs("enter new zip file comment (end with .):\n", mesg);
+#if (defined(AMIGA) && (defined(LATTICE)||defined(__SASC)))
+    flushall();  /* tty input/output is out of sync here */
+#endif
+#ifdef __human68k__
+    setmode(fileno(comment_stream), O_TEXT);
+#endif
+#ifdef MACOS
+    printf("\n enter new zip file comment \n");
+    if (fgets(e, MAXCOM+1, comment_stream) != NULL) {
+        if ((p = malloc((k = strlen(e))+1)) == NULL) {
+            free((zvoid *)e);
+            ZIPERR(ZE_MEM, "was reading comment lines");
+        }
+        strcpy(p, e);
+        if (p[k-1] == '\n') p[--k] = 0;
+        zcomment = p;
+    }
+#else /* !MACOS */
+    while (fgets(e, MAXCOM+1, comment_stream) != NULL && strcmp(e, ".\n"))
+    {
+      if (e[(r = strlen(e)) - 1] == '\n')
+        e[--r] = 0;
+      if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
+      {
+        free((zvoid *)e);
+        ZIPERR(ZE_MEM, "was reading comment lines");
+      }
+      if (*zcomment)
+        strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
+      else
+        strcpy(p, *e ? e : "\r\n");
+      free((zvoid *)zcomment);
+      zcomment = p;
+    }
+#endif /* ?MACOS */
+    free((zvoid *)e);
+#else /* WINDLL */
+    comment(zcomlen);
+    if ((p = malloc(strlen(szCommentBuf)+1)) == NULL) {
+      ZIPERR(ZE_MEM, "was setting comments to null");
+    }
+    if (szCommentBuf[0] != '\0')
+       lstrcpy(p, szCommentBuf);
+    else
+       p[0] = '\0';
+    free((zvoid *)zcomment);
+    GlobalUnlock(hStr);
+    GlobalFree(hStr);
+    zcomment = p;
+#endif /* WINDLL */
+    zcomlen = strlen(zcomment);
+  }
+
+  if (display_globaldots) {
+#ifndef WINDLL
+    putc('\n', mesg);
+#else
+    fprintf(stdout,"%c",'\n');
+#endif
+    mesg_line_started = 0;
+  }
+
+  /* Write central directory and end header to temporary zip */
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Writing central directory\n");
+    fflush(mesg);
+  }
+  diag("writing central directory");
+  k = 0;                        /* keep count for end header */
+  c = tempzn;                   /* get start of central */
+  n = t = 0;
+  for (z = zfiles; z != NULL; z = z->nxt)
+  {
+    if (z->mark || !(diff_mode || filesync)) {
+      if ((r = putcentral(z)) != ZE_OK) {
+        ZIPERR(r, tempzip);
+      }
+      tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+      n += z->len;
+      t += z->siz;
+      k++;
+    }
+  }
+
+  if (k == 0)
+    zipwarn("zip file empty", "");
+  if (verbose) {
+    fprintf(mesg, "total bytes=%s, compressed=%s -> %d%% savings\n",
+            zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+    fflush(mesg);
+  }
+  if (logall) {
+    fprintf(logfile, "total bytes=%s, compressed=%s -> %d%% savings\n",
+            zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+    fflush(logfile);
+  }
+  t = tempzn - c;               /* compute length of central */
+  diag("writing end of central directory");
+  if (show_what_doing) {
+    fprintf(mesg, "sd: Writing end of central directory\n");
+    fflush(mesg);
+  }
+
+  if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
+    ZIPERR(r, tempzip);
+  }
+
+  /*
+  tempzf = NULL;
+  */
+  if (fclose(y)) {
+    ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
+  }
+  y = NULL;
+  if (in_file != NULL) {
+    fclose(in_file);
+    in_file = NULL;
+  }
+  /*
+  if (x != NULL)
+    fclose(x);
+  */
+
+  /* Free some memory before spawning unzip */
+#ifdef USE_ZLIB
+  zl_deflate_free();
+#else
+  lm_free();
+#endif
+#ifdef BZIP2_SUPPORT
+  bz_compress_free();
+#endif
+
+#ifndef WINDLL
+  /* Test new zip file before overwriting old one or removing input files */
+  if (test)
+    check_zipfile(tempzip, argv[0]);
+#endif
+  /* Replace old zip file with new zip file, leaving only the new one */
+  if (strcmp(zipfile, "-") && !d)
+  {
+    diag("replacing old zip file with new zip file");
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Replacing old zip file\n");
+      fflush(mesg);
+    }
+    if ((r = replace(out_path, tempzip)) != ZE_OK)
+    {
+      zipwarn("new zip file left as: ", tempzip);
+      free((zvoid *)tempzip);
+      tempzip = NULL;
+      ZIPERR(r, "was replacing the original zip file");
+    }
+    free((zvoid *)tempzip);
+  }
+  tempzip = NULL;
+  if (zip_attributes && strcmp(zipfile, "-")) {
+    setfileattr(out_path, zip_attributes);
+#ifdef VMS
+    /* If the zip file existed previously, restore its record format: */
+    if (x != NULL)
+      (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
+#endif
+  }
+  if (strcmp(zipfile, "-")) {
+    if (show_what_doing) {
+      fprintf(mesg, "sd: Setting file type\n");
+      fflush(mesg);
+    }
+
+    set_filetype(out_path);
+  }
+
+#if defined(WIN32)
+  /* All looks good so, if requested, clear the DOS archive bits */
+  if (clear_archive_bits) {
+    if (noisy)
+      zipmessage("Clearing archive bits...", "");
+    for (z = zfiles; z != NULL; z = z->nxt)
+    {
+# ifdef UNICODE_SUPPORT
+      if (z->mark) {
+        if (!no_win32_wide) {
+          if (!ClearArchiveBitW(z->namew)){
+            zipwarn("Could not clear archive bit for: ", z->oname);
+          }
+        } else {
+          if (!ClearArchiveBit(z->name)){
+            zipwarn("Could not clear archive bit for: ", z->oname);
+          }
+        }
+      }
+# else
+      if (!ClearArchiveBit(z->name)){
+        zipwarn("Could not clear archive bit for: ", z->oname);
+      }
+# endif
+    }
+  }
+#endif
+
+  /* finish logfile (it gets closed in freeup() called by finish()) */
+  if (logfile) {
+      struct tm *now;
+      time_t clocktime;
+
+      fprintf(logfile, "\nTotal %ld entries (", files_total);
+      if (good_bytes_so_far != bytes_total) {
+        fprintf(logfile, "planned ");
+        DisplayNumString(logfile, bytes_total);
+        fprintf(logfile, " bytes, actual ");
+        DisplayNumString(logfile, good_bytes_so_far);
+        fprintf(logfile, " bytes)");
+      } else {
+        DisplayNumString(logfile, bytes_total);
+        fprintf(logfile, " bytes)");
+      }
+
+      /* get current time */
+
+      time(&clocktime);
+      now = localtime(&clocktime);
+      fprintf(logfile, "\nDone %s", asctime(now));
+  }
+
+  /* Finish up (process -o, -m, clean up).  Exit code depends on o. */
+#if (!defined(VMS) && !defined(CMS_MVS))
+  free((zvoid *) zipbuf);
+#endif /* !VMS && !CMS_MVS */
+  RETURN(finish(o ? ZE_OPEN : ZE_OK));
+}
Index: zip/create-3.0-format-security-patch/zip30-new
===================================================================
--- zip/create-3.0-format-security-patch/zip30-new	(nonexistent)
+++ zip/create-3.0-format-security-patch/zip30-new	(revision 5)

Property changes on: zip/create-3.0-format-security-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-format-security-patch
===================================================================
--- zip/create-3.0-format-security-patch	(nonexistent)
+++ zip/create-3.0-format-security-patch	(revision 5)

Property changes on: zip/create-3.0-format-security-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch/create.patch.sh
===================================================================
--- zip/create-3.0-man-pages-patch/create.patch.sh	(nonexistent)
+++ zip/create-3.0-man-pages-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr  zip${version}-orig  zip${version} > zip-${VERSION}-man-pages.patch
+
+mv zip-${VERSION}-man-pages.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig

Property changes on: zip/create-3.0-man-pages-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-man-pages-patch/file.list
===================================================================
--- zip/create-3.0-man-pages-patch/file.list	(nonexistent)
+++ zip/create-3.0-man-pages-patch/file.list	(revision 5)
@@ -0,0 +1,2 @@
+zip30/man/zipnote.1
+zip30/man/zipsplit.1
Index: zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1	(nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1	(revision 5)
@@ -0,0 +1,89 @@
+.TH zipnote 1 "v3.0 of 8 May 2008"
+.SH NAME
+zipnote \- write the comments in zipfile to stdout, edit comments and rename files in zipfile
+
+.SH SYNOPSIS
+.I zipnote
+.RB [ \-w ]
+.RB [ \-b\ path ]
+.RB [ \-h ]
+.RB [ \-q ]
+.RB [ \-v ]
+.RB [ \-L ]
+zipfile
+
+.SH ARGUMENTS
+.in +13
+.ti -13
+zipfile  Zipfile to read comments from or edit.
+
+.SH OPTIONS
+.TP
+.BI \-w
+Write comments to a zipfile from stdin (see below).
+.TP
+.BI \-b\ \fRpath
+Use path for the temporary zip file.
+.TP
+.BI \-h
+Show a short help.
+.TP
+.BI \-q
+Suppress some informational messages.
+.TP
+.BI \-v
+Show version information.
+.TP
+.BI \-L
+Show software license.
+
+.SH DESCRIPTION
+.I zipnote
+writes the comments in a zipfile to stdout.  This is the default mode.  A second mode
+allows updating the comments in a zipfile as well as allows changing the names
+of the files in the zipfile.  These modes are described below.
+
+.SH EXAMPLES
+To write all comments in a zipfile to stdout use for example
+.LP
+.nf
+     zipnote foo.zip > foo.tmp
+.fi
+.LP
+This writes all comments in the zipfile
+.I foo.zip
+to the file
+.I foo.tmp
+in a specific format.
+
+.LP
+If desired, this file can then be edited to change the comments and then used
+to update the zipfile.
+.LP
+.nf
+     zipnote -w foo.zip < foo.tmp
+.fi
+.LP
+The names of the files in the zipfile can also be changed in this way.  This is done by
+following lines like
+.nf
+     "@ name"
+.fi
+in the created temporary file (called
+.I foo.tmp
+here) with lines like
+.nf
+     "@=newname"
+.fi
+and then using the -w option as above.
+
+.SH BUGS
+The temporary file format is rather specific and zipnote is rather picky about it.
+It should be easier to change file names in a script.
+
+Does not yet support large (> 2 GB) or split archives.
+
+.SH SEE ALSO
+zip(1), unzip(1)
+.SH AUTHOR
+Info-ZIP
Index: zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1	(nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1	(revision 5)
@@ -0,0 +1,73 @@
+.TH zipnote 1 "v3.0 of 8 May 2008"
+.SH NAME
+zipsplit \- split a zipfile into smaller zipfiles
+
+.SH SYNOPSIS
+.I zipsplit
+.RB [ \-t ]
+.RB [ \-i ]
+.RB [ \-p ]
+.RB [ \-s ]
+.RB [ \-n\ size ]
+.RB [ \-r\ room ]
+.RB [ \-b\ path ]
+.RB [ \-h ]
+.RB [ \-q ]
+.RB [ \-v ]
+.RB [ \-L ]
+zipfile
+
+.SH ARGUMENTS
+.in +13
+.ti -13
+zipfile  Zipfile to split.
+
+.SH OPTIONS
+.TP
+.BI \-t
+Report how many files it will take, but don't make them.
+.TP
+.BI \-i
+Make index (zipsplit.idx) and count its size against first zip file.
+.TP
+.BI \-n\ \fRsize
+Make zip files no larger than "size" (default = 36000).
+.TP
+.BI \-r\ \fRroom
+Leave room for "room" bytes on the first disk (default = 0).
+.TP
+.BI \-b\ \fRpath
+Use path for the output zip files.
+.TP
+.BI \-p
+Pause between output zip files.
+.TP
+.BI \-s
+Do a sequential split even if it takes more zip files.
+.TP
+.BI \-h
+Show a short help.
+.TP
+.BI \-q
+Suppress some informational messages.
+.TP
+.BI \-v
+Show version information.
+.TP
+.BI \-L
+Show software license.
+
+.SH DESCRIPTION
+.I zipsplit
+reads a zipfile and splits it into smaller zipfiles.
+
+.SH EXAMPLES
+To be filled in.
+
+.SH BUGS
+Does not yet support large (> 2 GB) or split archives.
+
+.SH SEE ALSO
+zip(1), unzip(1)
+.SH AUTHOR
+Info-ZIP
Index: zip/create-3.0-man-pages-patch/zip30-new/man
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man	(nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man	(revision 5)

Property changes on: zip/create-3.0-man-pages-patch/zip30-new/man
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch/zip30-new
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new	(nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new	(revision 5)

Property changes on: zip/create-3.0-man-pages-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch
===================================================================
--- zip/create-3.0-man-pages-patch	(nonexistent)
+++ zip/create-3.0-man-pages-patch	(revision 5)

Property changes on: zip/create-3.0-man-pages-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-zipnote-patch/create.patch.sh
===================================================================
--- zip/create-3.0-zipnote-patch/create.patch.sh	(nonexistent)
+++ zip/create-3.0-zipnote-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr  zip${version}-orig  zip${version} > zip-${VERSION}-zipnote.patch
+
+mv zip-${VERSION}-zipnote.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig

Property changes on: zip/create-3.0-zipnote-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-zipnote-patch/file.list
===================================================================
--- zip/create-3.0-zipnote-patch/file.list	(nonexistent)
+++ zip/create-3.0-zipnote-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+zip30/zipnote.c
Index: zip/create-3.0-zipnote-patch/zip30-new/zipnote.c
===================================================================
--- zip/create-3.0-zipnote-patch/zip30-new/zipnote.c	(nonexistent)
+++ zip/create-3.0-zipnote-patch/zip30-new/zipnote.c	(revision 5)
@@ -0,0 +1,699 @@
+/*
+  zipnote.c - Zip 3
+
+  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+/*
+ *  zipnote.c by Mark Adler.
+ */
+#define __ZIPNOTE_C
+
+#ifndef UTIL
+#define UTIL
+#endif
+#include "zip.h"
+#define DEFCPYRT        /* main module: enable copyright string defines! */
+#include "revision.h"
+#include <signal.h>
+
+/* Calculate size of static line buffer used in write (-w) mode. */
+#define WRBUFSIZ 2047
+/* The line buffer size should be at least as large as FNMAX. */
+#if FNMAX > WRBUFSIZ
+#  undef WRBUFSIZ
+#  define WRBUFSIZ FNMAX
+#endif
+
+/* Character to mark zip entry names in the comment file */
+#define MARK '@'
+#define MARKE " (comment above this line)"
+#define MARKZ " (zip file comment below this line)"
+
+/* Temporary zip file pointer */
+local FILE *tempzf;
+
+
+/* Local functions */
+local void handler OF((int));
+local void license OF((void));
+local void help OF((void));
+local void version_info OF((void));
+local void putclean OF((char *, extent));
+/* getline name conflicts with GNU getline() function */
+local char *zgetline OF((char *, extent));
+local int catalloc OF((char * far *, char *));
+int main OF((int, char **));
+
+/* keep compiler happy until implement long options - 11/4/2003 EG */
+struct option_struct far options[] = {
+  /* short longopt        value_type        negatable        ID    name */
+    {"h",  "help",        o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
+    /* the end of the list */
+    {NULL, NULL,          o_NO_VALUE,       o_NOT_NEGATABLE, 0,    NULL} /* end has option_ID = 0 */
+  };
+
+#ifdef MACOS
+#define ziperr(c, h)    zipnoteerr(c, h)
+#define zipwarn(a, b)   zipnotewarn(a, b)
+
+void zipnoteerr(int c, ZCONST char *h);
+void zipnotewarn(ZCONST char *a, ZCONST char *b);
+#endif
+
+#ifdef QDOS
+#define exit(p1) QDOSexit()
+#endif
+
+int set_filetype(out_path)
+  char *out_path;
+{
+#ifdef __BEOS__
+  /* Set the filetype of the zipfile to "application/zip" */
+  setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+  /* Set the filetype of the zipfile to "application/x-zip" */
+  setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+  /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+  setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+  /* Set the filetype of the zipfile to &DDC */
+  setfiletype(out_path, 0xDDC);
+#endif
+  return ZE_OK;
+}
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+  char *temp_name;
+  char *out_path;
+{
+  int r;
+  /* Replace old zip file with new zip file, leaving only the new one */
+  if ((r = replace(out_path, temp_name)) != ZE_OK)
+  {
+    zipwarn("new zip file left as: ", temp_name);
+    free((zvoid *)tempzip);
+    tempzip = NULL;
+    ZIPERR(r, "was replacing split file");
+  }
+  if (zip_attributes) {
+    setfileattr(out_path, zip_attributes);
+  }
+  return ZE_OK;
+}
+
+void zipmessage_nl(a, nl)
+ZCONST char *a;     /* message string to output */
+int nl;             /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+   If nl true, print and add new line.  If logfile is
+   open then also write message to log file. */
+{
+  if (noisy) {
+    fprintf(mesg, "%s", a);
+    if (nl) {
+      fprintf(mesg, "\n");
+      mesg_line_started = 0;
+    } else {
+      mesg_line_started = 1;
+    }
+    fflush(mesg);
+  }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b;     /* message strings juxtaposed in output */
+/* Print a message to mesg and flush.  Also write to log file if
+   open.  Write new line first if current line has output already. */
+{
+  if (noisy) {
+    if (mesg_line_started)
+      fprintf(mesg, "\n");
+    fprintf(mesg, "%s%s\n", a, b);
+    mesg_line_started = 0;
+    fflush(mesg);
+  }
+}
+
+void ziperr(c, h)
+int c;                  /* error code from the ZE_ class */
+ZCONST char *h;         /* message about how it happened */
+/* Issue a message for the error, clean up files and memory, and exit. */
+{
+  if (PERR(c))
+    perror("zipnote error");
+  fprintf(mesg, "zipnote error: %s (%s)\n", ZIPERRORS(c), h);
+  if (tempzf != NULL)
+    fclose(tempzf);
+  if (tempzip != NULL)
+  {
+    destroy(tempzip);
+    free((zvoid *)tempzip);
+  }
+  if (zipfile != NULL)
+    free((zvoid *)zipfile);
+  EXIT(c);
+}
+
+
+local void handler(s)
+int s;                  /* signal number (ignored) */
+/* Upon getting a user interrupt, abort cleanly using ziperr(). */
+{
+#ifndef MSDOS
+  putc('\n', mesg);
+#endif /* !MSDOS */
+  ziperr(ZE_ABORT, "aborting");
+  s++;                                  /* keep some compilers happy */
+}
+
+
+void zipwarn(a, b)
+ZCONST char *a, *b;     /* message strings juxtaposed in output */
+/* Print a warning message to mesg (usually stderr) and return. */
+{
+  fprintf(mesg, "zipnote warning: %s%s\n", a, b);
+}
+
+
+local void license()
+/* Print license information to stdout. */
+{
+  extent i;             /* counter for copyright array */
+
+  for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
+    puts(swlicense[i]);
+}
+
+
+local void help()
+/* Print help (along with license info) to stdout. */
+{
+  extent i;             /* counter for help array */
+
+  /* help array */
+  static ZCONST char *text[] = {
+"",
+"ZipNote %s (%s)",
+#ifdef VM_CMS
+"Usage:  zipnote [-w] [-q] [-b fm] zipfile",
+#else
+"Usage:  zipnote [-w] [-q] [-b path] zipfile",
+#endif
+"  the default action is to write the comments in zipfile to stdout",
+"  -w   write the zipfile comments from stdin",
+#ifdef VM_CMS
+"  -b   use \"fm\" as the filemode for the temporary zip file",
+#else
+"  -b   use \"path\" for the temporary zip file",
+#endif
+"  -q   quieter operation, suppress some informational messages",
+"  -h   show this help    -v   show version info    -L   show software license",
+"",
+"Example:",
+#ifdef VMS
+"     define/user sys$output foo.tmp",
+"     zipnote foo.zip",
+"     edit foo.tmp",
+"     ... then you edit the comments, save, and exit ...",
+"     define/user sys$input foo.tmp",
+"     zipnote -w foo.zip",
+#else
+#ifdef RISCOS
+"     zipnote foo/zip > foo/tmp",
+"     <!Edit> foo/tmp",
+"     ... then you edit the comments, save, and exit ...",
+"     zipnote -w foo/zip < foo/tmp",
+#else
+#ifdef VM_CMS
+"     zipnote foo.zip > foo.tmp",
+"     xedit foo tmp",
+"     ... then you edit the comments, save, and exit ...",
+"     zipnote -w foo.zip < foo.tmp",
+#else
+"     zipnote foo.zip > foo.tmp",
+"     ed foo.tmp",
+"     ... then you edit the comments, save, and exit ...",
+"     zipnote -w foo.zip < foo.tmp",
+#endif /* VM_CMS */
+#endif /* RISCOS */
+#endif /* VMS */
+"",
+"  \"@ name\" can be followed by an \"@=newname\" line to change the name"
+  };
+
+  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
+    printf(copyright[i], "zipnote");
+    putchar('\n');
+  }
+  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+  {
+    printf(text[i], VERSION, REVDATE);
+    putchar('\n');
+  }
+}
+
+/*
+ * XXX put this in version.c
+ */
+
+local void version_info()
+/* Print verbose info about program version and compile time options
+   to stdout. */
+{
+  extent i;             /* counter in text arrays */
+
+  /* Options info array */
+  static ZCONST char *comp_opts[] = {
+#ifdef DEBUG
+    "DEBUG",
+#endif
+    NULL
+  };
+
+  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+  {
+    printf(copyright[i], "zipnote");
+    putchar('\n');
+  }
+
+  for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
+  {
+    printf(versinfolines[i], "ZipNote", VERSION, REVDATE);
+    putchar('\n');
+  }
+
+  version_local();
+
+  puts("ZipNote special compilation options:");
+  for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
+  {
+    printf("\t%s\n",comp_opts[i]);
+  }
+  if (i == 0)
+      puts("\t[none]");
+}
+
+
+local void putclean(s, n)
+char *s;                /* string to write to stdout */
+extent n;               /* length of string */
+/* Write the string s to stdout, filtering out control characters that are
+   not tab or newline (mainly to remove carriage returns), and prefix MARK's
+   and backslashes with a backslash.  Also, terminate with a newline if
+   needed. */
+{
+  int c;                /* next character in string */
+  int e;                /* last character written */
+
+  e = '\n';                     /* if empty, write nothing */
+  while (n--)
+  {
+    c = *(uch *)s++;
+    if (c == MARK || c == '\\')
+      putchar('\\');
+    if (c >= ' ' || c == '\t' || c == '\n')
+      { e=c; putchar(e); }
+  }
+  if (e != '\n')
+    putchar('\n');
+}
+
+
+local char *zgetline(buf, size)
+char *buf;
+extent size;
+/* Read a line of text from stdin into string buffer 'buf' of size 'size'.
+   In case of buffer overflow or EOF, a NULL pointer is returned. */
+{
+    char *line;
+    unsigned len;
+
+    line = fgets(buf, size, stdin);
+    if (line != NULL && (len = strlen(line)) > 0) {
+        if (len == size-1 && line[len-1] != '\n') {
+            /* buffer is full and record delimiter not seen -> overflow */
+            line = NULL;
+        } else {
+            /* delete trailing record delimiter */
+            if (line[len-1] == '\n') line[len-1] = '\0';
+        }
+    }
+    return line;
+}
+
+
+local int catalloc(a, s)
+char * far *a;          /* pointer to a pointer to a malloc'ed string */
+char *s;                /* string to concatenate on a */
+/* Concatentate the string s to the malloc'ed string pointed to by a.
+   Preprocess s by removing backslash escape characters. */
+{
+  char *p;              /* temporary pointer */
+  char *q;              /* temporary pointer */
+
+  for (p = q = s; *q; *p++ = *q++)
+    if (*q == '\\' && *(q+1))
+      q++;
+  *p = 0;
+  if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL)
+    return ZE_MEM;
+  strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s);
+  free((zvoid *)*a);
+  *a = p;
+  return ZE_OK;
+}
+
+
+#ifndef USE_ZIPNOTEMAIN
+int main(argc, argv)
+#else
+int zipnotemain(argc, argv)
+#endif
+int argc;               /* number of tokens in command line */
+char **argv;            /* command line tokens */
+/* Write the comments in the zipfile to stdout, or read them from stdin. */
+{
+  char abf[WRBUFSIZ+1]; /* input line buffer */
+  char *a;              /* pointer to line buffer or NULL */
+  zoff_t c;             /* start of central directory */
+  int k;                /* next argument type */
+  char *q;              /* steps through option arguments */
+  int r;                /* arg counter, temporary variable */
+  zoff_t s;             /* length of central directory */
+  int t;                /* attributes of zip file */
+  int w;                /* true if updating zip file from stdin */
+  FILE *x;              /* input file for testing if can write it */
+  struct zlist far *z;  /* steps through zfiles linked list */
+
+#ifdef THEOS
+  setlocale(LC_CTYPE, "I");
+#endif
+
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+  /* For Unix, set the locale to UTF-8.  Any UTF-8 locale is
+     OK and they should all be the same.  This allows seeing,
+     writing, and displaying (if the fonts are loaded) all
+     characters in UTF-8. */
+  {
+    char *loc;
+
+    /*
+      loc = setlocale(LC_CTYPE, NULL);
+      printf("  Initial language locale = '%s'\n", loc);
+    */
+
+    loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+    /*
+      printf("langinfo %s\n", nl_langinfo(CODESET));
+    */
+
+    if (loc != NULL) {
+      /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+      using_utf8 = 1;
+      /*
+        printf("  Locale set to %s\n", loc);
+      */
+    } else {
+      /*
+        printf("  Could not set Unicode UTF-8 locale\n");
+      */
+    }
+  }
+# endif
+#endif
+
+  /* If no args, show help */
+  if (argc == 1)
+  {
+    help();
+    EXIT(ZE_OK);
+  }
+
+  /* Direct info messages to stderr; stdout is used for data output. */
+  mesg = stderr;
+
+  init_upper();           /* build case map table */
+
+  /* Go through args */
+  zipfile = tempzip = NULL;
+  tempzf = NULL;
+  signal(SIGINT, handler);
+#ifdef SIGTERM              /* AMIGA has no SIGTERM */
+  signal(SIGTERM, handler);
+#endif
+#ifdef SIGABRT
+  signal(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+  signal(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+  signal(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+  signal(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+  signal(SIGSEGV, handler);
+#endif
+  k = w = 0;
+  for (r = 1; r < argc; r++)
+    if (*argv[r] == '-') {
+      if (argv[r][1])
+        for (q = argv[r]+1; *q; q++)
+          switch (*q)
+          {
+            case 'b':   /* Specify path for temporary file */
+              if (k)
+                ziperr(ZE_PARMS, "use -b before zip file name");
+              else
+                k = 1;          /* Next non-option is path */
+              break;
+            case 'h':   /* Show help */
+              help();  EXIT(ZE_OK);
+            case 'l':  case 'L':  /* Show copyright and disclaimer */
+              license();  EXIT(ZE_OK);
+            case 'q':   /* Quiet operation, suppress info messages */
+              noisy = 0;  break;
+            case 'v':   /* Show version info */
+              version_info();  EXIT(ZE_OK);
+            case 'w':
+              w = 1;  break;
+            default:
+              ziperr(ZE_PARMS, "unknown option");
+          }
+      else
+        ziperr(ZE_PARMS, "zip file cannot be stdin");
+    } else
+      if (k == 0)
+      {
+        if (zipfile == NULL)
+        {
+          if ((zipfile = ziptyp(argv[r])) == NULL)
+            ziperr(ZE_MEM, "was processing arguments");
+        }
+        else
+          ziperr(ZE_PARMS, "can only specify one zip file");
+      }
+      else
+      {
+        tempath = argv[r];
+        k = 0;
+      }
+  if (zipfile == NULL)
+    ziperr(ZE_PARMS, "need to specify zip file");
+
+  if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+    ziperr(ZE_MEM, "input");
+  }
+  strcpy(in_path, zipfile);
+
+  /* Read zip file */
+  if ((r = readzipfile()) != ZE_OK)
+    ziperr(r, zipfile);
+  if (zfiles == NULL)
+    ziperr(ZE_NAME, zipfile);
+
+  /* Put comments to stdout, if not -w */
+  if (!w)
+  {
+    for (z = zfiles; z != NULL; z = z->nxt)
+    {
+      printf("%c %s\n", MARK, z->zname);
+      putclean(z->comment, z->com);
+      printf("%c%s\n", MARK, MARKE);
+    }
+    printf("%c%s\n", MARK, MARKZ);
+    putclean(zcomment, zcomlen);
+    EXIT(ZE_OK);
+  }
+
+  /* If updating comments, make sure zip file is writeable */
+  if ((x = fopen(zipfile, "a")) == NULL)
+    ziperr(ZE_CREAT, zipfile);
+  fclose(x);
+  t = getfileattr(zipfile);
+
+  /* Process stdin, replacing comments */
+  z = zfiles;
+  while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL &&
+         (a[0] != MARK || strcmp(a + 1, MARKZ)))
+  {                                     /* while input and not file comment */
+    if (a[0] != MARK || a[1] != ' ')    /* better be "@ name" */
+      ziperr(ZE_NOTE, "unexpected input");
+    while (z != NULL && strcmp(a + 2, z->zname))
+      z = z->nxt;                       /* allow missing entries in order */
+    if (z == NULL)
+      ziperr(ZE_NOTE, "unknown entry name");
+    if ((a = zgetline(abf, WRBUFSIZ+1)) != NULL && a[0] == MARK && a[1] == '=')
+    {
+      if (z->name != z->iname)
+        free((zvoid *)z->iname);
+      if ((z->iname = malloc(strlen(a+1))) == NULL)
+        ziperr(ZE_MEM, "was changing name");
+#ifdef EBCDIC
+      strtoasc(z->iname, a+2);
+#else
+      strcpy(z->iname, a+2);
+#endif
+
+/*
+ * Don't update z->nam here, we need the old value a little later.....
+ * The update is handled in zipcopy().
+ */
+      a = zgetline(abf, WRBUFSIZ+1);
+    }
+    if (z->com)                         /* change zip entry comment */
+      free((zvoid *)z->comment);
+    z->comment = malloc(1);  *(z->comment) = 0;
+    while (a != NULL && *a != MARK)
+    {
+      if ((r = catalloc(&(z->comment), a)) != ZE_OK)
+        ziperr(r, "was building new zipentry comments");
+      a = zgetline(abf, WRBUFSIZ+1);
+    }
+    z->com = strlen(z->comment);
+    z = z->nxt;                         /* point to next entry */
+  }
+  if (a != NULL)                        /* change zip file comment */
+  {
+    zcomment = malloc(1);  *zcomment = 0;
+    while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL)
+      if ((r = catalloc(&zcomment, a)) != ZE_OK)
+        ziperr(r, "was building new zipfile comment");
+    zcomlen = strlen(zcomment);
+  }
+
+  /* Open output zip file for writing */
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+  {
+    int yd;
+    int i;
+
+    /* use mkstemp to avoid race condition and compiler warning */
+
+    if (tempath != NULL)
+    {
+      /* if -b used to set temp file dir use that for split temp */
+      if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+        ZIPERR(ZE_MEM, "allocating temp filename");
+      }
+      strcpy(tempzip, tempath);
+      if (lastchar(tempzip) != '/')
+        strcat(tempzip, "/");
+    }
+    else
+    {
+      /* create path by stripping name and appending template */
+      if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+      ZIPERR(ZE_MEM, "allocating temp filename");
+      }
+      strcpy(tempzip, zipfile);
+      for(i = strlen(tempzip); i > 0; i--) {
+        if (tempzip[i - 1] == '/')
+          break;
+      }
+      tempzip[i] = '\0';
+    }
+    strcat(tempzip, "ziXXXXXX");
+
+    if ((yd = mkstemp(tempzip)) == EOF) {
+      ZIPERR(ZE_TEMP, tempzip);
+    }
+    if ((tempzf = y = fdopen(yd, FOPW)) == NULL) {
+      ZIPERR(ZE_TEMP, tempzip);
+    }
+  }
+#else
+  if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
+    ziperr(ZE_TEMP, tempzip);
+#endif
+
+  /* Open input zip file again, copy preamble if any */
+  if ((in_file = fopen(zipfile, FOPR)) == NULL)
+    ziperr(ZE_NAME, zipfile);
+
+  if (zipbeg && (r = bfcopy(zipbeg)) != ZE_OK)
+    ziperr(r, r == ZE_TEMP ? tempzip : zipfile);
+  tempzn = zipbeg;
+
+  /* Go through local entries, copying them over as is */
+  fix = 3; /* needed for zipcopy if name changed */
+  for (z = zfiles; z != NULL; z = z->nxt) {
+    if ((r = zipcopy(z)) != ZE_OK)
+      ziperr(r, "was copying an entry");
+  }
+  fclose(in_file);
+
+  /* Write central directory and end of central directory with new comments */
+  if ((c = zftello(y)) == (zoff_t)-1)    /* get start of central */
+    ziperr(ZE_TEMP, tempzip);
+  for (z = zfiles; z != NULL; z = z->nxt)
+    if ((r = putcentral(z)) != ZE_OK)
+      ziperr(r, tempzip);
+  if ((s = zftello(y)) == (zoff_t)-1)    /* get end of central */
+    ziperr(ZE_TEMP, tempzip);
+  s -= c;                       /* compute length of central */
+  if ((r = putend((zoff_t)zcount, s, c, zcomlen, zcomment)) != ZE_OK)
+    ziperr(r, tempzip);
+  tempzf = NULL;
+  if (fclose(y))
+    ziperr(ZE_TEMP, tempzip);
+  if ((r = replace(zipfile, tempzip)) != ZE_OK)
+  {
+    zipwarn("new zip file left as: ", tempzip);
+    free((zvoid *)tempzip);
+    tempzip = NULL;
+    ziperr(r, "was replacing the original zip file");
+  }
+  free((zvoid *)tempzip);
+  tempzip = NULL;
+  setfileattr(zipfile, t);
+#ifdef RISCOS
+  /* Set the filetype of the zipfile to &DDC */
+  setfiletype(zipfile,0xDDC);
+#endif
+  free((zvoid *)zipfile);
+  zipfile = NULL;
+
+  /* Done! */
+  RETURN(0);
+}
Index: zip/create-3.0-zipnote-patch/zip30-new
===================================================================
--- zip/create-3.0-zipnote-patch/zip30-new	(nonexistent)
+++ zip/create-3.0-zipnote-patch/zip30-new	(revision 5)

Property changes on: zip/create-3.0-zipnote-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-zipnote-patch
===================================================================
--- zip/create-3.0-zipnote-patch	(nonexistent)
+++ zip/create-3.0-zipnote-patch	(revision 5)

Property changes on: zip/create-3.0-zipnote-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/patches/README
===================================================================
--- zip/patches/README	(nonexistent)
+++ zip/patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   TODO: Leave some comment here.
+
+ * end */
Index: zip/patches
===================================================================
--- zip/patches	(nonexistent)
+++ zip/patches	(revision 5)

Property changes on: zip/patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip
===================================================================
--- zip	(nonexistent)
+++ zip	(revision 5)

Property changes on: zip
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~