ports/146934: [NEW PORT] japanese/unzip NLS patched unzip. import from Ubuntu japan.

HASHI Hiroaki hashiz at meridiani.jp
Tue May 25 00:20:05 UTC 2010


>Number:         146934
>Category:       ports
>Synopsis:       [NEW PORT] japanese/unzip NLS patched unzip. import from Ubuntu japan.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 25 00:20:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     HASHI Hiroaki
>Release:        FreeBSD 8.1-PRERELEASE amd64
>Organization:
person
>Environment:
System: FreeBSD stenmark.meridiani.jp 8.1-PRERELEASE FreeBSD 8.1-PRERELEASE #0: Sat May 22 22:08:35 JST 2010 hashiz at stenmark.meridiani.jp:/usr/obj/amd64/usr/src/sys/STENMARK amd64


	
>Description:
	NLS patched unzip.
	It can convert filename encoding.(such as CP932 to UTF-8)
>How-To-Repeat:
	
>Fix:

	

--- unzip-nls.shar begins here ---
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	japanese/unzip
#	japanese/unzip/files
#	japanese/unzip/files/patch-aa
#	japanese/unzip/files/patch-ab
#	japanese/unzip/files/patch-contsts.h
#	japanese/unzip/files/patch-process.c
#	japanese/unzip/files/patch-fileio.c
#	japanese/unzip/files/patch-inflate.c
#	japanese/unzip/files/patch-unix_unix.c
#	japanese/unzip/files/patch-unzpriv.h
#	japanese/unzip/files/patch-unzip-5.52-nls-2
#	japanese/unzip/files/patch-unzip-5.52-nls-1
#	japanese/unzip/Makefile
#	japanese/unzip/distinfo
#	japanese/unzip/pkg-descr
#
echo c - japanese/unzip
mkdir -p japanese/unzip > /dev/null 2>&1
echo c - japanese/unzip/files
mkdir -p japanese/unzip/files > /dev/null 2>&1
echo x - japanese/unzip/files/patch-aa
sed 's/^X//' >japanese/unzip/files/patch-aa << '77fd31b65d2014fdcb24b9d66e92b0bb'
X--- unix/Makefile.orig	Mon Mar  1 20:37:24 2004
X+++ unix/Makefile	Wed May 26 21:43:04 2004
X@@ -42,7 +42,7 @@
X # such as -DDOSWILD).
X 
X # UnZip flags
X-CC = cc#	try using "gcc" target rather than changing this (CC and LD
X+CC ?= cc#	try using "gcc" target rather than changing this (CC and LD
X LD = $(CC)#	must match, else "unresolved symbol:  ___main" is possible)
X AS = as
X LOC = $(LOCAL_UNZIP)
X@@ -727,8 +727,8 @@
X # FreeBSD on Intel:
X freebsd:		unix_make
X 	@echo 'NOTE:  use bsd target for non-Intel FreeBSD compiles (if any).'
X-	$(MAKE) unzips CC=gcc LD=gcc AS=gcc\
X-	 CF="-O3 -Wall -I. -DASM_CRC -DUNIX -DBSD $(LOC)"\
X+	$(MAKE) unzips CC="$(CC)" LD="$(CC)" AS="$(CC)"\
X+	 CF="-Wall -I. -DASM_CRC -DUNIX -DBSD $(LOC)"\
X 	 AF="-Di386 $(AF)" CRC32=crc_gcc
X 
X # Generic BSDish Unix gcc.  ``The -O3 only works with later versions of gcc;
77fd31b65d2014fdcb24b9d66e92b0bb
echo x - japanese/unzip/files/patch-ab
sed 's/^X//' >japanese/unzip/files/patch-ab << 'b1115f0db860826c0abe92b8907bcd4b'
X--- unix/unix.c.bak	Wed May 26 21:40:00 2004
X+++ unix/unix.c	Wed May 26 21:40:09 2004
X@@ -533,7 +533,7 @@
X 
X             default:
X                 /* allow European characters in filenames: */
X-                if (isprint(workch) || (128 <= workch && workch <= 254))
X+                if (isprint(workch) || (128 <= workch && workch <= 255))
X                     *pp++ = (char)workch;
X         } /* end switch */
X 
b1115f0db860826c0abe92b8907bcd4b
echo x - japanese/unzip/files/patch-contsts.h
sed 's/^X//' >japanese/unzip/files/patch-contsts.h << '85dd49cfcaf718ec63dfe9eee8def91a'
X--- unzip-5.52.orig/consts.h
X+++ consts.h
X@@ -34,9 +34,9 @@
X   "error:  expected central file header signature not found (file #%lu).\n";
X ZCONST char Far SeekMsg[] =
X   "error [%s]:  attempt to seek before beginning of zipfile\n%s";
X-ZCONST char Far FilenameNotMatched[] = "caution: filename not matched:  %s\n";
X+ZCONST char Far FilenameNotMatched[] = "caution: filename not matched:  %.512s\n";
X ZCONST char Far ExclFilenameNotMatched[] =
X-  "caution: excluded filename not matched:  %s\n";
X+  "caution: excluded filename not matched:  %.512s\n";
X 
X #ifdef VMS
X   ZCONST char Far ReportMsg[] = "\
85dd49cfcaf718ec63dfe9eee8def91a
echo x - japanese/unzip/files/patch-process.c
sed 's/^X//' >japanese/unzip/files/patch-process.c << '2835a6670d2d2f3e820ee81defddc314'
X--- unzip-5.52.orig/process.c
X+++ process.c
X@@ -74,20 +74,20 @@
X    /* do_seekable() strings */
X # ifdef UNIX
X    static ZCONST char Far CannotFindZipfileDirMsg[] =
X-     "%s:  cannot find zipfile directory in one of %s or\n\
X-        %s%s.zip, and cannot find %s, period.\n";
X+     "%s:  cannot find zipfile directory in one of %.512s or\n\
X+        %s%.512s.zip, and cannot find %.512s, period.\n";
X    static ZCONST char Far CannotFindEitherZipfile[] =
X-     "%s:  cannot find or open %s, %s.zip or %s.\n";
X+     "%s:  cannot find or open %.512s, %.512s.zip or %.512s.\n";
X # else /* !UNIX */
X # ifndef AMIGA
X    static ZCONST char Far CannotFindWildcardMatch[] =
X-     "%s:  cannot find any matches for wildcard specification \"%s\".\n";
X+     "%s:  cannot find any matches for wildcard specification \"%.512s\".\n";
X # endif /* !AMIGA */
X    static ZCONST char Far CannotFindZipfileDirMsg[] =
X-     "%s:  cannot find zipfile directory in %s,\n\
X-        %sand cannot find %s, period.\n";
X+     "%s:  cannot find zipfile directory in %.512s,\n\
X+        %sand cannot find %.512s, period.\n";
X    static ZCONST char Far CannotFindEitherZipfile[] =
X-     "%s:  cannot find either %s or %s.\n";
X+     "%s:  cannot find either %.512s or %.512s.\n";
X # endif /* ?UNIX */
X    extern ZCONST char Far Zipnfo[];       /* in unzip.c */
X #ifndef WINDLL
2835a6670d2d2f3e820ee81defddc314
echo x - japanese/unzip/files/patch-fileio.c
sed 's/^X//' >japanese/unzip/files/patch-fileio.c << '2a18e18db0b418605d02160904a2d1d3'
X--- unzip-5.52.orig/fileio.c
X+++ fileio.c
X@@ -413,7 +413,11 @@
X #endif /* NOVELL_BUG_FAILSAFE */
X     Trace((stderr, "open_outfile:  doing fopen(%s) for writing\n",
X       FnFilter1(G.filename)));
X+#if defined(SYMLINKS) || defined(QLZIP)
X+    if ((G.outfile = fopen(G.filename, FOPWR)) == (FILE *)NULL) {
X+#else
X     if ((G.outfile = fopen(G.filename, FOPW)) == (FILE *)NULL) {
X+#endif
X         Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
X           FnFilter1(G.filename)));
X         return 1;
2a18e18db0b418605d02160904a2d1d3
echo x - japanese/unzip/files/patch-inflate.c
sed 's/^X//' >japanese/unzip/files/patch-inflate.c << '4c7959317848a19cb32198920c4940ba'
X--- unzip-5.52.orig/inflate.c
X+++ inflate.c
X@@ -983,6 +983,7 @@
X   unsigned l;           /* last length */
X   unsigned m;           /* mask for bit lengths table */
X   unsigned n;           /* number of lengths to get */
X+  struct huft *tlp;     
X   struct huft *tl;      /* literal/length code table */
X   struct huft *td;      /* distance code table */
X   unsigned bl;          /* lookup bits for tl */
X@@ -996,6 +997,8 @@
X   int retval = 0;       /* error code returned: initialized to "no error" */
X 
X 
X+  td = tlp = tl = (struct huft *)NULL;
X+
X   /* make local bit buffer */
X   Trace((stderr, "\ndynamic block"));
X   b = G.bb;
X@@ -1047,9 +1050,9 @@
X   while (i < n)
X   {
X     NEEDBITS(bl)
X-    j = (td = tl + ((unsigned)b & m))->b;
X+    j = (tlp = tl + ((unsigned)b & m))->b;
X     DUMPBITS(j)
X-    j = td->v.n;
X+    j = tlp->v.n;
X     if (j < 16)                 /* length of code in bits (0..15) */
X       ll[i++] = l = j;          /* save last length in l */
X     else if (j == 16)           /* repeat last length 3 to 6 times */
X@@ -1141,6 +1144,7 @@
X       huft_free(td);
X     }
X     huft_free(tl);
X+
X     return retval;
X   }
X 
X@@ -1149,8 +1153,8 @@
X 
X cleanup_and_exit:
X   /* free the decoding tables, return */
X-  huft_free(tl);
X-  huft_free(td);
X+  if (tl) huft_free(tl);
X+  if (td) huft_free(td);
X   return retval;
X }
X 
4c7959317848a19cb32198920c4940ba
echo x - japanese/unzip/files/patch-unix_unix.c
sed 's/^X//' >japanese/unzip/files/patch-unix_unix.c << 'a0916281acfcb9fe88bc613b3cb420ab'
X--- unzip-5.52.orig/unix/unix.c
X+++ unix/unix.c
X@@ -1042,8 +1042,6 @@
X     ush z_uidgid[2];
X     int have_uidgid_flg;
X 
X-    fclose(G.outfile);
X-
X /*---------------------------------------------------------------------------
X     If symbolic links are supported, allocate storage for a symlink control
X     structure, put the uncompressed "data" and other required info in it, and
X@@ -1063,6 +1061,7 @@
X             Info(slide, 0x201, ((char *)slide,
X               "warning:  symbolic link (%s) failed: mem alloc overflow\n",
X               FnFilter1(G.filename)));
X+            fclose(G.outfile);
X             return;
X         }
X 
X@@ -1070,6 +1069,7 @@
X             Info(slide, 0x201, ((char *)slide,
X               "warning:  symbolic link (%s) failed: no mem\n",
X               FnFilter1(G.filename)));
X+            fclose(G.outfile);
X             return;
X         }
X         slnk_entry->next = NULL;
X@@ -1079,11 +1079,10 @@
X         slnk_entry->fname = slnk_entry->target + ucsize + 1;
X         strcpy(slnk_entry->fname, G.filename);
X 
X-        /* reopen the "link data" file for reading */
X-        G.outfile = fopen(G.filename, FOPR);
X+        /* move back to the start of the file to re-read the "link data" */
X+        rewind(G.outfile);
X 
X-        if (!G.outfile ||
X-            fread(slnk_entry->target, 1, ucsize, G.outfile) != (int)ucsize)
X+        if (fread(slnk_entry->target, 1, ucsize, G.outfile) != (int)ucsize)
X         {
X             Info(slide, 0x201, ((char *)slide,
X               "warning:  symbolic link (%s) failed\n",
X@@ -1115,12 +1114,20 @@
X     }
X #endif
X 
X+#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
X+    fclose(G.outfile);
X+#endif
X+
X     have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
X 
X     /* if -X option was specified and we have UID/GID info, restore it */
X     if (have_uidgid_flg) {
X         TTrace((stderr, "close_outfile:  restoring Unix UID/GID info\n"));
X+#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
X         if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
X+#else
X+        if (fchown(fileno(G.outfile), (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
X+#endif
X         {
X             if (uO.qflag)
X                 Info(slide, 0x201, ((char *)slide,
X@@ -1133,6 +1140,18 @@
X         }
X     }
X 
X+#if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
X+/*---------------------------------------------------------------------------
X+    Change the file permissions from default ones to those stored in the
X+    zipfile.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
X+        perror("chmod (file attributes) error");
X+
X+    fclose(G.outfile);
X+#endif /* !NO_FCHOWN && !NO_FCHMOD */
X+
X     /* set the file's access and modification times */
X     if (utime(G.filename, &(zt.t2))) {
X #ifdef AOS_VS
X@@ -1151,6 +1170,7 @@
X #endif /* ?AOS_VS */
X     }
X 
X+#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
X /*---------------------------------------------------------------------------
X     Change the file permissions from default ones to those stored in the
X     zipfile.
X@@ -1160,6 +1180,7 @@
X     if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr)))
X         perror("chmod (file attributes) error");
X #endif
X+#endif /* NO_FCHOWN || NO_FCHMOD */
X 
X } /* end function close_outfile() */
X 
X@@ -1640,7 +1661,6 @@
X 
X             if ((long)LG(dlen) > 0)
X             {
X-                G.outfile = fopen(G.filename,"r+");
X                 fseek(G.outfile, -8, SEEK_END);
X                 fread(&ntc, 8, 1, G.outfile);
X                 if(ntc.id != *(long *)"XTcc")
X@@ -1650,7 +1670,6 @@
X                     fwrite (&ntc, 8, 1, G.outfile);
X                 }
X                 Info(slide, 0x201, ((char *)slide, "QData = %d", LG(dlen)));
X-                fclose(G.outfile);
X             }
X             return;     /* finished, cancel further extra field scanning */
X           }
a0916281acfcb9fe88bc613b3cb420ab
echo x - japanese/unzip/files/patch-unzpriv.h
sed 's/^X//' >japanese/unzip/files/patch-unzpriv.h << '11f6535ebaedcf29e578a26ff8504471'
X--- unzip-5.52.orig/unzpriv.h
X+++ unzpriv.h
X@@ -1081,6 +1081,7 @@
X #  define FOPR  "r","ctx=stm"
X #  define FOPM  "r+","ctx=stm","rfm=fix","mrs=512"
X #  define FOPW  "w","ctx=stm","rfm=fix","mrs=512"
X+#  define FOPWR "w+","ctx=stm","rfm=fix","mrs=512"
X #endif /* VMS */
X 
X #ifdef CMS_MVS
X@@ -1117,6 +1118,9 @@
X #  ifndef FOPWT
X #    define FOPWT "wt"
X #  endif
X+#  ifndef FOPWR
X+#    define FOPWR "w+b"
X+#  endif
X #else /* !MODERN */
X #  ifndef FOPR
X #    define FOPR "r"
X@@ -1130,6 +1134,9 @@
X #  ifndef FOPWT
X #    define FOPWT "w"
X #  endif
X+#  ifndef FOPWR
X+#    define FOPWR "w+b"
X+#  endif
X #endif /* ?MODERN */
X 
X /*
11f6535ebaedcf29e578a26ff8504471
echo x - japanese/unzip/files/patch-unzip-5.52-nls-2
sed 's/^X//' >japanese/unzip/files/patch-unzip-5.52-nls-2 << '17456131800990f99d2534468ad4a2b4'
X--- unix/Makefile-p1	2010-05-24 23:58:37.000000000 +0900
X+++ unix/Makefile	2010-05-25 00:00:06.000000000 +0900
X@@ -613,8 +613,7 @@
X bsd:		_bsd	# generic BSD (BSD 4.2 & Ultrix handled in unzip.h)
X 
X _bsd:		unix_make
X-	$(MAKE) unzips CF="$(CF) -DBSD"
X-
X+	$(MAKE) unzips CF="$(CF) -DBSD -I/usr/local/include -DNLS $(LOC)" LF="-o unzip -L/usr/local/lib -liconv" SL="-o unzipsfx -L/usr/local/lib -liconv"
X #----------------------------------------------------------------------------
X #  SysV group (for extern long timezone and ioctl.h instead of sgtty.h):
X #----------------------------------------------------------------------------
17456131800990f99d2534468ad4a2b4
echo x - japanese/unzip/files/patch-unzip-5.52-nls-1
sed 's/^X//' >japanese/unzip/files/patch-unzip-5.52-nls-1 << '0588af1d819e734dc985a056f2d05bf8'
Xdiff -ruN ../unzip-5.52.orig/fileio.c ./fileio.c
X--- ../unzip-5.52.orig/fileio.c	2005-02-27 11:10:12.000000000 +0900
X+++ ./fileio.c	2008-03-08 07:16:58.000000000 +0900
X@@ -2444,6 +2444,66 @@
X #endif /* REGULUS */
X 
X 
X+#ifdef NLS
X+char*
X+strdup_iconv (const char	*to_enc,
X+	      const char	*from_enc,
X+	      char		*str)
X+{
X+  iconv_t cd;
X+  char *outbuf, *outbufp, *inbufp;
X+  size_t outbufsize, inbytesleft, outbytesleft, ret;
X+
X+  inbufp = str;
X+  inbytesleft = strlen (str);
X+  outbytesleft = outbufsize = 8192;
X+  outbufp = outbuf = malloc (outbufsize);
X+  if (! outbuf)
X+    return NULL;
X+
X+  cd = iconv_open (to_enc, from_enc);
X+  if (cd == (iconv_t) -1)
X+    return NULL;
X+
X+  while (inbytesleft) {
X+    ret = iconv (cd, &inbufp, &inbytesleft, &outbufp, &outbytesleft);
X+    if (ret == (size_t) -1) {
X+      if (errno == E2BIG) {
X+	size_t offset = (size_t) outbufp - (size_t) outbuf;
X+	char *newbuf;
X+	/* grow size of memory */
X+	outbufsize += 8192;
X+	outbytesleft += 8192;
X+	newbuf = realloc (outbuf, outbufsize);
X+	if (! newbuf) {
X+	  iconv_close (cd);
X+	  free (outbuf);
X+	  return NULL;
X+	}
X+	outbuf = newbuf;
X+	outbufp = outbuf + offset;
X+      } else if (outbytesleft > 0 && inbytesleft > 0) {
X+	/* error but force to go forward */
X+	*outbufp ++ = *inbufp ++;
X+	inbytesleft --;
X+	outbytesleft --;
X+      } else break;
X+    }
X+  }
X+  iconv_close (cd);
X+
X+  outbufsize -= outbytesleft;
X+  if (outbufsize < 1) {
X+    free (outbuf);
X+    return NULL;
X+  }
X+
X+  outbuf = realloc (outbuf, outbufsize + 1);
X+  outbuf[outbufsize] = '\0';
X+
X+  return outbuf;
X+}
X+#endif
X 
X 
X #ifdef _MBCS
X@@ -2473,6 +2533,13 @@
X }
X 
X 
X+int uzmblen (ZCONST char *ptr) {
X+  int i = mblen (ptr, MB_CUR_MAX);
X+  if (i >= 0) return i;
X+  return 1; /* keep to go forward */
X+}
X+
X+
X #ifdef NEED_UZMBSCHR
X /***********************/
X /* Function uzmbschr() */
Xdiff -ruN ../unzip-5.52.orig/fileio.c.orig ./fileio.c.orig
X--- ../unzip-5.52.orig/fileio.c.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./fileio.c.orig	2005-02-27 11:10:12.000000000 +0900
X@@ -0,0 +1,2575 @@
X+/*
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  See the accompanying file LICENSE, version 2000-Apr-09 or later
X+  (the contents of which are also included in unzip.h) for terms of use.
X+  If, for some reason, all these files are missing, the Info-ZIP license
X+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
X+*/
X+/*---------------------------------------------------------------------------
X+
X+  fileio.c
X+
X+  This file contains routines for doing direct but relatively generic input/
X+  output, file-related sorts of things, plus some miscellaneous stuff.  Most
X+  of the stuff has to do with opening, closing, reading and/or writing files.
X+
X+  Contains:  open_input_file()
X+             open_outfile()           (not: VMS, AOS/VS, CMSMVS, MACOS, TANDEM)
X+             undefer_input()
X+             defer_leftover_input()
X+             readbuf()
X+             readbyte()
X+             fillinbuf()
X+             seek_zipf()
X+             flush()                  (non-VMS)
X+             is_vms_varlen_txt()      (non-VMS, VMS_TEXT_CONV only)
X+             disk_error()             (non-VMS)
X+             UzpMessagePrnt()
X+             UzpMessageNull()         (DLL only)
X+             UzpInput()
X+             UzpMorePause()
X+             UzpPassword()            (non-WINDLL)
X+             handler()
X+             dos_to_unix_time()       (non-VMS, non-VM/CMS, non-MVS)
X+             check_for_newer()        (non-VMS, non-OS/2, non-VM/CMS, non-MVS)
X+             do_string()
X+             makeword()
X+             makelong()
X+             str2iso()                (CRYPT && NEED_STR2ISO, only)
X+             str2oem()                (CRYPT && NEED_STR2OEM, only)
X+             memset()                 (ZMEM only)
X+             memcpy()                 (ZMEM only)
X+             zstrnicmp()              (NO_STRNICMP only)
X+             zstat()                  (REGULUS only)
X+             plastchar()              (_MBCS only)
X+             uzmbschr()               (_MBCS && NEED_UZMBSCHR, only)
X+             uzmbsrchr()              (_MBCS && NEED_UZMBSRCHR, only)
X+             fLoadFarString()         (SMALL_MEM only)
X+             fLoadFarStringSmall()    (SMALL_MEM only)
X+             fLoadFarStringSmall2()   (SMALL_MEM only)
X+             zfstrcpy()               (SMALL_MEM only)
X+             zfstrcmp()               (SMALL_MEM && !(SFX || FUNZIP) only)
X+
X+  ---------------------------------------------------------------------------*/
X+
X+
X+#define __FILEIO_C      /* identifies this source module */
X+#define UNZIP_INTERNAL
X+#include "unzip.h"
X+#ifdef WINDLL
X+#  ifdef POCKET_UNZIP
X+#    include "wince/intrface.h"
X+#  else
X+#    include "windll/windll.h"
X+#  endif
X+#  include <setjmp.h>
X+#endif
X+#include "crypt.h"
X+#include "ttyio.h"
X+
X+/* setup of codepage conversion for decryption passwords */
X+#if CRYPT
X+#  if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY))
X+#    define IZ_ISO2OEM_ARRAY            /* pull in iso2oem[] table */
X+#  endif
X+#  if (defined(CRYP_USES_OEM2ISO) && !defined(IZ_OEM2ISO_ARRAY))
X+#    define IZ_OEM2ISO_ARRAY            /* pull in oem2iso[] table */
X+#  endif
X+#endif
X+#include "ebcdic.h"   /* definition/initialization of ebcdic[] */
X+
X+
X+/*
X+   Note: Under Windows, the maximum size of the buffer that can be used
X+   with any of the *printf calls is 16,384, so win_fprintf was used to
X+   feed the fprintf clone no more than 16K chunks at a time. This should
X+   be valid for anything up to 64K (and probably beyond, assuming your
X+   buffers are that big).
X+*/
X+#ifdef WINDLL
X+#  define WriteError(buf,len,strm) \
X+   (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len))
X+#else /* !WINDLL */
X+#  ifdef USE_FWRITE
X+#    define WriteError(buf,len,strm) \
X+     ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
X+#  else
X+#    define WriteError(buf,len,strm) \
X+     ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
X+#  endif
X+#endif /* ?WINDLL */
X+
X+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
X+static int partflush OF((__GPRO__ uch *rawbuf, ulg size, int unshrink));
X+#endif
X+#ifdef VMS_TEXT_CONV
X+static int is_vms_varlen_txt OF((__GPRO__ uch *ef_buf, unsigned ef_len));
X+#endif
X+static int disk_error OF((__GPRO));
X+
X+
X+/****************************/
X+/* Strings used in fileio.c */
X+/****************************/
X+
X+static ZCONST char Far CannotOpenZipfile[] =
X+  "error:  cannot open zipfile [ %s ]\n        %s\n";
X+
X+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
X+#if (!defined(TANDEM))
X+#if (defined(ATH_BEO_THS_UNX) || defined(DOS_FLX_NLM_OS2_W32))
X+   static ZCONST char Far CannotDeleteOldFile[] =
X+     "error:  cannot delete old %s\n";
X+#ifdef UNIXBACKUP
X+   static ZCONST char Far CannotRenameOldFile[] =
X+     "error:  cannot rename old %s\n";
X+   static ZCONST char Far BackupSuffix[] = "~";
X+#endif
X+#endif /* ATH_BEO_THS_UNX || DOS_FLX_NLM_OS2_W32 */
X+#ifdef NOVELL_BUG_FAILSAFE
X+   static ZCONST char Far NovellBug[] =
X+     "error:  %s: stat() says does not exist, but fopen() found anyway\n";
X+#endif
X+   static ZCONST char Far CannotCreateFile[] = "error:  cannot create %s\n";
X+#endif /* !TANDEM */
X+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
X+
X+static ZCONST char Far ReadError[] = "error:  zipfile read error\n";
X+static ZCONST char Far FilenameTooLongTrunc[] =
X+  "warning:  filename too long--truncating.\n";
X+static ZCONST char Far ExtraFieldTooLong[] =
X+  "warning:  extra field too long (%d).  Ignoring...\n";
X+
X+#ifdef WINDLL
X+   static ZCONST char Far DiskFullQuery[] =
X+     "%s:  write error (disk full?).\n";
X+#else
X+   static ZCONST char Far DiskFullQuery[] =
X+     "%s:  write error (disk full?).  Continue? (y/n/^C) ";
X+   static ZCONST char Far ZipfileCorrupt[] =
X+     "error:  zipfile probably corrupt (%s)\n";
X+#  ifdef SYMLINKS
X+     static ZCONST char Far FileIsSymLink[] =
X+       "%s exists and is a symbolic link%s.\n";
X+#  endif
X+#  ifdef MORE
X+     static ZCONST char Far MorePrompt[] = "--More--(%lu)";
X+#  endif
X+   static ZCONST char Far QuitPrompt[] =
X+     "--- Press `Q' to quit, or any other key to continue ---";
X+   static ZCONST char Far HidePrompt[] = /* "\r                       \r"; */
X+     "\r                                                         \r";
X+#  if CRYPT
X+#    ifdef MACOS
X+       /* SPC: are names on MacOS REALLY so much longer than elsewhere ??? */
X+       static ZCONST char Far PasswPrompt[] = "[%s]\n %s password: ";
X+#    else
X+       static ZCONST char Far PasswPrompt[] = "[%s] %s password: ";
X+#    endif
X+     static ZCONST char Far PasswPrompt2[] = "Enter password: ";
X+     static ZCONST char Far PasswRetry[] = "password incorrect--reenter: ";
X+#  endif /* CRYPT */
X+#endif /* !WINDLL */
X+
X+
X+
X+
X+
X+/******************************/
X+/* Function open_input_file() */
X+/******************************/
X+
X+int open_input_file(__G)    /* return 1 if open failed */
X+    __GDEF
X+{
X+    /*
X+     *  open the zipfile for reading and in BINARY mode to prevent cr/lf
X+     *  translation, which would corrupt the bitstreams
X+     */
X+
X+#ifdef VMS
X+    G.zipfd = open(G.zipfn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
X+#else /* !VMS */
X+#ifdef MACOS
X+    G.zipfd = open(G.zipfn, 0);
X+#else /* !MACOS */
X+#ifdef CMS_MVS
X+    G.zipfd = vmmvs_open_infile(__G);
X+#else /* !CMS_MVS */
X+#ifdef USE_STRM_INPUT
X+    G.zipfd = fopen(G.zipfn, FOPR);
X+#else /* !USE_STRM_INPUT */
X+# ifdef O_BINARY
X+    G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);
X+# else
X+    G.zipfd = open(G.zipfn, O_RDONLY);
X+# endif
X+#endif /* ?USE_STRM_INPUT */
X+#endif /* ?CMS_MVS */
X+#endif /* ?MACOS */
X+#endif /* ?VMS */
X+
X+#ifdef USE_STRM_INPUT
X+    if (G.zipfd == NULL)
X+#else
X+    /* if (G.zipfd < 0) */  /* no good for Windows CE port */
X+    if (G.zipfd == -1)
X+#endif
X+    {
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile),
X+          G.zipfn, strerror(errno)));
X+        return 1;
X+    }
X+    return 0;
X+
X+} /* end function open_input_file() */
X+
X+
X+
X+
X+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
X+#if (!defined(TANDEM))
X+
X+/***************************/
X+/* Function open_outfile() */
X+/***************************/
X+
X+int open_outfile(__G)         /* return 1 if fail */
X+    __GDEF
X+{
X+#ifdef DLL
X+    if (G.redirect_data)
X+        return (redirect_outfile(__G) == FALSE);
X+#endif
X+#ifdef QDOS
X+    QFilename(__G__ G.filename);
X+#endif
X+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_THS_UNX))
X+#ifdef BORLAND_STAT_BUG
X+    /* Borland 5.0's stat() barfs if the filename has no extension and the
X+     * file doesn't exist. */
X+    if (access(G.filename, 0) == -1) {
X+        FILE *tmp = fopen(G.filename, "wb+");
X+
X+        /* file doesn't exist, so create a dummy file to keep stat() from
X+         * failing (will be over-written anyway) */
X+        fputc('0', tmp);  /* just to have something in the file */
X+        fclose(tmp);
X+    }
X+#endif /* BORLAND_STAT_BUG */
X+#ifdef SYMLINKS
X+    if (SSTAT(G.filename, &G.statbuf) == 0 || lstat(G.filename,&G.statbuf) == 0)
X+#else
X+    if (SSTAT(G.filename, &G.statbuf) == 0)
X+#endif /* ?SYMLINKS */
X+    {
X+        Trace((stderr, "open_outfile:  stat(%s) returns 0:  file exists\n",
X+          FnFilter1(G.filename)));
X+#ifdef UNIXBACKUP
X+        if (uO.B_flag) {    /* do backup */
X+            char *tname;
X+            struct stat tmpstat;
X+            int blen, flen, tlen;
X+
X+            blen = strlen(BackupSuffix);
X+            flen = strlen(G.filename);
X+            tlen = flen + blen + 6;    /* includes space for 5 digits */
X+            if (tlen >= FILNAMSIZ) {   /* in case name is too long, truncate */
X+                tname = (char *)malloc(FILNAMSIZ);
X+                if (tname == NULL)
X+                    return 1;                 /* in case we run out of space */
X+                tlen = FILNAMSIZ - 1 - blen;
X+                strcpy(tname, G.filename);    /* make backup name */
X+                tname[tlen] = '\0';
X+                if (flen > tlen) flen = tlen;
X+                tlen = FILNAMSIZ;
X+            } else {
X+                tname = (char *)malloc(tlen);
X+                if (tname == NULL)
X+                    return 1;                 /* in case we run out of space */
X+                strcpy(tname, G.filename);    /* make backup name */
X+            }
X+            strcpy(tname+flen, BackupSuffix);
X+
X+            if (IS_OVERWRT_ALL) {
X+                /* If there is a previous backup file, delete it,
X+                 * otherwise the following rename operation may fail.
X+                 */
X+                if (SSTAT(tname, &tmpstat) == 0)
X+                    unlink(tname);
X+            } else {
X+                /* Check if backupname exists, and, if it's true, try
X+                 * appending numbers of up to 5 digits to the BackupSuffix,
X+                 * until an unused name is found.
X+                 */
X+                unsigned maxtail, i;
X+                char *numtail = tname + flen + blen;
X+
X+                maxtail = 65535;
X+                switch (tlen - flen - blen - 1) {
X+                    case 4: maxtail = 9999; break;
X+                    case 3: maxtail = 999; break;
X+                    case 2: maxtail = 99; break;
X+                    case 1: maxtail = 9; break;
X+                    case 0: maxtail = 0; break;
X+                }
X+                /* while filename exists */
X+                for (i = 0; (i <= maxtail) && (SSTAT(tname, &tmpstat) == 0);)
X+                    sprintf(numtail,"%u", ++i);
X+            }
X+
X+            if (rename(G.filename, tname) != 0) {   /* move file */
X+                Info(slide, 0x401, ((char *)slide,
X+                  LoadFarString(CannotRenameOldFile), FnFilter1(G.filename)));
X+                free(tname);
X+                return 1;
X+            }
X+            Trace((stderr, "open_outfile:  %s now renamed into %s\n",
X+              FnFilter1(G.filename), FnFilter2(tname)));
X+            free(tname);
X+        } else
X+#endif /* UNIXBACKUP */
X+        {
X+#ifdef DOS_FLX_OS2_W32
X+            if (!(G.statbuf.st_mode & S_IWRITE)) {
X+                Trace((stderr,
X+                  "open_outfile:  existing file %s is read-only\n",
X+                  FnFilter1(G.filename)));
X+                chmod(G.filename, S_IREAD | S_IWRITE);
X+                Trace((stderr, "open_outfile:  %s now writable\n",
X+                  FnFilter1(G.filename)));
X+            }
X+#endif /* DOS_FLX_OS2_W32 */
X+#ifdef NLM
X+            /* Give the file read/write permission (non-POSIX shortcut) */
X+            chmod(G.filename, 0);
X+#endif /* NLM */
X+            if (unlink(G.filename) != 0) {
X+                Info(slide, 0x401, ((char *)slide,
X+                  LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename)));
X+                return 1;
X+            }
X+            Trace((stderr, "open_outfile:  %s now deleted\n",
X+              FnFilter1(G.filename)));
X+        }
X+    }
X+#endif /* DOS_FLX_NLM_OS2_W32 || ATH_BEO_THS_UNX */
X+#ifdef RISCOS
X+    if (SWI_OS_File_7(G.filename,0xDEADDEAD,0xDEADDEAD,G.lrec.ucsize)!=NULL) {
X+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
X+          FnFilter1(G.filename)));
X+        return 1;
X+    }
X+#endif /* RISCOS */
X+#ifdef TOPS20
X+    char *tfilnam;
X+
X+    if ((tfilnam = (char *)malloc(2*strlen(G.filename)+1)) == (char *)NULL)
X+        return 1;
X+    strcpy(tfilnam, G.filename);
X+    upper(tfilnam);
X+    enquote(tfilnam);
X+    if ((G.outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
X+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
X+          tfilnam));
X+        free(tfilnam);
X+        return 1;
X+    }
X+    free(tfilnam);
X+#else /* !TOPS20 */
X+#ifdef MTS
X+    if (uO.aflag)
X+        G.outfile = fopen(G.filename, FOPWT);
X+    else
X+        G.outfile = fopen(G.filename, FOPW);
X+    if (G.outfile == (FILE *)NULL) {
X+        Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
X+          FnFilter1(G.filename)));
X+        return 1;
X+    }
X+#else /* !MTS */
X+#ifdef DEBUG
X+    Info(slide, 1, ((char *)slide,
X+      "open_outfile:  doing fopen(%s) for reading\n", FnFilter1(G.filename)));
X+    if ((G.outfile = fopen(G.filename, FOPR)) == (FILE *)NULL)
X+        Info(slide, 1, ((char *)slide,
X+          "open_outfile:  fopen(%s) for reading failed:  does not exist\n",
X+          FnFilter1(G.filename)));
X+    else {
X+        Info(slide, 1, ((char *)slide,
X+          "open_outfile:  fopen(%s) for reading succeeded:  file exists\n",
X+          FnFilter1(G.filename)));
X+        fclose(G.outfile);
X+    }
X+#endif /* DEBUG */
X+#ifdef NOVELL_BUG_FAILSAFE
X+    if (G.dne && ((G.outfile = fopen(G.filename, FOPR)) != (FILE *)NULL)) {
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(NovellBug),
X+          FnFilter1(G.filename)));
X+        fclose(G.outfile);
X+        return 1;   /* with "./" fix in checkdir(), should never reach here */
X+    }
X+#endif /* NOVELL_BUG_FAILSAFE */
X+    Trace((stderr, "open_outfile:  doing fopen(%s) for writing\n",
X+      FnFilter1(G.filename)));
X+    if ((G.outfile = fopen(G.filename, FOPW)) == (FILE *)NULL) {
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
X+          FnFilter1(G.filename)));
X+        return 1;
X+    }
X+    Trace((stderr, "open_outfile:  fopen(%s) for writing succeeded\n",
X+      FnFilter1(G.filename)));
X+#endif /* !MTS */
X+#endif /* !TOPS20 */
X+
X+#ifdef USE_FWRITE
X+#ifdef DOS_NLM_OS2_W32
X+    /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE):  bogus */
X+    setbuf(G.outfile, (char *)NULL);   /* make output unbuffered */
X+#else /* !DOS_NLM_OS2_W32 */
X+#ifndef RISCOS
X+#ifdef _IOFBF  /* make output fully buffered (works just about like write()) */
X+    setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);
X+#else
X+    setbuf(G.outfile, (char *)slide);
X+#endif
X+#endif /* !RISCOS */
X+#endif /* ?DOS_NLM_OS2_W32 */
X+#endif /* USE_FWRITE */
X+#ifdef OS2_W32
X+    /* preallocate the final file size to prevent file fragmentation */
X+    SetFileSize(G.outfile, G.lrec.ucsize);
X+#endif
X+    return 0;
X+
X+} /* end function open_outfile() */
X+
X+#endif /* !TANDEM */
X+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
X+
X+
X+
X+
X+
X+/*
X+ * These functions allow NEXTBYTE to function without needing two bounds
X+ * checks.  Call defer_leftover_input() if you ever have filled G.inbuf
X+ * by some means other than readbyte(), and you then want to start using
X+ * NEXTBYTE.  When going back to processing bytes without NEXTBYTE, call
X+ * undefer_input().  For example, extract_or_test_member brackets its
X+ * central section that does the decompression with these two functions.
X+ * If you need to check the number of bytes remaining in the current
X+ * file while using NEXTBYTE, check (G.csize + G.incnt), not G.csize.
X+ */
X+
X+/****************************/
X+/* function undefer_input() */
X+/****************************/
X+
X+void undefer_input(__G)
X+    __GDEF
X+{
X+    if (G.incnt > 0)
X+        G.csize += G.incnt;
X+    if (G.incnt_leftover > 0) {
X+        /* We know that "(G.csize < MAXINT)" so we can cast G.csize to int:
X+         * This condition was checked when G.incnt_leftover was set > 0 in
X+         * defer_leftover_input(), and it is NOT allowed to touch G.csize
X+         * before calling undefer_input() when (G.incnt_leftover > 0)
X+         * (single exception: see read_byte()'s  "G.csize <= 0" handling) !!
X+         */
X+        G.incnt = G.incnt_leftover + (int)G.csize;
X+        G.inptr = G.inptr_leftover - (int)G.csize;
X+        G.incnt_leftover = 0;
X+    } else if (G.incnt < 0)
X+        G.incnt = 0;
X+} /* end function undefer_input() */
X+
X+
X+
X+
X+
X+/***********************************/
X+/* function defer_leftover_input() */
X+/***********************************/
X+
X+void defer_leftover_input(__G)
X+    __GDEF
X+{
X+    if ((long)G.incnt > G.csize) {
X+        /* (G.csize < MAXINT), we can safely cast it to int !! */
X+        if (G.csize < 0L)
X+            G.csize = 0L;
X+        G.inptr_leftover = G.inptr + (int)G.csize;
X+        G.incnt_leftover = G.incnt - (int)G.csize;
X+        G.incnt = (int)G.csize;
X+    } else
X+        G.incnt_leftover = 0;
X+    G.csize -= G.incnt;
X+} /* end function defer_leftover_input() */
X+
X+
X+
X+
X+
X+/**********************/
X+/* Function readbuf() */
X+/**********************/
X+
X+unsigned readbuf(__G__ buf, size)   /* return number of bytes read into buf */
X+    __GDEF
X+    char *buf;
X+    register unsigned size;
X+{
X+    register unsigned count;
X+    unsigned n;
X+
X+    n = size;
X+    while (size) {
X+        if (G.incnt <= 0) {
X+            if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
X+                return (n-size);
X+            else if (G.incnt < 0) {
X+                /* another hack, but no real harm copying same thing twice */
X+                (*G.message)((zvoid *)&G,
X+                  (uch *)LoadFarString(ReadError),  /* CANNOT use slide */
X+                  (ulg)strlen(LoadFarString(ReadError)), 0x401);
X+                return 0;  /* discarding some data; better than lock-up */
X+            }
X+            /* buffer ALWAYS starts on a block boundary:  */
X+            G.cur_zipfile_bufstart += INBUFSIZ;
X+            G.inptr = G.inbuf;
X+        }
X+        count = MIN(size, (unsigned)G.incnt);
X+        memcpy(buf, G.inptr, count);
X+        buf += count;
X+        G.inptr += count;
X+        G.incnt -= count;
X+        size -= count;
X+    }
X+    return n;
X+
X+} /* end function readbuf() */
X+
X+
X+
X+
X+
X+/***********************/
X+/* Function readbyte() */
X+/***********************/
X+
X+int readbyte(__G)   /* refill inbuf and return a byte if available, else EOF */
X+    __GDEF
X+{
X+    if (G.mem_mode)
X+        return EOF;
X+    if (G.csize <= 0) {
X+        G.csize--;             /* for tests done after exploding */
X+        G.incnt = 0;
X+        return EOF;
X+    }
X+    if (G.incnt <= 0) {
X+        if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) {
X+            G.incnt = 0;       /* do not allow negative value to affect stuff */
X+            return EOF;
X+        } else if (G.incnt < 0) {  /* "fail" (abort, retry, ...) returns this */
X+            /* another hack, but no real harm copying same thing twice */
X+            (*G.message)((zvoid *)&G,
X+              (uch *)LoadFarString(ReadError),
X+              (ulg)strlen(LoadFarString(ReadError)), 0x401);
X+            echon();
X+#ifdef WINDLL
X+            longjmp(dll_error_return, 1);
X+#else
X+            DESTROYGLOBALS();
X+            EXIT(PK_BADERR);    /* totally bailing; better than lock-up */
X+#endif
X+        }
X+        G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on block bndry */
X+        G.inptr = G.inbuf;
X+        defer_leftover_input(__G);           /* decrements G.csize */
X+    }
X+
X+#if CRYPT
X+    if (G.pInfo->encrypted) {
X+        uch *p;
X+        int n;
X+
X+        /* This was previously set to decrypt one byte beyond G.csize, when
X+         * incnt reached that far.  GRR said, "but it's required:  why?"  This
X+         * was a bug in fillinbuf() -- was it also a bug here?
X+         */
X+        for (n = G.incnt, p = G.inptr;  n--;  p++)
X+            zdecode(*p);
X+    }
X+#endif /* CRYPT */
X+
X+    --G.incnt;
X+    return *G.inptr++;
X+
X+} /* end function readbyte() */
X+
X+
X+
X+
X+
X+#ifdef USE_ZLIB
X+
X+/************************/
X+/* Function fillinbuf() */
X+/************************/
X+
X+int fillinbuf(__G) /* like readbyte() except returns number of bytes in inbuf */
X+    __GDEF
X+{
X+    if (G.mem_mode ||
X+                  (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
X+        return 0;
X+    G.cur_zipfile_bufstart += INBUFSIZ;  /* always starts on a block boundary */
X+    G.inptr = G.inbuf;
X+    defer_leftover_input(__G);           /* decrements G.csize */
X+
X+#if CRYPT
X+    if (G.pInfo->encrypted) {
X+        uch *p;
X+        int n;
X+
X+        for (n = G.incnt, p = G.inptr;  n--;  p++)
X+            zdecode(*p);
X+    }
X+#endif /* CRYPT */
X+
X+    return G.incnt;
X+
X+} /* end function fillinbuf() */
X+
X+#endif /* USE_ZLIB */
X+
X+
X+
X+
X+
X+/************************/
X+/* Function seek_zipf() */
X+/************************/
X+
X+int seek_zipf(__G__ abs_offset)
X+    __GDEF
X+    Z_OFF_T abs_offset;
X+{
X+/*
X+ *  Seek to the block boundary of the block which includes abs_offset,
X+ *  then read block into input buffer and set pointers appropriately.
X+ *  If block is already in the buffer, just set the pointers.  This function
X+ *  is used by do_seekable (process.c), extract_or_test_entrylist (extract.c)
X+ *  and do_string (fileio.c).  Also, a slightly modified version is embedded
X+ *  within extract_or_test_entrylist (extract.c).  readbyte() and readbuf()
X+ *  (fileio.c) are compatible.  NOTE THAT abs_offset is intended to be the
X+ *  "proper offset" (i.e., if there were no extra bytes prepended);
X+ *  cur_zipfile_bufstart contains the corrected offset.
X+ *
X+ *  Since seek_zipf() is never used during decompression, it is safe to
X+ *  use the slide[] buffer for the error message.
X+ *
X+ * returns PK error codes:
X+ *  PK_BADERR if effective offset in zipfile is negative
X+ *  PK_EOF if seeking past end of zipfile
X+ *  PK_OK when seek was successful
X+ */
X+    Z_OFF_T request = abs_offset + G.extra_bytes;
X+    Z_OFF_T inbuf_offset = request % INBUFSIZ;
X+    Z_OFF_T bufstart = request - inbuf_offset;
X+
X+    if (request < 0) {
X+        Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
X+             G.zipfn, LoadFarString(ReportMsg)));
X+        return(PK_BADERR);
X+    } else if (bufstart != G.cur_zipfile_bufstart) {
X+        Trace((stderr,
X+          "fpos_zip: abs_offset = %ld, G.extra_bytes = %ld\n",
X+          abs_offset, G.extra_bytes));
X+#ifdef USE_STRM_INPUT
X+        fseek(G.zipfd, bufstart, SEEK_SET);
X+        G.cur_zipfile_bufstart = ftell(G.zipfd);
X+#else /* !USE_STRM_INPUT */
X+        G.cur_zipfile_bufstart = lseek(G.zipfd, bufstart, SEEK_SET);
X+#endif /* ?USE_STRM_INPUT */
X+        Trace((stderr,
X+          "       request = %ld, (abs+extra) = %ld, inbuf_offset = %ld\n",
X+          request, (abs_offset+G.extra_bytes), inbuf_offset));
X+        Trace((stderr, "       bufstart = %ld, cur_zipfile_bufstart = %ld\n",
X+          bufstart, G.cur_zipfile_bufstart));
X+        if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
X+            return(PK_EOF);
X+        G.incnt -= (int)inbuf_offset;
X+        G.inptr = G.inbuf + (int)inbuf_offset;
X+    } else {
X+        G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset;
X+        G.inptr = G.inbuf + (int)inbuf_offset;
X+    }
X+    return(PK_OK);
X+} /* end function seek_zipf() */
X+
X+
X+
X+
X+
X+#ifndef VMS  /* for VMS use code in vms.c */
X+
X+/********************/
X+/* Function flush() */   /* returns PK error codes: */
X+/********************/   /* if cflag => always 0; PK_DISK if write error */
X+
X+int flush(__G__ rawbuf, size, unshrink)
X+    __GDEF
X+    uch *rawbuf;
X+    ulg size;
X+    int unshrink;
X+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
X+{
X+    int ret;
X+
X+    /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions
X+     * cannot handle writes of 64k blocks at once.  For these systems, the
X+     * blocks to flush are split into pieces of 32k or less.
X+     */
X+    while (size > 0x8000L) {
X+        ret = partflush(__G__ rawbuf, 0x8000L, unshrink);
X+        if (ret != PK_OK)
X+            return ret;
X+        size -= 0x8000L;
X+        rawbuf += (extent)0x8000;
X+    }
X+    return partflush(__G__ rawbuf, size, unshrink);
X+} /* end function flush() */
X+
X+
X+/************************/
X+/* Function partflush() */  /* returns PK error codes: */
X+/************************/  /* if cflag => always 0; PK_DISK if write error */
X+
X+static int partflush(__G__ rawbuf, size, unshrink)
X+    __GDEF
X+    uch *rawbuf;        /* cannot be ZCONST, gets passed to (*G.message)() */
X+    ulg size;
X+    int unshrink;
X+#endif /* USE_DEFLATE64 && __16BIT__ */
X+{
X+    register uch *p;
X+    register uch *q;
X+    uch *transbuf;
X+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
X+    ulg transbufsiz;
X+#endif
X+    /* static int didCRlast = FALSE;    moved to globals.h */
X+
X+
X+/*---------------------------------------------------------------------------
X+    Compute the CRC first; if testing or if disk is full, that's it.
X+  ---------------------------------------------------------------------------*/
X+
X+    G.crc32val = crc32(G.crc32val, rawbuf, (extent)size);
X+
X+#ifdef DLL
X+    if ((G.statreportcb != NULL) &&
X+        (*G.statreportcb)(__G__ UZ_ST_IN_PROGRESS, G.zipfn, G.filename, NULL))
X+        return IZ_CTRLC;        /* cancel operation by user request */
X+#endif
X+
X+    if (uO.tflag || size == 0L)  /* testing or nothing to write:  all done */
X+        return PK_OK;
X+
X+    if (G.disk_full)
X+        return PK_DISK;         /* disk already full:  ignore rest of file */
X+
X+/*---------------------------------------------------------------------------
X+    Write the bytes rawbuf[0..size-1] to the output device, first converting
X+    end-of-lines and ASCII/EBCDIC as needed.  If SMALL_MEM or MED_MEM are NOT
X+    defined, outbuf is assumed to be at least as large as rawbuf and is not
X+    necessarily checked for overflow.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (!G.pInfo->textmode) {   /* write raw binary data */
X+        /* GRR:  note that for standard MS-DOS compilers, size argument to
X+         * fwrite() can never be more than 65534, so WriteError macro will
X+         * have to be rewritten if size can ever be that large.  For now,
X+         * never more than 32K.  Also note that write() returns an int, which
X+         * doesn't necessarily limit size to 32767 bytes if write() is used
X+         * on 16-bit systems but does make it more of a pain; however, because
X+         * at least MSC 5.1 has a lousy implementation of fwrite() (as does
X+         * DEC Ultrix cc), write() is used anyway.
X+         */
X+#ifdef DLL
X+        if (G.redirect_data) {
X+#ifdef NO_SLIDE_REDIR
X+            if (writeToMemory(__G__ rawbuf, (extent)size)) return PK_ERR;
X+#else
X+            writeToMemory(__G__ rawbuf, (extent)size);
X+#endif
X+        } else
X+#endif
X+        if (!uO.cflag && WriteError(rawbuf, size, G.outfile))
X+            return disk_error(__G);
X+        else if (uO.cflag && (*G.message)((zvoid *)&G, rawbuf, size, 0))
X+            return PK_OK;
X+    } else {   /* textmode:  aflag is true */
X+        if (unshrink) {
X+            /* rawbuf = outbuf */
X+            transbuf = G.outbuf2;
X+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
X+            transbufsiz = TRANSBUFSIZ;
X+#endif
X+        } else {
X+            /* rawbuf = slide */
X+            transbuf = G.outbuf;
X+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
X+            transbufsiz = OUTBUFSIZ;
X+            Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n",
X+                   (unsigned)OUTBUFSIZ));
X+#endif
X+        }
X+        if (G.newfile) {
X+#ifdef VMS_TEXT_CONV
X+            if (G.pInfo->hostnum == VMS_ && G.extra_field &&
X+                is_vms_varlen_txt(__G__ G.extra_field,
X+                                  G.lrec.extra_field_length))
X+                G.VMS_line_state = 0;    /* 0: ready to read line length */
X+            else
X+                G.VMS_line_state = -1;   /* -1: don't treat as VMS text */
X+#endif
X+            G.didCRlast = FALSE;         /* no previous buffers written */
X+            G.newfile = FALSE;
X+        }
X+
X+#ifdef VMS_TEXT_CONV
X+        if (G.VMS_line_state >= 0)
X+        {
X+            p = rawbuf;
X+            q = transbuf;
X+            while ((extent)(p-rawbuf) < (extent)size) {
X+                switch (G.VMS_line_state) {
X+
X+                    /* 0: ready to read line length */
X+                    case 0:
X+                        G.VMS_line_length = 0;
X+                        if ((extent)(p-rawbuf) == (extent)size-1) {
X+                            /* last char */
X+                            G.VMS_line_length = (unsigned)(*p++);
X+                            G.VMS_line_state = 1;
X+                        } else {
X+                            G.VMS_line_length = makeword(p);
X+                            p += 2;
X+                            G.VMS_line_state = 2;
X+                        }
X+                        G.VMS_line_pad =
X+                               ((G.VMS_line_length & 1) != 0); /* odd */
X+                        break;
X+
X+                    /* 1: read one byte of length, need second */
X+                    case 1:
X+                        G.VMS_line_length += ((unsigned)(*p++) << 8);
X+                        G.VMS_line_state = 2;
X+                        break;
X+
X+                    /* 2: ready to read VMS_line_length chars */
X+                    case 2:
X+                        {
X+                            extent remaining = (extent)size+(rawbuf-p);
X+                            extent outroom;
X+
X+                            if (G.VMS_line_length < remaining) {
X+                                remaining = G.VMS_line_length;
X+                                G.VMS_line_state = 3;
X+                            }
X+
X+                            outroom = transbuf+(extent)transbufsiz-q;
X+                            if (remaining >= outroom) {
X+                                remaining -= outroom;
X+                                for (;outroom > 0; p++, outroom--)
X+                                    *q++ = native(*p);
X+#ifdef DLL
X+                                if (G.redirect_data) {
X+                                    if (writeToMemory(__G__ transbuf,
X+                                          (extent)(q-transbuf))) return PK_ERR;
X+                                } else
X+#endif
X+                                if (!uO.cflag && WriteError(transbuf,
X+                                    (extent)(q-transbuf), G.outfile))
X+                                    return disk_error(__G);
X+                                else if (uO.cflag && (*G.message)((zvoid *)&G,
X+                                         transbuf, (ulg)(q-transbuf), 0))
X+                                    return PK_OK;
X+                                q = transbuf;
X+                                /* fall through to normal case */
X+                            }
X+                            G.VMS_line_length -= remaining;
X+                            for (;remaining > 0; p++, remaining--)
X+                                *q++ = native(*p);
X+                        }
X+                        break;
X+
X+                    /* 3: ready to PutNativeEOL */
X+                    case 3:
X+                        if (q > transbuf+(extent)transbufsiz-lenEOL) {
X+#ifdef DLL
X+                            if (G.redirect_data) {
X+                                if (writeToMemory(__G__ transbuf,
X+                                      (extent)(q-transbuf))) return PK_ERR;
X+                            } else
X+#endif
X+                            if (!uO.cflag &&
X+                                WriteError(transbuf, (extent)(q-transbuf),
X+                                  G.outfile))
X+                                return disk_error(__G);
X+                            else if (uO.cflag && (*G.message)((zvoid *)&G,
X+                                     transbuf, (ulg)(q-transbuf), 0))
X+                                return PK_OK;
X+                            q = transbuf;
X+                        }
X+                        PutNativeEOL
X+                        G.VMS_line_state = G.VMS_line_pad ? 4 : 0;
X+                        break;
X+
X+                    /* 4: ready to read pad byte */
X+                    case 4:
X+                        ++p;
X+                        G.VMS_line_state = 0;
X+                        break;
X+                }
X+            } /* end while */
X+
X+        } else
X+#endif /* VMS_TEXT_CONV */
X+
X+    /*-----------------------------------------------------------------------
X+        Algorithm:  CR/LF => native; lone CR => native; lone LF => native.
X+        This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
X+        stream-oriented files, not record-oriented).
X+      -----------------------------------------------------------------------*/
X+
X+        /* else not VMS text */ {
X+            p = rawbuf;
X+            if (*p == LF && G.didCRlast)
X+                ++p;
X+            G.didCRlast = FALSE;
X+            for (q = transbuf;  (extent)(p-rawbuf) < (extent)size;  ++p) {
X+                if (*p == CR) {           /* lone CR or CR/LF: treat as EOL  */
X+                    PutNativeEOL
X+                    if ((extent)(p-rawbuf) == (extent)size-1)
X+                        /* last char in buffer */
X+                        G.didCRlast = TRUE;
X+                    else if (p[1] == LF)  /* get rid of accompanying LF */
X+                        ++p;
X+                } else if (*p == LF)      /* lone LF */
X+                    PutNativeEOL
X+                else
X+#ifndef DOS_FLX_OS2_W32
X+                if (*p != CTRLZ)          /* lose all ^Z's */
X+#endif
X+                    *q++ = native(*p);
X+
X+#if (defined(SMALL_MEM) || defined(MED_MEM))
X+# if (lenEOL == 1)   /* don't check unshrink:  both buffers small but equal */
X+                if (!unshrink)
X+# endif
X+                    /* check for danger of buffer overflow and flush */
X+                    if (q > transbuf+(extent)transbufsiz-lenEOL) {
X+                        Trace((stderr,
X+                          "p - rawbuf = %u   q-transbuf = %u   size = %lu\n",
X+                          (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
X+                        if (!uO.cflag && WriteError(transbuf,
X+                            (extent)(q-transbuf), G.outfile))
X+                            return disk_error(__G);
X+                        else if (uO.cflag && (*G.message)((zvoid *)&G,
X+                                 transbuf, (ulg)(q-transbuf), 0))
X+                            return PK_OK;
X+                        q = transbuf;
X+                        continue;
X+                    }
X+#endif /* SMALL_MEM || MED_MEM */
X+            }
X+        }
X+
X+    /*-----------------------------------------------------------------------
X+        Done translating:  write whatever we've got to file (or screen).
X+      -----------------------------------------------------------------------*/
X+
X+        Trace((stderr, "p - rawbuf = %u   q-transbuf = %u   size = %lu\n",
X+          (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
X+        if (q > transbuf) {
X+#ifdef DLL
X+            if (G.redirect_data) {
X+                if (writeToMemory(__G__ transbuf, (extent)(q-transbuf)))
X+                    return PK_ERR;
X+            } else
X+#endif
X+            if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf),
X+                G.outfile))
X+                return disk_error(__G);
X+            else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf,
X+                (ulg)(q-transbuf), 0))
X+                return PK_OK;
X+        }
X+    }
X+
X+    return PK_OK;
X+
X+} /* end function flush() [resp. partflush() for 16-bit Deflate64 support] */
X+
X+
X+
X+
X+
X+#ifdef VMS_TEXT_CONV
X+
X+/********************************/
X+/* Function is_vms_varlen_txt() */
X+/********************************/
X+
X+static int is_vms_varlen_txt(__G__ ef_buf, ef_len)
X+    __GDEF
X+    uch *ef_buf;        /* buffer containing extra field */
X+    unsigned ef_len;    /* total length of extra field */
X+{
X+    unsigned eb_id;
X+    unsigned eb_len;
X+    uch *eb_data;
X+    unsigned eb_datlen;
X+#define VMSREC_C_UNDEF  0
X+#define VMSREC_C_VAR    2
X+    uch vms_rectype = VMSREC_C_UNDEF;
X+    uch vms_fileorg = 0;
X+
X+#define VMSPK_ITEMID            0
X+#define VMSPK_ITEMLEN           2
X+#define VMSPK_ITEMHEADSZ        4
X+
X+#define VMSATR_C_RECATTR        4
X+#define VMS_FABSIG              0x42414656      /* "VFAB" */
X+/* offsets of interesting fields in VMS fabdef structure */
X+#define VMSFAB_B_RFM            31      /* record format byte */
X+#define VMSFAB_B_ORG            29      /* file organization byte */
X+
X+    if (ef_len == 0 || ef_buf == NULL)
X+        return FALSE;
X+
X+    while (ef_len >= EB_HEADSIZE) {
X+        eb_id = makeword(EB_ID + ef_buf);
X+        eb_len = makeword(EB_LEN + ef_buf);
X+
X+        if (eb_len > (ef_len - EB_HEADSIZE)) {
X+            /* discovered some extra field inconsistency! */
X+            Trace((stderr,
X+              "is_vms_varlen_txt: block length %u > rest ef_size %u\n", eb_len,
X+              ef_len - EB_HEADSIZE));
X+            break;
X+        }
X+
X+        switch (eb_id) {
X+          case EF_PKVMS:
X+            /* The PKVMS e.f. raw data part consists of:
X+             * a) 4 bytes CRC checksum
X+             * b) list of uncompressed variable-length data items
X+             * Each data item is introduced by a fixed header
X+             *  - 2 bytes data type ID
X+             *  - 2 bytes <size> of data
X+             *  - <size> bytes of actual attribute data
X+             */
X+
X+            /* get pointer to start of data and its total length */
X+            eb_data = ef_buf+(EB_HEADSIZE+4);
X+            eb_datlen = eb_len-4;
X+
X+            /* test the CRC checksum */
X+            if (makelong(ef_buf+EB_HEADSIZE) !=
X+                crc32(CRCVAL_INITIAL, eb_data, (extent)eb_datlen))
X+            {
X+                Info(slide, 1, ((char *)slide,
X+                  "[Warning: CRC error, discarding PKWARE extra field]\n"));
X+                /* skip over the data analysis code */
X+                break;
X+            }
X+
X+            /* scan through the attribute data items */
X+            while (eb_datlen > 4)
X+            {
X+                unsigned fldsize = makeword(&eb_data[VMSPK_ITEMLEN]);
X+
X+                /* check the item type word */
X+                switch (makeword(&eb_data[VMSPK_ITEMID])) {
X+                  case VMSATR_C_RECATTR:
X+                    /* we have found the (currently only) interesting
X+                     * data item */
X+                    if (fldsize >= 1) {
X+                        vms_rectype = eb_data[VMSPK_ITEMHEADSZ] & 15;
X+                        vms_fileorg = eb_data[VMSPK_ITEMHEADSZ] >> 4;
X+                    }
X+                    break;
X+                  default:
X+                    break;
X+                }
X+                /* skip to next data item */
X+                eb_datlen -= fldsize + VMSPK_ITEMHEADSZ;
X+                eb_data += fldsize + VMSPK_ITEMHEADSZ;
X+            }
X+            break;
X+
X+          case EF_IZVMS:
X+            if (makelong(ef_buf+EB_HEADSIZE) == VMS_FABSIG) {
X+                if ((eb_data = extract_izvms_block(__G__
X+                                                   ef_buf+EB_HEADSIZE, eb_len,
X+                                                   &eb_datlen, NULL, 0))
X+                    != NULL)
X+                {
X+                    if (eb_datlen >= VMSFAB_B_RFM+1) {
X+                        vms_rectype = eb_data[VMSFAB_B_RFM] & 15;
X+                        vms_fileorg = eb_data[VMSFAB_B_ORG] >> 4;
X+                    }
X+                    free(eb_data);
X+                }
X+            }
X+            break;
X+
X+          default:
X+            break;
X+        }
X+
X+        /* Skip this extra field block */
X+        ef_buf += (eb_len + EB_HEADSIZE);
X+        ef_len -= (eb_len + EB_HEADSIZE);
X+    }
X+
X+    return (vms_rectype == VMSREC_C_VAR);
X+
X+} /* end function is_vms_varlen_txtfile() */
X+
X+#endif /* VMS_TEXT_CONV */
X+
X+
X+
X+
X+/*************************/
X+/* Function disk_error() */
X+/*************************/
X+
X+static int disk_error(__G)
X+    __GDEF
X+{
X+    /* OK to use slide[] here because this file is finished regardless */
X+    Info(slide, 0x4a1, ((char *)slide, LoadFarString(DiskFullQuery),
X+      FnFilter1(G.filename)));
X+
X+#ifndef WINDLL
X+    fgets(G.answerbuf, 9, stdin);
X+    if (*G.answerbuf == 'y')   /* stop writing to this file */
X+        G.disk_full = 1;       /*  (outfile bad?), but new OK */
X+    else
X+#endif
X+        G.disk_full = 2;       /* no:  exit program */
X+
X+    return PK_DISK;
X+
X+} /* end function disk_error() */
X+
X+#endif /* !VMS */
X+
X+
X+
X+
X+
X+/*****************************/
X+/* Function UzpMessagePrnt() */
X+/*****************************/
X+
X+int UZ_EXP UzpMessagePrnt(pG, buf, size, flag)
X+    zvoid *pG;   /* globals struct:  always passed */
X+    uch *buf;    /* preformatted string to be printed */
X+    ulg size;    /* length of string (may include nulls) */
X+    int flag;    /* flag bits */
X+{
X+    /* IMPORTANT NOTE:
X+     *    The name of the first parameter of UzpMessagePrnt(), which passes
X+     *    the "Uz_Globs" address, >>> MUST <<< be identical to the string
X+     *    expansion of the __G__ macro in the REENTRANT case (see globals.h).
X+     *    This name identity is mandatory for the LoadFarString() macro
X+     *    (in the SMALL_MEM case) !!!
X+     */
X+    int error;
X+    uch *q=buf, *endbuf=buf+(unsigned)size;
X+#ifdef MORE
X+    uch *p=buf;
X+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
X+    int islinefeed = FALSE;
X+#endif
X+#endif
X+    FILE *outfp;
X+
X+
X+/*---------------------------------------------------------------------------
X+    These tests are here to allow fine-tuning of UnZip's output messages,
X+    but none of them will do anything without setting the appropriate bit
X+    in the flag argument of every Info() statement which is to be turned
X+    *off*.  That is, all messages are currently turned on for all ports.
X+    To turn off *all* messages, use the UzpMessageNull() function instead
X+    of this one.
X+  ---------------------------------------------------------------------------*/
X+
X+#if (defined(OS2) && defined(DLL))
X+    if (MSG_NO_DLL2(flag))  /* if OS/2 DLL bit is set, do NOT print this msg */
X+        return 0;
X+#endif
X+#ifdef WINDLL
X+    if (MSG_NO_WDLL(flag))
X+        return 0;
X+#endif
X+#ifdef WINDLL
X+    if (MSG_NO_WGUI(flag))
X+        return 0;
X+#endif
X+/*
X+#ifdef ACORN_GUI
X+    if (MSG_NO_AGUI(flag))
X+        return 0;
X+#endif
X+ */
X+#ifdef DLL                 /* don't display message if data is redirected */
X+    if (((Uz_Globs *)pG)->redirect_data &&
X+        !((Uz_Globs *)pG)->redirect_text)
X+        return 0;
X+#endif
X+
X+    if (MSG_STDERR(flag) && !((Uz_Globs *)pG)->UzO.tflag)
X+        outfp = (FILE *)stderr;
X+    else
X+        outfp = (FILE *)stdout;
X+
X+#ifdef QUERY_TRNEWLN
X+    /* some systems require termination of query prompts with '\n' to force
X+     * immediate display */
X+    if (MSG_MNEWLN(flag)) {   /* assumes writable buffer (e.g., slide[]) */
X+        *endbuf++ = '\n';     /*  with room for one more char at end of buf */
X+        ++size;               /*  (safe assumption:  only used for four */
X+    }                         /*  short queries in extract.c and fileio.c) */
X+#endif
X+
X+    if (MSG_TNEWLN(flag)) {   /* again assumes writable buffer:  fragile... */
X+        if ((!size && !((Uz_Globs *)pG)->sol) ||
X+            (size && (endbuf[-1] != '\n')))
X+        {
X+            *endbuf++ = '\n';
X+            ++size;
X+        }
X+    }
X+
X+#ifdef MORE
X+# ifdef SCREENSIZE
X+    /* room for --More-- and one line of overlap: */
X+#  if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
X+    SCREENSIZE(&((Uz_Globs *)pG)->height, &((Uz_Globs *)pG)->width);
X+#  else
X+    SCREENSIZE(&((Uz_Globs *)pG)->height, (int *)NULL);
X+#  endif
X+    ((Uz_Globs *)pG)->height -= 2;
X+# else
X+    /* room for --More-- and one line of overlap: */
X+    ((Uz_Globs *)pG)->height = SCREENLINES - 2;
X+#  if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
X+    ((Uz_Globs *)pG)->width = SCREENWIDTH;
X+#  endif
X+# endif
X+#endif /* MORE */
X+
X+    if (MSG_LNEWLN(flag) && !((Uz_Globs *)pG)->sol) {
X+        /* not at start of line:  want newline */
X+#ifdef OS2DLL
X+        if (!((Uz_Globs *)pG)->redirect_text) {
X+#endif
X+            putc('\n', outfp);
X+            fflush(outfp);
X+#ifdef MORE
X+            if (((Uz_Globs *)pG)->M_flag)
X+            {
X+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
X+                ((Uz_Globs *)pG)->chars = 0;
X+#endif
X+                ++((Uz_Globs *)pG)->numlines;
X+                ++((Uz_Globs *)pG)->lines;
X+                if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
X+                    (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
X+                      LoadFarString(MorePrompt), 1);
X+            }
X+#endif /* MORE */
X+            if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
X+                !isatty(1) && isatty(2))
X+            {
X+                /* error output from testing redirected:  also send to stderr */
X+                putc('\n', stderr);
X+                fflush(stderr);
X+            }
X+#ifdef OS2DLL
X+        } else
X+           REDIRECTC('\n');
X+#endif
X+        ((Uz_Globs *)pG)->sol = TRUE;
X+    }
X+
X+    /* put zipfile name, filename and/or error/warning keywords here */
X+
X+#ifdef MORE
X+    if (((Uz_Globs *)pG)->M_flag
X+#ifdef OS2DLL
X+         && !((Uz_Globs *)pG)->redirect_text
X+#endif
X+                                                 )
X+    {
X+        while (p < endbuf) {
X+            if (*p == '\n') {
X+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
X+                islinefeed = TRUE;
X+            } else if (SCREENLWRAP) {
X+                if (*p == '\r') {
X+                    ((Uz_Globs *)pG)->chars = 0;
X+                } else {
X+#  ifdef TABSIZE
X+                    if (*p == '\t')
X+                        ((Uz_Globs *)pG)->chars +=
X+                            (TABSIZE - (((Uz_Globs *)pG)->chars % TABSIZE));
X+                    else
X+#  endif
X+                        ++((Uz_Globs *)pG)->chars;
X+
X+                    if (((Uz_Globs *)pG)->chars >= ((Uz_Globs *)pG)->width)
X+                        islinefeed = TRUE;
X+                }
X+            }
X+            if (islinefeed) {
X+                islinefeed = FALSE;
X+                ((Uz_Globs *)pG)->chars = 0;
X+#endif /* (SCREENWIDTH && SCREEN_LWRAP) */
X+                ++((Uz_Globs *)pG)->numlines;
X+                ++((Uz_Globs *)pG)->lines;
X+                if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
X+                {
X+                    if ((error = WriteError(q, p-q+1, outfp)) != 0)
X+                        return error;
X+                    fflush(outfp);
X+                    ((Uz_Globs *)pG)->sol = TRUE;
X+                    q = p + 1;
X+                    (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
X+                      LoadFarString(MorePrompt), 1);
X+                }
X+            }
X+            INCSTR(p);
X+        } /* end while */
X+        size = (ulg)(p - q);   /* remaining text */
X+    }
X+#endif /* MORE */
X+
X+    if (size) {
X+#ifdef OS2DLL
X+        if (!((Uz_Globs *)pG)->redirect_text) {
X+#endif
X+            if ((error = WriteError(q, size, outfp)) != 0)
X+                return error;
X+            fflush(outfp);
X+            if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
X+                !isatty(1) && isatty(2))
X+            {
X+                /* error output from testing redirected:  also send to stderr */
X+                if ((error = WriteError(q, size, stderr)) != 0)
X+                    return error;
X+                fflush(stderr);
X+            }
X+#ifdef OS2DLL
X+        } else {                /* GRR:  this is ugly:  hide with macro */
X+            if ((error = REDIRECTPRINT(q, size)) != 0)
X+                return error;
X+        }
X+#endif /* OS2DLL */
X+        ((Uz_Globs *)pG)->sol = (endbuf[-1] == '\n');
X+    }
X+    return 0;
X+
X+} /* end function UzpMessagePrnt() */
X+
X+
X+
X+
X+
X+#ifdef DLL
X+
X+/*****************************/
X+/* Function UzpMessageNull() */  /* convenience routine for no output at all */
X+/*****************************/
X+
X+int UZ_EXP UzpMessageNull(pG, buf, size, flag)
X+    zvoid *pG;    /* globals struct:  always passed */
X+    uch *buf;     /* preformatted string to be printed */
X+    ulg size;     /* length of string (may include nulls) */
X+    int flag;     /* flag bits */
X+{
X+    return 0;
X+
X+} /* end function UzpMessageNull() */
X+
X+#endif /* DLL */
X+
X+
X+
X+
X+
X+/***********************/
X+/* Function UzpInput() */   /* GRR:  this is a placeholder for now */
X+/***********************/
X+
X+int UZ_EXP UzpInput(pG, buf, size, flag)
X+    zvoid *pG;    /* globals struct:  always passed */
X+    uch *buf;     /* preformatted string to be printed */
X+    int *size;    /* (address of) size of buf and of returned string */
X+    int flag;     /* flag bits (bit 0: no echo) */
X+{
X+    /* tell picky compilers to shut up about "unused variable" warnings */
X+    pG = pG; buf = buf; flag = flag;
X+
X+    *size = 0;
X+    return 0;
X+
X+} /* end function UzpInput() */
X+
X+
X+
X+
X+
X+#if (!defined(WINDLL) && !defined(MACOS))
X+
X+/***************************/
X+/* Function UzpMorePause() */
X+/***************************/
X+
X+void UZ_EXP UzpMorePause(pG, prompt, flag)
X+    zvoid *pG;            /* globals struct:  always passed */
X+    ZCONST char *prompt;  /* "--More--" prompt */
X+    int flag;             /* 0 = any char OK; 1 = accept only '\n', ' ', q */
X+{
X+    uch c;
X+
X+/*---------------------------------------------------------------------------
X+    Print a prompt and wait for the user to press a key, then erase prompt
X+    if possible.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (!((Uz_Globs *)pG)->sol)
X+        fprintf(stderr, "\n");
X+    /* numlines may or may not be used: */
X+    fprintf(stderr, prompt, ((Uz_Globs *)pG)->numlines);
X+    fflush(stderr);
X+    if (flag & 1) {
X+        do {
X+            c = (uch)FGETCH(0);
X+        } while (
X+#ifdef THEOS
X+                 c != 17 &&     /* standard QUIT key */
X+#endif
X+                 c != '\r' && c != '\n' && c != ' ' && c != 'q' && c != 'Q');
X+    } else
X+        c = (uch)FGETCH(0);
X+
X+    /* newline was not echoed, so cover up prompt line */
X+    fprintf(stderr, LoadFarString(HidePrompt));
X+    fflush(stderr);
X+
X+    if (
X+#ifdef THEOS
X+        (c == 17) ||            /* standard QUIT key */
X+#endif
X+        (ToLower(c) == 'q')) {
X+        DESTROYGLOBALS();
X+        EXIT(PK_COOL);
X+    }
X+
X+    ((Uz_Globs *)pG)->sol = TRUE;
X+
X+#ifdef MORE
X+    /* space for another screen, enter for another line. */
X+    if ((flag & 1) && c == ' ')
X+        ((Uz_Globs *)pG)->lines = 0;
X+#endif /* MORE */
X+
X+} /* end function UzpMorePause() */
X+
X+#endif /* !WINDLL && !MACOS */
X+
X+
X+
X+
X+#ifndef WINDLL
X+
X+/**************************/
X+/* Function UzpPassword() */
X+/**************************/
X+
X+int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, efn)
X+    zvoid *pG;         /* pointer to UnZip's internal global vars */
X+    int *rcnt;         /* retry counter */
X+    char *pwbuf;       /* buffer for password */
X+    int size;          /* size of password buffer */
X+    ZCONST char *zfn;  /* name of zip archive */
X+    ZCONST char *efn;  /* name of archive entry being processed */
X+{
X+#if CRYPT
X+    int r = IZ_PW_ENTERED;
X+    char *m;
X+    char *prompt;
X+
X+#ifndef REENTRANT
X+    /* tell picky compilers to shut up about "unused variable" warnings */
X+    pG = pG;
X+#endif
X+
X+    if (*rcnt == 0) {           /* First call for current entry */
X+        *rcnt = 2;
X+        if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
X+            sprintf(prompt, LoadFarString(PasswPrompt),
X+                    FnFilter1(zfn), FnFilter2(efn));
X+            m = prompt;
X+        } else
X+            m = (char *)LoadFarString(PasswPrompt2);
X+    } else {                    /* Retry call, previous password was wrong */
X+        (*rcnt)--;
X+        prompt = NULL;
X+        m = (char *)LoadFarString(PasswRetry);
X+    }
X+
X+    m = getp(__G__ m, pwbuf, size);
X+    if (prompt != (char *)NULL) {
X+        free(prompt);
X+    }
X+    if (m == (char *)NULL) {
X+        r = IZ_PW_ERROR;
X+    }
X+    else if (*pwbuf == '\0') {
X+        r = IZ_PW_CANCELALL;
X+    }
X+    return r;
X+
X+#else /* !CRYPT */
X+    /* tell picky compilers to shut up about "unused variable" warnings */
X+    pG = pG; rcnt = rcnt; pwbuf = pwbuf; size = size; zfn = zfn; efn = efn;
X+
X+    return IZ_PW_ERROR;  /* internal error; function should never get called */
X+#endif /* ?CRYPT */
X+
X+} /* end function UzpPassword() */
X+
X+
X+
X+
X+
X+/**********************/
X+/* Function handler() */
X+/**********************/
X+
X+void handler(signal)   /* upon interrupt, turn on echo and exit cleanly */
X+    int signal;
X+{
X+    GETGLOBALS();
X+
X+#if !(defined(SIGBUS) || defined(SIGSEGV))      /* add a newline if not at */
X+    (*G.message)((zvoid *)&G, slide, 0L, 0x41); /*  start of line (to stderr; */
X+#endif                                          /*  slide[] should be safe) */
X+
X+    echon();
X+
X+#ifdef SIGBUS
X+    if (signal == SIGBUS) {
X+        Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
X+          "bus error"));
X+        DESTROYGLOBALS();
X+        EXIT(PK_BADERR);
X+    }
X+#endif /* SIGBUS */
X+
X+#ifdef SIGSEGV
X+    if (signal == SIGSEGV) {
X+        Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
X+          "segmentation violation"));
X+        DESTROYGLOBALS();
X+        EXIT(PK_BADERR);
X+    }
X+#endif /* SIGSEGV */
X+
X+    /* probably ctrl-C */
X+    DESTROYGLOBALS();
X+#if defined(AMIGA) && defined(__SASC)
X+    _abort();
X+#endif
X+    EXIT(IZ_CTRLC);       /* was EXIT(0), then EXIT(PK_ERR) */
X+}
X+
X+#endif /* !WINDLL */
X+
X+
X+
X+
X+#if (!defined(VMS) && !defined(CMS_MVS))
X+#if (!defined(OS2) || defined(TIMESTAMP))
X+
X+#if (!defined(HAVE_MKTIME) || defined(WIN32))
X+/* also used in amiga/filedate.c and win32/win32.c */
X+ZCONST ush ydays[] =
X+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
X+#endif
X+
X+/*******************************/
X+/* Function dos_to_unix_time() */ /* used for freshening/updating/timestamps */
X+/*******************************/
X+
X+time_t dos_to_unix_time(dosdatetime)
X+    ulg dosdatetime;
X+{
X+    time_t m_time;
X+
X+#ifdef HAVE_MKTIME
X+
X+    ZCONST time_t now = time(NULL);
X+    struct tm *tm;
X+#   define YRBASE  1900
X+
X+    tm = localtime(&now);
X+    tm->tm_isdst = -1;          /* let mktime determine if DST is in effect */
X+
X+    /* dissect date */
X+    tm->tm_year = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
X+    tm->tm_mon  = ((int)(dosdatetime >> 21) & 0x0f) - 1;
X+    tm->tm_mday = ((int)(dosdatetime >> 16) & 0x1f);
X+
X+    /* dissect time */
X+    tm->tm_hour = (int)((unsigned)dosdatetime >> 11) & 0x1f;
X+    tm->tm_min  = (int)((unsigned)dosdatetime >> 5) & 0x3f;
X+    tm->tm_sec  = (int)((unsigned)dosdatetime << 1) & 0x3e;
X+
X+    m_time = mktime(tm);
X+    NATIVE_TO_TIMET(m_time)     /* NOP unless MSC 7.0 or Macintosh */
X+    TTrace((stderr, "  final m_time  =       %lu\n", (ulg)m_time));
X+
X+#else /* !HAVE_MKTIME */
X+
X+    int yr, mo, dy, hh, mm, ss;
X+#ifdef TOPS20
X+#   define YRBASE  1900
X+    struct tmx *tmx;
X+    char temp[20];
X+#else /* !TOPS20 */
X+#   define YRBASE  1970
X+    int leap;
X+    unsigned days;
X+    struct tm *tm;
X+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
X+#ifdef WIN32
X+    TIME_ZONE_INFORMATION tzinfo;
X+    DWORD res;
X+#else /* ! WIN32 */
X+#ifndef BSD4_4   /* GRR:  change to !defined(MODERN) ? */
X+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
X+    struct timeb tbp;
X+#else /* !(BSD || MTS || __GO32__) */
X+#ifdef DECLARE_TIMEZONE
X+    extern time_t timezone;
X+#endif
X+#endif /* ?(BSD || MTS || __GO32__) */
X+#endif /* !BSD4_4 */
X+#endif /* ?WIN32 */
X+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
X+#endif /* ?TOPS20 */
X+
X+
X+    /* dissect date */
X+    yr = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
X+    mo = ((int)(dosdatetime >> 21) & 0x0f) - 1;
X+    dy = ((int)(dosdatetime >> 16) & 0x1f) - 1;
X+
X+    /* dissect time */
X+    hh = (int)((unsigned)dosdatetime >> 11) & 0x1f;
X+    mm = (int)((unsigned)dosdatetime >> 5) & 0x3f;
X+    ss = (int)((unsigned)dosdatetime & 0x1f) * 2;
X+
X+#ifdef TOPS20
X+    tmx = (struct tmx *)malloc(sizeof(struct tmx));
X+    sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
X+    time_parse(temp, tmx, (char *)0);
X+    m_time = time_make(tmx);
X+    free(tmx);
X+
X+#else /* !TOPS20 */
X+
X+/*---------------------------------------------------------------------------
X+    Calculate the number of seconds since the epoch, usually 1 January 1970.
X+  ---------------------------------------------------------------------------*/
X+
X+    /* leap = # of leap yrs from YRBASE up to but not including current year */
X+    leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
X+
X+    /* calculate days from BASE to this year and add expired days this year */
X+    days = (yr * 365) + (leap - 492) + ydays[mo];
X+
X+    /* if year is a leap year and month is after February, add another day */
X+    if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
X+        ++days;                 /* OK through 2199 */
X+
X+    /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
X+    m_time = (time_t)((unsigned long)(days + dy) * 86400L +
X+                      (unsigned long)hh * 3600L +
X+                      (unsigned long)(mm * 60 + ss));
X+      /* - 1;   MS-DOS times always rounded up to nearest even second */
X+    TTrace((stderr, "dos_to_unix_time:\n"));
X+    TTrace((stderr, "  m_time before timezone = %lu\n", (ulg)m_time));
X+
X+/*---------------------------------------------------------------------------
X+    Adjust for local standard timezone offset.
X+  ---------------------------------------------------------------------------*/
X+
X+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
X+#ifdef WIN32
X+    /* account for timezone differences */
X+    res = GetTimeZoneInformation(&tzinfo);
X+    if (res != TIME_ZONE_ID_INVALID)
X+    {
X+    m_time += 60*(tzinfo.Bias);
X+#else /* !WIN32 */
X+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
X+#ifdef BSD4_4
X+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
X+         (m_time < (time_t)0x70000000L) )
X+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
X+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
X+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
X+    if ((tm = localtime(&m_time)) != (struct tm *)NULL)
X+        m_time -= tm->tm_gmtoff;                /* sec. EAST of GMT: subtr. */
X+#else /* !(BSD4_4 */
X+    ftime(&tbp);                                /* get `timezone' */
X+    m_time += tbp.timezone * 60L;               /* seconds WEST of GMT:  add */
X+#endif /* ?(BSD4_4 || __EMX__) */
X+#else /* !(BSD || MTS || __GO32__) */
X+    /* tzset was already called at start of process_zipfiles() */
X+    /* tzset(); */              /* set `timezone' variable */
X+#ifndef __BEOS__                /* BeOS DR8 has no timezones... */
X+    m_time += timezone;         /* seconds WEST of GMT:  add */
X+#endif
X+#endif /* ?(BSD || MTS || __GO32__) */
X+#endif /* ?WIN32 */
X+    TTrace((stderr, "  m_time after timezone =  %lu\n", (ulg)m_time));
X+
X+/*---------------------------------------------------------------------------
X+    Adjust for local daylight savings (summer) time.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef BSD4_4  /* (DST already added to tm_gmtoff, so skip tm_isdst) */
X+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
X+         (m_time < (time_t)0x70000000L) )
X+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
X+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
X+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
X+    TIMET_TO_NATIVE(m_time)     /* NOP unless MSC 7.0 or Macintosh */
X+    if (((tm = localtime((time_t *)&m_time)) != NULL) && tm->tm_isdst)
X+#ifdef WIN32
X+        m_time += 60L * tzinfo.DaylightBias;    /* adjust with DST bias */
X+    else
X+        m_time += 60L * tzinfo.StandardBias;    /* add StdBias (normally 0) */
X+#else
X+        m_time -= 60L * 60L;    /* adjust for daylight savings time */
X+#endif
X+    NATIVE_TO_TIMET(m_time)     /* NOP unless MSC 7.0 or Macintosh */
X+    TTrace((stderr, "  m_time after DST =       %lu\n", (ulg)m_time));
X+#endif /* !BSD4_4 */
X+#ifdef WIN32
X+    }
X+#endif
X+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
X+#endif /* ?TOPS20 */
X+
X+#endif /* ?HAVE_MKTIME */
X+
X+    if ( (dosdatetime >= DOSTIME_2038_01_18) &&
X+         (m_time < (time_t)0x70000000L) )
X+        m_time = U_TIME_T_MAX;  /* saturate in case of (unsigned) overflow */
X+    if (m_time < (time_t)0L)    /* a converted DOS time cannot be negative */
X+        m_time = S_TIME_T_MAX;  /*  -> saturate at max signed time_t value */
X+
X+    return m_time;
X+
X+} /* end function dos_to_unix_time() */
X+
X+#endif /* !OS2 || TIMESTAMP */
X+#endif /* !VMS && !CMS_MVS */
X+
X+
X+
X+#if (!defined(VMS) && !defined(OS2) && !defined(CMS_MVS))
X+
X+/******************************/
X+/* Function check_for_newer() */  /* used for overwriting/freshening/updating */
X+/******************************/
X+
X+int check_for_newer(__G__ filename)  /* return 1 if existing file is newer */
X+    __GDEF                           /*  or equal; 0 if older; -1 if doesn't */
X+    char *filename;                  /*  exist yet */
X+{
X+    time_t existing, archive;
X+#ifdef USE_EF_UT_TIME
X+    iztimes z_utime;
X+#endif
X+#ifdef AOS_VS
X+    long    dyy, dmm, ddd, dhh, dmin, dss;
X+
X+
X+    dyy = (lrec.last_mod_dos_datetime >> 25) + 1980;
X+    dmm = (lrec.last_mod_dos_datetime >> 21) & 0x0f;
X+    ddd = (lrec.last_mod_dos_datetime >> 16) & 0x1f;
X+    dhh = (lrec.last_mod_dos_datetime >> 11) & 0x1f;
X+    dmin = (lrec.last_mod_dos_datetime >> 5) & 0x3f;
X+    dss = (lrec.last_mod_dos_datetime & 0x1f) * 2;
X+
X+    /* under AOS/VS, file times can only be set at creation time,
X+     * with the info in a special DG format.  Make sure we can create
X+     * it here - we delete it later & re-create it, whether or not
X+     * it exists now.
X+     */
X+    if (!zvs_create(filename, (((ulg)dgdate(dmm, ddd, dyy)) << 16) |
X+        (dhh*1800L + dmin*30L + dss/2L), -1L, -1L, (char *) -1, -1, -1, -1))
X+        return DOES_NOT_EXIST;
X+#endif /* AOS_VS */
X+
X+    Trace((stderr, "check_for_newer:  doing stat(%s)\n", FnFilter1(filename)));
X+    if (SSTAT(filename, &G.statbuf)) {
X+        Trace((stderr,
X+          "check_for_newer:  stat(%s) returns %d:  file does not exist\n",
X+          FnFilter1(filename), SSTAT(filename, &G.statbuf)));
X+#ifdef SYMLINKS
X+        Trace((stderr, "check_for_newer:  doing lstat(%s)\n",
X+          FnFilter1(filename)));
X+        /* GRR OPTION:  could instead do this test ONLY if G.symlnk is true */
X+        if (lstat(filename, &G.statbuf) == 0) {
X+            Trace((stderr,
X+              "check_for_newer:  lstat(%s) returns 0:  symlink does exist\n",
X+              FnFilter1(filename)));
X+            if (QCOND2 && !IS_OVERWRT_ALL)
X+                Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
X+                  FnFilter1(filename), " with no real file"));
X+            return EXISTS_AND_OLDER;   /* symlink dates are meaningless */
X+        }
X+#endif /* SYMLINKS */
X+        return DOES_NOT_EXIST;
X+    }
X+    Trace((stderr, "check_for_newer:  stat(%s) returns 0:  file exists\n",
X+      FnFilter1(filename)));
X+
X+#ifdef SYMLINKS
X+    /* GRR OPTION:  could instead do this test ONLY if G.symlnk is true */
X+    if (lstat(filename, &G.statbuf) == 0 && S_ISLNK(G.statbuf.st_mode)) {
X+        Trace((stderr, "check_for_newer:  %s is a symbolic link\n",
X+          FnFilter1(filename)));
X+        if (QCOND2 && !IS_OVERWRT_ALL)
X+            Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
X+              FnFilter1(filename), ""));
X+        return EXISTS_AND_OLDER;   /* symlink dates are meaningless */
X+    }
X+#endif /* SYMLINKS */
X+
X+    NATIVE_TO_TIMET(G.statbuf.st_mtime)   /* NOP unless MSC 7.0 or Macintosh */
X+
X+#ifdef USE_EF_UT_TIME
X+    /* The `Unix extra field mtime' should be used for comparison with the
X+     * time stamp of the existing file >>>ONLY<<< when the EF info is also
X+     * used to set the modification time of the extracted file.
X+     */
X+    if (G.extra_field &&
X+#ifdef IZ_CHECK_TZ
X+        G.tz_is_valid &&
X+#endif
X+        (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
X+                          G.lrec.last_mod_dos_datetime, &z_utime, NULL)
X+         & EB_UT_FL_MTIME))
X+    {
X+        TTrace((stderr, "check_for_newer:  using Unix extra field mtime\n"));
X+        existing = G.statbuf.st_mtime;
X+        archive  = z_utime.mtime;
X+    } else {
X+        /* round up existing filetime to nearest 2 seconds for comparison,
X+         * but saturate in case of arithmetic overflow
X+         */
X+        existing = ((G.statbuf.st_mtime & 1) &&
X+                    (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
X+                   G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
X+        archive  = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
X+    }
X+#else /* !USE_EF_UT_TIME */
X+    /* round up existing filetime to nearest 2 seconds for comparison,
X+     * but saturate in case of arithmetic overflow
X+     */
X+    existing = ((G.statbuf.st_mtime & 1) &&
X+                (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
X+               G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
X+    archive  = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
X+#endif /* ?USE_EF_UT_TIME */
X+
X+    TTrace((stderr, "check_for_newer:  existing %lu, archive %lu, e-a %ld\n",
X+      (ulg)existing, (ulg)archive, (long)(existing-archive)));
X+
X+    return (existing >= archive);
X+
X+} /* end function check_for_newer() */
X+
X+#endif /* !VMS && !OS2 && !CMS_MVS */
X+
X+
X+
X+
X+
X+/************************/
X+/* Function do_string() */
X+/************************/
X+
X+int do_string(__G__ length, option)   /* return PK-type error code */
X+    __GDEF
X+    unsigned int length;        /* without prototype, ush converted to this */
X+    int option;
X+{
X+    unsigned comment_bytes_left;
X+    unsigned int block_len;
X+    int error=PK_OK;
X+#ifdef AMIGA
X+    char tmp_fnote[2 * AMIGA_FILENOTELEN];   /* extra room for squozen chars */
X+#endif
X+
X+
X+/*---------------------------------------------------------------------------
X+    This function processes arbitrary-length (well, usually) strings.  Four
X+    major options are allowed:  SKIP, wherein the string is skipped (pretty
X+    logical, eh?); DISPLAY, wherein the string is printed to standard output
X+    after undergoing any necessary or unnecessary character conversions;
X+    DS_FN, wherein the string is put into the filename[] array after under-
X+    going appropriate conversions (including case-conversion, if that is
X+    indicated: see the global variable pInfo->lcflag); and EXTRA_FIELD,
X+    wherein the `string' is assumed to be an extra field and is copied to
X+    the (freshly malloced) buffer G.extra_field.  The third option should
X+    be OK since filename is dimensioned at 1025, but we check anyway.
X+
X+    The string, by the way, is assumed to start at the current file-pointer
X+    position; its length is given by 'length'.  So start off by checking the
X+    length of the string:  if zero, we're already done.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (!length)
X+        return PK_COOL;
X+
X+    switch (option) {
X+
X+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
X+    /*
X+     * Special case: See if the comment begins with an autorun command line.
X+     * Save that and display (or skip) the remainder.
X+     */
X+
X+    case CHECK_AUTORUN:
X+    case CHECK_AUTORUN_Q:
X+        comment_bytes_left = length;
X+        if (length >= 10)
X+        {
X+            block_len = readbuf(__G__ (char *)G.outbuf, 10);
X+            if (block_len == 0)
X+                return PK_EOF;
X+            comment_bytes_left -= block_len;
X+            G.outbuf[block_len] = '\0';
X+            if (!strcmp((char *)G.outbuf, "$AUTORUN$>")) {
X+                char *eol;
X+                length -= 10;
X+                block_len = readbuf(__G__ G.autorun_command,
X+                                    MIN(length, sizeof(G.autorun_command)-1));
X+                if (block_len == 0)
X+                    return PK_EOF;
X+                comment_bytes_left -= block_len;
X+                G.autorun_command[block_len] = '\0';
X+                A_TO_N(G.autorun_command);
X+                eol = strchr(G.autorun_command, '\n');
X+                if (!eol)
X+                    eol = G.autorun_command + strlen(G.autorun_command) - 1;
X+                length -= eol + 1 - G.autorun_command;
X+                while (eol >= G.autorun_command && isspace(*eol))
X+                    *eol-- = '\0';
X+#if (defined(WIN32) && !defined(_WIN32_WCE))
X+                /* Win9x console always uses OEM character coding, and
X+                   WinNT console is set to OEM charset by default, too */
X+                INTERN_TO_OEM(G.autorun_command, G.autorun_command);
X+#endif /* (WIN32 && !_WIN32_WCE) */
X+            }
X+        }
X+        if (option == CHECK_AUTORUN_Q)  /* don't display the remainder */
X+            length = 0;
X+        /* seek to beginning of remaining part of comment -- rewind if */
X+        /* displaying entire comment, or skip to end if discarding it  */
X+        seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
X+                  (G.inptr - G.inbuf) + comment_bytes_left - length);
X+        if (!length)
X+            break;
X+        /*  FALL THROUGH...  */
X+#endif /* SFX && CHEAP_SFX_AUTORUN */
X+
X+    /*
X+     * First normal case:  print string on standard output.  First set loop
X+     * variables, then loop through the comment in chunks of OUTBUFSIZ bytes,
X+     * converting formats and printing as we go.  The second half of the
X+     * loop conditional was added because the file might be truncated, in
X+     * which case comment_bytes_left will remain at some non-zero value for
X+     * all time.  outbuf and slide are used as scratch buffers because they
X+     * are available (we should be either before or in between any file pro-
X+     * cessing).
X+     */
X+
X+    case DISPLAY:
X+    case DISPL_8:
X+        comment_bytes_left = length;
X+        block_len = OUTBUFSIZ;       /* for the while statement, first time */
X+        while (comment_bytes_left > 0 && block_len > 0) {
X+            register uch *p = G.outbuf;
X+            register uch *q = G.outbuf;
X+
X+            if ((block_len = readbuf(__G__ (char *)G.outbuf,
X+                   MIN((unsigned)OUTBUFSIZ, comment_bytes_left))) == 0)
X+                return PK_EOF;
X+            comment_bytes_left -= block_len;
X+
X+            /* this is why we allocated an extra byte for outbuf:  terminate
X+             *  with zero (ASCIIZ) */
X+            G.outbuf[block_len] = '\0';
X+
X+            /* remove all ASCII carriage returns from comment before printing
X+             * (since used before A_TO_N(), check for CR instead of '\r')
X+             */
X+            while (*p) {
X+                while (*p == CR)
X+                    ++p;
X+                *q++ = *p++;
X+            }
X+            /* could check whether (p - outbuf) == block_len here */
X+            *q = '\0';
X+
X+            if (option == DISPL_8) {
X+                /* translate the text coded in the entry's host-dependent
X+                   "extended ASCII" charset into the compiler's (system's)
X+                   internal text code page */
X+                Ext_ASCII_TO_Native((char *)G.outbuf, G.pInfo->hostnum,
X+                                    G.pInfo->hostver, G.pInfo->HasUxAtt,
X+                                    FALSE);
X+#ifdef WINDLL
X+                /* translate to ANSI (RTL internal codepage may be OEM) */
X+                INTERN_TO_ISO((char *)G.outbuf, (char *)G.outbuf);
X+#else /* !WINDLL */
X+#if (defined(WIN32) && !defined(_WIN32_WCE))
X+                /* Win9x console always uses OEM character coding, and
X+                   WinNT console is set to OEM charset by default, too */
X+                INTERN_TO_OEM((char *)G.outbuf, (char *)G.outbuf);
X+#endif /* (WIN32 && !_WIN32_WCE) */
X+#endif /* ?WINDLL */
X+            } else {
X+                A_TO_N(G.outbuf);   /* translate string to native */
X+            }
X+
X+#ifdef WINDLL
X+            /* ran out of local mem -- had to cheat */
X+            win_fprintf((zvoid *)&G, stdout, length, (char *)G.outbuf);
X+            win_fprintf((zvoid *)&G, stdout, 2, (char *)"\n\n");
X+#else /* !WINDLL */
X+#ifdef NOANSIFILT       /* GRR:  can ANSI be used with EBCDIC? */
X+            (*G.message)((zvoid *)&G, G.outbuf, (ulg)(q-G.outbuf), 0);
X+#else /* ASCII, filter out ANSI escape sequences and handle ^S (pause) */
X+            p = G.outbuf - 1;
X+            q = slide;
X+            while (*++p) {
X+                int pause = FALSE;
X+
X+                if (*p == 0x1B) {          /* ASCII escape char */
X+                    *q++ = '^';
X+                    *q++ = '[';
X+                } else if (*p == 0x13) {   /* ASCII ^S (pause) */
X+                    pause = TRUE;
X+                    if (p[1] == LF)        /* ASCII LF */
X+                        *q++ = *++p;
X+                    else if (p[1] == CR && p[2] == LF) {  /* ASCII CR LF */
X+                        *q++ = *++p;
X+                        *q++ = *++p;
X+                    }
X+                } else
X+                    *q++ = *p;
X+                if ((unsigned)(q-slide) > WSIZE-3 || pause) {   /* flush */
X+                    (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
X+                    q = slide;
X+                    if (pause && G.extract_flag) /* don't pause for list/test */
X+                        (*G.mpause)((zvoid *)&G, LoadFarString(QuitPrompt), 0);
X+                }
X+            }
X+            (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
X+#endif /* ?NOANSIFILT */
X+#endif /* ?WINDLL */
X+        }
X+        /* add '\n' if not at start of line */
X+        (*G.message)((zvoid *)&G, slide, 0L, 0x40);
X+        break;
X+
X+    /*
X+     * Second case:  read string into filename[] array.  The filename should
X+     * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
X+     * just to be sure.
X+     */
X+
X+    case DS_FN:
X+    case DS_FN_L:
X+        if (length >= FILNAMSIZ) {
X+            Info(slide, 0x401, ((char *)slide,
X+              LoadFarString(FilenameTooLongTrunc)));
X+            error = PK_WARN;
X+            /* remember excess length in block_len */
X+            block_len = length - (FILNAMSIZ - 1);
X+            length = FILNAMSIZ - 1;
X+        } else
X+            /* no excess size */
X+            block_len = 0;
X+        if (readbuf(__G__ G.filename, length) == 0)
X+            return PK_EOF;
X+        G.filename[length] = '\0';      /* terminate w/zero:  ASCIIZ */
X+
X+        /* translate the Zip entry filename coded in host-dependent "extended
X+           ASCII" into the compiler's (system's) internal text code page */
X+        Ext_ASCII_TO_Native(G.filename, G.pInfo->hostnum, G.pInfo->hostver,
X+                            G.pInfo->HasUxAtt, (option == DS_FN_L));
X+
X+        if (G.pInfo->lcflag)      /* replace with lowercase filename */
X+            STRLOWER(G.filename, G.filename);
X+
X+        if (G.pInfo->vollabel && length > 8 && G.filename[8] == '.') {
X+            char *p = G.filename+8;
X+            while (*p++)
X+                p[-1] = *p;  /* disk label, and 8th char is dot:  remove dot */
X+        }
X+
X+        if (!block_len)         /* no overflow, we're done here */
X+            break;
X+
X+        /*
X+         * We truncated the filename, so print what's left and then fall
X+         * through to the SKIP routine.
X+         */
X+        Info(slide, 0x401, ((char *)slide, "[ %s ]\n", FnFilter1(G.filename)));
X+        length = block_len;     /* SKIP the excess bytes... */
X+        /*  FALL THROUGH...  */
X+
X+    /*
X+     * Third case:  skip string, adjusting readbuf's internal variables
X+     * as necessary (and possibly skipping to and reading a new block of
X+     * data).
X+     */
X+
X+    case SKIP:
X+        /* cur_zipfile_bufstart already takes account of extra_bytes, so don't
X+         * correct for it twice: */
X+        seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
X+                  (G.inptr-G.inbuf) + length);
X+        break;
X+
X+    /*
X+     * Fourth case:  assume we're at the start of an "extra field"; malloc
X+     * storage for it and read data into the allocated space.
X+     */
X+
X+    case EXTRA_FIELD:
X+        if (G.extra_field != (uch *)NULL)
X+            free(G.extra_field);
X+        if ((G.extra_field = (uch *)malloc(length)) == (uch *)NULL) {
X+            Info(slide, 0x401, ((char *)slide, LoadFarString(ExtraFieldTooLong),
X+              length));
X+            /* cur_zipfile_bufstart already takes account of extra_bytes,
X+             * so don't correct for it twice: */
X+            seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
X+                      (G.inptr-G.inbuf) + length);
X+        } else
X+            if (readbuf(__G__ (char *)G.extra_field, length) == 0)
X+                return PK_EOF;
X+        break;
X+
X+#ifdef AMIGA
X+    /*
X+     * Fifth case, for the Amiga only:  take the comment that would ordinarily
X+     * be skipped over, and turn it into a 79 character string that will be
X+     * attached to the file as a "filenote" after it is extracted.
X+     */
X+
X+    case FILENOTE:
X+        if ((block_len = readbuf(__G__ tmp_fnote, (unsigned)
X+                                 MIN(length, 2 * AMIGA_FILENOTELEN - 1))) == 0)
X+            return PK_EOF;
X+        if ((length -= block_len) > 0)  /* treat remainder as in case SKIP: */
X+            seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes
X+                      + (G.inptr - G.inbuf) + length);
X+        /* convert multi-line text into single line with no ctl-chars: */
X+        tmp_fnote[block_len] = '\0';
X+        while ((short int) --block_len >= 0)
X+            if ((unsigned) tmp_fnote[block_len] < ' ')
X+                if (tmp_fnote[block_len+1] == ' ')     /* no excess */
X+                    strcpy(tmp_fnote+block_len, tmp_fnote+block_len+1);
X+                else
X+                    tmp_fnote[block_len] = ' ';
X+        tmp_fnote[AMIGA_FILENOTELEN - 1] = '\0';
X+        if (G.filenotes[G.filenote_slot])
X+            free(G.filenotes[G.filenote_slot]);     /* should not happen */
X+        G.filenotes[G.filenote_slot] = NULL;
X+        if (tmp_fnote[0]) {
X+            if (!(G.filenotes[G.filenote_slot] = malloc(strlen(tmp_fnote)+1)))
X+                return PK_MEM;
X+            strcpy(G.filenotes[G.filenote_slot], tmp_fnote);
X+        }
X+        break;
X+#endif /* AMIGA */
X+
X+    } /* end switch (option) */
X+
X+    return error;
X+
X+} /* end function do_string() */
X+
X+
X+
X+
X+
X+/***********************/
X+/* Function makeword() */
X+/***********************/
X+
X+ush makeword(b)
X+    ZCONST uch *b;
X+{
X+    /*
X+     * Convert Intel style 'short' integer to non-Intel non-16-bit
X+     * host format.  This routine also takes care of byte-ordering.
X+     */
X+    return (ush)((b[1] << 8) | b[0]);
X+}
X+
X+
X+
X+
X+
X+/***********************/
X+/* Function makelong() */
X+/***********************/
X+
X+ulg makelong(sig)
X+    ZCONST uch *sig;
X+{
X+    /*
X+     * Convert intel style 'long' variable to non-Intel non-16-bit
X+     * host format.  This routine also takes care of byte-ordering.
X+     */
X+    return (((ulg)sig[3]) << 24)
X+        + (((ulg)sig[2]) << 16)
X+        + (((ulg)sig[1]) << 8)
X+        + ((ulg)sig[0]);
X+}
X+
X+
X+
X+#if CRYPT
X+
X+#ifdef NEED_STR2ISO
X+/**********************/
X+/* Function str2iso() */
X+/**********************/
X+
X+char *str2iso(dst, src)
X+    char *dst;                          /* destination buffer */
X+    register ZCONST char *src;          /* source string */
X+{
X+#ifdef INTERN_TO_ISO
X+    INTERN_TO_ISO(src, dst);
X+#else
X+    register uch c;
X+    register char *dstp = dst;
X+
X+    do {
X+        c = (uch)foreign(*src++);
X+        *dstp++ = (char)ASCII2ISO(c);
X+    } while (c != '\0');
X+#endif
X+
X+    return dst;
X+}
X+#endif /* NEED_STR2ISO */
X+
X+
X+#ifdef NEED_STR2OEM
X+/**********************/
X+/* Function str2oem() */
X+/**********************/
X+
X+char *str2oem(dst, src)
X+    char *dst;                          /* destination buffer */
X+    register ZCONST char *src;          /* source string */
X+{
X+#ifdef INTERN_TO_OEM
X+    INTERN_TO_OEM(src, dst);
X+#else
X+    register uch c;
X+    register char *dstp = dst;
X+
X+    do {
X+        c = (uch)foreign(*src++);
X+        *dstp++ = (char)ASCII2OEM(c);
X+    } while (c != '\0');
X+#endif
X+
X+    return dst;
X+}
X+#endif /* NEED_STR2OEM */
X+
X+#endif /* CRYPT */
X+
X+
X+#ifdef ZMEM  /* memset/memcmp/memcpy for systems without either them or */
X+             /* bzero/bcmp/bcopy */
X+             /* (no known systems as of 960211) */
X+
X+/*********************/
X+/* Function memset() */
X+/*********************/
X+
X+zvoid *memset(buf, init, len)
X+    register zvoid *buf;        /* buffer location */
X+    register int init;          /* initializer character */
X+    register unsigned int len;  /* length of the buffer */
X+{
X+    zvoid *start;
X+
X+    start = buf;
X+    while (len--)
X+        *((char *)buf++) = (char)init;
X+    return start;
X+}
X+
X+
X+
X+/*********************/
X+/* Function memcmp() */
X+/*********************/
X+
X+int memcmp(b1, b2, len)
X+    register ZCONST zvoid *b1;
X+    register ZCONST zvoid *b2;
X+    register unsigned int len;
X+{
X+    register int c;
X+
X+    if (len > 0) do {
X+        if ((c = (int)(*((ZCONST unsigned char *)b1)++) -
X+                 (int)(*((ZCONST unsigned char *)b2)++)) != 0)
X+           return c;
X+    } while (--len > 0)
X+    return 0;
X+}
X+
X+
X+
X+/*********************/
X+/* Function memcpy() */
X+/*********************/
X+
X+zvoid *memcpy(dst, src, len)
X+    register zvoid *dst;
X+    register ZCONST zvoid *src;
X+    register unsigned int len;
X+{
X+    zvoid *start;
X+
X+    start = dst;
X+    while (len-- > 0)
X+        *((char *)dst)++ = *((ZCONST char *)src)++;
X+    return start;
X+}
X+
X+#endif /* ZMEM */
X+
X+
X+
X+
X+#ifdef NO_STRNICMP
X+
X+/************************/
X+/* Function zstrnicmp() */
X+/************************/
X+
X+int zstrnicmp(s1, s2, n)
X+    register ZCONST char *s1, *s2;
X+    register unsigned n;
X+{
X+    for (; n > 0;  --n, ++s1, ++s2) {
X+
X+        if (ToLower(*s1) != ToLower(*s2))
X+            /* test includes early termination of one string */
X+            return (ToLower(*s1) < ToLower(*s2))? -1 : 1;
X+
X+        if (*s1 == '\0')   /* both strings terminate early */
X+            return 0;
X+    }
X+    return 0;
X+}
X+
X+#endif /* NO_STRNICMP */
X+
X+
X+
X+
X+#ifdef REGULUS  /* returns the inode number on success(!)...argh argh argh */
X+#  undef stat
X+
X+/********************/
X+/* Function zstat() */
X+/********************/
X+
X+int zstat(p, s)
X+    ZCONST char *p;
X+    struct stat *s;
X+{
X+    return (stat((char *)p,s) >= 0? 0 : (-1));
X+}
X+
X+#endif /* REGULUS */
X+
X+
X+
X+
X+#ifdef _MBCS
X+
X+/* DBCS support for Info-ZIP's zip  (mainly for japanese (-: )
X+ * by Yoshioka Tsuneo (QWF00133 at nifty.ne.jp,tsuneo-y at is.aist-nara.ac.jp)
X+ * This code is public domain!   Date: 1998/12/20
X+ */
X+
X+/************************/
X+/* Function plastchar() */
X+/************************/
X+
X+char *plastchar(ptr, len)
X+    ZCONST char *ptr;
X+    extent len;
X+{
X+    unsigned clen;
X+    ZCONST char *oldptr = ptr;
X+    while(*ptr != '\0' && len > 0){
X+        oldptr = ptr;
X+        clen = CLEN(ptr);
X+        ptr += clen;
X+        len -= clen;
X+    }
X+    return (char *)oldptr;
X+}
X+
X+
X+#ifdef NEED_UZMBSCHR
X+/***********************/
X+/* Function uzmbschr() */
X+/***********************/
X+
X+unsigned char *uzmbschr(str, c)
X+    ZCONST unsigned char *str;
X+    unsigned int c;
X+{
X+    while(*str != '\0'){
X+        if (*str == c) {return (unsigned char *)str;}
X+        INCSTR(str);
X+    }
X+    return NULL;
X+}
X+#endif /* NEED_UZMBSCHR */
X+
X+
X+#ifdef NEED_UZMBSRCHR
X+/************************/
X+/* Function uzmbsrchr() */
X+/************************/
X+
X+unsigned char *uzmbsrchr(str, c)
X+    ZCONST unsigned char *str;
X+    unsigned int c;
X+{
X+    unsigned char *match = NULL;
X+    while(*str != '\0'){
X+        if (*str == c) {match = (unsigned char *)str;}
X+        INCSTR(str);
X+    }
X+    return match;
X+}
X+#endif /* NEED_UZMBSRCHR */
X+#endif /* _MBCS */
X+
X+
X+
X+
X+
X+#ifdef SMALL_MEM
X+
X+/*******************************/
X+/*  Function fLoadFarString()  */   /* (and friends...) */
X+/*******************************/
X+
X+char *fLoadFarString(__GPRO__ const char Far *sz)
X+{
X+    (void)zfstrcpy(G.rgchBigBuffer, sz);
X+    return G.rgchBigBuffer;
X+}
X+
X+char *fLoadFarStringSmall(__GPRO__ const char Far *sz)
X+{
X+    (void)zfstrcpy(G.rgchSmallBuffer, sz);
X+    return G.rgchSmallBuffer;
X+}
X+
X+char *fLoadFarStringSmall2(__GPRO__ const char Far *sz)
X+{
X+    (void)zfstrcpy(G.rgchSmallBuffer2, sz);
X+    return G.rgchSmallBuffer2;
X+}
X+
X+
X+
X+
X+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
X+/*************************/
X+/*  Function zfstrcpy()  */   /* portable clone of _fstrcpy() */
X+/*************************/
X+
X+char Far * Far zfstrcpy(char Far *s1, const char Far *s2)
X+{
X+    char Far *p = s1;
X+
X+    while ((*s1++ = *s2++) != '\0');
X+    return p;
X+}
X+
X+#if (!(defined(SFX) || defined(FUNZIP)))
X+/*************************/
X+/*  Function zfstrcmp()  */   /* portable clone of _fstrcmp() */
X+/*************************/
X+
X+int Far zfstrcmp(const char Far *s1, const char Far *s2)
X+{
X+    int ret;
X+
X+    while ((ret = (int)(uch)*s1 - (int)(uch)*s2) == 0
X+           && *s2 != '\0') {
X+        ++s2; ++s1;
X+    }
X+    return ret;
X+}
X+#endif /* !(SFX || FUNZIP) */
X+#endif /* !_MSC_VER || (_MSC_VER < 600) */
X+
X+#endif /* SMALL_MEM */
Xdiff -ruN ../unzip-5.52.orig/unix/unix.c ./unix/unix.c
X--- ../unzip-5.52.orig/unix/unix.c	2005-02-27 04:43:42.000000000 +0900
X+++ ./unix/unix.c	2008-03-08 07:16:58.000000000 +0900
X@@ -196,7 +196,7 @@
X         }
X 
X         /* break the wildspec into a directory part and a wildcard filename */
X-        if ((G.wildname = (ZCONST char *)strrchr(wildspec, '/')) == NULL) {
X+        if ((G.wildname = (ZCONST char *)MBSRCHR(wildspec, '/')) == NULL) {
X             G.dirname = ".";
X             G.dirnamelen = 1;
X             G.have_dirname = FALSE;
X@@ -431,7 +431,11 @@
X              */
X             if ((tmp & 0x10) == 0) {
X                 extent fnlen = strlen(G.filename);
X+#ifdef _MBCS
X+		if (lastchar(G.filename, fnlen) == '/')
X+#else
X                 if (fnlen > 0 && G.filename[fnlen-1] == '/')
X+#endif
X                     tmp |= 0x10;
X             }
X             /* read-only bit --> write perms; subdir bit --> dir exec bit */
X@@ -508,7 +512,7 @@
X     *pathcomp = '\0';           /* initialize translation buffer */
X     pp = pathcomp;              /* point to translation buffer */
X     if (uO.jflag)               /* junking directories */
X-        cp = (char *)strrchr(G.filename, '/');
X+        cp = (char *)MBSRCHR(G.filename, '/');
X     if (cp == (char *)NULL)     /* no '/' or not junking dirs */
X         cp = G.filename;        /* point to internal zipfile-member pathname */
X     else
X@@ -594,7 +598,11 @@
X     fore exiting.
X   ---------------------------------------------------------------------------*/
X 
X+#ifdef _MBCS
X+    if (lastchar(G.filename, strlen(G.filename)) == '/') {
X+#else
X     if (G.filename[strlen(G.filename) - 1] == '/') {
X+#endif
X         checkdir(__G__ G.filename, GETPATH);
X         if (G.created_dir) {
X             if (QCOND2) {
X@@ -883,7 +891,11 @@
X                 return MPN_NOMEM;
X             }
X             strcpy(tmproot, pathcomp);
X+#ifdef _MBCS
X+	    if (lastchar(tmproot, G.rootlen) == '/') {
X+#else
X             if (tmproot[G.rootlen-1] == '/') {
X+#endif
X                 tmproot[--G.rootlen] = '\0';
X             }
X             if (G.rootlen > 0 && (SSTAT(tmproot, &G.statbuf) ||
Xdiff -ruN ../unzip-5.52.orig/unix/unix.c.orig ./unix/unix.c.orig
X--- ../unzip-5.52.orig/unix/unix.c.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./unix/unix.c.orig	2005-02-27 04:43:42.000000000 +0900
X@@ -0,0 +1,1668 @@
X+/*
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  See the accompanying file LICENSE, version 2000-Apr-09 or later
X+  (the contents of which are also included in unzip.h) for terms of use.
X+  If, for some reason, all these files are missing, the Info-ZIP license
X+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
X+*/
X+/*---------------------------------------------------------------------------
X+
X+  unix.c
X+
X+  Unix-specific routines for use with Info-ZIP's UnZip 5.41 and later.
X+
X+  Contains:  readdir()
X+             do_wild()           <-- generic enough to put in fileio.c?
X+             mapattr()
X+             mapname()
X+             checkdir()
X+             mkdir()
X+             close_outfile()
X+             defer_dir_attribs()
X+             set_direc_attribs()
X+             stamp_file()
X+             version()
X+
X+  ---------------------------------------------------------------------------*/
X+
X+
X+#define UNZIP_INTERNAL
X+#include "unzip.h"
X+
X+#ifdef SCO_XENIX
X+#  define SYSNDIR
X+#else  /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
X+#  if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
X+#    define DIRENT
X+#  endif
X+#endif
X+#if defined(_AIX) || defined(__mpexl)
X+#  define DIRENT
X+#endif
X+#ifdef COHERENT
X+#  if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
X+#    define DIRENT
X+#  endif
X+#endif
X+
X+#ifdef _POSIX_VERSION
X+#  ifndef DIRENT
X+#    define DIRENT
X+#  endif
X+#endif
X+
X+#ifdef DIRENT
X+#  include <dirent.h>
X+#else
X+#  ifdef SYSV
X+#    ifdef SYSNDIR
X+#      include <sys/ndir.h>
X+#    else
X+#      include <ndir.h>
X+#    endif
X+#  else /* !SYSV */
X+#    ifndef NO_SYSDIR
X+#      include <sys/dir.h>
X+#    endif
X+#  endif /* ?SYSV */
X+#  ifndef dirent
X+#    define dirent direct
X+#  endif
X+#endif /* ?DIRENT */
X+
X+#ifdef SET_DIR_ATTRIB
X+typedef struct uxdirattr {      /* struct for holding unix style directory */
X+    struct uxdirattr *next;     /*  info until can be sorted and set at end */
X+    char *fn;                   /* filename of directory */
X+    union {
X+        iztimes t3;             /* mtime, atime, ctime */
X+        ztimbuf t2;             /* modtime, actime */
X+    } u;
X+    unsigned perms;             /* same as min_info.file_attr */
X+    int have_uidgid;            /* flag */
X+    ush uidgid[2];
X+    char fnbuf[1];              /* buffer stub for directory name */
X+} uxdirattr;
X+#define UxAtt(d)  ((uxdirattr *)d)    /* typecast shortcut */
X+#endif /* SET_DIR_ATTRIB */
X+
X+#ifdef ACORN_FTYPE_NFS
X+/* Acorn bits for NFS filetyping */
X+typedef struct {
X+  uch ID[2];
X+  uch size[2];
X+  uch ID_2[4];
X+  uch loadaddr[4];
X+  uch execaddr[4];
X+  uch attr[4];
X+} RO_extra_block;
X+
X+#endif /* ACORN_FTYPE_NFS */
X+
X+/* static int created_dir;      */      /* used in mapname(), checkdir() */
X+/* static int renamed_fullpath; */      /* ditto */
X+
X+static unsigned filtattr OF((__GPRO__ unsigned perms));
X+
X+
X+#ifndef SFX
X+#ifdef NO_DIR                  /* for AT&T 3B1 */
X+
X+#define opendir(path) fopen(path,"r")
X+#define closedir(dir) fclose(dir)
X+typedef FILE DIR;
X+typedef struct zdir {
X+    FILE *dirhandle;
X+    struct dirent *entry;
X+} DIR
X+DIR *opendir OF((ZCONST char *dirspec));
X+void closedir OF((DIR *dirp));
X+struct dirent *readdir OF((DIR *dirp));
X+
X+DIR *opendir(dirspec)
X+    ZCONST char *dirspec;
X+{
X+    DIR *dirp;
X+
X+    if ((dirp = malloc(sizeof(DIR)) != NULL) {
X+        if ((dirp->dirhandle = fopen(dirspec, "r")) == NULL) {
X+            free(dirp);
X+            dirp = NULL;
X+        }
X+    }
X+    return dirp;
X+}
X+
X+void closedir(dirp)
X+    DIR *dirp;
X+{
X+    fclose(dirp->dirhandle);
X+    free(dirp);
X+}
X+
X+/*
X+ *  Apparently originally by Rich Salz.
X+ *  Cleaned up and modified by James W. Birdsall.
X+ */
X+struct dirent *readdir(dirp)
X+    DIR *dirp;
X+{
X+
X+    if (dirp == NULL)
X+        return NULL;
X+
X+    for (;;)
X+        if (fread(&(dirp->entry), sizeof (struct dirent), 1,
X+                  dirp->dirhandle) == 0)
X+            return (struct dirent *)NULL;
X+        else if ((dirp->entry).d_ino)
X+            return &(dirp->entry);
X+
X+} /* end function readdir() */
X+
X+#endif /* NO_DIR */
X+
X+
X+/**********************/
X+/* Function do_wild() */   /* for porting: dir separator; match(ignore_case) */
X+/**********************/
X+
X+char *do_wild(__G__ wildspec)
X+    __GDEF
X+    ZCONST char *wildspec;  /* only used first time on a given dir */
X+{
X+/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in unxcfg.h:
X+    static DIR *wild_dir = (DIR *)NULL;
X+    static ZCONST char *wildname;
X+    static char *dirname, matchname[FILNAMSIZ];
X+    static int notfirstcall=FALSE, have_dirname, dirnamelen;
X+*/
X+    struct dirent *file;
X+
X+    /* Even when we're just returning wildspec, we *always* do so in
X+     * matchname[]--calling routine is allowed to append four characters
X+     * to the returned string, and wildspec may be a pointer to argv[].
X+     */
X+    if (!G.notfirstcall) {  /* first call:  must initialize everything */
X+        G.notfirstcall = TRUE;
X+
X+        if (!iswild(wildspec)) {
X+            strncpy(G.matchname, wildspec, FILNAMSIZ);
X+            G.matchname[FILNAMSIZ-1] = '\0';
X+            G.have_dirname = FALSE;
X+            G.wild_dir = NULL;
X+            return G.matchname;
X+        }
X+
X+        /* break the wildspec into a directory part and a wildcard filename */
X+        if ((G.wildname = (ZCONST char *)strrchr(wildspec, '/')) == NULL) {
X+            G.dirname = ".";
X+            G.dirnamelen = 1;
X+            G.have_dirname = FALSE;
X+            G.wildname = wildspec;
X+        } else {
X+            ++G.wildname;     /* point at character after '/' */
X+            G.dirnamelen = G.wildname - wildspec;
X+            if ((G.dirname = (char *)malloc(G.dirnamelen+1)) == (char *)NULL) {
X+                Info(slide, 0x201, ((char *)slide,
X+                  "warning:  cannot allocate wildcard buffers\n"));
X+                strncpy(G.matchname, wildspec, FILNAMSIZ);
X+                G.matchname[FILNAMSIZ-1] = '\0';
X+                return G.matchname; /* but maybe filespec was not a wildcard */
X+            }
X+            strncpy(G.dirname, wildspec, G.dirnamelen);
X+            G.dirname[G.dirnamelen] = '\0';   /* terminate for strcpy below */
X+            G.have_dirname = TRUE;
X+        }
X+
X+        if ((G.wild_dir = (zvoid *)opendir(G.dirname)) != (zvoid *)NULL) {
X+            while ((file = readdir((DIR *)G.wild_dir)) !=
X+                   (struct dirent *)NULL) {
X+                Trace((stderr, "do_wild:  readdir returns %s\n",
X+                  FnFilter1(file->d_name)));
X+                if (file->d_name[0] == '.' && G.wildname[0] != '.')
X+                    continue; /* Unix:  '*' and '?' do not match leading dot */
X+                if (match(file->d_name, G.wildname, 0 WISEP) &&/*0=case sens.*/
X+                    /* skip "." and ".." directory entries */
X+                    strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
X+                    Trace((stderr, "do_wild:  match() succeeds\n"));
X+                    if (G.have_dirname) {
X+                        strcpy(G.matchname, G.dirname);
X+                        strcpy(G.matchname+G.dirnamelen, file->d_name);
X+                    } else
X+                        strcpy(G.matchname, file->d_name);
X+                    return G.matchname;
X+                }
X+            }
X+            /* if we get to here directory is exhausted, so close it */
X+            closedir((DIR *)G.wild_dir);
X+            G.wild_dir = (zvoid *)NULL;
X+        }
X+        Trace((stderr, "do_wild:  opendir(%s) returns NULL\n",
X+          FnFilter1(G.dirname)));
X+
X+        /* return the raw wildspec in case that works (e.g., directory not
X+         * searchable, but filespec was not wild and file is readable) */
X+        strncpy(G.matchname, wildspec, FILNAMSIZ);
X+        G.matchname[FILNAMSIZ-1] = '\0';
X+        return G.matchname;
X+    }
X+
X+    /* last time through, might have failed opendir but returned raw wildspec */
X+    if ((DIR *)G.wild_dir == (DIR *)NULL) {
X+        G.notfirstcall = FALSE; /* nothing left--reset for new wildspec */
X+        if (G.have_dirname)
X+            free(G.dirname);
X+        return (char *)NULL;
X+    }
X+
X+    /* If we've gotten this far, we've read and matched at least one entry
X+     * successfully (in a previous call), so dirname has been copied into
X+     * matchname already.
X+     */
X+    while ((file = readdir((DIR *)G.wild_dir)) != (struct dirent *)NULL) {
X+        Trace((stderr, "do_wild:  readdir returns %s\n",
X+          FnFilter1(file->d_name)));
X+        if (file->d_name[0] == '.' && G.wildname[0] != '.')
X+            continue;   /* Unix:  '*' and '?' do not match leading dot */
X+        if (match(file->d_name, G.wildname, 0 WISEP)) { /* 0 == case sens. */
X+            Trace((stderr, "do_wild:  match() succeeds\n"));
X+            if (G.have_dirname) {
X+                /* strcpy(G.matchname, G.dirname); */
X+                strcpy(G.matchname+G.dirnamelen, file->d_name);
X+            } else
X+                strcpy(G.matchname, file->d_name);
X+            return G.matchname;
X+        }
X+    }
X+
X+    closedir((DIR *)G.wild_dir);  /* at least one entry read; nothing left */
X+    G.wild_dir = (zvoid *)NULL;
X+    G.notfirstcall = FALSE;       /* reset for new wildspec */
X+    if (G.have_dirname)
X+        free(G.dirname);
X+    return (char *)NULL;
X+
X+} /* end function do_wild() */
X+
X+#endif /* !SFX */
X+
X+
X+
X+
X+#ifndef S_ISUID
X+# define S_ISUID        0004000 /* set user id on execution */
X+#endif
X+#ifndef S_ISGID
X+# define S_ISGID        0002000 /* set group id on execution */
X+#endif
X+#ifndef	S_ISVTX
X+# define S_ISVTX        0001000 /* save swapped text even after use */
X+#endif
X+
X+/************************/
X+/*  Function filtattr() */
X+/************************/
X+/* This is used to clear or keep the SUID and GID bits on file permissions.
X+ * It's possible that a file in an archive could have one of these bits set
X+ * and, unknown to the person unzipping, could allow others to execute the
X+ * file as the user or group.  The new option -K bypasses this check.
X+ */
X+
X+static unsigned filtattr(__G__ perms)
X+    __GDEF
X+    unsigned perms;
X+{
X+    /* keep setuid/setgid/tacky perms? */
X+    if (!uO.K_flag)
X+        perms &= ~(S_ISUID | S_ISGID | S_ISVTX);
X+
X+    return (0xffff & perms);
X+} /* end function filtattr() */
X+
X+
X+
X+
X+
X+/**********************/
X+/* Function mapattr() */
X+/**********************/
X+
X+int mapattr(__G)
X+    __GDEF
X+{
X+    ulg tmp = G.crec.external_file_attributes;
X+
X+    G.pInfo->file_attr = 0;
X+    /* initialized to 0 for check in "default" branch below... */
X+
X+    switch (G.pInfo->hostnum) {
X+        case AMIGA_:
X+            tmp = (unsigned)(tmp>>17 & 7);   /* Amiga RWE bits */
X+            G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
X+            break;
X+        case THEOS_:
X+            tmp &= 0xF1FFFFFFL;
X+            if ((tmp & 0xF0000000L) != 0x40000000L)
X+                tmp &= 0x01FFFFFFL;     /* not a dir, mask all ftype bits */
X+            else
X+                tmp &= 0x41FFFFFFL;     /* leave directory bit as set */
X+            /* fall through! */
X+        case UNIX_:
X+        case VMS_:
X+        case ACORN_:
X+        case ATARI_:
X+        case ATHEOS_:
X+        case BEOS_:
X+        case QDOS_:
X+        case TANDEM_:
X+            G.pInfo->file_attr = (unsigned)(tmp >> 16);
X+            if (G.pInfo->file_attr != 0 || !G.extra_field) {
X+                return 0;
X+            } else {
X+                /* Some (non-Info-ZIP) implementations of Zip for Unix and
X+                 * VMS (and probably others ??) leave 0 in the upper 16-bit
X+                 * part of the external_file_attributes field. Instead, they
X+                 * store file permission attributes in some extra field.
X+                 * As a work-around, we search for the presence of one of
X+                 * these extra fields and fall back to the MSDOS compatible
X+                 * part of external_file_attributes if one of the known
X+                 * e.f. types has been detected.
X+                 * Later, we might implement extraction of the permission
X+                 * bits from the VMS extra field. But for now, the work-around
X+                 * should be sufficient to provide "readable" extracted files.
X+                 * (For ASI Unix e.f., an experimental remap of the e.f.
X+                 * mode value IS already provided!)
X+                 */
X+                ush ebID;
X+                unsigned ebLen;
X+                uch *ef = G.extra_field;
X+                unsigned ef_len = G.crec.extra_field_length;
X+                int r = FALSE;
X+
X+                while (!r && ef_len >= EB_HEADSIZE) {
X+                    ebID = makeword(ef);
X+                    ebLen = (unsigned)makeword(ef+EB_LEN);
X+                    if (ebLen > (ef_len - EB_HEADSIZE))
X+                        /* discoverd some e.f. inconsistency! */
X+                        break;
X+                    switch (ebID) {
X+                      case EF_ASIUNIX:
X+                        if (ebLen >= (EB_ASI_MODE+2)) {
X+                            G.pInfo->file_attr =
X+                              (unsigned)makeword(ef+(EB_HEADSIZE+EB_ASI_MODE));
X+                            /* force stop of loop: */
X+                            ef_len = (ebLen + EB_HEADSIZE);
X+                            break;
X+                        }
X+                        /* else: fall through! */
X+                      case EF_PKVMS:
X+                        /* "found nondecypherable e.f. with perm. attr" */
X+                        r = TRUE;
X+                      default:
X+                        break;
X+                    }
X+                    ef_len -= (ebLen + EB_HEADSIZE);
X+                    ef += (ebLen + EB_HEADSIZE);
X+                }
X+                if (!r)
X+                    return 0;
X+            }
X+            /* fall through! */
X+        /* all remaining cases:  expand MSDOS read-only bit into write perms */
X+        case FS_FAT_:
X+            /* PKWARE's PKZip for Unix marks entries as FS_FAT_, but stores the
X+             * Unix attributes in the upper 16 bits of the external attributes
X+             * field, just like Info-ZIP's Zip for Unix.  We try to use that
X+             * value, after a check for consistency with the MSDOS attribute
X+             * bits (see below).
X+             */
X+            G.pInfo->file_attr = (unsigned)(tmp >> 16);
X+            /* fall through! */
X+        case FS_HPFS_:
X+        case FS_NTFS_:
X+        case MAC_:
X+        case TOPS20_:
X+        default:
X+            /* Ensure that DOS subdir bit is set when the entry's name ends
X+             * in a '/'.  Some third-party Zip programs fail to set the subdir
X+             * bit for directory entries.
X+             */
X+            if ((tmp & 0x10) == 0) {
X+                extent fnlen = strlen(G.filename);
X+                if (fnlen > 0 && G.filename[fnlen-1] == '/')
X+                    tmp |= 0x10;
X+            }
X+            /* read-only bit --> write perms; subdir bit --> dir exec bit */
X+            tmp = !(tmp & 1) << 1  |  (tmp & 0x10) >> 4;
X+            if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6))
X+                /* keep previous G.pInfo->file_attr setting, when its "owner"
X+                 * part appears to be consistent with DOS attribute flags!
X+                 */
X+                return 0;
X+            G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
X+            break;
X+    } /* end switch (host-OS-created-by) */
X+
X+    /* for originating systems with no concept of "group," "other," "system": */
X+    umask( (int)(tmp=umask(0)) );    /* apply mask to expanded r/w(/x) perms */
X+    G.pInfo->file_attr &= ~tmp;
X+
X+    return 0;
X+
X+} /* end function mapattr() */
X+
X+
X+
X+
X+
X+/************************/
X+/*  Function mapname()  */
X+/************************/
X+
X+int mapname(__G__ renamed)
X+    __GDEF
X+    int renamed;
X+/*
X+ * returns:
X+ *  MPN_OK          - no problem detected
X+ *  MPN_INF_TRUNC   - caution (truncated filename)
X+ *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist)
X+ *  MPN_ERR_SKIP    - error -> skip entry
X+ *  MPN_ERR_TOOLONG - error -> path is too long
X+ *  MPN_NOMEM       - error (memory allocation failed) -> skip entry
X+ *  [also MPN_VOL_LABEL, MPN_CREATED_DIR]
X+ */
X+{
X+    char pathcomp[FILNAMSIZ];      /* path-component buffer */
X+    char *pp, *cp=(char *)NULL;    /* character pointers */
X+    char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */
X+#ifdef ACORN_FTYPE_NFS
X+    char *lastcomma=(char *)NULL;  /* pointer to last comma in pathcomp */
X+    RO_extra_block *ef_spark;      /* pointer Acorn FTYPE ef block */
X+#endif
X+    int killed_ddot = FALSE;       /* is set when skipping "../" pathcomp */
X+    int error = MPN_OK;
X+    register unsigned workch;      /* hold the character being tested */
X+
X+
X+/*---------------------------------------------------------------------------
X+    Initialize various pointers and counters and stuff.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (G.pInfo->vollabel)
X+        return MPN_VOL_LABEL;   /* can't set disk volume labels in Unix */
X+
X+    /* can create path as long as not just freshening, or if user told us */
X+    G.create_dirs = (!uO.fflag || renamed);
X+
X+    G.created_dir = FALSE;      /* not yet */
X+
X+    /* user gave full pathname:  don't prepend rootpath */
X+    G.renamed_fullpath = (renamed && (*G.filename == '/'));
X+
X+    if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
X+        return MPN_NOMEM;       /* initialize path buffer, unless no memory */
X+
X+    *pathcomp = '\0';           /* initialize translation buffer */
X+    pp = pathcomp;              /* point to translation buffer */
X+    if (uO.jflag)               /* junking directories */
X+        cp = (char *)strrchr(G.filename, '/');
X+    if (cp == (char *)NULL)     /* no '/' or not junking dirs */
X+        cp = G.filename;        /* point to internal zipfile-member pathname */
X+    else
X+        ++cp;                   /* point to start of last component of path */
X+
X+/*---------------------------------------------------------------------------
X+    Begin main loop through characters in filename.
X+  ---------------------------------------------------------------------------*/
X+
X+    while ((workch = (uch)*cp++) != 0) {
X+
X+        switch (workch) {
X+            case '/':             /* can assume -j flag not given */
X+                *pp = '\0';
X+                if (strcmp(pathcomp, ".") == 0) {
X+                    /* don't bother appending "./" to the path */
X+                    *pathcomp = '\0';
X+                } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {
X+                    /* "../" dir traversal detected, skip over it */
X+                    *pathcomp = '\0';
X+                    killed_ddot = TRUE;     /* set "show message" flag */
X+                }
X+                /* when path component is not empty, append it now */
X+                if (*pathcomp != '\0' &&
X+                    ((error = checkdir(__G__ pathcomp, APPEND_DIR))
X+                     & MPN_MASK) > MPN_INF_TRUNC)
X+                    return error;
X+                pp = pathcomp;    /* reset conversion buffer for next piece */
X+                lastsemi = (char *)NULL; /* leave direct. semi-colons alone */
X+                break;
X+
X+#ifdef __CYGWIN__   /* Cygwin runs on Win32, apply FAT/NTFS filename rules */
X+            case ':':         /* drive spec not stored, so no colon allowed */
X+            case '\\':        /* '\\' may come as normal filename char (not */
X+            case '<':         /*  dir sep char!) from unix-like file system */
X+            case '>':         /* no redirection symbols allowed either */
X+            case '|':         /* no pipe signs allowed */
X+            case '"':         /* no double quotes allowed */
X+            case '?':         /* no wildcards allowed */
X+            case '*':
X+                *pp++ = '_';  /* these rules apply equally to FAT and NTFS */
X+                break;
X+#endif
X+
X+            case ';':             /* VMS version (or DEC-20 attrib?) */
X+                lastsemi = pp;
X+                *pp++ = ';';      /* keep for now; remove VMS ";##" */
X+                break;            /*  later, if requested */
X+
X+#ifdef ACORN_FTYPE_NFS
X+            case ',':             /* NFS filetype extension */
X+                lastcomma = pp;
X+                *pp++ = ',';      /* keep for now; may need to remove */
X+                break;            /*  later, if requested */
X+#endif
X+
X+#ifdef MTS
X+            case ' ':             /* change spaces to underscore under */
X+                *pp++ = '_';      /*  MTS; leave as spaces under Unix */
X+                break;
X+#endif
X+
X+            default:
X+                /* allow European characters in filenames: */
X+                if (isprint(workch) || (128 <= workch && workch <= 254))
X+                    *pp++ = (char)workch;
X+        } /* end switch */
X+
X+    } /* end while loop */
X+
X+    /* Show warning when stripping insecure "parent dir" path components */
X+    if (killed_ddot && QCOND2) {
X+        Info(slide, 0, ((char *)slide,
X+          "warning:  skipped \"../\" path component(s) in %s\n",
X+          FnFilter1(G.filename)));
X+        if (!(error & ~MPN_MASK))
X+            error = (error & MPN_MASK) | PK_WARN;
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Report if directory was created (and no file to create:  filename ended
X+    in '/'), check name to be sure it exists, and combine path and name be-
X+    fore exiting.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (G.filename[strlen(G.filename) - 1] == '/') {
X+        checkdir(__G__ G.filename, GETPATH);
X+        if (G.created_dir) {
X+            if (QCOND2) {
X+                Info(slide, 0, ((char *)slide, "   creating: %s\n",
X+                  FnFilter1(G.filename)));
X+            }
X+#ifndef NO_CHMOD
X+            /* set approx. dir perms (make sure can still read/write in dir) */
X+            if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr) | 0700))
X+                perror("chmod (directory attributes) error");
X+#endif
X+            /* set dir time (note trailing '/') */
X+            return (error & ~MPN_MASK) | MPN_CREATED_DIR;
X+        }
X+        /* dir existed already; don't look for data to extract */
X+        return (error & ~MPN_MASK) | MPN_INF_SKIP;
X+    }
X+
X+    *pp = '\0';                   /* done with pathcomp:  terminate it */
X+
X+    /* if not saving them, remove VMS version numbers (appended ";###") */
X+    if (!uO.V_flag && lastsemi) {
X+        pp = lastsemi + 1;
X+        while (isdigit((uch)(*pp)))
X+            ++pp;
X+        if (*pp == '\0')          /* only digits between ';' and end:  nuke */
X+            *lastsemi = '\0';
X+    }
X+
X+#ifdef ACORN_FTYPE_NFS
X+    /* translate Acorn filetype information if asked to do so */
X+    if (uO.acorn_nfs_ext &&
X+        (ef_spark = (RO_extra_block *)
X+                    getRISCOSexfield(G.extra_field, G.lrec.extra_field_length))
X+        != (RO_extra_block *)NULL)
X+    {
X+        /* file *must* have a RISC OS extra field */
X+        long ft = (long)makelong(ef_spark->loadaddr);
X+        /*32-bit*/
X+        if (lastcomma) {
X+            pp = lastcomma + 1;
X+            while (isxdigit((uch)(*pp))) ++pp;
X+            if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */
X+        }
X+        if ((ft & 1<<31)==0) ft=0x000FFD00;
X+        sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF);
X+    }
X+#endif /* ACORN_FTYPE_NFS */
X+
X+    if (*pathcomp == '\0') {
X+        Info(slide, 1, ((char *)slide, "mapname:  conversion of %s failed\n",
X+          FnFilter1(G.filename)));
X+        return (error & ~MPN_MASK) | MPN_ERR_SKIP;
X+    }
X+
X+    checkdir(__G__ pathcomp, APPEND_NAME);  /* returns 1 if truncated: care? */
X+    checkdir(__G__ G.filename, GETPATH);
X+
X+    return error;
X+
X+} /* end function mapname() */
X+
X+
X+
X+
X+#if 0  /*========== NOTES ==========*/
X+
X+  extract-to dir:      a:path/
X+  buildpath:           path1/path2/ ...   (NULL-terminated)
X+  pathcomp:                filename
X+
X+  mapname():
X+    loop over chars in zipfile member name
X+      checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
X+        (d:/tmp/unzip/)                    (disk:[tmp.unzip.)
X+        (d:/tmp/unzip/jj/)                 (disk:[tmp.unzip.jj.)
X+        (d:/tmp/unzip/jj/temp/)            (disk:[tmp.unzip.jj.temp.)
X+    finally add filename itself and check for existence? (could use with rename)
X+        (d:/tmp/unzip/jj/temp/msg.outdir)  (disk:[tmp.unzip.jj.temp]msg.outdir)
X+    checkdir(name, GETPATH)     -->  copy path to name and free space
X+
X+#endif /* 0 */
X+
X+
X+
X+
X+/***********************/
X+/* Function checkdir() */
X+/***********************/
X+
X+int checkdir(__G__ pathcomp, flag)
X+    __GDEF
X+    char *pathcomp;
X+    int flag;
X+/*
X+ * returns:
X+ *  MPN_OK          - no problem detected
X+ *  MPN_INF_TRUNC   - (on APPEND_NAME) truncated filename
X+ *  MPN_INF_SKIP    - path doesn't exist, not allowed to create
X+ *  MPN_ERR_SKIP    - path doesn't exist, tried to create and failed; or path
X+ *                    exists and is not a directory, but is supposed to be
X+ *  MPN_ERR_TOOLONG - path is too long
X+ *  MPN_NOMEM       - can't allocate memory for filename buffers
X+ */
X+{
X+ /* static int rootlen = 0; */  /* length of rootpath */
X+ /* static char *rootpath;  */  /* user's "extract-to" directory */
X+ /* static char *buildpath; */  /* full path (so far) to extracted file */
X+ /* static char *end;       */  /* pointer to end of buildpath ('\0') */
X+
X+#   define FN_MASK   7
X+#   define FUNCTION  (flag & FN_MASK)
X+
X+
X+
X+/*---------------------------------------------------------------------------
X+    APPEND_DIR:  append the path component to the path being built and check
X+    for its existence.  If doesn't exist and we are creating directories, do
X+    so for this one; else signal success or error as appropriate.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (FUNCTION == APPEND_DIR) {
X+        int too_long = FALSE;
X+#ifdef SHORT_NAMES
X+        char *old_end = end;
X+#endif
X+
X+        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
X+        while ((*G.end = *pathcomp++) != '\0')
X+            ++G.end;
X+#ifdef SHORT_NAMES   /* path components restricted to 14 chars, typically */
X+        if ((G.end-old_end) > FILENAME_MAX)  /* GRR:  proper constant? */
X+            *(G.end = old_end + FILENAME_MAX) = '\0';
X+#endif
X+
X+        /* GRR:  could do better check, see if overrunning buffer as we go:
X+         * check end-buildpath after each append, set warning variable if
X+         * within 20 of FILNAMSIZ; then if var set, do careful check when
X+         * appending.  Clear variable when begin new path. */
X+
X+        /* next check: need to append '/', at least one-char name, '\0' */
X+        if ((G.end-G.buildpath) > FILNAMSIZ-3)
X+            too_long = TRUE;                    /* check if extracting dir? */
X+        if (SSTAT(G.buildpath, &G.statbuf)) {   /* path doesn't exist */
X+            if (!G.create_dirs) { /* told not to create (freshening) */
X+                free(G.buildpath);
X+                return MPN_INF_SKIP;    /* path doesn't exist: nothing to do */
X+            }
X+            if (too_long) {
X+                Info(slide, 1, ((char *)slide,
X+                  "checkdir error:  path too long: %s\n",
X+                  FnFilter1(G.buildpath)));
X+                free(G.buildpath);
X+                /* no room for filenames:  fatal */
X+                return MPN_ERR_TOOLONG;
X+            }
X+            if (mkdir(G.buildpath, 0777) == -1) {   /* create the directory */
X+                Info(slide, 1, ((char *)slide,
X+                  "checkdir error:  cannot create %s\n\
X+                 unable to process %s.\n",
X+                  FnFilter2(G.buildpath), FnFilter1(G.filename)));
X+                free(G.buildpath);
X+                /* path didn't exist, tried to create, failed */
X+                return MPN_ERR_SKIP;
X+            }
X+            G.created_dir = TRUE;
X+        } else if (!S_ISDIR(G.statbuf.st_mode)) {
X+            Info(slide, 1, ((char *)slide,
X+              "checkdir error:  %s exists but is not directory\n\
X+                 unable to process %s.\n",
X+              FnFilter2(G.buildpath), FnFilter1(G.filename)));
X+            free(G.buildpath);
X+            /* path existed but wasn't dir */
X+            return MPN_ERR_SKIP;
X+        }
X+        if (too_long) {
X+            Info(slide, 1, ((char *)slide,
X+              "checkdir error:  path too long: %s\n", FnFilter1(G.buildpath)));
X+            free(G.buildpath);
X+            /* no room for filenames:  fatal */
X+            return MPN_ERR_TOOLONG;
X+        }
X+        *G.end++ = '/';
X+        *G.end = '\0';
X+        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
X+        return MPN_OK;
X+
X+    } /* end if (FUNCTION == APPEND_DIR) */
X+
X+/*---------------------------------------------------------------------------
X+    GETPATH:  copy full path to the string pointed at by pathcomp, and free
X+    G.buildpath.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (FUNCTION == GETPATH) {
X+        strcpy(pathcomp, G.buildpath);
X+        Trace((stderr, "getting and freeing path [%s]\n",
X+          FnFilter1(pathcomp)));
X+        free(G.buildpath);
X+        G.buildpath = G.end = (char *)NULL;
X+        return MPN_OK;
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    APPEND_NAME:  assume the path component is the filename; append it and
X+    return without checking for existence.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (FUNCTION == APPEND_NAME) {
X+#ifdef SHORT_NAMES
X+        char *old_end = end;
X+#endif
X+
X+        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
X+        while ((*G.end = *pathcomp++) != '\0') {
X+            ++G.end;
X+#ifdef SHORT_NAMES  /* truncate name at 14 characters, typically */
X+            if ((G.end-old_end) > FILENAME_MAX)    /* GRR:  proper constant? */
X+                *(G.end = old_end + FILENAME_MAX) = '\0';
X+#endif
X+            if ((G.end-G.buildpath) >= FILNAMSIZ) {
X+                *--G.end = '\0';
X+                Info(slide, 0x201, ((char *)slide,
X+                  "checkdir warning:  path too long; truncating\n\
X+                   %s\n                -> %s\n",
X+                  FnFilter1(G.filename), FnFilter2(G.buildpath)));
X+                return MPN_INF_TRUNC;   /* filename truncated */
X+            }
X+        }
X+        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
X+        /* could check for existence here, prompt for new name... */
X+        return MPN_OK;
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    INIT:  allocate and initialize buffer space for the file currently being
X+    extracted.  If file was renamed with an absolute path, don't prepend the
X+    extract-to path.
X+  ---------------------------------------------------------------------------*/
X+
X+/* GRR:  for VMS and TOPS-20, add up to 13 to strlen */
X+
X+    if (FUNCTION == INIT) {
X+        Trace((stderr, "initializing buildpath to "));
X+#ifdef ACORN_FTYPE_NFS
X+        if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+
X+                                          (uO.acorn_nfs_ext ? 5 : 1)))
X+#else
X+        if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+1))
X+#endif
X+            == (char *)NULL)
X+            return MPN_NOMEM;
X+        if ((G.rootlen > 0) && !G.renamed_fullpath) {
X+            strcpy(G.buildpath, G.rootpath);
X+            G.end = G.buildpath + G.rootlen;
X+        } else {
X+            *G.buildpath = '\0';
X+            G.end = G.buildpath;
X+        }
X+        Trace((stderr, "[%s]\n", FnFilter1(G.buildpath)));
X+        return MPN_OK;
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    ROOT:  if appropriate, store the path in rootpath and create it if
X+    necessary; else assume it's a zipfile member and return.  This path
X+    segment gets used in extracting all members from every zipfile specified
X+    on the command line.
X+  ---------------------------------------------------------------------------*/
X+
X+#if (!defined(SFX) || defined(SFX_EXDIR))
X+    if (FUNCTION == ROOT) {
X+        Trace((stderr, "initializing root path to [%s]\n",
X+          FnFilter1(pathcomp)));
X+        if (pathcomp == (char *)NULL) {
X+            G.rootlen = 0;
X+            return MPN_OK;
X+        }
X+        if (G.rootlen > 0)      /* rootpath was already set, nothing to do */
X+            return MPN_OK;
X+        if ((G.rootlen = strlen(pathcomp)) > 0) {
X+            char *tmproot;
X+
X+            if ((tmproot = (char *)malloc(G.rootlen+2)) == (char *)NULL) {
X+                G.rootlen = 0;
X+                return MPN_NOMEM;
X+            }
X+            strcpy(tmproot, pathcomp);
X+            if (tmproot[G.rootlen-1] == '/') {
X+                tmproot[--G.rootlen] = '\0';
X+            }
X+            if (G.rootlen > 0 && (SSTAT(tmproot, &G.statbuf) ||
X+                                  !S_ISDIR(G.statbuf.st_mode)))
X+            {   /* path does not exist */
X+                if (!G.create_dirs /* || iswild(tmproot) */ ) {
X+                    free(tmproot);
X+                    G.rootlen = 0;
X+                    /* skip (or treat as stored file) */
X+                    return MPN_INF_SKIP;
X+                }
X+                /* create the directory (could add loop here scanning tmproot
X+                 * to create more than one level, but why really necessary?) */
X+                if (mkdir(tmproot, 0777) == -1) {
X+                    Info(slide, 1, ((char *)slide,
X+                      "checkdir:  cannot create extraction directory: %s\n",
X+                      FnFilter1(tmproot)));
X+                    free(tmproot);
X+                    G.rootlen = 0;
X+                    /* path didn't exist, tried to create, and failed: */
X+                    /* file exists, or 2+ subdir levels required */
X+                    return MPN_ERR_SKIP;
X+                }
X+            }
X+            tmproot[G.rootlen++] = '/';
X+            tmproot[G.rootlen] = '\0';
X+            if ((G.rootpath = (char *)realloc(tmproot, G.rootlen+1)) == NULL) {
X+                free(tmproot);
X+                G.rootlen = 0;
X+                return MPN_NOMEM;
X+            }
X+            Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath)));
X+        }
X+        return MPN_OK;
X+    }
X+#endif /* !SFX || SFX_EXDIR */
X+
X+/*---------------------------------------------------------------------------
X+    END:  free rootpath, immediately prior to program exit.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (FUNCTION == END) {
X+        Trace((stderr, "freeing rootpath\n"));
X+        if (G.rootlen > 0) {
X+            free(G.rootpath);
X+            G.rootlen = 0;
X+        }
X+        return MPN_OK;
X+    }
X+
X+    return MPN_INVALID; /* should never reach */
X+
X+} /* end function checkdir() */
X+
X+
X+
X+
X+
X+#ifdef NO_MKDIR
X+
X+/********************/
X+/* Function mkdir() */
X+/********************/
X+
X+int mkdir(path, mode)
X+    ZCONST char *path;
X+    int mode;   /* ignored */
X+/*
X+ * returns:   0 - successful
X+ *           -1 - failed (errno not set, however)
X+ */
X+{
X+    char command[FILNAMSIZ+40]; /* buffer for system() call */
X+
X+    /* GRR 930416:  added single quotes around path to avoid bug with
X+     * creating directories with ampersands in name; not yet tested */
X+    sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
X+    if (system(command))
X+        return -1;
X+    return 0;
X+}
X+
X+#endif /* NO_MKDIR */
X+
X+
X+
X+
X+#if (!defined(MTS) || defined(SET_DIR_ATTRIB))
X+static int get_extattribs OF((__GPRO__ iztimes *pzt, ush z_uidgid[2]));
X+
X+static int get_extattribs(__G__ pzt, z_uidgid)
X+    __GDEF
X+    iztimes *pzt;
X+    ush z_uidgid[2];
X+{
X+/*---------------------------------------------------------------------------
X+    Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
X+    time:  adjust base year from 1980 to 1970, do usual conversions from
X+    yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
X+    light savings time differences.  If we have a Unix extra field, however,
X+    we're laughing:  both mtime and atime are ours.  On the other hand, we
X+    then have to check for restoration of UID/GID.
X+  ---------------------------------------------------------------------------*/
X+    int have_uidgid_flg;
X+    unsigned eb_izux_flg;
X+
X+    eb_izux_flg = (G.extra_field ? ef_scan_for_izux(G.extra_field,
X+                   G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
X+#ifdef IZ_CHECK_TZ
X+                   (G.tz_is_valid ? pzt : NULL),
X+#else
X+                   pzt,
X+#endif
X+                   z_uidgid) : 0);
X+    if (eb_izux_flg & EB_UT_FL_MTIME) {
X+        TTrace((stderr, "\nget_extattribs:  Unix e.f. modif. time = %ld\n",
X+          pzt->mtime));
X+    } else {
X+        pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
X+    }
X+    if (eb_izux_flg & EB_UT_FL_ATIME) {
X+        TTrace((stderr, "get_extattribs:  Unix e.f. access time = %ld\n",
X+          pzt->atime));
X+    } else {
X+        pzt->atime = pzt->mtime;
X+        TTrace((stderr, "\nget_extattribs:  modification/access times = %ld\n",
X+          pzt->mtime));
X+    }
X+
X+    /* if -X option was specified and we have UID/GID info, restore it */
X+    have_uidgid_flg =
X+#ifdef RESTORE_UIDGID
X+            (uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
X+#else
X+            0;
X+#endif
X+    return have_uidgid_flg;
X+}
X+#endif /* !MTS || SET_DIR_ATTRIB */
X+
X+
X+
X+#ifndef MTS
X+
X+/****************************/
X+/* Function close_outfile() */
X+/****************************/
X+
X+void close_outfile(__G)    /* GRR: change to return PK-style warning level */
X+    __GDEF
X+{
X+    union {
X+        iztimes t3;             /* mtime, atime, ctime */
X+        ztimbuf t2;             /* modtime, actime */
X+    } zt;
X+    ush z_uidgid[2];
X+    int have_uidgid_flg;
X+
X+    fclose(G.outfile);
X+
X+/*---------------------------------------------------------------------------
X+    If symbolic links are supported, allocate storage for a symlink control
X+    structure, put the uncompressed "data" and other required info in it, and
X+    add the structure to the "deferred symlinks" chain.  Since we know it's a
X+    symbolic link to start with, we shouldn't have to worry about overflowing
X+    unsigned ints with unsigned longs.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef SYMLINKS
X+    if (G.symlnk) {
X+        unsigned ucsize = (unsigned)G.lrec.ucsize;
X+        extent slnk_entrysize = sizeof(slinkentry) + ucsize +
X+                                strlen(G.filename);
X+        slinkentry *slnk_entry;
X+
X+        if ((unsigned)slnk_entrysize < ucsize) {
X+            Info(slide, 0x201, ((char *)slide,
X+              "warning:  symbolic link (%s) failed: mem alloc overflow\n",
X+              FnFilter1(G.filename)));
X+            return;
X+        }
X+
X+        if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
X+            Info(slide, 0x201, ((char *)slide,
X+              "warning:  symbolic link (%s) failed: no mem\n",
X+              FnFilter1(G.filename)));
X+            return;
X+        }
X+        slnk_entry->next = NULL;
X+        slnk_entry->targetlen = ucsize;
X+        slnk_entry->attriblen = 0;      /* don't set attributes for symlinks */
X+        slnk_entry->target = slnk_entry->buf;
X+        slnk_entry->fname = slnk_entry->target + ucsize + 1;
X+        strcpy(slnk_entry->fname, G.filename);
X+
X+        /* reopen the "link data" file for reading */
X+        G.outfile = fopen(G.filename, FOPR);
X+
X+        if (!G.outfile ||
X+            fread(slnk_entry->target, 1, ucsize, G.outfile) != (int)ucsize)
X+        {
X+            Info(slide, 0x201, ((char *)slide,
X+              "warning:  symbolic link (%s) failed\n",
X+              FnFilter1(G.filename)));
X+            free(slnk_entry);
X+            fclose(G.outfile);
X+            return;
X+        }
X+        fclose(G.outfile);                  /* close "link" file for good... */
X+        slnk_entry->target[ucsize] = '\0';
X+        if (QCOND2)
X+            Info(slide, 0, ((char *)slide, "-> %s ",
X+              FnFilter1(slnk_entry->target)));
X+        /* add this symlink record to the list of deferred symlinks */
X+        if (G.slink_last != NULL)
X+            G.slink_last->next = slnk_entry;
X+        else
X+            G.slink_head = slnk_entry;
X+        G.slink_last = slnk_entry;
X+        return;
X+    }
X+#endif /* SYMLINKS */
X+
X+#ifdef QLZIP
X+    if (G.extra_field) {
X+        static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len));
X+
X+        qlfix(__G__ G.extra_field, G.lrec.extra_field_length);
X+    }
X+#endif
X+
X+    have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
X+
X+    /* if -X option was specified and we have UID/GID info, restore it */
X+    if (have_uidgid_flg) {
X+        TTrace((stderr, "close_outfile:  restoring Unix UID/GID info\n"));
X+        if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
X+        {
X+            if (uO.qflag)
X+                Info(slide, 0x201, ((char *)slide,
X+                  "warning:  cannot set UID %d and/or GID %d for %s\n",
X+                  z_uidgid[0], z_uidgid[1], FnFilter1(G.filename)));
X+            else
X+                Info(slide, 0x201, ((char *)slide,
X+                  " (warning) cannot set UID %d and/or GID %d",
X+                  z_uidgid[0], z_uidgid[1]));
X+        }
X+    }
X+
X+    /* set the file's access and modification times */
X+    if (utime(G.filename, &(zt.t2))) {
X+#ifdef AOS_VS
X+        if (uO.qflag)
X+            Info(slide, 0x201, ((char *)slide, "... cannot set time for %s\n",
X+              FnFilter1(G.filename)));
X+        else
X+            Info(slide, 0x201, ((char *)slide, "... cannot set time"));
X+#else
X+        if (uO.qflag)
X+            Info(slide, 0x201, ((char *)slide,
X+              "warning:  cannot set times for %s\n", FnFilter1(G.filename)));
X+        else
X+            Info(slide, 0x201, ((char *)slide,
X+              " (warning) cannot set times"));
X+#endif /* ?AOS_VS */
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Change the file permissions from default ones to those stored in the
X+    zipfile.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef NO_CHMOD
X+    if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr)))
X+        perror("chmod (file attributes) error");
X+#endif
X+
X+} /* end function close_outfile() */
X+
X+#endif /* !MTS */
X+
X+
X+#ifdef SET_DIR_ATTRIB
X+/* messages of code for setting directory attributes */
X+static ZCONST char Far DirlistUidGidFailed[] =
X+  "warning:  cannot set UID %d and/or GID %d for %s\n";
X+static ZCONST char Far DirlistUtimeFailed[] =
X+  "warning:  cannot set modification, access times for %s\n";
X+#  ifndef NO_CHMOD
X+  static ZCONST char Far DirlistChmodFailed[] =
X+    "warning:  cannot set permissions for %s\n";
X+#  endif
X+
X+
X+int defer_dir_attribs(__G__ pd)
X+    __GDEF
X+    direntry **pd;
X+{
X+    uxdirattr *d_entry;
X+
X+    d_entry = (uxdirattr *)malloc(sizeof(uxdirattr) + strlen(G.filename));
X+    *pd = (direntry *)d_entry;
X+    if (d_entry == (uxdirattr *)NULL) {
X+        return PK_MEM;
X+    }
X+    d_entry->fn = d_entry->fnbuf;
X+    strcpy(d_entry->fn, G.filename);
X+
X+    d_entry->perms = G.pInfo->file_attr;
X+
X+    d_entry->have_uidgid = get_extattribs(__G__ &(d_entry->u.t3),
X+                                          d_entry->uidgid);
X+    return PK_OK;
X+} /* end function defer_dir_attribs() */
X+
X+
X+int set_direc_attribs(__G__ d)
X+    __GDEF
X+    direntry *d;
X+{
X+    int errval = PK_OK;
X+
X+    if (UxAtt(d)->have_uidgid &&
X+        chown(UxAtt(d)->fn, (uid_t)UxAtt(d)->uidgid[0],
X+              (gid_t)UxAtt(d)->uidgid[1]))
X+    {
X+        Info(slide, 0x201, ((char *)slide,
X+          LoadFarString(DirlistUidGidFailed),
X+          UxAtt(d)->uidgid[0], UxAtt(d)->uidgid[1], FnFilter1(d->fn)));
X+        if (!errval)
X+            errval = PK_WARN;
X+    }
X+    if (utime(d->fn, &UxAtt(d)->u.t2)) {
X+        Info(slide, 0x201, ((char *)slide,
X+          LoadFarString(DirlistUtimeFailed), FnFilter1(d->fn)));
X+        if (!errval)
X+            errval = PK_WARN;
X+    }
X+#ifndef NO_CHMOD
X+    if (chmod(d->fn, filtattr(__G__ UxAtt(d)->perms))) {
X+        Info(slide, 0x201, ((char *)slide,
X+          LoadFarString(DirlistChmodFailed), FnFilter1(d->fn)));
X+        /* perror("chmod (file attributes) error"); */
X+        if (!errval)
X+            errval = PK_WARN;
X+    }
X+#endif /* !NO_CHMOD */
X+    return errval;
X+} /* end function set_direc_attribs() */
X+
X+#endif /* SET_DIR_ATTRIB */
X+
X+
X+
X+
X+#ifdef TIMESTAMP
X+
X+/***************************/
X+/*  Function stamp_file()  */
X+/***************************/
X+
X+int stamp_file(fname, modtime)
X+    ZCONST char *fname;
X+    time_t modtime;
X+{
X+    ztimbuf tp;
X+
X+    tp.modtime = tp.actime = modtime;
X+    return (utime(fname, &tp));
X+
X+} /* end function stamp_file() */
X+
X+#endif /* TIMESTAMP */
X+
X+
X+
X+
X+#ifndef SFX
X+
X+/************************/
X+/*  Function version()  */
X+/************************/
X+
X+void version(__G)
X+    __GDEF
X+{
X+#if (defined(__GNUC__) && defined(NX_CURRENT_COMPILER_RELEASE))
X+    char cc_namebuf[40];
X+    char cc_versbuf[40];
X+#else
X+#if (defined(CRAY) && defined(_RELEASE))
X+    char cc_versbuf[40];
X+#endif
X+#endif
X+#if ((defined(CRAY) || defined(cray)) && defined(_UNICOS))
X+    char os_namebuf[40];
X+#else
X+#if defined(__NetBSD__)
X+    char os_namebuf[40];
X+#endif
X+#endif
X+
X+    /* Pyramid, NeXT have problems with huge macro expansion, too:  no Info() */
X+    sprintf((char *)slide, LoadFarString(CompiledWith),
X+
X+#ifdef __GNUC__
X+#  ifdef NX_CURRENT_COMPILER_RELEASE
X+      (sprintf(cc_namebuf, "NeXT DevKit %d.%02d ",
X+        NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100),
X+       cc_namebuf),
X+      (strlen(__VERSION__) > 8)? "(gcc)" :
X+        (sprintf(cc_versbuf, "(gcc %s)", __VERSION__), cc_versbuf),
X+#  else
X+      "gcc ", __VERSION__,
X+#  endif
X+#else
X+#  if defined(CRAY) && defined(_RELEASE)
X+      "cc ", (sprintf(cc_versbuf, "version %d", _RELEASE), cc_versbuf),
X+#  else
X+#  ifdef __VERSION__
X+#   ifndef IZ_CC_NAME
X+#    define IZ_CC_NAME "cc "
X+#   endif
X+      IZ_CC_NAME, __VERSION__
X+#  else
X+#   ifndef IZ_CC_NAME
X+#    define IZ_CC_NAME "cc"
X+#   endif
X+      IZ_CC_NAME, "",
X+#  endif
X+#  endif
X+#endif /* ?__GNUC__ */
X+
X+#ifndef IZ_OS_NAME
X+#  define IZ_OS_NAME "Unix"
X+#endif
X+      IZ_OS_NAME,
X+
X+#if defined(sgi) || defined(__sgi)
X+      " (Silicon Graphics IRIX)",
X+#else
X+#ifdef sun
X+#  ifdef sparc
X+#    ifdef __SVR4
X+      " (Sun SPARC/Solaris)",
X+#    else /* may or may not be SunOS */
X+      " (Sun SPARC)",
X+#    endif
X+#  else
X+#  if defined(sun386) || defined(i386)
X+      " (Sun 386i)",
X+#  else
X+#  if defined(mc68020) || defined(__mc68020__)
X+      " (Sun 3)",
X+#  else /* mc68010 or mc68000:  Sun 2 or earlier */
X+      " (Sun 2)",
X+#  endif
X+#  endif
X+#  endif
X+#else
X+#ifdef __hpux
X+      " (HP/UX)",
X+#else
X+#ifdef __osf__
X+      " (DEC OSF/1)",
X+#else
X+#ifdef _AIX
X+      " (IBM AIX)",
X+#else
X+#ifdef aiws
X+      " (IBM RT/AIX)",
X+#else
X+#if defined(CRAY) || defined(cray)
X+#  ifdef _UNICOS
X+      (sprintf(os_namebuf, " (Cray UNICOS release %d)", _UNICOS), os_namebuf),
X+#  else
X+      " (Cray UNICOS)",
X+#  endif
X+#else
X+#if defined(uts) || defined(UTS)
X+      " (Amdahl UTS)",
X+#else
X+#ifdef NeXT
X+#  ifdef mc68000
X+      " (NeXTStep/black)",
X+#  else
X+      " (NeXTStep for Intel)",
X+#  endif
X+#else              /* the next dozen or so are somewhat order-dependent */
X+#ifdef LINUX
X+#  ifdef __ELF__
X+      " (Linux ELF)",
X+#  else
X+      " (Linux a.out)",
X+#  endif
X+#else
X+#ifdef MINIX
X+      " (Minix)",
X+#else
X+#ifdef M_UNIX
X+      " (SCO Unix)",
X+#else
X+#ifdef M_XENIX
X+      " (SCO Xenix)",
X+#else
X+#ifdef __NetBSD__
X+#  ifdef NetBSD0_8
X+      (sprintf(os_namebuf, " (NetBSD 0.8%c)", (char)(NetBSD0_8 - 1 + 'A')),
X+       os_namebuf),
X+#  else
X+#  ifdef NetBSD0_9
X+      (sprintf(os_namebuf, " (NetBSD 0.9%c)", (char)(NetBSD0_9 - 1 + 'A')),
X+       os_namebuf),
X+#  else
X+#  ifdef NetBSD1_0
X+      (sprintf(os_namebuf, " (NetBSD 1.0%c)", (char)(NetBSD1_0 - 1 + 'A')),
X+       os_namebuf),
X+#  else
X+      (BSD4_4 == 0.5)? " (NetBSD before 0.9)" : " (NetBSD 1.1 or later)",
X+#  endif
X+#  endif
X+#  endif
X+#else
X+#ifdef __FreeBSD__
X+      (BSD4_4 == 0.5)? " (FreeBSD 1.x)" : " (FreeBSD 2.0 or later)",
X+#else
X+#ifdef __bsdi__
X+      (BSD4_4 == 0.5)? " (BSD/386 1.0)" : " (BSD/386 1.1 or later)",
X+#else
X+#ifdef __386BSD__
X+      (BSD4_4 == 1)? " (386BSD, post-4.4 release)" : " (386BSD)",
X+#else
X+#ifdef __CYGWIN__
X+      " (Cygwin)",
X+#else
X+#if defined(i686) || defined(__i686) || defined(__i686__)
X+      " (Intel 686)",
X+#else
X+#if defined(i586) || defined(__i586) || defined(__i586__)
X+      " (Intel 586)",
X+#else
X+#if defined(i486) || defined(__i486) || defined(__i486__)
X+      " (Intel 486)",
X+#else
X+#if defined(i386) || defined(__i386) || defined(__i386__)
X+      " (Intel 386)",
X+#else
X+#ifdef pyr
X+      " (Pyramid)",
X+#else
X+#ifdef ultrix
X+#  ifdef mips
X+      " (DEC/MIPS)",
X+#  else
X+#  ifdef vax
X+      " (DEC/VAX)",
X+#  else /* __alpha? */
X+      " (DEC/Alpha)",
X+#  endif
X+#  endif
X+#else
X+#ifdef gould
X+      " (Gould)",
X+#else
X+#ifdef MTS
X+      " (MTS)",
X+#else
X+#ifdef __convexc__
X+      " (Convex)",
X+#else
X+#ifdef __QNX__
X+      " (QNX 4)",
X+#else
X+#ifdef __QNXNTO__
X+      " (QNX Neutrino)",
X+#else
X+#ifdef Lynx
X+      " (LynxOS)",
X+#else
X+      "",
X+#endif /* Lynx */
X+#endif /* QNX Neutrino */
X+#endif /* QNX 4 */
X+#endif /* Convex */
X+#endif /* MTS */
X+#endif /* Gould */
X+#endif /* DEC */
X+#endif /* Pyramid */
X+#endif /* 386 */
X+#endif /* 486 */
X+#endif /* 586 */
X+#endif /* 686 */
X+#endif /* Cygwin */
X+#endif /* 386BSD */
X+#endif /* BSDI BSD/386 */
X+#endif /* NetBSD */
X+#endif /* FreeBSD */
X+#endif /* SCO Xenix */
X+#endif /* SCO Unix */
X+#endif /* Minix */
X+#endif /* Linux */
X+#endif /* NeXT */
X+#endif /* Amdahl */
X+#endif /* Cray */
X+#endif /* RT/AIX */
X+#endif /* AIX */
X+#endif /* OSF/1 */
X+#endif /* HP/UX */
X+#endif /* Sun */
X+#endif /* SGI */
X+
X+#ifdef __DATE__
X+      " on ", __DATE__
X+#else
X+      "", ""
X+#endif
X+    );
X+
X+    (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
X+
X+} /* end function version() */
X+
X+#endif /* !SFX */
X+
X+
X+
X+
X+#ifdef QLZIP
X+
X+struct qdirect  {
X+    long            d_length __attribute__ ((packed));  /* file length */
X+    unsigned char   d_access __attribute__ ((packed));  /* file access type */
X+    unsigned char   d_type __attribute__ ((packed));    /* file type */
X+    long            d_datalen __attribute__ ((packed)); /* data length */
X+    long            d_reserved __attribute__ ((packed));/* Unused */
X+    short           d_szname __attribute__ ((packed));  /* size of name */
X+    char            d_name[36] __attribute__ ((packed));/* name area */
X+    long            d_update __attribute__ ((packed));  /* last update */
X+    long            d_refdate __attribute__ ((packed));
X+    long            d_backup __attribute__ ((packed));   /* EOD */
X+};
X+
X+#define LONGID  "QDOS02"
X+#define EXTRALEN (sizeof(struct qdirect) + 8)
X+#define JBLONGID    "QZHD"
X+#define JBEXTRALEN  (sizeof(jbextra)  - 4 * sizeof(char))
X+
X+typedef struct {
X+    char        eb_header[4] __attribute__ ((packed));  /* place_holder */
X+    char        longid[8] __attribute__ ((packed));
X+    struct      qdirect     header __attribute__ ((packed));
X+} qdosextra;
X+
X+typedef struct {
X+    char        eb_header[4];                           /* place_holder */
X+    char        longid[4];
X+    struct      qdirect     header;
X+} jbextra;
X+
X+
X+
X+/*  The following two functions SH() and LG() convert big-endian short
X+ *  and long numbers into native byte order.  They are some kind of
X+ *  counterpart to the generic UnZip's makeword() and makelong() functions.
X+ */
X+static ush SH(ush val)
X+{
X+    uch swapbuf[2];
X+
X+    swapbuf[1] = (uch)(val & 0xff);
X+    swapbuf[0] = (uch)(val >> 8);
X+    return (*(ush *)swapbuf);
X+}
X+
X+
X+
X+static ulg LG(ulg val)
X+{
X+    /*  convert the big-endian unsigned long number `val' to the machine
X+     *  dependant representation
X+     */
X+    ush swapbuf[2];
X+
X+    swapbuf[1] = SH((ush)(val & 0xffff));
X+    swapbuf[0] = SH((ush)(val >> 16));
X+    return (*(ulg *)swapbuf);
X+}
X+
X+
X+
X+static void qlfix(__G__ ef_ptr, ef_len)
X+    __GDEF
X+    uch *ef_ptr;
X+    unsigned ef_len;
X+{
X+    while (ef_len >= EB_HEADSIZE)
X+    {
X+        unsigned    eb_id  = makeword(EB_ID + ef_ptr);
X+        unsigned    eb_len = makeword(EB_LEN + ef_ptr);
X+
X+        if (eb_len > (ef_len - EB_HEADSIZE)) {
X+            /* discovered some extra field inconsistency! */
X+            Trace((stderr,
X+              "qlfix: block length %u > rest ef_size %u\n", eb_len,
X+              ef_len - EB_HEADSIZE));
X+            break;
X+        }
X+
X+        switch (eb_id) {
X+          case EF_QDOS:
X+          {
X+            struct _ntc_
X+            {
X+                long id;
X+                long dlen;
X+            } ntc;
X+            long dlen = 0;
X+
X+            qdosextra   *extra = (qdosextra *)ef_ptr;
X+            jbextra     *jbp   = (jbextra   *)ef_ptr;
X+
X+            if (!strncmp(extra->longid, LONGID, strlen(LONGID)))
X+            {
X+                if (eb_len != EXTRALEN)
X+                    if (uO.qflag)
X+                        Info(slide, 0x201, ((char *)slide,
X+                          "warning:  invalid length in Qdos field for %s\n",
X+                          FnFilter1(G.filename)));
X+                    else
X+                        Info(slide, 0x201, ((char *)slide,
X+                          "warning:  invalid length in Qdos field"));
X+
X+                if (extra->header.d_type)
X+                {
X+                    dlen = extra->header.d_datalen;
X+                }
X+            }
X+
X+            if (!strncmp(jbp->longid, JBLONGID, strlen(JBLONGID)))
X+            {
X+                if (eb_len != JBEXTRALEN)
X+                    if (uO.qflag)
X+                        Info(slide, 0x201, ((char *)slide,
X+                          "warning:  invalid length in QZ field for %s\n",
X+                          FnFilter1(G.filename)));
X+                    else
X+                        Info(slide, 0x201, ((char *)slide,
X+                          "warning:  invalid length in QZ field"));
X+                if(jbp->header.d_type)
X+                {
X+                    dlen = jbp->header.d_datalen;
X+                }
X+            }
X+
X+            if ((long)LG(dlen) > 0)
X+            {
X+                G.outfile = fopen(G.filename,"r+");
X+                fseek(G.outfile, -8, SEEK_END);
X+                fread(&ntc, 8, 1, G.outfile);
X+                if(ntc.id != *(long *)"XTcc")
X+                {
X+                    ntc.id = *(long *)"XTcc";
X+                    ntc.dlen = dlen;
X+                    fwrite (&ntc, 8, 1, G.outfile);
X+                }
X+                Info(slide, 0x201, ((char *)slide, "QData = %d", LG(dlen)));
X+                fclose(G.outfile);
X+            }
X+            return;     /* finished, cancel further extra field scanning */
X+          }
X+
X+          default:
X+            Trace((stderr,"qlfix: unknown extra field block, ID=%d\n",
X+               eb_id));
X+        }
X+
X+        /* Skip this extra field block */
X+        ef_ptr += (eb_len + EB_HEADSIZE);
X+        ef_len -= (eb_len + EB_HEADSIZE);
X+    }
X+}
X+#endif /* QLZIP */
Xdiff -ruN ../unzip-5.52.orig/unzip.c ./unzip.c
X--- ../unzip-5.52.orig/unzip.c	2005-02-27 13:37:14.000000000 +0900
X+++ ./unzip.c	2008-03-08 07:16:58.000000000 +0900
X@@ -667,6 +667,9 @@
X #endif /* NO_EXCEPT_SIGNALS */
X 
X     SETLOCALE(LC_CTYPE,"");
X+#ifdef NLS /* needs locale support */
X+    uO.charenc_sys = nl_langinfo (CODESET);
X+#endif
X 
X #if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
X     extern void DebugMalloc(void);
X@@ -1217,6 +1220,29 @@
X #endif /* !SFX || SFX_EXDIR */
X                 case ('e'):    /* just ignore -e, -x options (extract) */
X                     break;
X+#ifdef NLS
X+		case 'E':  /* -E:  character encoding for archive */
X+		  if (negative) {
X+		    uO.charenc_arch = NULL;
X+		  } else {
X+		    uO.charenc_arch = s;
X+		    if (*uO.charenc_arch == '\0') {
X+		      if (! (-- argc)) {
X+			Info(slide, 0x401, ((char *)slide,
X+			     "error:  must give character encording name\n"));
X+			return PK_PARAM;
X+		      }
X+		      uO.charenc_arch = *(++ argv);
X+		      if (*uO.charenc_arch == '-') {
X+			Info(slide, 0x401, ((char *)slide,
X+			     "error:  must give character encording name\n"));
X+			return PK_PARAM;
X+		      }
X+		    }
X+		    else while (*(++ s));
X+		  }
X+		  break;
X+#endif /* NLS */
X #ifdef MACOS
X                 case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
X                     if( negative ) {
Xdiff -ruN ../unzip-5.52.orig/unzip.c.orig ./unzip.c.orig
X--- ../unzip-5.52.orig/unzip.c.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./unzip.c.orig	2005-02-27 13:37:14.000000000 +0900
X@@ -0,0 +1,2042 @@
X+/*
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  See the accompanying file LICENSE, version 2000-Apr-09 or later
X+  (the contents of which are also included in unzip.h) for terms of use.
X+  If, for some reason, all these files are missing, the Info-ZIP license
X+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
X+*/
X+/*---------------------------------------------------------------------------
X+
X+  unzip.c
X+
X+  UnZip - a zipfile extraction utility.  See below for make instructions, or
X+  read the comments in Makefile and the various Contents files for more de-
X+  tailed explanations.  To report a bug, submit a *complete* description via
X+  //www.info-zip.org/zip-bug.html; include machine type, operating system and
X+  version, compiler and version, and reasonably detailed error messages or
X+  problem report.  To join Info-ZIP, see the instructions in README.
X+
X+  UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
X+  which in turn was almost a complete rewrite of version 3.x.  For a detailed
X+  revision history, see UnzpHist.zip at quest.jpl.nasa.gov.  For a list of
X+  the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
X+  distribution.
X+
X+  ---------------------------------------------------------------------------
X+
X+  [from original zipinfo.c]
X+
X+  This program reads great gobs of totally nifty information, including the
X+  central directory stuff, from ZIP archives ("zipfiles" for short).  It
X+  started as just a testbed for fooling with zipfiles, but at this point it
X+  is actually a useful utility.  It also became the basis for the rewrite of
X+  UnZip (3.16 -> 4.0), using the central directory for processing rather than
X+  the individual (local) file headers.
X+
X+  As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
X+  If the executable is named "unzip" (or "unzip.exe", depending), it behaves
X+  like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
X+  ZipInfo.  The ZipInfo behavior may also be triggered by use of unzip's -Z
X+  option; for example, "unzip -Z [zipinfo_options] archive.zip".
X+
X+  Another dandy product from your buddies at Newtware!
X+
X+  Author:  Greg Roelofs, newt at pobox.com, http://pobox.com/~newt/
X+           23 August 1990 -> April 1997
X+
X+  ---------------------------------------------------------------------------
X+
X+  Version:  unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
X+              Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
X+              AtheOS, BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos
X+              and TOPS-20.
X+
X+  Copyrights:  see accompanying file "LICENSE" in UnZip source distribution.
X+               (This software is free but NOT IN THE PUBLIC DOMAIN.)
X+
X+  ---------------------------------------------------------------------------*/
X+
X+
X+
X+#define __UNZIP_C       /* identifies this source module */
X+#define UNZIP_INTERNAL
X+#include "unzip.h"      /* includes, typedefs, macros, prototypes, etc. */
X+#include "crypt.h"
X+#include "unzvers.h"
X+
X+#ifndef WINDLL          /* The WINDLL port uses windll/windll.c instead... */
X+
X+/***************************/
X+/* Local type declarations */
X+/***************************/
X+
X+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
X+typedef struct _sign_info
X+    {
X+        struct _sign_info *previous;
X+        void (*sighandler)(int);
X+        int sigtype;
X+    } savsigs_info;
X+#endif
X+
X+/*******************/
X+/* Local Functions */
X+/*******************/
X+
X+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
X+static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
X+                                int signal_type, void (*newhandler)(int)));
X+#endif
X+#ifndef SFX
X+static void  show_version_info  OF((__GPRO));
X+#endif
X+
X+
X+/*************/
X+/* Constants */
X+/*************/
X+
X+#include "consts.h"  /* all constant global variables are in here */
X+                     /* (non-constant globals were moved to globals.c) */
X+
X+/* constant local variables: */
X+
X+#ifndef SFX
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+   static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
X+   static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
X+   static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
X+   static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
X+#ifdef RISCOS
X+   static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
X+#endif /* RISCOS */
X+  static ZCONST char Far NoMemArguments[] =
X+    "envargs:  cannot get memory for arguments";
X+#endif /* !_WIN32_WCE */
X+#endif /* !SFX */
X+
X+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
X+  static ZCONST char Far CantSaveSigHandler[] =
X+    "error:  cannot save signal handler settings\n";
X+#endif
X+
X+#if (!defined(SFX) || defined(SFX_EXDIR))
X+   static ZCONST char Far NotExtracting[] =
X+     "caution:  not extracting; -d ignored\n";
X+   static ZCONST char Far MustGiveExdir[] =
X+     "error:  must specify directory to which to extract with -d option\n";
X+   static ZCONST char Far OnlyOneExdir[] =
X+     "error:  -d option used more than once (only one exdir allowed)\n";
X+#endif
X+
X+#if CRYPT
X+   static ZCONST char Far MustGivePasswd[] =
X+     "error:  must give decryption password with -P option\n";
X+#endif
X+
X+#ifndef SFX
X+   static ZCONST char Far Zfirst[] =
X+   "error:  -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
X+#endif
X+static ZCONST char Far InvalidOptionsMsg[] = "error:\
X+  -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
X+static ZCONST char Far IgnoreOOptionMsg[] =
X+  "caution:  both -n and -o specified; ignoring -o\n";
X+
X+/* usage() strings */
X+#ifndef SFX
X+#ifdef VMS
X+   static ZCONST char Far Example3[] = "vms.c";
X+   static ZCONST char Far Example2[] = "  unzip \"-V\" foo \"Bar\"\
X+ (Quote names to preserve case, unless SET PROC/PARS=EXT)\n";
X+#else /* !VMS */
X+   static ZCONST char Far Example3[] = "ReadMe";
X+#ifdef RISCOS
X+   static ZCONST char Far Example2[] =
X+"  unzip foo -d RAM:$   => extract all files from foo into RAMDisc\n";
X+#else /* !RISCOS */
X+#if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
X+   static ZCONST char Far Example2[] =
X+     "";                /* no room:  too many local3[] items */
X+#else /* !OS2 */
X+#ifdef MACOS
X+   static ZCONST char Far Example2[] = ""; /* not needed */
X+#else /* !MACOS */
X+   static ZCONST char Far Example2[] = " \
X+ unzip -p foo | more  => send contents of foo.zip via pipe into program more\n";
X+#endif /* ?MACOS */
X+#endif /* ?OS2 */
X+#endif /* ?RISCOS */
X+#endif /* ?VMS */
X+
X+/* local1[]:  command options */
X+#if (defined(DLL) && defined(API_DOC))
X+   static ZCONST char Far local1[] =
X+     "  -A  print extended help for API functions";
X+#else /* !(DLL && API_DOC) */
X+   static ZCONST char Far local1[] = "";
X+#endif /* ?(DLL && API_DOC) */
X+
X+/* local2[] and local3[]:  modifier options */
X+#ifdef DOS_FLX_H68_OS2_W32
X+#ifdef FLEXOS
X+   static ZCONST char Far local2[] = "";
X+#else
X+   static ZCONST char Far local2[] =
X+     " -$  label removables (-$$ => fixed disks)";
X+#endif
X+#ifdef OS2
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "\
X+  -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\
X+                                             -M  pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = " \
X+ -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\n";
X+#endif /* ?MORE */
X+#else /* !OS2 */
X+#ifdef WIN32
X+#ifdef NTSD_EAS
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "\
X+  -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\
X+                                             -M  pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = " \
X+ -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\n";
X+#endif /* ?MORE */
X+#else /* !NTSD_EAS */
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "\
X+  -M  pipe through \"more\" pager            \
X+  -s  spaces in filenames => '_'\n\n";
X+#else
X+   static ZCONST char Far local3[] = " \
X+                                            -s  spaces in filenames => '_'\n\n";
X+#endif /* ?MORE */
X+#endif /* ?NTSD_EAS */
X+#else /* !WIN32 */
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "  -\
X+M  pipe through \"more\" pager              -s  spaces in filenames => '_'\n\n";
X+#else
X+   static ZCONST char Far local3[] = "\
X+                                             -s  spaces in filenames => '_'\n";
X+#endif
X+#endif /* ?WIN32 */
X+#endif /* ?OS2 || ?WIN32 */
X+#else /* !DOS_FLX_OS2_W32 */
X+#ifdef VMS
X+   static ZCONST char Far local2[] = "\"-X\" restore owner/protection info";
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "  \
X+                                          \"-M\" pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = "\n";
X+#endif
X+#else /* !VMS */
X+#ifdef ATH_BEO_UNX
X+   static ZCONST char Far local2[] = " -X  restore UID/GID info";
X+#ifdef MORE
X+   static ZCONST char Far local3[] = "\
X+  -K  keep setuid/setgid/tacky permissions   -M  pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = "\
X+  -K  keep setuid/setgid/tacky permissions\n";
X+#endif
X+#else /* !ATH_BEO_UNX */
X+#ifdef TANDEM
X+   static ZCONST char Far local2[] = "\
X+ -X  restore Tandem User ID                 -r  remove file extensions\n\
X+  -b  create 'C' (180) text files          ";
X+#ifdef MORE
X+   static ZCONST char Far local3[] = " \
X+                                            -M  pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = "\n";
X+#endif
X+#else /* !TANDEM */
X+#ifdef AMIGA
X+   static ZCONST char Far local2[] = " -N  restore comments as filenotes";
X+#ifdef MORE
X+   static ZCONST char Far local3[] = " \
X+                                            -M  pipe through \"more\" pager\n";
X+#else
X+   static ZCONST char Far local3[] = "\n";
X+#endif
X+#else /* !AMIGA */
X+#ifdef MACOS
X+   static ZCONST char Far local2[] = " -E  show Mac info during extraction";
X+   static ZCONST char Far local3[] = " \
X+ -i  ignore filenames in mac extra info     -J  junk (ignore) Mac extra info\n\
X+\n";
X+#else /* !MACOS */
X+#ifdef MORE
X+   static ZCONST char Far local2[] = " -M  pipe through \"more\" pager";
X+   static ZCONST char Far local3[] = "\n";
X+#else
X+   static ZCONST char Far local2[] = "";   /* Atari, Mac, CMS/MVS etc. */
X+   static ZCONST char Far local3[] = "";
X+#endif
X+#endif /* ?MACOS */
X+#endif /* ?AMIGA */
X+#endif /* ?TANDEM */
X+#endif /* ?ATH_BEO_UNX */
X+#endif /* ?VMS */
X+#endif /* ?DOS_FLX_OS2_W32 */
X+#endif /* !SFX */
X+
X+#ifndef NO_ZIPINFO
X+#ifdef VMS
X+   static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
X+#else
X+   static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
X+#endif
X+
X+static ZCONST char Far ZipInfoUsageLine1[] = "\
X+ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
X+\n\
X+List name, date/time, attribute, size, compression method, etc., about files\n\
X+in list (excluding those in xlist) contained in the specified .zip archive(s).\
X+\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
X+   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
X+      or:  unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
X+
X+static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
X+ listing-format options:             -s  short Unix \"ls -l\" format (def.)\n\
X+  -1  filenames ONLY, one per line       -m  medium Unix \"ls -l\" format\n\
X+  -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
X+                                         -v  verbose, multi-page format\n";
X+
X+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
X+  -h  print header line       -t  print totals for listed files or for all\n\
X+  -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
X+\n %c-C%c be case-insensitive   %s\
X+  -x  exclude filenames that follow from listing\n";
X+#ifdef MORE
X+#ifdef VMS
X+   static ZCONST char Far ZipInfoUsageLine4[] =
X+     " \"-M\" page output through built-in \"more\"\n";
X+#else
X+   static ZCONST char Far ZipInfoUsageLine4[] =
X+     "  -M  page output through built-in \"more\"\n";
X+#endif
X+#else /* !MORE */
X+   static ZCONST char Far ZipInfoUsageLine4[] = "";
X+#endif /* ?MORE */
X+#endif /* !NO_ZIPINFO */
X+
X+#ifdef BETA
X+#  ifdef VMSCLI
X+   /* BetaVersion[] is also used in vms/cmdline.c:  do not make it static */
X+     ZCONST char Far BetaVersion[] = "%s\
X+        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
X+#  else
X+     static ZCONST char Far BetaVersion[] = "%s\
X+        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
X+#  endif
X+#endif
X+
X+#ifdef SFX
X+#  ifdef VMSCLI
X+   /* UnzipSFXBanner[] is also used in vms/cmdline.c:  do not make it static */
X+     ZCONST char Far UnzipSFXBanner[] =
X+#  else
X+     static ZCONST char Far UnzipSFXBanner[] =
X+#  endif
X+     "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (http://www.info-zip.org).\n";
X+#  ifdef SFX_EXDIR
X+     static ZCONST char Far UnzipSFXOpts[] =
X+    "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
X+#  else
X+     static ZCONST char Far UnzipSFXOpts[] =
X+       "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
X+#  endif
X+#else /* !SFX */
X+   static ZCONST char Far CompileOptions[] =
X+     "UnZip special compilation options:\n";
X+   static ZCONST char Far CompileOptFormat[] = "\t%s\n";
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+   static ZCONST char Far EnvOptions[] =
X+     "\nUnZip and ZipInfo environment options:\n";
X+   static ZCONST char Far EnvOptFormat[] = "%16s:  %s\n";
X+#endif
X+   static ZCONST char Far None[] = "[none]";
X+#  ifdef ACORN_FTYPE_NFS
X+     static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
X+#  endif
X+#  ifdef ASM_CRC
X+     static ZCONST char Far AsmCRC[] = "ASM_CRC";
X+#  endif
X+#  ifdef ASM_INFLATECODES
X+     static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
X+#  endif
X+#  ifdef CHECK_VERSIONS
X+     static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
X+#  endif
X+#  ifdef COPYRIGHT_CLEAN
X+     static ZCONST char Far Copyright_Clean[] =
X+     "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
X+#  endif
X+#  ifdef DEBUG
X+     static ZCONST char Far UDebug[] = "DEBUG";
X+#  endif
X+#  ifdef DEBUG_TIME
X+     static ZCONST char Far DebugTime[] = "DEBUG_TIME";
X+#  endif
X+#  ifdef DLL
X+     static ZCONST char Far Dll[] = "DLL";
X+#  endif
X+#  ifdef DOSWILD
X+     static ZCONST char Far DosWild[] = "DOSWILD";
X+#  endif
X+#  ifdef LZW_CLEAN
X+     static ZCONST char Far LZW_Clean[] =
X+     "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
X+#  endif
X+#  ifndef MORE
X+     static ZCONST char Far No_More[] = "NO_MORE";
X+#  endif
X+#  ifdef NO_ZIPINFO
X+     static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
X+#  endif
X+#  ifdef NTSD_EAS
X+     static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
X+#  endif
X+#  if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
X+     static ZCONST char Far W32NoIZTimeFix[] = "NO_W32TIMES_IZFIX";
X+#  endif
X+#  ifdef OLD_THEOS_EXTRA
X+     static ZCONST char Far OldTheosExtra[] =
X+     "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
X+#  endif
X+#  ifdef OS2_EAS
X+     static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
X+#  endif
X+#  ifdef QLZIP
X+     static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
X+#  endif
X+#  ifdef REENTRANT
X+     static ZCONST char Far Reentrant[] = "REENTRANT";
X+#  endif
X+#  ifdef REGARGS
X+     static ZCONST char Far RegArgs[] = "REGARGS";
X+#  endif
X+#  ifdef RETURN_CODES
X+     static ZCONST char Far Return_Codes[] = "RETURN_CODES";
X+#  endif
X+#  ifdef SET_DIR_ATTRIB
X+     static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
X+#  endif
X+#  ifdef TIMESTAMP
X+     static ZCONST char Far TimeStamp[] = "TIMESTAMP";
X+#  endif
X+#  ifdef UNIXBACKUP
X+     static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
X+#  endif
X+#  ifdef USE_EF_UT_TIME
X+     static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
X+#  endif
X+#  ifndef LZW_CLEAN
X+     static ZCONST char Far Use_Unshrink[] =
X+     "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
X+#  endif
X+#  ifndef COPYRIGHT_CLEAN
X+     static ZCONST char Far Use_Smith_Code[] =
X+     "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
X+#  endif
X+#  ifdef USE_DEFLATE64
X+     static ZCONST char Far Use_Deflate64[] =
X+     "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
X+#  endif
X+#  ifdef MULT_VOLUME
X+     static ZCONST char Far Use_MultiVol[] =
X+     "MULT_VOLUME (multi-volume archives supported)";
X+#  endif
X+#  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
X+#    ifdef USE_DJGPP_ENV
X+       static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
X+#    endif
X+#    ifdef USE_DJGPP_GLOB
X+       static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
X+#    endif
X+#  endif /* __DJGPP__ && (__DJGPP__ >= 2) */
X+#  ifdef USE_VFAT
X+     static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
X+#  endif
X+#  ifdef USE_ZLIB
X+     static ZCONST char Far UseZlib[] =
X+     "USE_ZLIB (compiled with version %s; using version %s)";
X+#  endif
X+#  ifdef VMS_TEXT_CONV
X+     static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
X+#  endif
X+#  ifdef VMSCLI
X+     static ZCONST char Far VmsCLI[] = "VMSCLI";
X+#  endif
X+#  ifdef VMSWILD
X+     static ZCONST char Far VmsWild[] = "VMSWILD";
X+#  endif
X+#  ifdef WILD_STOP_AT_DIR
X+     static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
X+#  endif
X+#  if CRYPT
X+#    ifdef PASSWD_FROM_STDIN
X+       static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
X+#    endif
X+     static ZCONST char Far Decryption[] =
X+       "\t[decryption, version %d.%d%s of %s]\n";
X+     static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
X+#  endif
X+#  ifndef __RSXNT__
X+#    ifdef __EMX__
X+       static ZCONST char Far EnvEMX[] = "EMX";
X+       static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
X+#    endif
X+#    if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
X+       static ZCONST char Far EnvGO32[] = "GO32";
X+       static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
X+#    endif
X+#  endif /* !__RSXNT__ */
X+
X+#ifdef VMS
X+/* UnzipUsageLine1[] is also used in vms/cmdline.c:  do not make it static */
X+   ZCONST char Far UnzipUsageLine1[] = "\
X+UnZip %d.%d%d%s of %s, by Info-ZIP.  For more details see: unzip -v.\n\n";
X+# ifdef COPYRIGHT_CLEAN
X+   static ZCONST char Far UnzipUsageLine1v[] = "\
X+UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
X+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
X+\n\n";
X+# else
X+   static ZCONST char Far UnzipUsageLine1v[] = "\
X+UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
X+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
X+\n\n";
X+# endif /* ?COPYRIGHT_CLEAN */
X+#else /* !VMS */
X+# ifdef COPYRIGHT_CLEAN
X+   static ZCONST char Far UnzipUsageLine1[] = "\
X+UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
X+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
X+\n\n";
X+# else
X+   static ZCONST char Far UnzipUsageLine1[] = "\
X+UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
X+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
X+\n\n";
X+# endif /* ?COPYRIGHT_CLEAN */
X+# define UnzipUsageLine1v       UnzipUsageLine1
X+#endif /* ?VMS */
X+
X+static ZCONST char Far UnzipUsageLine2v[] = "\
X+Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
X+\nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
X+\n\n";
X+
X+#ifdef MACOS
X+static ZCONST char Far UnzipUsageLine2[] = "\
X+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n \
X+ Default action is to extract files in list, to exdir;\n\
X+  file[.zip] may be a wildcard.  %s\n";
X+#else /* !MACOS */
X+#ifdef VM_CMS
X+static ZCONST char Far UnzipUsageLine2[] = "\
X+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n \
X+ Default action is to extract files in list, except those in xlist, to disk fm;\
X+\n  file[.zip] may be a wildcard.  %s\n";
X+#else /* !VM_CMS */
X+static ZCONST char Far UnzipUsageLine2[] = "\
X+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
X+ Default action is to extract files in list, except those in xlist, to exdir;\n\
X+  file[.zip] may be a wildcard.  %s\n";
X+#endif /* ?VM_CMS */
X+#endif /* ?MACOS */
X+
X+#ifdef NO_ZIPINFO
X+#  define ZIPINFO_MODE_OPTION  ""
X+   static ZCONST char Far ZipInfoMode[] =
X+     "(ZipInfo mode is disabled in this version.)";
X+#else
X+#  define ZIPINFO_MODE_OPTION  "[-Z] "
X+#  ifdef VMS
X+     static ZCONST char Far ZipInfoMode[] =
X+       "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).";
X+#  else
X+     static ZCONST char Far ZipInfoMode[] =
X+       "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
X+#  endif
X+#endif /* ?NO_ZIPINFO */
X+
X+#ifdef VMS
X+   static ZCONST char Far VMSusageLine2b[] = "\
X+=> define foreign command symbol in LOGIN.COM:  $ unzip :== $dev:[dir]unzip.exe\
X+\n";
X+#endif
X+
X+#ifdef MACOS
X+static ZCONST char Far UnzipUsageLine3[] = "\n\
X+  -d  extract files into exdir               -l  list files (short format)\n\
X+  -f  freshen existing files, create none    -t  test compressed archive data\n\
X+  -u  update files, create if necessary      -z  display archive comment\n\
X+%s\n";
X+#else /* !MACOS */
X+#ifdef VM_CMS
X+static ZCONST char Far UnzipUsageLine3[] = "\n\
X+  -p  extract files to pipe, no messages     -l  list files (short format)\n\
X+  -f  freshen existing files, create none    -t  test compressed archive data\n\
X+  -u  update files, create if necessary      -z  display archive comment\n\
X+  -x  exclude files that follow (in xlist)   -d  extract files onto disk fm\n\
X+%s\n";
X+#else /* !VM_CMS */
X+static ZCONST char Far UnzipUsageLine3[] = "\n\
X+  -p  extract files to pipe, no messages     -l  list files (short format)\n\
X+  -f  freshen existing files, create none    -t  test compressed archive data\n\
X+  -u  update files, create if necessary      -z  display archive comment\n\
X+  -x  exclude files that follow (in xlist)   -d  extract files into exdir\n\
X+%s\n";
X+#endif /* ?VM_CMS */
X+#endif /* ?MACOS */
X+
X+static ZCONST char Far UnzipUsageLine4[] = "\
X+modifiers:                                   -q  quiet mode (-qq => quieter)\n\
X+  -n  never overwrite existing files         -a  auto-convert any text files\n\
X+  -o  overwrite files WITHOUT prompting      -aa treat ALL files as text\n \
X+ -j  junk paths (do not make directories)   -v  be verbose/print version info\n\
X+ %c-C%c match filenames case-insensitively    %c-L%c make (some) names \
X+lowercase\n %-42s %c-V%c retain VMS version numbers\n%s";
X+
X+static ZCONST char Far UnzipUsageLine5[] = "\
X+Examples (see unzip.txt for more info):\n\
X+  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip\n\
X+%s\
X+  unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
X+#endif /* ?SFX */
X+
X+
X+
X+
X+
X+/*****************************/
X+/*  main() / UzpMain() stub  */
X+/*****************************/
X+
X+int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
X+    int argc;
X+    char *argv[];
X+{
X+    int r;
X+
X+    CONSTRUCTGLOBALS();
X+    r = unzip(__G__ argc, argv);
X+    DESTROYGLOBALS();
X+    RETURN(r);
X+}
X+
X+
X+
X+
X+/*******************************/
X+/*  Primary UnZip entry point  */
X+/*******************************/
X+
X+int unzip(__G__ argc, argv)
X+    __GDEF
X+    int argc;
X+    char *argv[];
X+{
X+#ifndef NO_ZIPINFO
X+    char *p;
X+#endif
X+#ifdef DOS_FLX_H68_NLM_OS2_W32
X+    int i;
X+#endif
X+    int retcode, error=FALSE;
X+#ifndef NO_EXCEPT_SIGNALS
X+#ifdef REENTRANT
X+    savsigs_info *oldsighandlers = NULL;
X+#   define SET_SIGHANDLER(sigtype, newsighandler) \
X+      if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
X+                                      (newsighandler))) > PK_WARN) \
X+          goto cleanup_and_exit
X+#else
X+#   define SET_SIGHANDLER(sigtype, newsighandler) \
X+      signal((sigtype), (newsighandler))
X+#endif
X+#endif /* NO_EXCEPT_SIGNALS */
X+
X+    SETLOCALE(LC_CTYPE,"");
X+
X+#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
X+    extern void DebugMalloc(void);
X+
X+    atexit(DebugMalloc);
X+#endif
X+
X+#ifdef MALLOC_WORK
X+    /* The following (rather complex) expression determines the allocation
X+       size of the decompression work area.  It simulates what the
X+       combined "union" and "struct" declaration of the "static" work
X+       area reservation achieves automatically at compile time.
X+       Any decent compiler should evaluate this expression completely at
X+       compile time and provide constants to the zcalloc() call.
X+       (For better readability, some subexpressions are encapsulated
X+       in temporarly defined macros.)
X+     */
X+#   define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
X+#   define UZ_NUMOF_CHUNKS \
X+      (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
X+                 (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
X+    G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
X+#   undef UZ_SLIDE_CHUNK
X+#   undef UZ_NUMOF_CHUNKS
X+    G.area.shrink.Parent = (shrint *)G.area.Slide;
X+    G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
X+    G.area.shrink.Stack = G.area.Slide +
X+                           (sizeof(shrint) + sizeof(uch))*(HSIZE);
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Set signal handler for restoring echo, warn of zipfile corruption, etc.
X+  ---------------------------------------------------------------------------*/
X+#ifndef NO_EXCEPT_SIGNALS
X+#ifdef SIGINT
X+    SET_SIGHANDLER(SIGINT, handler);
X+#endif
X+#ifdef SIGTERM                 /* some systems really have no SIGTERM */
X+    SET_SIGHANDLER(SIGTERM, handler);
X+#endif
X+#ifdef SIGBUS
X+    SET_SIGHANDLER(SIGBUS, handler);
X+#endif
X+#ifdef SIGSEGV
X+    SET_SIGHANDLER(SIGSEGV, handler);
X+#endif
X+#endif /* NO_EXCEPT_SIGNALS */
X+
X+#if (defined(WIN32) && defined(__RSXNT__))
X+    for (i = 0 ; i < argc; i++) {
X+       _ISO_INTERN(argv[i]);
X+    }
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Macintosh initialization code.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef MACOS
X+    {
X+        int a;
X+
X+        for (a = 0;  a < 4;  ++a)
X+            G.rghCursor[a] = GetCursor(a+128);
X+        G.giCursor = 0;
X+    }
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    NetWare initialization code.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef NLM
X+    InitUnZipConsole();
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Acorn RISC OS initialization code.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef RISCOS
X+    set_prefix();
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Theos initialization code.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef THEOS
X+    /* The easiest way found to force creation of libraries when selected
X+     * members are to be unzipped. Explicitely add libraries names to the
X+     * arguments list before the first member of the library.
X+     */
X+    if (! _setargv(&argc, &argv)) {
X+        Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
X+        retcode = PK_MEM;
X+        goto cleanup_and_exit;
X+    }
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    First figure out if we're running in UnZip mode or ZipInfo mode, and put
X+    the appropriate environment-variable options into the queue.  Then rip
X+    through any command-line options lurking about...
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef SFX
X+    G.argv0 = argv[0];
X+#if (defined(OS2) || defined(WIN32))
X+    G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
X+#else
X+    G.zipfn = G.argv0;
X+#endif
X+
X+#ifdef VMSCLI
X+    {
X+        ulg status = vms_unzip_cmdline(&argc, &argv);
X+        if (!(status & 1)) {
X+            retcode = (int)status;
X+            goto cleanup_and_exit;
X+        }
X+    }
X+#endif /* VMSCLI */
X+
X+    uO.zipinfo_mode = FALSE;
X+    error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
X+
X+#else /* !SFX */
X+
X+#ifdef RISCOS
X+    /* get the extensions to swap from environment */
X+    getRISCOSexts(ENV_UNZIPEXTS);
X+#endif
X+
X+#ifdef MSDOS
X+    /* extract MKS extended argument list from environment (before envargs!) */
X+    mksargs(&argc, &argv);
X+#endif
X+
X+#ifdef VMSCLI
X+    {
X+        ulg status = vms_unzip_cmdline(&argc, &argv);
X+        if (!(status & 1)) {
X+            retcode = (int)status;
X+            goto cleanup_and_exit;
X+        }
X+    }
X+#endif /* VMSCLI */
X+
X+    G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
X+
X+#ifndef NO_ZIPINFO
X+    for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
X+        if (*p == DIR_END
X+#ifdef DIR_END2
X+            || *p == DIR_END2
X+#endif
X+           )
X+            break;
X+    }
X+    ++p;
X+
X+#ifdef THEOS
X+    if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
X+        strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
X+#else
X+    if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
X+        STRNICMP(p, "ii", 2) == 0 ||
X+#endif
X+        (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
X+    {
X+        uO.zipinfo_mode = TRUE;
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
X+                             LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
X+            perror(LoadFarString(NoMemArguments));
X+        else
X+#endif
X+            error = zi_opts(__G__ &argc, &argv);
X+    } else
X+#endif /* !NO_ZIPINFO */
X+    {
X+        uO.zipinfo_mode = FALSE;
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
X+                             LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
X+            perror(LoadFarString(NoMemArguments));
X+        else
X+#endif
X+            error = uz_opts(__G__ &argc, &argv);
X+    }
X+
X+#endif /* ?SFX */
X+
X+    if ((argc < 0) || error) {
X+        retcode = error;
X+        goto cleanup_and_exit;
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Now get the zipfile name from the command line and then process any re-
X+    maining options and file specifications.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef DOS_FLX_H68_NLM_OS2_W32
X+    /* convert MSDOS-style 'backward slash' directory separators to Unix-style
X+     * 'forward slashes' for user's convenience (include zipfile name itself)
X+     */
X+#ifdef SFX
X+    for (G.pfnames = argv, i = argc;  i > 0;  --i) {
X+#else
X+    /* argc does not include the zipfile specification */
X+    for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
X+#endif
X+#ifdef __human68k__
X+        extern char *_toslash(char *);
X+        _toslash(*G.pfnames);
X+#else /* !__human68k__ */
X+        char *q = *G.pfnames;
X+
X+        while (*q != '\0') {
X+            if (*q == '\\')
X+                *q = '/';
X+            INCSTR(q);
X+        }
X+        ++G.pfnames;
X+#endif /* ?__human68k__ */
X+    }
X+#endif /* DOS_FLX_H68_NLM_OS2_W32 */
X+
X+#ifndef SFX
X+    G.wildzipfn = *argv++;
X+#endif
X+
X+#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
X+
X+    G.filespecs = argc;
X+    G.xfilespecs = 0;
X+
X+    if (argc > 0) {
X+        char **pp = argv-1;
X+
X+        G.pfnames = argv;
X+        while (*++pp)
X+            if (strcmp(*pp, "-x") == 0) {
X+                if (pp > argv) {
X+                    *pp = 0;              /* terminate G.pfnames */
X+                    G.filespecs = pp - G.pfnames;
X+                } else {
X+                    G.pfnames = (char **)fnames;  /* defaults */
X+                    G.filespecs = 0;
X+                }
X+                G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
X+                G.xfilespecs = argc - G.filespecs - 1;
X+                break;                    /* skip rest of args */
X+            }
X+        G.process_all_files = FALSE;
X+    } else
X+        G.process_all_files = TRUE;      /* for speed */
X+
X+#else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
X+
X+    G.filespecs = argc;
X+    G.xfilespecs = 0;
X+
X+    if (argc > 0) {
X+        int in_files=FALSE, in_xfiles=FALSE;
X+        char **pp = argv-1;
X+
X+        G.process_all_files = FALSE;
X+        G.pfnames = argv;
X+        while (*++pp) {
X+            Trace((stderr, "pp - argv = %d\n", pp-argv));
X+#ifdef CMS_MVS
X+            if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
X+#else
X+            if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
X+#endif
X+                int firstarg = (pp == argv);
X+
X+                uO.exdir = (*pp) + 2;
X+                if (in_files) {      /* ... zipfile ... -d exdir ... */
X+                    *pp = (char *)NULL;         /* terminate G.pfnames */
X+                    G.filespecs = pp - G.pfnames;
X+                    in_files = FALSE;
X+                } else if (in_xfiles) {
X+                    *pp = (char *)NULL;         /* terminate G.pxnames */
X+                    G.xfilespecs = pp - G.pxnames;
X+                    /* "... -x xlist -d exdir":  nothing left */
X+                }
X+                /* first check for "-dexdir", then for "-d exdir" */
X+                if (*uO.exdir == '\0') {
X+                    if (*++pp)
X+                        uO.exdir = *pp;
X+                    else {
X+                        Info(slide, 0x401, ((char *)slide,
X+                          LoadFarString(MustGiveExdir)));
X+                        /* don't extract here by accident */
X+                        retcode = PK_PARAM;
X+                        goto cleanup_and_exit;
X+                    }
X+                }
X+                if (firstarg) { /* ... zipfile -d exdir ... */
X+                    if (pp[1]) {
X+                        G.pfnames = pp + 1;  /* argv+2 */
X+                        G.filespecs = argc - (G.pfnames-argv);  /* for now... */
X+                    } else {
X+                        G.process_all_files = TRUE;
X+                        G.pfnames = (char **)fnames;  /* GRR: necessary? */
X+                        G.filespecs = 0;     /* GRR: necessary? */
X+                        break;
X+                    }
X+                }
X+            } else if (!in_xfiles) {
X+                if (strcmp(*pp, "-x") == 0) {
X+                    in_xfiles = TRUE;
X+                    if (pp == G.pfnames) {
X+                        G.pfnames = (char **)fnames;  /* defaults */
X+                        G.filespecs = 0;
X+                    } else if (in_files) {
X+                        *pp = 0;                   /* terminate G.pfnames */
X+                        G.filespecs = pp - G.pfnames;  /* adjust count */
X+                        in_files = FALSE;
X+                    }
X+                    G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
X+                    G.xfilespecs = argc - (G.pxnames-argv);  /* anything left */
X+                } else
X+                    in_files = TRUE;
X+            }
X+        }
X+    } else
X+        G.process_all_files = TRUE;      /* for speed */
X+
X+    if (uO.exdir != (char *)NULL && !G.extract_flag)    /* -d ignored */
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
X+#endif /* ?(SFX && !SFX_EXDIR) */
X+
X+/*---------------------------------------------------------------------------
X+    Okey dokey, we have everything we need to get started.  Let's roll.
X+  ---------------------------------------------------------------------------*/
X+
X+    retcode = process_zipfiles(__G);
X+
X+cleanup_and_exit:
X+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
X+    /* restore all signal handlers back to their state at function entry */
X+    while (oldsighandlers != NULL) {
X+        savsigs_info *thissigsav = oldsighandlers;
X+
X+        signal(thissigsav->sigtype, thissigsav->sighandler);
X+        oldsighandlers = thissigsav->previous;
X+        free(thissigsav);
X+    }
X+#endif
X+#if (defined(MALLOC_WORK) && !defined(REENTRANT))
X+    if (G.area.Slide != (uch *)NULL) {
X+        free(G.area.Slide);
X+        G.area.Slide = (uch *)NULL;
X+    }
X+#endif
X+    return(retcode);
X+
X+} /* end main()/unzip() */
X+
X+
X+
X+
X+
X+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
X+/*******************************/
X+/* Function setsignalhandler() */
X+/*******************************/
X+
X+static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
X+                            newhandler)
X+    __GDEF
X+    savsigs_info **p_savedhandler_chain;
X+    int signal_type;
X+    void (*newhandler)(int);
X+{
X+    savsigs_info *savsig;
X+
X+    savsig = malloc(sizeof(savsigs_info));
X+    if (savsig == NULL) {
X+        /* error message and break */
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
X+        return PK_MEM;
X+    }
X+    savsig->sigtype = signal_type;
X+    savsig->sighandler = signal(SIGINT, newhandler);
X+    if (savsig->sighandler == SIG_ERR) {
X+        free(savsig);
X+    } else {
X+        savsig->previous = *p_savedhandler_chain;
X+        *p_savedhandler_chain = savsig;
X+    }
X+    return PK_OK;
X+
X+} /* end function setsignalhandler() */
X+
X+#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
X+
X+
X+
X+
X+
X+/**********************/
X+/* Function uz_opts() */
X+/**********************/
X+
X+int uz_opts(__G__ pargc, pargv)
X+    __GDEF
X+    int *pargc;
X+    char ***pargv;
X+{
X+    char **argv, *s;
X+    int argc, c, error=FALSE, negative=0;
X+
X+
X+    argc = *pargc;
X+    argv = *pargv;
X+
X+    while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
X+        s = *argv + 1;
X+        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
X+#ifdef CMS_MVS
X+            switch (tolower(c))
X+#else
X+            switch (c)
X+#endif
X+            {
X+                case ('-'):
X+                    ++negative;
X+                    break;
X+#ifdef RISCOS
X+                case ('/'):
X+                    if (negative) {   /* negative not allowed with -/ swap */
X+                        Info(slide, 0x401, ((char *)slide,
X+                          "error:  must give extensions list"));
X+                        return(PK_PARAM);  /* don't extract here by accident */
X+                    }
X+                    exts2swap = s; /* override Unzip$Exts */
X+                    s += strlen(s);
X+                    break;
X+#endif
X+                case ('a'):
X+                    if (negative) {
X+                        uO.aflag = MAX(uO.aflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.aflag;
X+                    break;
X+#if (defined(DLL) && defined(API_DOC))
X+                case ('A'):    /* extended help for API */
X+                    APIhelp(__G__ argc, argv);
X+                    *pargc = -1;  /* signal to exit successfully */
X+                    return 0;
X+#endif
X+                case ('b'):
X+                    if (negative) {
X+#if (defined(TANDEM) || defined(VMS))
X+                        uO.bflag = MAX(uO.bflag-negative,0);
X+#endif
X+                        negative = 0;   /* do nothing:  "-b" is default */
X+                    } else {
X+#ifdef VMS
X+                        if (uO.aflag == 0)
X+                           ++uO.bflag;
X+#endif
X+#ifdef TANDEM
X+                        ++uO.bflag;
X+#endif
X+                        uO.aflag = 0;
X+                    }
X+                    break;
X+#ifdef UNIXBACKUP
X+                case ('B'): /* -B: back up existing files */
X+                    if (negative)
X+                        uO.B_flag = FALSE, negative = 0;
X+                    else
X+                        uO.B_flag = TRUE;
X+                    break;
X+#endif
X+                case ('c'):
X+                    if (negative) {
X+                        uO.cflag = FALSE, negative = 0;
X+#ifdef NATIVE
X+                        uO.aflag = 0;
X+#endif
X+                    } else {
X+                        uO.cflag = TRUE;
X+#ifdef NATIVE
X+                        uO.aflag = 2;   /* so you can read it on the screen */
X+#endif
X+#ifdef DLL
X+                        if (G.redirect_text)
X+                            G.redirect_data = 2;
X+#endif
X+                    }
X+                    break;
X+#ifndef CMS_MVS
X+                case ('C'):    /* -C:  match filenames case-insensitively */
X+                    if (negative)
X+                        uO.C_flag = FALSE, negative = 0;
X+                    else
X+                        uO.C_flag = TRUE;
X+                    break;
X+#endif /* !CMS_MVS */
X+#if (!defined(SFX) || defined(SFX_EXDIR))
X+                case ('d'):
X+                    if (negative) {   /* negative not allowed with -d exdir */
X+                        Info(slide, 0x401, ((char *)slide,
X+                          LoadFarString(MustGiveExdir)));
X+                        return(PK_PARAM);  /* don't extract here by accident */
X+                    }
X+                    if (uO.exdir != (char *)NULL) {
X+                        Info(slide, 0x401, ((char *)slide,
X+                          LoadFarString(OnlyOneExdir)));
X+                        return(PK_PARAM);    /* GRR:  stupid restriction? */
X+                    } else {
X+                        /* first check for "-dexdir", then for "-d exdir" */
X+                        uO.exdir = s;
X+                        if (*uO.exdir == '\0') {
X+                            if (argc > 1) {
X+                                --argc;
X+                                uO.exdir = *++argv;
X+                                if (*uO.exdir == '-') {
X+                                    Info(slide, 0x401, ((char *)slide,
X+                                      LoadFarString(MustGiveExdir)));
X+                                    return(PK_PARAM);
X+                                }
X+                                /* else uO.exdir points at extraction dir */
X+                            } else {
X+                                Info(slide, 0x401, ((char *)slide,
X+                                  LoadFarString(MustGiveExdir)));
X+                                return(PK_PARAM);
X+                            }
X+                        }
X+                        /* uO.exdir now points at extraction dir (-dexdir or
X+                         *  -d exdir); point s at end of exdir to avoid mis-
X+                         *  interpretation of exdir characters as more options
X+                         */
X+                        if (*s != 0)
X+                            while (*++s != 0)
X+                                ;
X+                    }
X+                    break;
X+#endif /* !SFX || SFX_EXDIR */
X+                case ('e'):    /* just ignore -e, -x options (extract) */
X+                    break;
X+#ifdef MACOS
X+                case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
X+                    if( negative ) {
X+                        uO.E_flag = FALSE, negative = 0;
X+                    } else {
X+                        uO.E_flag = TRUE;
X+                    }
X+                    break;
X+#endif /* MACOS */
X+                case ('f'):    /* "freshen" (extract only newer files) */
X+                    if (negative)
X+                        uO.fflag = uO.uflag = FALSE, negative = 0;
X+                    else
X+                        uO.fflag = uO.uflag = TRUE;
X+                    break;
X+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
X+                case ('F'):    /* Acorn filetype & NFS extension handling */
X+                    if (negative)
X+                        uO.acorn_nfs_ext = FALSE, negative = 0;
X+                    else
X+                        uO.acorn_nfs_ext = TRUE;
X+                    break;
X+#endif /* RISCOS || ACORN_FTYPE_NFS */
X+                case ('h'):    /* just print help message and quit */
X+                    *pargc = -1;
X+                    return USAGE(PK_OK);
X+#ifdef MACOS
X+                case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
X+                    if( negative ) {
X+                        uO.i_flag = FALSE, negative = 0;
X+                    } else {
X+                        uO.i_flag = TRUE;
X+                    }
X+                    break;
X+#endif  /* MACOS */
X+                case ('j'):    /* junk pathnames/directory structure */
X+                    if (negative)
X+                        uO.jflag = FALSE, negative = 0;
X+                    else
X+                        uO.jflag = TRUE;
X+                    break;
X+#if (defined(ATH_BEO) || defined(MACOS))
X+                case ('J'):    /* Junk AtheOS, BeOS or MacOS file attributes */
X+                    if( negative ) {
X+                        uO.J_flag = FALSE, negative = 0;
X+                    } else {
X+                        uO.J_flag = TRUE;
X+                    }
X+                    break;
X+#endif /* ATH_BEO || MACOS */
X+#ifdef ATH_BEO_UNX
X+                case ('K'):
X+                    if (negative) {
X+                        uO.K_flag = FALSE, negative = 0;
X+                    } else {
X+                        uO.K_flag = TRUE;
X+                    }
X+                    break;
X+#endif /* ATH_BEO_UNX */
X+#ifndef SFX
X+                case ('l'):
X+                    if (negative) {
X+                        uO.vflag = MAX(uO.vflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.vflag;
X+                    break;
X+#endif /* !SFX */
X+#ifndef CMS_MVS
X+                case ('L'):    /* convert (some) filenames to lowercase */
X+                    if (negative) {
X+                        uO.L_flag = MAX(uO.L_flag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.L_flag;
X+                    break;
X+#endif /* !CMS_MVS */
X+#ifdef MORE
X+#ifdef CMS_MVS
X+                case ('m'):
X+#endif
X+                case ('M'):    /* send all screen output through "more" fn. */
X+/* GRR:  eventually check for numerical argument => height */
X+                    if (negative)
X+                        G.M_flag = FALSE, negative = 0;
X+                    else
X+                        G.M_flag = TRUE;
X+                    break;
X+#endif /* MORE */
X+                case ('n'):    /* don't overwrite any files */
X+                    if (negative)
X+                        uO.overwrite_none = FALSE, negative = 0;
X+                    else
X+                        uO.overwrite_none = TRUE;
X+                    break;
X+#ifdef AMIGA
X+                case ('N'):    /* restore comments as filenotes */
X+                    if (negative)
X+                        uO.N_flag = FALSE, negative = 0;
X+                    else
X+                        uO.N_flag = TRUE;
X+                    break;
X+#endif /* AMIGA */
X+                case ('o'):    /* OK to overwrite files without prompting */
X+                    if (negative) {
X+                        uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.overwrite_all;
X+                    break;
X+                case ('p'):    /* pipes:  extract to stdout, no messages */
X+                    if (negative) {
X+                        uO.cflag = FALSE;
X+                        uO.qflag = MAX(uO.qflag-999,0);
X+                        negative = 0;
X+                    } else {
X+                        uO.cflag = TRUE;
X+                        uO.qflag += 999;
X+                    }
X+                    break;
X+#if CRYPT
X+                /* GRR:  yes, this is highly insecure, but dozens of people
X+                 * have pestered us for this, so here we go... */
X+                case ('P'):
X+                    if (negative) {   /* negative not allowed with -P passwd */
X+                        Info(slide, 0x401, ((char *)slide,
X+                          LoadFarString(MustGivePasswd)));
X+                        return(PK_PARAM);  /* don't extract here by accident */
X+                    }
X+                    if (uO.pwdarg != (char *)NULL) {
X+/*
X+                        GRR:  eventually support multiple passwords?
X+                        Info(slide, 0x401, ((char *)slide,
X+                          LoadFarString(OnlyOnePasswd)));
X+                        return(PK_PARAM);
X+ */
X+                    } else {
X+                        /* first check for "-Ppasswd", then for "-P passwd" */
X+                        uO.pwdarg = s;
X+                        if (*uO.pwdarg == '\0') {
X+                            if (argc > 1) {
X+                                --argc;
X+                                uO.pwdarg = *++argv;
X+                                if (*uO.pwdarg == '-') {
X+                                    Info(slide, 0x401, ((char *)slide,
X+                                      LoadFarString(MustGivePasswd)));
X+                                    return(PK_PARAM);
X+                                }
X+                                /* else pwdarg points at decryption password */
X+                            } else {
X+                                Info(slide, 0x401, ((char *)slide,
X+                                  LoadFarString(MustGivePasswd)));
X+                                return(PK_PARAM);
X+                            }
X+                        }
X+                        /* pwdarg now points at decryption password (-Ppasswd or
X+                         *  -P passwd); point s at end of passwd to avoid mis-
X+                         *  interpretation of passwd characters as more options
X+                         */
X+                        if (*s != 0)
X+                            while (*++s != 0)
X+                                ;
X+                    }
X+                    break;
X+#endif /* CRYPT */
X+                case ('q'):    /* quiet:  fewer comments/messages */
X+                    if (negative) {
X+                        uO.qflag = MAX(uO.qflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.qflag;
X+                    break;
X+#ifdef QDOS
X+                case ('Q'):   /* QDOS flags */
X+                    qlflag ^= strtol(s, &s, 10);
X+                    break;    /* we XOR this as we can config qlflags */
X+#endif
X+#ifdef TANDEM
X+                case ('r'):    /* remove file extensions */
X+                    if (negative)
X+                        uO.rflag = FALSE, negative = 0;
X+                    else
X+                        uO.rflag = TRUE;
X+                    break;
X+#endif /* TANDEM */
X+#ifdef DOS_FLX_NLM_OS2_W32
X+                case ('s'):    /* spaces in filenames:  allow by default */
X+                    if (negative)
X+                        uO.sflag = FALSE, negative = 0;
X+                    else
X+                        uO.sflag = TRUE;
X+                    break;
X+#endif /* DOS_FLX_NLM_OS2_W32 */
X+                case ('t'):
X+                    if (negative)
X+                        uO.tflag = FALSE, negative = 0;
X+                    else
X+                        uO.tflag = TRUE;
X+                    break;
X+#ifdef TIMESTAMP
X+                case ('T'):
X+                    if (negative)
X+                        uO.T_flag = FALSE, negative = 0;
X+                    else
X+                        uO.T_flag = TRUE;
X+                    break;
X+#endif
X+                case ('u'):    /* update (extract only new and newer files) */
X+                    if (negative)
X+                        uO.uflag = FALSE, negative = 0;
X+                    else
X+                        uO.uflag = TRUE;
X+                    break;
X+#ifndef CMS_MVS
X+                case ('U'):    /* obsolete; to be removed in version 6.0 */
X+                    if (negative)
X+                        uO.L_flag = TRUE, negative = 0;
X+                    else
X+                        uO.L_flag = FALSE;
X+                    break;
X+#endif /* !CMS_MVS */
X+#ifndef SFX
X+                case ('v'):    /* verbose */
X+                    if (negative) {
X+                        uO.vflag = MAX(uO.vflag-negative,0);
X+                        negative = 0;
X+                    } else if (uO.vflag)
X+                        ++uO.vflag;
X+                    else
X+                        uO.vflag = 2;
X+                    break;
X+#endif /* !SFX */
X+#ifndef CMS_MVS
X+                case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
X+                    if (negative)
X+                        uO.V_flag = FALSE, negative = 0;
X+                    else
X+                        uO.V_flag = TRUE;
X+                    break;
X+#endif /* !CMS_MVS */
X+#ifdef WILD_STOP_AT_DIR
X+                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
X+                    if (negative)
X+                        uO.W_flag = FALSE, negative = 0;
X+                    else
X+                        uO.W_flag = TRUE;
X+                    break;
X+#endif /* WILD_STOP_AT_DIR */
X+                case ('x'):    /* extract:  default */
X+#ifdef SFX
X+                    /* when 'x' is the only option in this argument, and the
X+                     * next arg is not an option, assume this initiates an
X+                     * exclusion list (-x xlist):  terminate option-scanning
X+                     * and leave uz_opts with argv still pointing to "-x";
X+                     * the xlist is processed later
X+                     */
X+                    if (s - argv[0] == 2 && *s == '\0' &&
X+                        argc > 1 && argv[1][0] != '-') {
X+                        /* break out of nested loops without "++argv;--argc" */
X+                        goto opts_done;
X+                    }
X+#endif /* SFX */
X+                    break;
X+#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
X+                case ('X'):   /* restore owner/protection info (need privs?) */
X+                    if (negative) {
X+                        uO.X_flag = MAX(uO.X_flag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.X_flag;
X+                    break;
X+#endif /* RESTORE_UIDGID || RESTORE_ACL */
X+                case ('z'):    /* display only the archive comment */
X+                    if (negative) {
X+                        uO.zflag = MAX(uO.zflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.zflag;
X+                    break;
X+#ifndef SFX
X+                case ('Z'):    /* should have been first option (ZipInfo) */
X+                    Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
X+                    error = TRUE;
X+                    break;
X+#endif /* !SFX */
X+#ifdef DOS_H68_OS2_W32
X+                case ('$'):
X+                    if (negative) {
X+                        uO.volflag = MAX(uO.volflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.volflag;
X+                    break;
X+#endif /* DOS_H68_OS2_W32 */
X+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
X+                case (':'):
X+                    if (negative) {
X+                        uO.ddotflag = MAX(uO.ddotflag-negative,0);
X+                        negative = 0;
X+                    } else
X+                        ++uO.ddotflag;
X+                    break;
X+#endif /* !RISCOS && !CMS_MVS && !TANDEM */
X+                default:
X+                    error = TRUE;
X+                    break;
X+
X+            } /* end switch */
X+        } /* end while (not end of argument string) */
X+    } /* end while (not done with switches) */
X+
X+/*---------------------------------------------------------------------------
X+    Check for nonsensical combinations of options.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef SFX
X+opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
X+#endif
X+
X+    if ((uO.cflag && uO.tflag) || (uO.cflag && uO.uflag) ||
X+        (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
X+    {
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
X+        error = TRUE;
X+    }
X+    if (uO.aflag > 2)
X+        uO.aflag = 2;
X+#ifdef VMS
X+    if (uO.bflag > 2)
X+        uO.bflag = 2;
X+#endif
X+    if (uO.overwrite_all && uO.overwrite_none) {
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
X+        uO.overwrite_all = FALSE;
X+    }
X+#ifdef MORE
X+    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func. useless */
X+        G.M_flag = 0;
X+#endif
X+
X+#ifdef SFX
X+    if (error)
X+#else
X+    if ((argc-- == 0) || error)
X+#endif
X+    {
X+        *pargc = argc;
X+        *pargv = argv;
X+#ifndef SFX
X+        if (uO.vflag >= 2 && argc == -1) {              /* "unzip -v" */
X+            show_version_info(__G);
X+            return PK_OK;
X+        }
X+        if (!G.noargs && !error)
X+            error = PK_PARAM;   /* had options (not -h or -v) but no zipfile */
X+#endif /* !SFX */
X+        return USAGE(error);
X+    }
X+
X+#ifdef SFX
X+    /* print our banner unless we're being fairly quiet */
X+    if (uO.qflag < 2)
X+        Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
X+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
X+          LoadFarStringSmall(VersionDate)));
X+#ifdef BETA
X+    /* always print the beta warning:  no unauthorized distribution!! */
X+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
X+      "SFX"));
X+#endif
X+#endif /* SFX */
X+
X+    if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
X+#ifdef TIMESTAMP
X+                                                     || uO.T_flag
X+#endif
X+                                                                 )
X+        G.extract_flag = FALSE;
X+    else
X+        G.extract_flag = TRUE;
X+
X+    *pargc = argc;
X+    *pargv = argv;
X+    return PK_OK;
X+
X+} /* end function uz_opts() */
X+
X+
X+
X+
X+/********************/
X+/* Function usage() */
X+/********************/
X+
X+#ifdef SFX
X+#  ifdef VMS
X+#    define LOCAL "X.\n\
X+(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
X+#  endif
X+#  ifdef UNIX
X+#    define LOCAL "X"
X+#  endif
X+#  ifdef DOS_OS2_W32
X+#    define LOCAL "s$"
X+#  endif
X+#  if (defined(FLEXOS) || defined(NLM))
X+#    define LOCAL "s"
X+#  endif
X+#  ifdef AMIGA
X+#    define LOCAL "N"
X+#  endif
X+   /* Default for all other systems: */
X+#  ifndef LOCAL
X+#    define LOCAL ""
X+#  endif
X+
X+#  ifdef MORE
X+#    define SFXOPT1 "M"
X+#  else
X+#    define SFXOPT1 ""
X+#  endif
X+
X+int usage(__G__ error)   /* return PK-type error code */
X+    __GDEF
X+    int error;
X+{
X+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
X+      UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
X+      LoadFarStringSmall(VersionDate)));
X+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
X+      SFXOPT1, LOCAL));
X+#ifdef BETA
X+    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
X+      "SFX"));
X+#endif
X+
X+    if (error)
X+        return PK_PARAM;
X+    else
X+        return PK_COOL;     /* just wanted usage screen: no error */
X+
X+} /* end function usage() */
X+
X+
X+
X+
X+
X+#else /* !SFX */
X+#  ifdef VMS
X+#    define QUOT '\"'
X+#    define QUOTS "\""
X+#  else
X+#    define QUOT ' '
X+#    define QUOTS ""
X+#  endif
X+
X+int usage(__G__ error)   /* return PK-type error code */
X+    __GDEF
X+    int error;
X+{
X+    int flag = (error? 1 : 0);
X+
X+
X+/*---------------------------------------------------------------------------
X+    Print either ZipInfo usage or UnZip usage, depending on incantation.
X+    (Strings must be no longer than 512 bytes for Turbo C, apparently.)
X+  ---------------------------------------------------------------------------*/
X+
X+    if (uO.zipinfo_mode) {
X+
X+#ifndef NO_ZIPINFO
X+
X+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
X+          ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
X+          LoadFarStringSmall(VersionDate),
X+          LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
X+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
X+        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
X+          QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(ZipInfoUsageLine4)));
X+#ifdef VMS
X+        Info(slide, flag, ((char *)slide, "\n\
X+You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
X+\n"));
X+#endif
X+
X+#endif /* !NO_ZIPINFO */
X+
X+    } else {   /* UnZip mode */
X+
X+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
X+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
X+          LoadFarStringSmall(VersionDate)));
X+#ifdef BETA
X+        Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
X+#endif
X+
X+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
X+          ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
X+#ifdef VMS
X+        if (!error)  /* maybe no command-line tail found; show extra help */
X+            Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
X+#endif
X+
X+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
X+          LoadFarStringSmall(local1)));
X+
X+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
X+          QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(local2), QUOT,QUOT,
X+          LoadFarStringSmall2(local3)));
X+
X+        /* This is extra work for SMALL_MEM, but it will work since
X+         * LoadFarStringSmall2 uses the same buffer.  Remember, this
X+         * is a hack. */
X+        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
X+          LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
X+          LoadFarStringSmall2(Example3)));
X+
X+    } /* end if (uO.zipinfo_mode) */
X+
X+    if (error)
X+        return PK_PARAM;
X+    else
X+        return PK_COOL;     /* just wanted usage screen: no error */
X+
X+} /* end function usage() */
X+
X+#endif /* ?SFX */
X+
X+
X+
X+
X+#ifndef SFX
X+
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+#if (!defined(MODERN) || defined(NO_STDLIB_H))
X+/* Declare getenv() to be sure (might be missing in some environments) */
X+extern char *getenv();
X+#endif
X+#endif
X+
X+/********************************/
X+/* Function show_version_info() */
X+/********************************/
X+
X+static void show_version_info(__G)
X+    __GDEF
X+{
X+    if (uO.qflag > 3)                           /* "unzip -vqqqq" */
X+        Info(slide, 0, ((char *)slide, "%d\n",
X+          (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
X+    else {
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+        char *envptr;
X+#endif
X+        int numopts = 0;
X+
X+        Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
X+          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
X+          LoadFarStringSmall(VersionDate)));
X+        Info(slide, 0, ((char *)slide,
X+          LoadFarString(UnzipUsageLine2v)));
X+        version(__G);
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
X+#ifdef ACORN_FTYPE_NFS
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(AcornFtypeNFS)));
X+        ++numopts;
X+#endif
X+#ifdef ASM_CRC
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(AsmCRC)));
X+        ++numopts;
X+#endif
X+#ifdef ASM_INFLATECODES
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(AsmInflateCodes)));
X+        ++numopts;
X+#endif
X+#ifdef CHECK_VERSIONS
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Check_Versions)));
X+        ++numopts;
X+#endif
X+#ifdef COPYRIGHT_CLEAN
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Copyright_Clean)));
X+        ++numopts;
X+#endif
X+#ifdef DEBUG
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(UDebug)));
X+        ++numopts;
X+#endif
X+#ifdef DEBUG_TIME
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(DebugTime)));
X+        ++numopts;
X+#endif
X+#ifdef DLL
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Dll)));
X+        ++numopts;
X+#endif
X+#ifdef DOSWILD
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(DosWild)));
X+        ++numopts;
X+#endif
X+#ifdef LZW_CLEAN
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(LZW_Clean)));
X+        ++numopts;
X+#endif
X+#ifndef MORE
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(No_More)));
X+        ++numopts;
X+#endif
X+#ifdef NO_ZIPINFO
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(No_ZipInfo)));
X+        ++numopts;
X+#endif
X+#ifdef NTSD_EAS
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(NTSDExtAttrib)));
X+        ++numopts;
X+#endif
X+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(W32NoIZTimeFix)));
X+        ++numopts;
X+#endif
X+#ifdef OLD_THEOS_EXTRA
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(OldTheosExtra)));
X+        ++numopts;
X+#endif
X+#ifdef OS2_EAS
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(OS2ExtAttrib)));
X+        ++numopts;
X+#endif
X+#ifdef QLZIP
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(SMSExFldOnUnix)));
X+        ++numopts;
X+#endif
X+#ifdef REENTRANT
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Reentrant)));
X+        ++numopts;
X+#endif
X+#ifdef REGARGS
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(RegArgs)));
X+        ++numopts;
X+#endif
X+#ifdef RETURN_CODES
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Return_Codes)));
X+        ++numopts;
X+#endif
X+#ifdef SET_DIR_ATTRIB
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(SetDirAttrib)));
X+        ++numopts;
X+#endif
X+#ifdef TIMESTAMP
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(TimeStamp)));
X+        ++numopts;
X+#endif
X+#ifdef UNIXBACKUP
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(UnixBackup)));
X+        ++numopts;
X+#endif
X+#ifdef USE_EF_UT_TIME
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_EF_UT_time)));
X+        ++numopts;
X+#endif
X+#ifndef COPYRIGHT_CLEAN
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_Smith_Code)));
X+        ++numopts;
X+#endif
X+#ifndef LZW_CLEAN
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_Unshrink)));
X+        ++numopts;
X+#endif
X+#ifdef USE_DEFLATE64
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_Deflate64)));
X+        ++numopts;
X+#endif
X+#ifdef MULT_VOLUME
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_MultiVol)));
X+        ++numopts;
X+#endif
X+#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
X+#  ifdef USE_DJGPP_ENV
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_DJGPP_Env)));
X+        ++numopts;
X+#  endif
X+#  ifdef USE_DJGPP_GLOB
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_DJGPP_Glob)));
X+        ++numopts;
X+#  endif
X+#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
X+#ifdef USE_VFAT
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(Use_VFAT_support)));
X+        ++numopts;
X+#endif
X+#ifdef USE_ZLIB
X+        sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
X+          ZLIB_VERSION, zlibVersion());
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          (char *)(slide+256)));
X+        ++numopts;
X+#endif
X+#ifdef VMS_TEXT_CONV
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(VmsTextConv)));
X+        ++numopts;
X+#endif
X+#ifdef VMSCLI
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(VmsCLI)));
X+        ++numopts;
X+#endif
X+#ifdef VMSWILD
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(VmsWild)));
X+        ++numopts;
X+#endif
X+#ifdef WILD_STOP_AT_DIR
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(WildStopAtDir)));
X+        ++numopts;
X+#endif
X+#if CRYPT
X+# ifdef PASSWD_FROM_STDIN
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
X+          LoadFarStringSmall(PasswdStdin)));
X+# endif
X+        Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
X+          CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
X+          LoadFarStringSmall(CryptDate)));
X+        ++numopts;
X+#endif /* CRYPT */
X+        if (numopts == 0)
X+            Info(slide, 0, ((char *)slide,
X+              LoadFarString(CompileOptFormat),
X+              LoadFarStringSmall(None)));
X+
X+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
X+        envptr = getenv(LoadFarStringSmall(EnvUnZip));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvUnZip),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+        envptr = getenv(LoadFarStringSmall(EnvUnZip2));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvUnZip2),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+        envptr = getenv(LoadFarStringSmall(EnvZipInfo));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvZipInfo),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+        envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvZipInfo2),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+#ifndef __RSXNT__
X+#ifdef __EMX__
X+        envptr = getenv(LoadFarStringSmall(EnvEMX));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvEMX),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+        envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvEMXOPT),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+#endif /* __EMX__ */
X+#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
X+        envptr = getenv(LoadFarStringSmall(EnvGO32));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvGO32),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+        envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvGO32TMP),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+#endif /* __GO32__ && !(__DJGPP__ >= 2) */
X+#endif /* !__RSXNT__ */
X+#ifdef RISCOS
X+        envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
X+        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
X+          LoadFarStringSmall(EnvUnZipExts),
X+          (envptr == (char *)NULL || *envptr == 0)?
X+          LoadFarStringSmall2(None) : envptr));
X+#endif /* RISCOS */
X+#endif /* !_WIN32_WCE */
X+    }
X+} /* end function show_version() */
X+
X+#endif /* !SFX */
X+#endif /* !WINDLL */
Xdiff -ruN ../unzip-5.52.orig/unzip.h ./unzip.h
X--- ../unzip-5.52.orig/unzip.h	2005-02-27 00:23:18.000000000 +0900
X+++ ./unzip.h	2008-03-08 07:16:58.000000000 +0900
X@@ -427,6 +427,10 @@
X #ifndef FUNZIP
X     char *exdir;        /* pointer to extraction root directory (-d option) */
X     char *pwdarg;       /* pointer to command-line password (-P option) */
X+#ifdef NLS
X+    char *charenc_sys;  /* character encoding for the system. */
X+    char *charenc_arch; /* character encoding for an archive. */
X+#endif
X     int zipinfo_mode;   /* behave like ZipInfo or like normal UnZip? */
X     int aflag;          /* -a: do ASCII-EBCDIC and/or end-of-line translation */
X #ifdef VMS
Xdiff -ruN ../unzip-5.52.orig/unzip.h.orig ./unzip.h.orig
X--- ../unzip-5.52.orig/unzip.h.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./unzip.h.orig	2005-02-27 00:23:18.000000000 +0900
X@@ -0,0 +1,658 @@
X+/*---------------------------------------------------------------------------
X+
X+  unzip.h (new)
X+
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  This header file contains the public macros and typedefs required by
X+  both the UnZip sources and by any application using the UnZip API.  If
X+  UNZIP_INTERNAL is defined, it includes unzpriv.h (containing includes,
X+  prototypes and extern variables used by the actual UnZip sources).
X+
X+  ---------------------------------------------------------------------------*/
X+/*---------------------------------------------------------------------------
X+This is version 2005-Feb-10 of the Info-ZIP copyright and license.
X+The definitive version of this document should be available at
X+ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
X+
X+
X+Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+For the purposes of this copyright and license, "Info-ZIP" is defined as
X+the following set of individuals:
X+
X+   Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
X+   Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth,
X+   Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
X+   David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
X+   Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
X+   Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda,
X+   Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren,
X+   Rich Wales, Mike White
X+
X+This software is provided "as is," without warranty of any kind, express
X+or implied.  In no event shall Info-ZIP or its contributors be held liable
X+for any direct, indirect, incidental, special or consequential damages
X+arising out of the use of or inability to use this software.
X+
X+Permission is granted to anyone to use this software for any purpose,
X+including commercial applications, and to alter it and redistribute it
X+freely, subject to the following restrictions:
X+
X+    1. Redistributions of source code must retain the above copyright notice,
X+       definition, disclaimer, and this list of conditions.
X+
X+    2. Redistributions in binary form (compiled executables) must reproduce
X+       the above copyright notice, definition, disclaimer, and this list of
X+       conditions in documentation and/or other materials provided with the
X+       distribution.  The sole exception to this condition is redistribution
X+       of a standard UnZipSFX binary (including SFXWiz) as part of a
X+       self-extracting archive; that is permitted without inclusion of this
X+       license, as long as the normal SFX banner has not been removed from
X+       the binary or disabled.
X+
X+    3. Altered versions--including, but not limited to, ports to new operating
X+       systems, existing ports with new graphical interfaces, and dynamic,
X+       shared, or static library versions--must be plainly marked as such
X+       and must not be misrepresented as being the original source.  Such
X+       altered versions also must not be misrepresented as being Info-ZIP
X+       releases--including, but not limited to, labeling of the altered
X+       versions with the names "Info-ZIP" (or any variation thereof, including,
X+       but not limited to, different capitalizations), "Pocket UnZip," "WiZ"
X+       or "MacZip" without the explicit permission of Info-ZIP.  Such altered
X+       versions are further prohibited from misrepresentative use of the
X+       Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s).
X+
X+    4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
X+       "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its
X+       own source and binary releases.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef __unzip_h   /* prevent multiple inclusions */
X+#define __unzip_h
X+
X+/*---------------------------------------------------------------------------
X+    Predefined, machine-specific macros.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef __GO32__                 /* MS-DOS extender:  NOT Unix */
X+#  ifdef unix
X+#    undef unix
X+#  endif
X+#  ifdef _unix
X+#    undef _unix
X+#  endif
X+#  ifdef __unix
X+#    undef __unix
X+#  endif
X+#  ifdef __unix__
X+#    undef __unix__
X+#  endif
X+#endif
X+
X+#if ((defined(__convex__) || defined(__convexc__)) && !defined(CONVEX))
X+#  define CONVEX
X+#endif
X+
X+#if (defined(unix) || defined(_unix) || defined(__unix) || defined(__unix__))
X+#  ifndef UNIX
X+#    define UNIX
X+#  endif
X+#endif /* unix || _unix || __unix || __unix__ */
X+#if (defined(M_XENIX) || defined(COHERENT) || defined(__hpux))
X+#  ifndef UNIX
X+#    define UNIX
X+#  endif
X+#endif /* M_XENIX || COHERENT || __hpux */
X+#if (defined(__NetBSD__) || defined(__FreeBSD__))
X+#  ifndef UNIX
X+#    define UNIX
X+#  endif
X+#endif /* __NetBSD__ || __FreeBSD__ */
X+#if (defined(CONVEX) || defined(MINIX) || defined(_AIX) || defined(__QNX__))
X+#  ifndef UNIX
X+#    define UNIX
X+#  endif
X+#endif /* CONVEX || MINIX || _AIX || __QNX__ */
X+
X+#if (defined(VM_CMS) || defined(MVS))
X+#  define CMS_MVS
X+#endif
X+
X+#if (defined(__OS2__) && !defined(OS2))
X+#  define OS2
X+#endif
X+
X+#if (defined(__TANDEM) && !defined(TANDEM))
X+#  define TANDEM
X+#endif
X+
X+#if (defined(__VMS) && !defined(VMS))
X+#  define VMS
X+#endif
X+
X+#if ((defined(__WIN32__) || defined(_WIN32)) && !defined(WIN32))
X+#  define WIN32
X+#endif
X+#if ((defined(__WINNT__) || defined(__WINNT)) && !defined(WIN32))
X+#  define WIN32
X+#endif
X+
X+#if defined(_WIN32_WCE)
X+#  ifndef WIN32         /* WinCE is treated as a variant of the Win32 API */
X+#    define WIN32
X+#  endif
X+#  ifndef UNICODE       /* WinCE requires UNICODE wide character support */
X+#    define UNICODE
X+#  endif
X+#endif
X+
X+#ifdef __COMPILER_KCC__
X+#  include <c-env.h>
X+#  ifdef SYS_T20
X+#    define TOPS20
X+#  endif
X+#endif /* __COMPILER_KCC__ */
X+
X+/* Borland C does not define __TURBOC__ if compiling for a 32-bit platform */
X+#ifdef __BORLANDC__
X+#  ifndef __TURBOC__
X+#    define __TURBOC__
X+#  endif
X+#  if (!defined(__MSDOS__) && !defined(OS2) && !defined(WIN32))
X+#    define __MSDOS__
X+#  endif
X+#endif
X+
X+/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C */
X+#ifdef __POWERC
X+#  define __TURBOC__
X+#  define MSDOS
X+#endif /* __POWERC */
X+
X+#if (defined(__MSDOS__) && !defined(MSDOS))   /* just to make sure */
X+#  define MSDOS
X+#endif
X+
X+/* RSXNTDJ (at least up to v1.3) compiles for WIN32 (RSXNT) using a derivate
X+   of the EMX environment, but defines MSDOS and __GO32__. ARG !!! */
X+#if (defined(MSDOS) && defined(WIN32))
X+#  undef MSDOS                  /* WIN32 is >>>not<<< MSDOS */
X+#endif
X+#if (defined(__GO32__) && defined(__EMX__) && defined(__RSXNT__))
X+#  undef __GO32__
X+#endif
X+
X+#if (defined(linux) && !defined(LINUX))
X+#  define LINUX
X+#endif
X+
X+#ifdef __riscos
X+#  define RISCOS
X+#endif
X+
X+#if (defined(THINK_C) || defined(MPW))
X+#  define MACOS
X+#endif
X+#if (defined(__MWERKS__) && defined(macintosh))
X+#  define MACOS
X+#endif
X+
X+/* use prototypes and ANSI libraries if __STDC__, or MS-DOS, or OS/2, or Win32,
X+ * or IBM C Set/2, or Borland C, or Watcom C, or GNU gcc (emx or Cygwin),
X+ * or Macintosh, or Sequent, or Atari, or IBM RS/6000, or Silicon Graphics,
X+ * or Convex?, or AtheOS, or BeOS.
X+ */
X+#if (defined(__STDC__) || defined(MSDOS) || defined(OS2) || defined(WIN32))
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+#if (defined(__IBMC__) || defined(__BORLANDC__) || defined(__WATCOMC__))
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+#if (defined(__EMX__) || defined(__CYGWIN__))
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+#if (defined(MACOS) || defined(ATARI_ST) || defined(RISCOS) || defined(THEOS))
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+/* Sequent running Dynix/ptx:  non-modern compiler */
X+#if (defined(_AIX) || defined(sgi) || (defined(_SEQUENT_) && !defined(PTX)))
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+#if (defined(CMS_MVS) || defined(__ATHEOS__) || defined(__BEOS__))
X+/* || defined(CONVEX) ? */
X+#  ifndef PROTO
X+#    define PROTO
X+#  endif
X+#  ifndef MODERN
X+#    define MODERN
X+#  endif
X+#endif
X+
X+/* turn off prototypes if requested */
X+#if (defined(NOPROTO) && defined(PROTO))
X+#  undef PROTO
X+#endif
X+
X+/* used to remove arguments in function prototypes for non-ANSI C */
X+#ifdef PROTO
X+#  define OF(a) a
X+#else
X+#  define OF(a) ()
X+#endif
X+
X+/* enable the "const" keyword only if MODERN and if not otherwise instructed */
X+#ifdef MODERN
X+#  if (!defined(ZCONST) && (defined(USE_CONST) || !defined(NO_CONST)))
X+#    define ZCONST const
X+#  endif
X+#endif
X+
X+#ifndef ZCONST
X+#  define ZCONST
X+#endif
X+
X+
X+/*---------------------------------------------------------------------------
X+    Grab system-specific public include headers.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef POCKET_UNZIP             /* WinCE port */
X+#  include "wince/punzip.h"     /* must appear before windows.h */
X+#endif
X+
X+#ifdef WINDLL
X+   /* for UnZip, the "basic" part of the win32 api is sufficient */
X+#  ifndef WIN32_LEAN_AND_MEAN
X+#    define WIN32_LEAN_AND_MEAN
X+#    define IZ_HASDEFINED_WIN32LEAN
X+#  endif
X+#  include <windows.h>
X+#  include "windll/structs.h"
X+#  ifdef IZ_HASDEFINED_WIN32LEAN
X+#    undef WIN32_LEAN_AND_MEAN
X+#    undef IZ_HASDEFINED_WIN32LEAN
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Grab system-dependent definition of EXPENTRY for prototypes below.
X+  ---------------------------------------------------------------------------*/
X+
X+#if 0
X+#if (defined(OS2) && !defined(FUNZIP))
X+#  ifdef UNZIP_INTERNAL
X+#    define INCL_NOPM
X+#    define INCL_DOSNLS
X+#    define INCL_DOSPROCESS
X+#    define INCL_DOSDEVICES
X+#    define INCL_DOSDEVIOCTL
X+#    define INCL_DOSERRORS
X+#    define INCL_DOSMISC
X+#    ifdef OS2DLL
X+#      define INCL_REXXSAA
X+#      include <rexxsaa.h>
X+#    endif
X+#  endif /* UNZIP_INTERNAL */
X+#  include <os2.h>
X+#  define UZ_EXP EXPENTRY
X+#endif /* OS2 && !FUNZIP */
X+#endif /* 0 */
X+
X+#if (defined(OS2) && !defined(FUNZIP))
X+#  if (defined(__IBMC__) || defined(__WATCOMC__))
X+#    define UZ_EXP  _System    /* compiler keyword */
X+#  else
X+#    define UZ_EXP
X+#  endif
X+#endif /* OS2 && !FUNZIP */
X+
X+#if (defined(WINDLL) || defined(USE_UNZIP_LIB))
X+#  ifndef EXPENTRY
X+#    define UZ_EXP WINAPI
X+#  else
X+#    define UZ_EXP EXPENTRY
X+#  endif
X+#endif
X+
X+#ifndef UZ_EXP
X+#  define UZ_EXP
X+#endif
X+
X+#ifdef __cplusplus
X+extern "C" {
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Public typedefs.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef _IZ_TYPES_DEFINED
X+#ifdef MODERN
X+   typedef void zvoid;
X+#else /* !MODERN */
X+#  ifndef AOS_VS         /* mostly modern? */
X+#    ifndef VAXC         /* not fully modern, but has knows 'void' */
X+#      define void int
X+#    endif /* !VAXC */
X+#  endif /* !AOS_VS */
X+   typedef char zvoid;
X+#endif /* ?MODERN */
X+typedef unsigned char   uch;    /* code assumes unsigned bytes; these type-  */
X+typedef unsigned short  ush;    /*  defs replace byte/UWORD/ULONG (which are */
X+typedef unsigned long   ulg;    /*  predefined on some systems) & match zip  */
X+#define _IZ_TYPES_DEFINED
X+#endif /* !_IZ_TYPES_DEFINED */
X+
X+/* InputFn is not yet used and is likely to change: */
X+#ifdef PROTO
X+   typedef int   (UZ_EXP MsgFn)     (zvoid *pG, uch *buf, ulg size, int flag);
X+   typedef int   (UZ_EXP InputFn)   (zvoid *pG, uch *buf, int *size, int flag);
X+   typedef void  (UZ_EXP PauseFn)   (zvoid *pG, ZCONST char *prompt, int flag);
X+   typedef int   (UZ_EXP PasswdFn)  (zvoid *pG, int *rcnt, char *pwbuf,
X+                                     int size, ZCONST char *zfn,
X+                                     ZCONST char *efn);
X+   typedef int   (UZ_EXP StatCBFn)  (zvoid *pG, int fnflag, ZCONST char *zfn,
X+                                     ZCONST char *efn, ZCONST zvoid *details);
X+   typedef void  (UZ_EXP UsrIniFn)  (void);
X+#else /* !PROTO */
X+   typedef int   (UZ_EXP MsgFn)     ();
X+   typedef int   (UZ_EXP InputFn)   ();
X+   typedef void  (UZ_EXP PauseFn)   ();
X+   typedef int   (UZ_EXP PasswdFn)  ();
X+   typedef int   (UZ_EXP StatCBFn)  ();
X+   typedef void  (UZ_EXP UsrIniFn)  ();
X+#endif /* ?PROTO */
X+
X+typedef struct _UzpBuffer {    /* rxstr */
X+    ulg   strlength;           /* length of string */
X+    char  *strptr;             /* pointer to string */
X+} UzpBuffer;
X+
X+typedef struct _UzpInit {
X+    ulg structlen;             /* length of the struct being passed */
X+
X+    /* GRR: can we assume that each of these is a 32-bit pointer?  if not,
X+     * does it matter? add "far" keyword to make sure? */
X+    MsgFn *msgfn;
X+    InputFn *inputfn;
X+    PauseFn *pausefn;
X+    UsrIniFn *userfn;          /* user init function to be called after */
X+                               /*  globals constructed and initialized */
X+
X+    /* pointer to program's environment area or something? */
X+    /* hooks for performance testing? */
X+    /* hooks for extra unzip -v output? (detect CPU or other hardware?) */
X+    /* anything else?  let me (Greg) know... */
X+} UzpInit;
X+
X+typedef struct _UzpCB {
X+    ulg structlen;             /* length of the struct being passed */
X+    /* GRR: can we assume that each of these is a 32-bit pointer?  if not,
X+     * does it matter? add "far" keyword to make sure? */
X+    MsgFn *msgfn;
X+    InputFn *inputfn;
X+    PauseFn *pausefn;
X+    PasswdFn *passwdfn;
X+    StatCBFn *statrepfn;
X+} UzpCB;
X+
X+/* the collection of general UnZip option flags and option arguments */
X+typedef struct _UzpOpts {
X+#ifndef FUNZIP
X+    char *exdir;        /* pointer to extraction root directory (-d option) */
X+    char *pwdarg;       /* pointer to command-line password (-P option) */
X+    int zipinfo_mode;   /* behave like ZipInfo or like normal UnZip? */
X+    int aflag;          /* -a: do ASCII-EBCDIC and/or end-of-line translation */
X+#ifdef VMS
X+    int bflag;          /* -b: force fixed record format for binary files */
X+#endif
X+#ifdef TANDEM
X+    int bflag;          /* -b: create text files in 'C' format (180)*/
X+#endif
X+#ifdef UNIXBACKUP
X+    int B_flag;         /* -B: back up existing files by renaming to *~ first */
X+#endif
X+    int cflag;          /* -c: output to stdout */
X+    int C_flag;         /* -C: match filenames case-insensitively */
X+#ifdef MACOS
X+    int E_flag;         /* -E: [MacOS] show Mac extra field during restoring */
X+#endif
X+    int fflag;          /* -f: "freshen" (extract only newer files) */
X+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
X+    int acorn_nfs_ext;  /* -F: RISC OS types & NFS filetype extensions */
X+#endif
X+    int hflag;          /* -h: header line (zipinfo) */
X+#ifdef MACOS
X+    int i_flag;         /* -i: [MacOS] ignore filenames stored in Mac e.f. */
X+#endif
X+#ifdef RISCOS
X+    int scanimage;      /* -I: scan image files */
X+#endif
X+    int jflag;          /* -j: junk pathnames (unzip) */
X+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(MACOS))
X+    int J_flag;         /* -J: ignore AtheOS/BeOS/MacOS e. f. info (unzip) */
X+#endif
X+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
X+    int K_flag;         /* -K: keep setuid/setgid/tacky permissions */
X+#endif
X+    int lflag;          /* -12slmv: listing format (zipinfo) */
X+    int L_flag;         /* -L: convert filenames from some OSes to lowercase */
X+    int overwrite_none; /* -n: never overwrite files (no prompting) */
X+#ifdef AMIGA
X+    int N_flag;         /* -N: restore comments as AmigaDOS filenotes */
X+#endif
X+    int overwrite_all;  /* -o: OK to overwrite files without prompting */
X+#endif /* !FUNZIP */
X+    int qflag;          /* -q: produce a lot less output */
X+#ifdef TANDEM
X+    int rflag;          /* -r: remove file extensions */
X+#endif
X+#ifndef FUNZIP
X+#if (defined(MSDOS) || defined(FLEXOS) || defined(OS2) || defined(WIN32))
X+    int sflag;          /* -s: convert spaces in filenames to underscores */
X+#endif
X+#if (defined(NLM))
X+    int sflag;          /* -s: convert spaces in filenames to underscores */
X+#endif
X+#if (defined(MSDOS) || defined(__human68k__) || defined(OS2) || defined(WIN32))
X+    int volflag;        /* -$: extract volume labels */
X+#endif
X+    int tflag;          /* -t: test (unzip) or totals line (zipinfo) */
X+    int T_flag;         /* -T: timestamps (unzip) or dec. time fmt (zipinfo) */
X+    int uflag;          /* -u: "update" (extract only newer/brand-new files) */
X+    int vflag;          /* -v: (verbosely) list directory */
X+    int V_flag;         /* -V: don't strip VMS version numbers */
X+    int W_flag;         /* -W: wildcard '*' won't match '/' dir separator */
X+#if (defined (__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
X+    int X_flag;         /* -X: restore owner/protection or UID/GID or ACLs */
X+#else
X+#if (defined(TANDEM) || defined(THEOS))
X+    int X_flag;         /* -X: restore owner/protection or UID/GID or ACLs */
X+#else
X+#if (defined(OS2) || defined(VMS) || defined(WIN32))
X+    int X_flag;         /* -X: restore owner/protection or UID/GID or ACLs */
X+#endif
X+#endif
X+#endif
X+    int zflag;          /* -z: display the zipfile comment (only, for unzip) */
X+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
X+    int ddotflag;       /* -:: don't skip over "../" path elements */
X+#endif
X+#endif /* !FUNZIP */
X+} UzpOpts;
X+
X+/* intended to be a private struct: */
X+typedef struct _ver {
X+    uch major;              /* e.g., integer 5 */
X+    uch minor;              /* e.g., 2 */
X+    uch patchlevel;         /* e.g., 0 */
X+    uch not_used;
X+} _version_type;
X+
X+typedef struct _UzpVer {
X+    ulg structlen;          /* length of the struct being passed */
X+    ulg flag;               /* bit 0: is_beta   bit 1: uses_zlib */
X+    char *betalevel;        /* e.g., "g BETA" or "" */
X+    char *date;             /* e.g., "4 Sep 95" (beta) or "4 September 1995" */
X+    char *zlib_version;     /* e.g., "0.95" or NULL */
X+    _version_type unzip;
X+    _version_type zipinfo;
X+    _version_type os2dll;
X+    _version_type windll;
X+} UzpVer;
X+
X+/* for Visual BASIC access to Windows DLLs: */
X+typedef struct _UzpVer2 {
X+    ulg structlen;          /* length of the struct being passed */
X+    ulg flag;               /* bit 0: is_beta   bit 1: uses_zlib */
X+    char betalevel[10];     /* e.g., "g BETA" or "" */
X+    char date[20];          /* e.g., "4 Sep 95" (beta) or "4 September 1995" */
X+    char zlib_version[10];  /* e.g., "0.95" or NULL */
X+    _version_type unzip;
X+    _version_type zipinfo;
X+    _version_type os2dll;
X+    _version_type windll;
X+} UzpVer2;
X+
X+typedef struct central_directory_file_header { /* CENTRAL */
X+    uch version_made_by[2];
X+    uch version_needed_to_extract[2];
X+    ush general_purpose_bit_flag;
X+    ush compression_method;
X+    ulg last_mod_dos_datetime;
X+    ulg crc32;
X+    ulg csize;
X+    ulg ucsize;
X+    ush filename_length;
X+    ush extra_field_length;
X+    ush file_comment_length;
X+    ush disk_number_start;
X+    ush internal_file_attributes;
X+    ulg external_file_attributes;
X+    ulg relative_offset_local_header;
X+} cdir_file_hdr;
X+
X+
X+#define UZPINIT_LEN   sizeof(UzpInit)
X+#define UZPVER_LEN    sizeof(UzpVer)
X+#define cbList(func)  int (* UZ_EXP func)(char *filename, cdir_file_hdr *crec)
X+
X+
X+/*---------------------------------------------------------------------------
X+    Return (and exit) values of the public UnZip API functions.
X+  ---------------------------------------------------------------------------*/
X+
X+/* external return codes */
X+#define PK_OK              0   /* no error */
X+#define PK_COOL            0   /* no error */
X+#define PK_WARN            1   /* warning error */
X+#define PK_ERR             2   /* error in zipfile */
X+#define PK_BADERR          3   /* severe error in zipfile */
X+#define PK_MEM             4   /* insufficient memory (during initialization) */
X+#define PK_MEM2            5   /* insufficient memory (password failure) */
X+#define PK_MEM3            6   /* insufficient memory (file decompression) */
X+#define PK_MEM4            7   /* insufficient memory (memory decompression) */
X+#define PK_MEM5            8   /* insufficient memory (not yet used) */
X+#define PK_NOZIP           9   /* zipfile not found */
X+#define PK_PARAM          10   /* bad or illegal parameters specified */
X+#define PK_FIND           11   /* no files found */
X+#define PK_DISK           50   /* disk full */
X+#define PK_EOF            51   /* unexpected EOF */
X+
X+#define IZ_CTRLC          80   /* user hit ^C to terminate */
X+#define IZ_UNSUP          81   /* no files found: all unsup. compr/encrypt. */
X+#define IZ_BADPWD         82   /* no files found: all had bad password */
X+
X+/* return codes of password fetches (negative = user abort; positive = error) */
X+#define IZ_PW_ENTERED      0   /* got some password string; use/try it */
X+#define IZ_PW_CANCEL      -1   /* no password available (for this entry) */
X+#define IZ_PW_CANCELALL   -2   /* no password, skip any further pwd. request */
X+#define IZ_PW_ERROR        5   /* = PK_MEM2 : failure (no mem, no tty, ...) */
X+
X+/* flag values for status callback function */
X+#define UZ_ST_START_EXTRACT     1       /* no details */
X+#define UZ_ST_IN_PROGRESS       2       /* no details */
X+#define UZ_ST_FINISH_MEMBER     3       /* 'details': extracted size */
X+
X+/* return values of status callback function */
X+#define UZ_ST_CONTINUE          0
X+#define UZ_ST_BREAK             1
X+
X+
X+/*---------------------------------------------------------------------------
X+    Prototypes for public UnZip API (DLL) functions.
X+  ---------------------------------------------------------------------------*/
X+
X+#define  UzpMatch match
X+
X+int      UZ_EXP UzpMain            OF((int argc, char **argv));
X+int      UZ_EXP UzpAltMain         OF((int argc, char **argv, UzpInit *init));
X+UzpVer * UZ_EXP UzpVersion         OF((void));
X+void     UZ_EXP UzpFreeMemBuffer   OF((UzpBuffer *retstr));
X+#ifndef WINDLL
X+int      UZ_EXP UzpUnzipToMemory   OF((char *zip, char *file, UzpOpts *optflgs,
X+                                       UzpCB *UsrFunc, UzpBuffer *retstr));
X+int      UZ_EXP UzpGrep            OF((char *archive, char *file,
X+                                       char *pattern, int cmd, int SkipBin,
X+                                       UzpCB *UsrFunc));
X+#endif
X+#ifdef OS2
X+int      UZ_EXP UzpFileTree        OF((char *name, cbList(callBack),
X+                                       char *cpInclude[], char *cpExclude[]));
X+#endif
X+
X+void     UZ_EXP UzpVersion2        OF((UzpVer2 *version));
X+int      UZ_EXP UzpValidate        OF((char *archive, int AllCodes));
X+
X+
X+/* default I/O functions (can be swapped out via UzpAltMain() entry point): */
X+
X+int      UZ_EXP UzpMessagePrnt   OF((zvoid *pG, uch *buf, ulg size, int flag));
X+int      UZ_EXP UzpMessageNull   OF((zvoid *pG, uch *buf, ulg size, int flag));
X+int      UZ_EXP UzpInput         OF((zvoid *pG, uch *buf, int *size, int flag));
X+void     UZ_EXP UzpMorePause     OF((zvoid *pG, ZCONST char *prompt, int flag));
X+int      UZ_EXP UzpPassword      OF((zvoid *pG, int *rcnt, char *pwbuf,
X+                                     int size, ZCONST char *zfn,
X+                                     ZCONST char *efn));
X+
X+#ifdef __cplusplus
X+}
X+#endif
X+
X+
X+/*---------------------------------------------------------------------------
X+    Remaining private stuff for UnZip compilation.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef UNZIP_INTERNAL
X+#  include "unzpriv.h"
X+#endif
X+
X+
X+#endif /* !__unzip_h */
Xdiff -ruN ../unzip-5.52.orig/unzpriv.h ./unzpriv.h
X--- ../unzip-5.52.orig/unzpriv.h	2005-02-04 08:26:42.000000000 +0900
X+++ ./unzpriv.h	2008-03-08 07:16:58.000000000 +0900
X@@ -1159,6 +1159,19 @@
X 
X #define FILNAMSIZ  PATH_MAX
X 
X+#ifdef NLS
X+#  ifndef _MBCS
X+#    define _MBCS
X+#  endif
X+#  include <langinfo.h>
X+#  include <iconv.h>
X+char* strdup_iconv (const char *to_name, const char *from_name, char *str);
X+#  if (OUTBUFSIZ < FILNAMSIZ)
X+#    undef OUTBUFSIZ
X+#    define OUTBUFSIZ FILNAMSIZ
X+#  endif
X+#endif
X+
X /* DBCS support for Info-ZIP  (mainly for japanese (-: )
X  * by Yoshioka Tsuneo (QWF00133 at nifty.ne.jp,tsuneo-y at is.aist-nara.ac.jp)
X  */
X@@ -1167,7 +1180,8 @@
X    /* Multi Byte Character Set */
X #  define ___MBS_TMP_DEF  char *___tmp_ptr;
X #  define ___TMP_PTR      ___tmp_ptr
X-#  define CLEN(ptr) mblen((ZCONST char *)(ptr), MB_CUR_MAX)
X+#  define CLEN(ptr) uzmblen(ptr)
X+   int  uzmblen (ZCONST char *ptr);
X #  ifndef PREINCSTR
X #    define PREINCSTR(ptr) (ptr += CLEN(ptr))
X #  endif
X@@ -2451,6 +2465,15 @@
X  *  code page.  As with A_TO_N(), conversion is done in place.
X  */
X #ifndef _ISO_INTERN
X+#  ifdef NLS
X+#    define _ISO_INTERN(str1) { \
X+    char *tmp = strdup_iconv (uO.charenc_sys, "CP1252", str1); \
X+    if (tmp) { \
X+      strncpy (str1, tmp, FILNAMSIZ); \
X+      free (tmp); \
X+    } \
X+  }
X+#  else
X #  ifdef CRTL_CP_IS_OEM
X #    ifndef IZ_ISO2OEM_ARRAY
X #      define IZ_ISO2OEM_ARRAY
X@@ -2461,9 +2484,19 @@
X #  else
X #    define _ISO_INTERN(str1)   A_TO_N(str1)
X #  endif
X+#  endif /* NLS */
X #endif
X 
X #ifndef _OEM_INTERN
X+#  ifdef NLS
X+#    define _OEM_INTERN(str1) { \
X+    char *tmp = strdup_iconv (uO.charenc_sys, "CP437", str1); \
X+    if (tmp) { \
X+      strncpy (str1, tmp, FILNAMSIZ); \
X+      free (tmp); \
X+    } \
X+  }
X+#  else
X #  ifdef CRTL_CP_IS_OEM
X #    define _OEM_INTERN(str1)   A_TO_N(str1)
X #  else
X@@ -2474,6 +2507,7 @@
X        for (p=(uch *)(str1); *p; p++)\
X          *p = native((*p & 0x80) ? oem2iso[*p & 0x7f] : *p);}
X #  endif
X+#  endif /* NSL */
X #endif
X 
X #ifndef STR_TO_ISO
X@@ -2558,6 +2592,26 @@
X  * All other ports are assumed to code zip entry filenames in ISO 8859-1.
X  */
X #ifndef Ext_ASCII_TO_Native
X+#  ifdef NLS
X+#   define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
X+    if (uO.charenc_arch) { \
X+      char *tmp = strdup_iconv (uO.charenc_sys, uO.charenc_arch, string); \
X+      if (tmp) { \
X+	strncpy (string, tmp, FILNAMSIZ); \
X+	free (tmp); \
X+      } \
X+    } else { \
X+    if (((hostnum) == FS_FAT_ && \
X+         !(((islochdr) || (isuxatt)) && \
X+           ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
X+        (hostnum) == FS_HPFS_ || \
X+        ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
X+        _OEM_INTERN((string)); \
X+    } else { \
X+        _ISO_INTERN((string)); \
X+    } \
X+    }
X+#  else
X #  define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
X     if (((hostnum) == FS_FAT_ && \
X          !(((islochdr) || (isuxatt)) && \
X@@ -2568,6 +2622,7 @@
X     } else { \
X         _ISO_INTERN((string)); \
X     }
X+#  endif /* NLS */
X #endif
X 
X 
Xdiff -ruN ../unzip-5.52.orig/unzpriv.h.orig ./unzpriv.h.orig
X--- ../unzip-5.52.orig/unzpriv.h.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./unzpriv.h.orig	2005-02-04 08:26:42.000000000 +0900
X@@ -0,0 +1,2618 @@
X+/*
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  See the accompanying file LICENSE, version 2000-Apr-09 or later
X+  (the contents of which are also included in unzip.h) for terms of use.
X+  If, for some reason, all these files are missing, the Info-ZIP license
X+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
X+*/
X+/*---------------------------------------------------------------------------
X+
X+  unzpriv.h
X+
X+  This header file contains private (internal) macros, typedefs, prototypes
X+  and global-variable declarations used by all of the UnZip source files.
X+  In a prior life it was part of the main unzip.h header, but now it is only
X+  included by that header if UNZIP_INTERNAL is defined.
X+
X+  ---------------------------------------------------------------------------*/
X+
X+
X+
X+#ifndef __unzpriv_h   /* prevent multiple inclusions */
X+#define __unzpriv_h
X+
X+/* First thing: Signal all following code that we compile UnZip utilities! */
X+#ifndef UNZIP
X+#  define UNZIP
X+#endif
X+
X+/* GRR 960204:  MORE defined here in preparation for removal altogether */
X+#ifndef MORE
X+# ifndef RISCOS
X+#  define MORE
X+# endif
X+#endif
X+
X+/* fUnZip should never need to be reentrant */
X+#ifdef FUNZIP
X+#  ifdef REENTRANT
X+#    undef REENTRANT
X+#  endif
X+#  ifdef DLL
X+#    undef DLL
X+#  endif
X+#  ifdef SFX    /* fUnZip is NOT the sfx stub! */
X+#    undef SFX
X+#  endif
X+#endif
X+
X+#if (defined(USE_ZLIB) && !defined(NO_DEFLATE64))
X+   /* zlib does not (yet?) provide Deflate64(tm) support */
X+#  define NO_DEFLATE64
X+#endif
X+
X+#ifdef NO_DEFLATE64
X+   /* disable support for Deflate64(tm) */
X+#  ifdef USE_DEFLATE64
X+#    undef USE_DEFLATE64
X+#  endif
X+#else
X+   /* enable Deflate64(tm) support unless compiling for SFX stub */
X+#  if (!defined(USE_DEFLATE64) && !defined(SFX))
X+#    define USE_DEFLATE64
X+#  endif
X+#endif
X+
X+#if (defined(NO_VMS_TEXT_CONV) || defined(VMS))
X+#  ifdef VMS_TEXT_CONV
X+#    undef VMS_TEXT_CONV
X+#  endif
X+#else
X+#  if (!defined(VMS_TEXT_CONV) && !defined(SFX))
X+#    define VMS_TEXT_CONV
X+#  endif
X+#endif
X+
X+#if (defined(DLL) && !defined(REENTRANT))
X+#  define REENTRANT
X+#endif
X+
X+#if (!defined(DYNAMIC_CRC_TABLE) && !defined(FUNZIP))
X+#  define DYNAMIC_CRC_TABLE
X+#endif
X+
X+#if (defined(DYNAMIC_CRC_TABLE) && !defined(REENTRANT))
X+#  ifndef DYNALLOC_CRCTAB
X+#    define DYNALLOC_CRCTAB
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    OS-dependent configuration for UnZip internals
X+  ---------------------------------------------------------------------------*/
X+
X+/* Some compiler distributions for Win32/i386 systems try to emulate
X+ * a Unix (POSIX-compatible) environment.
X+ */
X+#if (defined(WIN32) && defined(UNIX))
X+   /* UnZip does not support merging both ports in a single executable. */
X+#  if (defined(FORCE_WIN32_OVER_UNIX) && defined(FORCE_UNIX_OVER_WIN32))
X+     /* conflicting choice requests -> we prefer the Win32 environment */
X+#    undef FORCE_UNIX_OVER_WIN32
X+#  endif
X+#  ifdef FORCE_WIN32_OVER_UNIX
X+     /* native Win32 support was explicitely requested... */
X+#    undef UNIX
X+#  else
X+     /* use the POSIX (Unix) emulation features by default... */
X+#    undef WIN32
X+#  endif
X+#endif
X+
X+/* bad or (occasionally?) missing stddef.h: */
X+#if (defined(M_XENIX) || defined(DNIX))
X+#  define NO_STDDEF_H
X+#endif
X+
X+#if (defined(M_XENIX) && !defined(M_UNIX))   /* SCO Xenix only, not SCO Unix */
X+#  define SCO_XENIX
X+#  define NO_LIMITS_H        /* no limits.h, but MODERN defined */
X+#  define NO_UID_GID         /* no uid_t/gid_t */
X+#  define size_t int
X+#endif
X+
X+#ifdef realix   /* Modcomp Real/IX, real-time SysV.3 variant */
X+#  define SYSV
X+#  define NO_UID_GID         /* no uid_t/gid_t */
X+#endif
X+
X+#if (defined(_AIX) && !defined(_ALL_SOURCE))
X+#  define _ALL_SOURCE
X+#endif
X+
X+#if defined(apollo)          /* defines __STDC__ */
X+#    define NO_STDLIB_H
X+#endif
X+
X+#ifdef DNIX
X+#  define SYSV
X+#  define SHORT_NAMES         /* 14-char limitation on path components */
X+/* #  define FILENAME_MAX  14 */
X+#  define FILENAME_MAX  NAME_MAX    /* GRR:  experiment */
X+#endif
X+
X+#if (defined(SYSTEM_FIVE) || defined(__SYSTEM_FIVE))
X+#  ifndef SYSV
X+#    define SYSV
X+#  endif
X+#endif /* SYSTEM_FIVE || __SYSTEM_FIVE */
X+#if (defined(M_SYSV) || defined(M_SYS5))
X+#  ifndef SYSV
X+#    define SYSV
X+#  endif
X+#endif /* M_SYSV || M_SYS5 */
X+/* __SVR4 and __svr4__ catch Solaris on at least some combos of compiler+OS */
X+#if (defined(__SVR4) || defined(__svr4__) || defined(sgi) || defined(__hpux))
X+#  ifndef SYSV
X+#    define SYSV
X+#  endif
X+#endif /* __SVR4 || __svr4__ || sgi || __hpux */
X+#if (defined(LINUX) || defined(__QNX__))
X+#  ifndef SYSV
X+#    define SYSV
X+#  endif
X+#endif /* LINUX || __QNX__ */
X+
X+#if (defined(ultrix) || defined(__ultrix) || defined(bsd4_2))
X+#  if (!defined(BSD) && !defined(SYSV))
X+#    define BSD
X+#  endif
X+#endif /* ultrix || __ultrix || bsd4_2 */
X+#if (defined(sun) || defined(pyr) || defined(CONVEX))
X+#  if (!defined(BSD) && !defined(SYSV))
X+#    define BSD
X+#  endif
X+#endif /* sun || pyr || CONVEX */
X+
X+#ifdef pyr  /* Pyramid:  has BSD and AT&T "universes" */
X+#  ifdef BSD
X+#    define pyr_bsd
X+#    define USE_STRINGS_H  /* instead of more common string.h */
X+#    define ZMEM           /* ZMEM now uses bcopy/bzero: not in AT&T universe */
X+#  endif                   /* (AT&T memcpy claimed to be very slow, though) */
X+#  define DECLARE_ERRNO
X+#endif /* pyr */
X+
X+/* stat() bug for Borland, VAX C RTL, and Atari ST MiNT on TOS
X+ * filesystems:  returns 0 for wildcards!  (returns 0xffffffff on Minix
X+ * filesystem or `U:' drive under Atari MiNT.)  Watcom C was previously
X+ * included on this list; it would be good to know what version the problem
X+ * was fixed at, if it did exist.  */
X+#if (defined(__TURBOC__) && !defined(WIN32))
X+/*#  define WILD_STAT_BUG*/
X+#endif
X+#if (defined(VMS) || defined(__MINT__))
X+#  define WILD_STAT_BUG
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    OS-dependent includes
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef EFT
X+#  define Z_OFF_T off_t  /* Amdahl UTS nonsense ("extended file types") */
X+#else
X+#if (defined(UNIX) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64))
X+#  define Z_OFF_T off_t /* 64bit offsets to support 2GB < zipfile size < 4GB */
X+#else
X+#  define Z_OFF_T long
X+#endif
X+#endif
X+
X+#ifdef MODERN
X+#  ifndef NO_STDDEF_H
X+#    include <stddef.h>
X+#  endif
X+#  ifndef NO_STDLIB_H
X+#    include <stdlib.h>  /* standard library prototypes, malloc(), etc. */
X+#  endif
X+   typedef size_t extent;
X+#else /* !MODERN */
X+#  ifndef AOS_VS         /* mostly modern? */
X+     Z_OFF_T lseek();
X+#    ifdef VAXC          /* not fully modern, but has stdlib.h and void */
X+#      include <stdlib.h>
X+#    else
X+       char *malloc();
X+#    endif /* ?VAXC */
X+#  endif /* !AOS_VS */
X+   typedef unsigned int extent;
X+#endif /* ?MODERN */
X+
X+
X+#ifndef MINIX            /* Minix needs it after all the other includes (?) */
X+#  include <stdio.h>
X+#endif
X+#include <ctype.h>       /* skip for VMS, to use tolower() function? */
X+#include <errno.h>       /* used in mapname() */
X+#ifdef USE_STRINGS_H
X+#  include <strings.h>   /* strcpy, strcmp, memcpy, index/rindex, etc. */
X+#else
X+#  include <string.h>    /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */
X+#endif
X+#if (defined(MODERN) && !defined(NO_LIMITS_H))
X+#  include <limits.h>    /* GRR:  EXPERIMENTAL!  (can be deleted) */
X+#endif
X+
X+/* this include must be down here for SysV.4, for some reason... */
X+#include <signal.h>      /* used in unzip.c, fileio.c */
X+
X+
X+/*---------------------------------------------------------------------------
X+    API (DLL) section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef DLL
X+#  define MAIN   UZ_EXP UzpMain   /* was UzpUnzip */
X+#  ifdef OS2DLL
X+#    undef Info
X+#    define REDIRECTC(c)             varputchar(__G__ c)
X+#    define REDIRECTPRINT(buf,size)  varmessage(__G__ buf, size)
X+#    define FINISH_REDIRECT()        finish_REXX_redirect(__G)
X+#  else
X+#    define REDIRECTC(c)
X+#    define REDIRECTPRINT(buf,size)  0
X+#    define FINISH_REDIRECT()        close_redirect(__G)
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Acorn RISCOS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef RISCOS
X+#  include "acorn/riscos.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Amiga section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef AMIGA
X+#  include "amiga/amiga.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    AOS/VS section (somewhat similar to Unix, apparently):
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef AOS_VS
X+#  ifdef __FILEIO_C
X+#    include "aosvs/aosvs.h"
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Atari ST section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef ATARI
X+#  include <time.h>
X+#  include <stat.h>
X+#  include <fcntl.h>
X+#  include <limits.h>
X+#  define SYMLINKS
X+#  define EXE_EXTENSION  ".tos"
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT  DF_DMY
X+#  endif
X+#  define DIR_END        '/'
X+#  define INT_SPRINTF
X+#  define timezone      _timezone
X+#  define lenEOL        2
X+#  define PutNativeEOL  {*q++ = native(CR); *q++ = native(LF);}
X+#  undef SHORT_NAMES
X+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
X+#    define TIMESTAMP
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    AtheOS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef __ATHEOS__
X+#  include "atheos/athcfg.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    BeOS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef __BEOS__
X+#  include "beos/beocfg.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Human68k/X680x0 section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef __human68k__
X+   /* DO NOT DEFINE DOS_OS2 HERE!  If Human68k is so much */
X+   /*  like MS-DOS and/or OS/2, create DOS_H68_OS2 macro. */
X+#  ifndef _MBCS
X+#    define _MBCS
X+#  endif
X+#  include <time.h>
X+#  include <fcntl.h>
X+#  include <io.h>
X+#  include <conio.h>
X+#  include <sys/stat.h>
X+#  ifdef HAVE_MBSTRING_H
X+#    include <mbstring.h>
X+#  endif
X+#  ifdef HAVE_MBCTYPE_H
X+#    include <mbctype.h>
X+#  else
X+#    ifndef _ismbblead
X+#      define _ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c)))
X+#    endif
X+#  endif
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT DF_YMD   /* Japanese standard */
X+#  endif
X+#  define lenEOL        1
X+#  define PutNativeEOL  *q++ = native(LF);
X+#  define INT_SPRINTF
X+#  define SYMLINKS
X+#  ifdef SFX
X+#    define MAIN main_sfx
X+#  endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Mac section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef MACOS
X+#  include "maccfg.h"
X+#endif /* MACOS */
X+
X+/*---------------------------------------------------------------------------
X+    MS-DOS, OS/2, FLEXOS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef WINDLL
X+#  ifdef MORE
X+#    undef MORE
X+#  endif
X+#  ifdef OS2_EAS
X+#    undef OS2_EAS
X+#  endif
X+#endif
X+
X+#if (defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)))
X+#  ifndef MSC
X+#    define MSC               /* This should work for older MSC, too!  */
X+#  endif
X+#endif
X+
X+#if (defined(MSDOS) || defined(OS2) || defined(FLEXOS))
X+#  include <sys/types.h>      /* off_t, time_t, dev_t, ... */
X+#  include <sys/stat.h>
X+#  include <io.h>             /* lseek(), open(), setftime(), dup(), creat() */
X+#  include <time.h>           /* localtime() */
X+#  include <fcntl.h>          /* O_BINARY for open() w/o CR/LF translation */
X+
X+#  ifdef OS2                  /* defined for all OS/2 compilers */
X+#    include "os2/os2cfg.h"
X+#  else
X+#    ifdef FLEXOS
X+#      include "flexos/flxcfg.h"
X+#    else
X+#      include "msdos/doscfg.h"
X+#    endif
X+#  endif
X+
X+#  if (defined(_MSC_VER) && (_MSC_VER == 700) && !defined(GRR))
X+    /*
X+     * ARGH.  MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not
X+     *  1970 Jan 1 00:00.  So we have to diddle time_t's appropriately:  add or
X+     *  subtract 70 years' worth of seconds; i.e., number of days times 86400;
X+     *  i.e., (70*365 regular days + 17 leap days + 1 1899 day) * 86400 ==
X+     *  (25550 + 17 + 1) * 86400 == 2209075200 seconds.  We know time_t is an
X+     *  unsigned long (ulg) on the only system with this bug.
X+     */
X+#    define TIMET_TO_NATIVE(x)  (x) += (ulg)2209075200L;
X+#    define NATIVE_TO_TIMET(x)  (x) -= (ulg)2209075200L;
X+#  endif
X+#  if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0450))
X+#    define timezone      _timezone
X+#  endif
X+#  if (defined(__GO32__) || defined(FLEXOS))
X+#    define DIR_END       '/'
X+#  else
X+#    define DIR_END       '\\'  /* OS uses '\\' as directory separator */
X+#    define DIR_END2      '/'   /* also check for '/' (RTL may convert) */
X+#  endif
X+#  ifdef DATE_FORMAT
X+#    undef DATE_FORMAT
X+#  endif
X+#  define DATE_FORMAT     dateformat()
X+#  define lenEOL          2
X+#  define PutNativeEOL    {*q++ = native(CR); *q++ = native(LF);}
X+#  if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
X+#    define USE_EF_UT_TIME
X+#  endif
X+#endif /* MSDOS || OS2 || FLEXOS */
X+
X+/*---------------------------------------------------------------------------
X+    MTS section (piggybacks UNIX, I think):
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef MTS
X+#  include <sys/types.h>      /* off_t, time_t, dev_t, ... */
X+#  include <sys/stat.h>
X+#  include <sys/file.h>       /* MTS uses this instead of fcntl.h */
X+#  include <timeb.h>
X+#  include <time.h>
X+#  include <unix.h>           /* some important non-ANSI routines */
X+#  define mkdir(s,n) (-1)     /* no "make directory" capability */
X+#  define EBCDIC              /* set EBCDIC conversion on */
X+#  define NO_STRNICMP         /* unzip's is as good the one in MTS */
X+#  define USE_FWRITE
X+#  define close_outfile()  fclose(G.outfile)   /* can't set time on files */
X+#  define umask(n)            /* don't have umask() on MTS */
X+#  define FOPWT         "w"   /* open file for writing in TEXT mode */
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT DF_MDY
X+#  endif
X+#  define lenEOL        1
X+#  define PutNativeEOL  *q++ = native(LF);
X+#endif /* MTS */
X+
X+ /*---------------------------------------------------------------------------
X+    Novell NLM section
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef NLM
X+#  include "novell/nlmcfg.h"
X+#endif
X+
X+ /*---------------------------------------------------------------------------
X+    QDOS section
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef QDOS
X+#  define DIRENT
X+#  include <fcntl.h>
X+#  include <unistd.h>
X+#  include <sys/stat.h>
X+#  include <time.h>
X+#  include "qdos/izqdos.h"
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT DF_MDY
X+#  endif
X+#  define lenEOL        1
X+#  define PutNativeEOL  *q++ = native(LF);
X+#  define DIR_END       '_'
X+#  define RETURN        QReturn
X+#  undef PATH_MAX
X+#  define PATH_MAX      36
X+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
X+#    define TIMESTAMP
X+#  endif
X+#  define SCREENSIZE(ttrows, ttcols)  screensize(ttrows, ttcols)
X+#  define SCREENWIDTH 80
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Tandem NSK section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef TANDEM
X+#  include "tandem.h"
X+#  include <fcntl.h>
X+#  ifndef __INT32
X+     /* We are compiling with non-WIDE memory model, int = 16 bits */
X+#    ifndef INT_16BIT
X+#      define INT_16BIT   /* report "int" size is 16-bit to inflate setup */
X+#    endif
X+#    ifdef USE_DEFLATE64
X+       /* Following required for 64k WSIZE of Deflate64 support */
X+#      define MED_MEM     /* else OUTBUFSIZ is 64K and fails in do_string */
X+#      define INBUFSIZ  8192  /* but larger buffer for real OSes */
X+#    endif
X+#  endif
X+   /* use a single LF delimiter so that writes to 101 text files work */
X+#  define PutNativeEOL  *q++ = native(LF);
X+#  define lenEOL        1
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT  DF_DMY
X+#  endif
X+#  define SCREENLINES   25
X+   /* USE_EF_UT_TIME is set in tandem.h */
X+#  define RESTORE_UIDGID
X+#  define NO_STRNICMP
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    THEOS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef THEOS
X+#  include "theos/thscfg.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    TOPS-20 section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef TOPS20
X+#  include <sys/types.h>        /* off_t, time_t, dev_t, ... */
X+#  include <sys/stat.h>
X+#  include <sys/param.h>
X+#  include <sys/time.h>
X+#  include <sys/timeb.h>
X+#  include <sys/file.h>
X+#  include <timex.h>
X+#  include <monsym.h>           /* get amazing monsym() macro */
X+   extern int open(), close(), read();
X+   extern int stat(), unlink(), jsys(), fcntl();
X+   extern long lseek(), dup(), creat();
X+#  define strchr    index       /* GRR: necessary? */
X+#  define strrchr   rindex
X+#  define REALLY_SHORT_SYMS
X+#  define NO_MKDIR
X+#  ifndef HAVE_STRNICMP
X+#    define NO_STRNICMP           /* probably not provided by TOPS20 C RTL  */
X+#  endif
X+#  define DIR_BEG       '<'
X+#  define DIR_END       '>'
X+#  define DIR_EXT       ".directory"
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT DF_MDY
X+#  endif
X+#  define EXE_EXTENSION ".exe"  /* just a guess... */
X+#endif /* TOPS20 */
X+
X+/*---------------------------------------------------------------------------
X+    Unix section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef UNIX
X+#  include "unix/unxcfg.h"
X+#endif /* UNIX */
X+
X+/*---------------------------------------------------------------------------
X+    VM/CMS and MVS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef CMS_MVS
X+#  include "vmmvs.h"
X+#  define CLOSE_INFILE()  close_infile(__G)
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    VMS section:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef VMS
X+#  include <types.h>                    /* GRR:  experimenting... */
X+#  include <stat.h>
X+#  include <time.h>                     /* the usual non-BSD time functions */
X+#  include <file.h>                     /* same things as fcntl.h has */
X+#  include <unixio.h>
X+#  include <rms.h>
X+#  define _MAX_PATH (NAM$C_MAXRSS+1)    /* to define FILNAMSIZ below */
X+#  ifndef HAVE_STRNICMP                 /* use our private zstrnicmp() */
X+#    define NO_STRNICMP                 /*  unless explicitely overridden */
X+#  endif
X+#  ifdef RETURN_CODES  /* VMS interprets standard PK return codes incorrectly */
X+#    define RETURN(ret) return_VMS(__G__ (ret))   /* verbose version */
X+#    define EXIT(ret)   return_VMS(__G__ (ret))
X+#  else
X+#    define RETURN      return_VMS                /* quiet version */
X+#    define EXIT        return_VMS
X+#  endif
X+#  ifdef VMSCLI
X+#    define USAGE(ret)  VMSCLI_usage(__G__ (ret))
X+#  endif
X+#  define DIR_BEG       '['
X+#  define DIR_END       ']'
X+#  define DIR_EXT       ".dir"
X+#  ifndef DATE_FORMAT
X+#    define DATE_FORMAT DF_MDY
X+#  endif
X+#  define lenEOL        1
X+#  define PutNativeEOL  *q++ = native(LF);
X+#  define SCREENSIZE(ttrows, ttcols)  screensize(ttrows, ttcols)
X+#  define SCREENWIDTH   80
X+#  define SCREENLWRAP   screenlinewrap()
X+#  if (defined(__VMS_VERSION) && !defined(VMS_VERSION))
X+#    define VMS_VERSION __VMS_VERSION
X+#  endif
X+#  if (defined(__VMS_VER) && !defined(__CRTL_VER))
X+#    define __CRTL_VER __VMS_VER
X+#  endif
X+#  if ((!defined(__CRTL_VER)) || (__CRTL_VER < 70000000))
X+#    define NO_GMTIME           /* gmtime() of earlier VMS C RTLs is broken */
X+#  else
X+#    if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
X+#      define USE_EF_UT_TIME
X+#    endif
X+#  endif
X+#  if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
X+#    define TIMESTAMP
X+#  endif
X+#  define RESTORE_UIDGID
X+#  ifdef __DECC
X+     /* File open callback ID values. */
X+#    define OPENR_ID 1
X+     /* File open callback ID storage. */
X+     extern int openr_id;
X+     /* File open callback function. */
X+     extern int acc_cb();
X+     /* Option macros for open().
X+      * General: Stream access
X+      *
X+      * Callback function (DEC C only) sets deq, mbc, mbf, rah, wbh, ...
X+      */
X+#    define OPNZIP_RMS_ARGS "ctx=stm", "acc", acc_cb, &openr_id
X+#  else /* !__DECC */ /* (So, GNU C, VAX C, ...)*/
X+#    define OPNZIP_RMS_ARGS "ctx=stm"
X+#  endif /* ?__DECC */
X+#endif /* VMS */
X+
X+/*---------------------------------------------------------------------------
X+    Win32 (Windows 95/NT) section:
X+  ---------------------------------------------------------------------------*/
X+
X+#if (defined(WIN32) && !defined(POCKET_UNZIP) && !defined(_WIN32_WCE))
X+#  include "win32/w32cfg.h"
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Win32 Windows CE section (when not using POCKET_UNZIP)
X+  ---------------------------------------------------------------------------*/
X+
X+#if (defined(_WIN32_WCE) || defined(POCKET_UNZIP))
X+#  include "wince/wcecfg.h"
X+#endif
X+
X+
X+
X+
X+
X+/*************/
X+/*  Defines  */
X+/*************/
X+
X+#ifdef USE_DEFLATE64
X+#  define UNZIP_VERSION   21   /* compatible with PKUNZIP 4.0 */
X+#else
X+#  define UNZIP_VERSION   20   /* compatible with PKUNZIP 2.0 */
X+#endif
X+#define VMS_UNZIP_VERSION 42   /* if OS-needed-to-extract is VMS:  can do */
X+
X+#if (defined(MSDOS) || defined(OS2))
X+#  define DOS_OS2
X+#endif
X+
X+#if (defined(OS2) || defined(WIN32))
X+#  define OS2_W32
X+#endif
X+
X+#if (defined(DOS_OS2) || defined(WIN32))
X+#  define DOS_OS2_W32
X+#  define DOS_W32_OS2          /* historical:  don't use */
X+#endif
X+
X+#if (defined(DOS_OS2_W32) || defined(__human68k__))
X+#  define DOS_H68_OS2_W32
X+#endif
X+
X+#if (defined(DOS_OS2) || defined(FLEXOS))
X+#  define DOS_FLX_OS2
X+#endif
X+
X+#if (defined(DOS_OS2_W32) || defined(FLEXOS))
X+#  define DOS_FLX_OS2_W32
X+#endif
X+
X+#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS))
X+#  define DOS_FLX_H68_OS2_W32
X+#endif
X+
X+#if (defined(DOS_FLX_OS2) || defined(NLM))
X+#  define DOS_FLX_NLM_OS2
X+#endif
X+
X+#if (defined(DOS_FLX_OS2_W32) || defined(NLM))
X+#  define DOS_FLX_NLM_OS2_W32
X+#endif
X+
X+#if (defined(DOS_FLX_H68_OS2_W32) || defined(NLM))
X+#  define DOS_FLX_H68_NLM_OS2_W32
X+#endif
X+
X+#if (defined(TOPS20) || defined(VMS))
X+#  define T20_VMS
X+#endif
X+
X+#if (defined(MSDOS) || defined(T20_VMS))
X+#  define DOS_T20_VMS
X+#endif
X+
X+#if (defined(__ATHEOS__) || defined(__BEOS__))
X+#  define ATH_BEO
X+#endif
X+
X+#if (defined(ATH_BEO) || defined(UNIX))
X+#  define ATH_BEO_UNX
X+#endif
X+
X+#if (defined(ATH_BEO_UNX) || defined(THEOS))
X+#  define ATH_BEO_THS_UNX
X+#endif
X+
X+/* clean up with a few defaults */
X+#ifndef DIR_END
X+#  define DIR_END       '/'     /* last char before program name or filename */
X+#endif
X+#ifndef DATE_FORMAT
X+#  define DATE_FORMAT   DF_MDY  /* defaults to US convention */
X+#endif
X+#ifndef DATE_SEPCHAR
X+#  define DATE_SEPCHAR  '-'
X+#endif
X+#ifndef CLOSE_INFILE
X+#  define CLOSE_INFILE()  close(G.zipfd)
X+#endif
X+#ifndef RETURN
X+#  define RETURN        return  /* only used in main() */
X+#endif
X+#ifndef EXIT
X+#  define EXIT          exit
X+#endif
X+#ifndef USAGE
X+#  define USAGE(ret)    usage(__G__ (ret))    /* used in unzip.c, zipinfo.c */
X+#endif
X+#ifndef TIMET_TO_NATIVE         /* everybody but MSC 7.0 and Macintosh */
X+#  define TIMET_TO_NATIVE(x)
X+#  define NATIVE_TO_TIMET(x)
X+#endif
X+#ifndef SSTAT
X+#  ifdef WILD_STAT_BUG
X+#    define SSTAT(path,pbuf) (iswild(path) || stat(path,pbuf))
X+#  else
X+#    define SSTAT stat
X+#  endif
X+#endif
X+#ifndef STRNICMP
X+#  ifdef NO_STRNICMP
X+#    define STRNICMP zstrnicmp
X+#  else
X+#    define STRNICMP strnicmp
X+#  endif
X+#endif
X+
X+
X+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_UNX) || defined(RISCOS))
X+#  ifndef HAVE_UNLINK
X+#    define HAVE_UNLINK
X+#  endif
X+#endif
X+#if (defined(AOS_VS) || defined(ATARI)) /* GRR: others? */
X+#  ifndef HAVE_UNLINK
X+#    define HAVE_UNLINK
X+#  endif
X+#endif
X+
X+/* OS-specific exceptions to the "ANSI <--> INT_SPRINTF" rule */
X+
X+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
X+#  if (defined(SYSV) || defined(CONVEX) || defined(NeXT) || defined(BSD4_4))
X+#    define INT_SPRINTF      /* sprintf() returns int:  SysVish/Posix */
X+#  endif
X+#  if (defined(DOS_FLX_NLM_OS2_W32) || defined(VMS) || defined(AMIGA))
X+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI */
X+#  endif
X+#  if (defined(ultrix) || defined(__ultrix)) /* Ultrix 4.3 and newer */
X+#    if (defined(POSIX) || defined(__POSIX))
X+#      define INT_SPRINTF    /* sprintf() returns int:  ANSI/Posix */
X+#    endif
X+#    ifdef __GNUC__
X+#      define PCHAR_SPRINTF  /* undetermined actual return value */
X+#    endif
X+#  endif
X+#  if (defined(__osf__) || defined(_AIX) || defined(CMS_MVS) || defined(THEOS))
X+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI/Posix */
X+#  endif
X+#  if defined(sun)
X+#    define PCHAR_SPRINTF    /* sprintf() returns char *:  SunOS cc *and* gcc */
X+#  endif
X+#endif
X+
X+/* defaults that we hope will take care of most machines in the future */
X+
X+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
X+#  ifdef __STDC__
X+#    define INT_SPRINTF      /* sprintf() returns int:  ANSI */
X+#  endif
X+#  ifndef INT_SPRINTF
X+#    define PCHAR_SPRINTF    /* sprintf() returns char *:  BSDish */
X+#  endif
X+#endif
X+
X+#define MSG_STDERR(f)  (f & 1)        /* bit 0:  0 = stdout, 1 = stderr */
X+#define MSG_INFO(f)    ((f & 6) == 0) /* bits 1 and 2:  0 = info */
X+#define MSG_WARN(f)    ((f & 6) == 2) /* bits 1 and 2:  1 = warning */
X+#define MSG_ERROR(f)   ((f & 6) == 4) /* bits 1 and 2:  2 = error */
X+#define MSG_FATAL(f)   ((f & 6) == 6) /* bits 1 and 2:  (3 = fatal error) */
X+#define MSG_ZFN(f)     (f & 0x0008)   /* bit 3:  1 = print zipfile name */
X+#define MSG_FN(f)      (f & 0x0010)   /* bit 4:  1 = print filename */
X+#define MSG_LNEWLN(f)  (f & 0x0020)   /* bit 5:  1 = leading newline if !SOL */
X+#define MSG_TNEWLN(f)  (f & 0x0040)   /* bit 6:  1 = trailing newline if !SOL */
X+#define MSG_MNEWLN(f)  (f & 0x0080)   /* bit 7:  1 = trailing NL for prompts */
X+/* the following are subject to change */
X+#define MSG_NO_WGUI(f) (f & 0x0100)   /* bit 8:  1 = skip if Windows GUI */
X+#define MSG_NO_AGUI(f) (f & 0x0200)   /* bit 9:  1 = skip if Acorn GUI */
X+#define MSG_NO_DLL2(f) (f & 0x0400)   /* bit 10:  1 = skip if OS/2 DLL */
X+#define MSG_NO_NDLL(f) (f & 0x0800)   /* bit 11:  1 = skip if WIN32 DLL */
X+#define MSG_NO_WDLL(f) (f & 0x1000)   /* bit 12:  1 = skip if Windows DLL */
X+
X+#if (defined(MORE) && !defined(SCREENLINES))
X+#  ifdef DOS_FLX_NLM_OS2_W32
X+#    define SCREENLINES 25  /* can be (should be) a function instead */
X+#  else
X+#    define SCREENLINES 24  /* VT-100s are assumed to be minimal hardware */
X+#  endif
X+#endif
X+#if (defined(MORE) && !defined(SCREENSIZE))
X+#  ifndef SCREENWIDTH
X+#    define SCREENSIZE(scrrows, scrcols) { \
X+          if ((scrrows) != NULL) *(scrrows) = SCREENLINES; }
X+#  else
X+#    define SCREENSIZE(scrrows, scrcols) { \
X+          if ((scrrows) != NULL) *(scrrows) = SCREENLINES; \
X+          if ((scrcols) != NULL) *(scrcols) = SCREENWIDTH; }
X+#  endif
X+#endif
X+
X+#define DIR_BLKSIZ  64      /* number of directory entries per block
X+                             *  (should fit in 4096 bytes, usually) */
X+#ifndef WSIZE
X+#  ifdef USE_DEFLATE64
X+#    define WSIZE   65536L  /* window size--must be a power of two, and */
X+#  else                     /*  at least 64K for PKZip's deflate64 method */
X+#    define WSIZE   0x8000  /* window size--must be a power of two, and */
X+#  endif                    /*  at least 32K for zip's deflate method */
X+#endif
X+
X+#ifdef __16BIT__
X+#  ifndef INT_16BIT
X+#    define INT_16BIT       /* on 16-bit systems int size is 16 bits */
X+#  endif
X+#else
X+#  define nearmalloc  malloc
X+#  define nearfree    free
X+#  if (!defined(__IBMC__) || !defined(OS2))
X+#    ifndef near
X+#      define near
X+#    endif
X+#    ifndef far
X+#      define far
X+#    endif
X+#  endif
X+#endif
X+
X+#if (defined(DYNALLOC_CRCTAB) && !defined(DYNAMIC_CRC_TABLE))
X+#  undef DYNALLOC_CRCTAB
X+#endif
X+
X+#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
X+#  undef DYNALLOC_CRCTAB   /* not safe with reentrant code */
X+#endif
X+
X+#if (defined(USE_ZLIB) && !defined(USE_OWN_CRCTAB))
X+#  ifdef DYNALLOC_CRCTAB
X+#    undef DYNALLOC_CRCTAB
X+#  endif
X+#endif
X+
X+#if (defined(USE_ZLIB) && defined(ASM_CRC))
X+#  undef ASM_CRC
X+#endif
X+
X+#ifndef INBUFSIZ
X+#  if (defined(MED_MEM) || defined(SMALL_MEM))
X+#    define INBUFSIZ  2048  /* works for MS-DOS small model */
X+#  else
X+#    define INBUFSIZ  8192  /* larger buffers for real OSes */
X+#  endif
X+#endif
X+
X+#if (defined(INT_16BIT) && (defined(USE_DEFLATE64) || lenEOL > 1))
X+   /* For environments using 16-bit integers OUTBUFSIZ must be limited to
X+    * less than 64k (do_string() uses "unsigned" in calculations involving
X+    * OUTBUFSIZ).  This is achieved by defining MED_MEM when WSIZE = 64k (aka
X+    * Deflate64 support enabled) or EOL markers consist multiple characters.
X+    * (The rule gets applied AFTER the default rule for INBUFSIZ because it
X+    * is not neccessary to reduce INBUFSIZE in this case.)
X+    */
X+#  if (!defined(SMALL_MEM) && !defined(MED_MEM))
X+#    define MED_MEM
X+#  endif
X+#endif
X+
X+/* Logic for case of small memory, length of EOL > 1:  if OUTBUFSIZ == 2048,
X+ * OUTBUFSIZ>>1 == 1024 and OUTBUFSIZ>>7 == 16; therefore rawbuf is 1008 bytes
X+ * and transbuf 1040 bytes.  Have room for 32 extra EOL chars; 1008/32 == 31.5
X+ * chars/line, smaller than estimated 35-70 characters per line for C source
X+ * and normal text.  Hence difference is sufficient for most "average" files.
X+ * (Argument scales for larger OUTBUFSIZ.)
X+ */
X+#ifdef SMALL_MEM          /* i.e., 16-bit OSes:  MS-DOS, OS/2 1.x, etc. */
X+#  define LoadFarString(x)       fLoadFarString(__G__ (x))
X+#  define LoadFarStringSmall(x)  fLoadFarStringSmall(__G__ (x))
X+#  define LoadFarStringSmall2(x) fLoadFarStringSmall2(__G__ (x))
X+#  if (defined(_MSC_VER) && (_MSC_VER >= 600))
X+#    define zfstrcpy(dest, src)  _fstrcpy((dest), (src))
X+#    define zfstrcmp(s1, s2)     _fstrcmp((s1), (s2))
X+#  endif
X+#  if !(defined(SFX) || defined(FUNZIP))
X+#    if (defined(_MSC_VER))
X+#      define zfmalloc(sz)       _fmalloc((sz))
X+#      define zffree(x)          _ffree(x)
X+#    endif
X+#    if (defined(__TURBOC__))
X+#      include <alloc.h>
X+#      define zfmalloc(sz)       farmalloc((unsigned long)(sz))
X+#      define zffree(x)          farfree(x)
X+#    endif
X+#  endif /* !(SFX || FUNZIP) */
X+#  ifndef Far
X+#    define Far far  /* __far only works for MSC 6.00, not 6.0a or Borland */
X+#  endif
X+#  define OUTBUFSIZ INBUFSIZ
X+#  if (lenEOL == 1)
X+#    define RAWBUFSIZ (OUTBUFSIZ>>1)
X+#  else
X+#    define RAWBUFSIZ ((OUTBUFSIZ>>1) - (OUTBUFSIZ>>7))
X+#  endif
X+#  define TRANSBUFSIZ (OUTBUFSIZ-RAWBUFSIZ)
X+   typedef short  shrint;            /* short/int or "shrink int" (unshrink) */
X+#else
X+#  define zfstrcpy(dest, src)       strcpy((dest), (src))
X+#  define zfstrcmp(s1, s2)          strcmp((s1), (s2))
X+#  define zfmalloc                  malloc
X+#  define zffree(x)                 free(x)
X+#  ifdef QDOS
X+#    define LoadFarString(x)        Qstrfix(x)   /* fix up _ for '.' */
X+#    define LoadFarStringSmall(x)   Qstrfix(x)
X+#    define LoadFarStringSmall2(x)  Qstrfix(x)
X+#  else
X+#    define LoadFarString(x)        (char *)(x)
X+#    define LoadFarStringSmall(x)   (char *)(x)
X+#    define LoadFarStringSmall2(x)  (char *)(x)
X+#  endif
X+#  ifdef MED_MEM
X+#    define OUTBUFSIZ 0xFF80         /* can't malloc arrays of 0xFFE8 or more */
X+#    define TRANSBUFSIZ 0xFF80
X+     typedef short  shrint;
X+#  else
X+#    define OUTBUFSIZ (lenEOL*WSIZE) /* more efficient text conversion */
X+#    define TRANSBUFSIZ (lenEOL*OUTBUFSIZ)
X+#    ifdef AMIGA
X+       typedef short shrint;
X+#    else
X+       typedef int  shrint;          /* for efficiency/speed, we hope... */
X+#    endif
X+#  endif /* ?MED_MEM */
X+#  define RAWBUFSIZ OUTBUFSIZ
X+#endif /* ?SMALL_MEM */
X+
X+#ifndef Far
X+#  define Far
X+#endif
X+
X+#ifndef Cdecl
X+#  define Cdecl
X+#endif
X+
X+#ifndef MAIN
X+#  define MAIN  main
X+#endif
X+
X+#ifdef SFX      /* disable some unused features for SFX executables */
X+#  ifndef NO_ZIPINFO
X+#    define NO_ZIPINFO
X+#  endif
X+#  ifdef TIMESTAMP
X+#    undef TIMESTAMP
X+#  endif
X+#endif
X+
X+#ifdef SFX
X+#  ifdef CHEAP_SFX_AUTORUN
X+#    ifndef NO_SFX_EXDIR
X+#      define NO_SFX_EXDIR
X+#    endif
X+#  endif
X+#  ifndef NO_SFX_EXDIR
X+#    ifndef SFX_EXDIR
X+#      define SFX_EXDIR
X+#    endif
X+#  else
X+#    ifdef SFX_EXDIR
X+#      undef SFX_EXDIR
X+#    endif
X+#  endif
X+#endif
X+
X+/* user may have defined both by accident...  NOTIMESTAMP takes precedence */
X+#if (defined(TIMESTAMP) && defined(NOTIMESTAMP))
X+#  undef TIMESTAMP
X+#endif
X+
X+#if (!defined(COPYRIGHT_CLEAN) && !defined(USE_SMITH_CODE))
X+#  define COPYRIGHT_CLEAN
X+#endif
X+
X+/* The LZW patent is expired worldwide since 2004-Jul-07, so USE_UNSHRINK
X+ * is now enabled by default.  See unshrink.c.
X+ */
X+#if (!defined(LZW_CLEAN) && !defined(USE_UNSHRINK))
X+#  define USE_UNSHRINK
X+#endif
X+
X+#ifndef O_BINARY
X+#  define O_BINARY  0
X+#endif
X+
X+#ifndef PIPE_ERROR
X+#  define PIPE_ERROR (errno == EPIPE)
X+#endif
X+
X+/* File operations--use "b" for binary if allowed or fixed length 512 on VMS */
X+#ifdef VMS
X+#  define FOPR  "r","ctx=stm"
X+#  define FOPM  "r+","ctx=stm","rfm=fix","mrs=512"
X+#  define FOPW  "w","ctx=stm","rfm=fix","mrs=512"
X+#endif /* VMS */
X+
X+#ifdef CMS_MVS
X+/* Binary files must be RECFM=F,LRECL=1 for ftell() to get correct pos */
X+/* ...unless byteseek is used.  Let's try that for a while.            */
X+#  define FOPR "rb,byteseek"
X+#  define FOPM "r+b,byteseek"
X+#  ifdef MVS
X+#    define FOPW "wb,recfm=u,lrecl=32760,byteseek" /* New binary files */
X+#    define FOPWE "wb"                             /* Existing binary files */
X+#    define FOPWT "w,lrecl=133"                    /* New text files */
X+#    define FOPWTE "w"                             /* Existing text files */
X+#  else
X+#    define FOPW "wb,recfm=v,lrecl=32760"
X+#    define FOPWT "w"
X+#  endif
X+#endif /* CMS_MVS */
X+
X+#ifdef TOPS20          /* TOPS-20 MODERN?  You kidding? */
X+#  define FOPW "w8"
X+#endif /* TOPS20 */
X+
X+/* Defaults when nothing special has been defined previously. */
X+#ifdef MODERN
X+#  ifndef FOPR
X+#    define FOPR "rb"
X+#  endif
X+#  ifndef FOPM
X+#    define FOPM "r+b"
X+#  endif
X+#  ifndef FOPW
X+#    define FOPW "wb"
X+#  endif
X+#  ifndef FOPWT
X+#    define FOPWT "wt"
X+#  endif
X+#else /* !MODERN */
X+#  ifndef FOPR
X+#    define FOPR "r"
X+#  endif
X+#  ifndef FOPM
X+#    define FOPM "r+"
X+#  endif
X+#  ifndef FOPW
X+#    define FOPW "w"
X+#  endif
X+#  ifndef FOPWT
X+#    define FOPWT "w"
X+#  endif
X+#endif /* ?MODERN */
X+
X+/*
X+ * If <limits.h> exists on most systems, should include that, since it may
X+ * define some or all of the following:  NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
X+ * _POSIX_PATH_MAX.
X+ */
X+#ifdef DOS_FLX_NLM_OS2_W32
X+#  include <limits.h>
X+#endif
X+
X+#ifndef PATH_MAX
X+#  ifdef MAXPATHLEN
X+#    define PATH_MAX      MAXPATHLEN    /* in <sys/param.h> on some systems */
X+#  else
X+#    ifdef _MAX_PATH
X+#      define PATH_MAX    _MAX_PATH
X+#    else
X+#      if FILENAME_MAX > 255
X+#        define PATH_MAX  FILENAME_MAX  /* used like PATH_MAX on some systems */
X+#      else
X+#        define PATH_MAX  1024
X+#      endif
X+#    endif /* ?_MAX_PATH */
X+#  endif /* ?MAXPATHLEN */
X+#endif /* !PATH_MAX */
X+
X+#define FILNAMSIZ  PATH_MAX
X+
X+/* DBCS support for Info-ZIP  (mainly for japanese (-: )
X+ * by Yoshioka Tsuneo (QWF00133 at nifty.ne.jp,tsuneo-y at is.aist-nara.ac.jp)
X+ */
X+#ifdef _MBCS
X+#  include <locale.h>
X+   /* Multi Byte Character Set */
X+#  define ___MBS_TMP_DEF  char *___tmp_ptr;
X+#  define ___TMP_PTR      ___tmp_ptr
X+#  define CLEN(ptr) mblen((ZCONST char *)(ptr), MB_CUR_MAX)
X+#  ifndef PREINCSTR
X+#    define PREINCSTR(ptr) (ptr += CLEN(ptr))
X+#  endif
X+#  define POSTINCSTR(ptr) (___TMP_PTR=(char *)(ptr), PREINCSTR(ptr),___TMP_PTR)
X+   char *plastchar OF((ZCONST char *ptr, extent len));
X+#  define lastchar(ptr, len) ((int)(unsigned)*plastchar(ptr, len))
X+#  ifndef MBSCHR
X+#    define NEED_UZMBSCHR
X+#    define MBSCHR(str,c) (char *)uzmbschr((ZCONST unsigned char *)(str), c)
X+#  endif
X+#  ifndef MBSRCHR
X+#    define NEED_UZMBSRCHR
X+#    define MBSRCHR(str,c) (char *)uzmbsrchr((ZCONST unsigned char *)(str), c)
X+#  endif
X+#  define SETLOCALE(category, locale) setlocale(category, locale)
X+#else /* !_MBCS */
X+#  define ___MBS_TMP_DEF
X+#  define ___TMP_PTR
X+#  define CLEN(ptr) 1
X+#  define PREINCSTR(ptr) (++(ptr))
X+#  define POSTINCSTR(ptr) ((ptr)++)
X+#  define plastchar(ptr, len) (&ptr[(len)-1])
X+#  define lastchar(ptr, len) (ptr[(len)-1])
X+#  define MBSCHR(str, c) strchr(str, c)
X+#  define MBSRCHR(str, c) strrchr(str, c)
X+#  define SETLOCALE(category, locale)
X+#endif /* ?_MBCS */
X+#define INCSTR(ptr) PREINCSTR(ptr)
X+
X+
X+#if (defined(MALLOC_WORK) && !defined(MY_ZCALLOC))
X+   /* Any system without a special calloc function */
X+# ifndef zcalloc
X+#  define zcalloc(items, size) \
X+          (zvoid far *)calloc((unsigned)(items), (unsigned)(size))
X+# endif
X+# ifndef zcfree
X+#  define zcfree    free
X+# endif
X+#endif /* MALLOC_WORK && !MY_ZCALLOC */
X+
X+#ifdef REGULUS  /* returns the inode number on success(!)...argh argh argh */
X+#  define stat(p,s) zstat((p),(s))
X+#endif
X+
X+#if (defined(CRAY) && defined(ZMEM))
X+#  undef ZMEM
X+#endif
X+
X+#ifdef ZMEM
X+#  undef ZMEM
X+#  define memcmp(b1,b2,len)      bcmp(b2,b1,len)
X+#  define memcpy(dest,src,len)   bcopy(src,dest,len)
X+#  define memzero                bzero
X+#else
X+#  define memzero(dest,len)      memset(dest,0,len)
X+#endif
X+
X+#ifndef TRUE
X+#  define TRUE      1   /* sort of obvious */
X+#endif
X+#ifndef FALSE
X+#  define FALSE     0
X+#endif
X+
X+#ifndef SEEK_SET
X+#  define SEEK_SET  0
X+#  define SEEK_CUR  1
X+#  define SEEK_END  2
X+#endif
X+
X+#if (!defined(S_IEXEC) && defined(S_IXUSR))
X+#  define S_IEXEC   S_IXUSR
X+#endif
X+
X+#if (defined(UNIX) && defined(S_IFLNK) && !defined(MTS))
X+#  define SYMLINKS
X+#  ifndef S_ISLNK
X+#    define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)
X+#  endif
X+#endif /* UNIX && S_IFLNK && !MTS */
X+
X+#ifndef S_ISDIR
X+#  ifdef CMS_MVS
X+#    define S_ISDIR(m)  (FALSE)
X+#  else
X+#    define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
X+# endif
X+#endif
X+
X+#ifndef IS_VOLID
X+#  define IS_VOLID(m)  ((m) & 0x08)
X+#endif
X+
X+
X+#ifdef SHORT_SYMS                   /* Mark Williams C, ...? */
X+#  define extract_or_test_files     xtr_or_tst_files
X+#  define extract_or_test_member    xtr_or_tst_member
X+#endif
X+
X+#ifdef REALLY_SHORT_SYMS            /* TOPS-20 linker:  first 6 chars */
X+#  define process_cdir_file_hdr     XXpcdfh
X+#  define process_local_file_hdr    XXplfh
X+#  define extract_or_test_files     XXxotf  /* necessary? */
X+#  define extract_or_test_member    XXxotm  /* necessary? */
X+#  define check_for_newer           XXcfn
X+#  define overwrite_all             XXoa
X+#  define process_all_files         XXpaf
X+#  define extra_field               XXef
X+#  define explode_lit8              XXel8
X+#  define explode_lit4              XXel4
X+#  define explode_nolit8            XXnl8
X+#  define explode_nolit4            XXnl4
X+#  define cpdist8                   XXcpdist8
X+#  define inflate_codes             XXic
X+#  define inflate_stored            XXis
X+#  define inflate_fixed             XXif
X+#  define inflate_dynamic           XXid
X+#  define inflate_block             XXib
X+#  define maxcodemax                XXmax
X+#endif
X+
X+#ifndef S_TIME_T_MAX            /* max value of signed (>= 32-bit) time_t */
X+#  define S_TIME_T_MAX  ((time_t)(ulg)0x7fffffffL)
X+#endif
X+#ifndef U_TIME_T_MAX            /* max value of unsigned (>= 32-bit) time_t */
X+#  define U_TIME_T_MAX  ((time_t)(ulg)0xffffffffL)
X+#endif
X+#ifdef DOSTIME_MINIMUM          /* min DOSTIME value (1980-01-01) */
X+#  undef DOSTIME_MINIMUM
X+#endif
X+#define DOSTIME_MINIMUM ((ulg)0x00210000L)
X+#ifdef DOSTIME_2038_01_18       /* approximate DOSTIME equivalent of */
X+#  undef DOSTIME_2038_01_18     /*  the signed-32-bit time_t limit */
X+#endif
X+#define DOSTIME_2038_01_18 ((ulg)0x74320000L)
X+
X+#ifdef QDOS
X+#  define ZSUFX         "_zip"
X+#  define ALT_ZSUFX     ".zip"
X+#else
X+#  ifdef RISCOS
X+#    define ZSUFX       "/zip"
X+#  else
X+#    define ZSUFX       ".zip"
X+#  endif
X+#  define ALT_ZSUFX     ".ZIP"   /* Unix-only so far (only case-sensitive fs) */
X+#endif
X+
X+#define CENTRAL_HDR_SIG   "\001\002"   /* the infamous "PK" signature bytes, */
X+#define LOCAL_HDR_SIG     "\003\004"   /*  w/o "PK" (so unzip executable not */
X+#define END_CENTRAL_SIG   "\005\006"   /*  mistaken for zipfile itself) */
X+#define EXTD_LOCAL_SIG    "\007\010"   /* [ASCII "\113" == EBCDIC "\080" ??] */
X+
X+/** internal-only return codes **/
X+#define IZ_DIR            76   /* potential zipfile is a directory */
X+/* special return codes for mapname() */
X+#define MPN_OK            0      /* mapname successful */
X+#define MPN_INF_TRUNC    (1<<8)  /* caution - filename truncated */
X+#define MPN_INF_SKIP     (2<<8)  /* info  - skipped because nothing to do */
X+#define MPN_ERR_SKIP     (3<<8)  /* error - entry skipped */
X+#define MPN_ERR_TOOLONG  (4<<8)  /* error - path too long */
X+#define MPN_NOMEM        (10<<8) /* error - out of memory, file skipped */
X+#define MPN_CREATED_DIR  (16<<8) /* directory created: set time & permission */
X+#define MPN_VOL_LABEL    (17<<8) /* volume label, but can't set on hard disk */
X+#define MPN_INVALID      (99<<8) /* internal logic error, should never reach */
X+/* mask for internal mapname&checkdir return codes */
X+#define MPN_MASK          0x7F00
X+/* error code for extracting/testing extra field blocks */
X+#define IZ_EF_TRUNC       79   /* local extra field truncated (PKZIP'd) */
X+
X+/* choice of activities for do_string() */
X+#define SKIP              0             /* skip header block */
X+#define DISPLAY           1             /* display archive comment (ASCII) */
X+#define DISPL_8           5             /* display file comment (ext. ASCII) */
X+#define DS_FN             2             /* read filename (ext. ASCII, chead) */
X+#define DS_FN_C           2             /* read filename from central header */
X+#define DS_FN_L           6             /* read filename from local header */
X+#define EXTRA_FIELD       3             /* copy extra field into buffer */
X+#define DS_EF             3
X+#ifdef AMIGA
X+#  define FILENOTE        4             /* convert file comment to filenote */
X+#endif
X+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
X+#  define CHECK_AUTORUN   7             /* copy command, display remainder */
X+#  define CHECK_AUTORUN_Q 8             /* copy command, skip remainder */
X+#endif
X+
X+#define DOES_NOT_EXIST    -1   /* return values for check_for_newer() */
X+#define EXISTS_AND_OLDER  0
X+#define EXISTS_AND_NEWER  1
X+
X+#define OVERWRT_QUERY     0    /* status values for G.overwrite_mode */
X+#define OVERWRT_ALWAYS    1
X+#define OVERWRT_NEVER     2
X+
X+#define IS_OVERWRT_ALL    (G.overwrite_mode == OVERWRT_ALWAYS)
X+#define IS_OVERWRT_NONE   (G.overwrite_mode == OVERWRT_NEVER)
X+
X+#define ROOT              0    /* checkdir() extract-to path:  called once */
X+#define INIT              1    /* allocate buildpath:  called once per member */
X+#define APPEND_DIR        2    /* append a dir comp.:  many times per member */
X+#define APPEND_NAME       3    /* append actual filename:  once per member */
X+#define GETPATH           4    /* retrieve the complete path and free it */
X+#define END               5    /* free root path prior to exiting program */
X+
X+/* version_made_by codes (central dir):  make sure these */
X+/*  are not defined on their respective systems!! */
X+#define FS_FAT_           0    /* filesystem used by MS-DOS, OS/2, Win32 */
X+#define AMIGA_            1
X+#define VMS_              2
X+#define UNIX_             3
X+#define VM_CMS_           4
X+#define ATARI_            5    /* what if it's a minix filesystem? [cjh] */
X+#define FS_HPFS_          6    /* filesystem used by OS/2 (and NT 3.x) */
X+#define MAC_              7    /* HFS filesystem used by MacOS */
X+#define Z_SYSTEM_         8
X+#define CPM_              9
X+#define TOPS20_           10
X+#define FS_NTFS_          11   /* filesystem used by Windows NT */
X+#define QDOS_             12
X+#define ACORN_            13   /* Archimedes Acorn RISC OS */
X+#define FS_VFAT_          14   /* filesystem used by Windows 95, NT */
X+#define MVS_              15
X+#define BEOS_             16   /* hybrid POSIX/database filesystem */
X+#define TANDEM_           17   /* Tandem NSK */
X+#define THEOS_            18   /* THEOS */
X+#define MAC_OSX_          19   /* Mac OS/X (Darwin) */
X+#define ATHEOS_           30   /* AtheOS */
X+#define NUM_HOSTS         31   /* index of last system + 1 */
X+/* don't forget to update zipinfo.c appropiately if NUM_HOSTS changes! */
X+
X+#define STORED            0    /* compression methods */
X+#define SHRUNK            1
X+#define REDUCED1          2
X+#define REDUCED2          3
X+#define REDUCED3          4
X+#define REDUCED4          5
X+#define IMPLODED          6
X+#define TOKENIZED         7
X+#define DEFLATED          8
X+#define ENHDEFLATED       9
X+#define DCLIMPLODED      10
X+#define PKRESMOD11       11
X+#define BZIP2ED          12
X+#define NUM_METHODS      13    /* index of last method + 1 */
X+/* don't forget to update list_files(), extract.c and zipinfo.c appropriately
X+ * if NUM_METHODS changes */
X+
X+/* (the PK-class error codes are public and have been moved into unzip.h) */
X+
X+#define DF_MDY            0    /* date format 10/26/91 (USA only) */
X+#define DF_DMY            1    /* date format 26/10/91 (most of the world) */
X+#define DF_YMD            2    /* date format 91/10/26 (a few countries) */
X+
X+/*---------------------------------------------------------------------------
X+    Extra-field block ID values and offset info.
X+  ---------------------------------------------------------------------------*/
X+/* extra-field ID values, all little-endian: */
X+#define EF_PKSZ64    0x0001    /* PKWARE's 64-bit filesize extensions */
X+#define EF_AV        0x0007    /* PKWARE's authenticity verification */
X+#define EF_OS2       0x0009    /* OS/2 extended attributes */
X+#define EF_PKW32     0x000a    /* PKWARE's Win95/98/WinNT filetimes */
X+#define EF_PKVMS     0x000c    /* PKWARE's VMS */
X+#define EF_PKUNIX    0x000d    /* PKWARE's Unix */
X+#define EF_IZVMS     0x4d49    /* Info-ZIP's VMS ("IM") */
X+#define EF_IZUNIX    0x5855    /* Info-ZIP's old Unix[1] ("UX") */
X+#define EF_IZUNIX2   0x7855    /* Info-ZIP's new Unix[2] ("Ux") */
X+#define EF_TIME      0x5455    /* universal timestamp ("UT") */
X+#define EF_MAC3      0x334d    /* Info-ZIP's new Macintosh (= "M3") */
X+#define EF_JLMAC     0x07c8    /* Johnny Lee's old Macintosh (= 1992) */
X+#define EF_ZIPIT     0x2605    /* Thomas Brown's Macintosh (ZipIt) */
X+#define EF_ZIPIT2    0x2705    /* T. Brown's Mac (ZipIt) v 1.3.8 and newer ? */
X+#define EF_SMARTZIP  0x4d63    /* Mac SmartZip by Marco Bambini */
X+#define EF_VMCMS     0x4704    /* Info-ZIP's VM/CMS ("\004G") */
X+#define EF_MVS       0x470f    /* Info-ZIP's MVS ("\017G") */
X+#define EF_ACL       0x4c41    /* (OS/2) access control list ("AL") */
X+#define EF_NTSD      0x4453    /* NT security descriptor ("SD") */
X+#define EF_ATHEOS    0x7441    /* AtheOS ("At") */
X+#define EF_BEOS      0x6542    /* BeOS ("Be") */
X+#define EF_QDOS      0xfb4a    /* SMS/QDOS ("J\373") */
X+#define EF_AOSVS     0x5356    /* AOS/VS ("VS") */
X+#define EF_SPARK     0x4341    /* David Pilling's Acorn/SparkFS ("AC") */
X+#define EF_TANDEM    0x4154    /* Tandem NSK ("TA") */
X+#define EF_THEOS     0x6854    /* Jean-Michel Dubois' Theos "Th" */
X+#define EF_THEOSO    0x4854    /* old Theos port */
X+#define EF_MD5       0x4b46    /* Fred Kantor's MD5 ("FK") */
X+#define EF_ASIUNIX   0x756e    /* ASi's Unix ("nu") */
X+
X+#define EB_HEADSIZE       4    /* length of extra field block header */
X+#define EB_ID             0    /* offset of block ID in header */
X+#define EB_LEN            2    /* offset of data length field in header */
X+#define EB_UCSIZE_P       0    /* offset of ucsize field in compr. data */
X+#define EB_CMPRHEADLEN    6    /* lenght of compression header */
X+
X+#define EB_UX_MINLEN      8    /* minimal "UX" field contains atime, mtime */
X+#define EB_UX_FULLSIZE    12   /* full "UX" field (atime, mtime, uid, gid) */
X+#define EB_UX_ATIME       0    /* offset of atime in "UX" extra field data */
X+#define EB_UX_MTIME       4    /* offset of mtime in "UX" extra field data */
X+#define EB_UX_UID         8    /* byte offset of UID in "UX" field data */
X+#define EB_UX_GID         10   /* byte offset of GID in "UX" field data */
X+
X+#define EB_UX2_MINLEN     4    /* minimal "Ux" field contains UID/GID */
X+#define EB_UX2_UID        0    /* byte offset of UID in "Ux" field data */
X+#define EB_UX2_GID        2    /* byte offset of GID in "Ux" field data */
X+#define EB_UX2_VALID      (1 << 8)      /* UID/GID present */
X+
X+#define EB_UT_MINLEN      1    /* minimal UT field contains Flags byte */
X+#define EB_UT_FLAGS       0    /* byte offset of Flags field */
X+#define EB_UT_TIME1       1    /* byte offset of 1st time value */
X+#define EB_UT_FL_MTIME    (1 << 0)      /* mtime present */
X+#define EB_UT_FL_ATIME    (1 << 1)      /* atime present */
X+#define EB_UT_FL_CTIME    (1 << 2)      /* ctime present */
X+
X+#define EB_FLGS_OFFS      4    /* offset of flags area in generic compressed
X+                                  extra field blocks (BEOS, MAC, and others) */
X+#define EB_OS2_HLEN       4    /* size of OS2/ACL compressed data header */
X+#define EB_BEOS_HLEN      5    /* length of BeOS&AtheOS e.f attribute header */
X+#define EB_BE_FL_UNCMPR   0x01 /* "BeOS&AtheOS attribs uncompr." bit flag */
X+#define EB_MAC3_HLEN      14   /* length of Mac3 attribute block header */
X+#define EB_SMARTZIP_HLEN  64   /* fixed length of the SmartZip extra field */
X+#define EB_M3_FL_DATFRK   0x01 /* "this entry is data fork" flag */
X+#define EB_M3_FL_UNCMPR   0x04 /* "Mac3 attributes uncompressed" bit flag */
X+#define EB_M3_FL_TIME64   0x08 /* "Mac3 time fields are 64 bit wide" flag */
X+#define EB_M3_FL_NOUTC    0x10 /* "Mac3 timezone offset fields missing" flag */
X+
X+#define EB_NTSD_C_LEN     4    /* length of central NT security data */
X+#define EB_NTSD_L_LEN     5    /* length of minimal local NT security data */
X+#define EB_NTSD_VERSION   4    /* offset of NTSD version byte */
X+#define EB_NTSD_MAX_VER   (0)  /* maximum version # we know how to handle */
X+
X+#define EB_ASI_CRC32      0    /* offset of ASI Unix field's crc32 checksum */
X+#define EB_ASI_MODE       4    /* offset of ASI Unix permission mode field */
X+
X+#define EB_IZVMS_HLEN     12   /* length of IZVMS attribute block header */
X+#define EB_IZVMS_FLGS     4    /* offset of compression type flag */
X+#define EB_IZVMS_UCSIZ    6    /* offset of ucsize field in IZVMS header */
X+#define EB_IZVMS_BCMASK   07   /* 3 bits for compression type */
X+#define EB_IZVMS_BCSTOR   0    /*  Stored */
X+#define EB_IZVMS_BC00     1    /*  0byte -> 0bit compression */
X+#define EB_IZVMS_BCDEFL   2    /*  Deflated */
X+
X+
X+/*---------------------------------------------------------------------------
X+    True sizes of the various headers, as defined by PKWARE--so it is not
X+    likely that these will ever change.  But if they do, make sure both these
X+    defines AND the typedefs below get updated accordingly.
X+  ---------------------------------------------------------------------------*/
X+#define LREC_SIZE   26   /* lengths of local file headers, central */
X+#define CREC_SIZE   42   /*  directory headers, and the end-of-    */
X+#define ECREC_SIZE  18   /*  central-dir record, respectively      */
X+
X+#define MAX_BITS    13                 /* used in unshrink() */
X+#define HSIZE       (1 << MAX_BITS)    /* size of global work area */
X+
X+#define LF     10        /* '\n' on ASCII machines; must be 10 due to EBCDIC */
X+#define CR     13        /* '\r' on ASCII machines; must be 13 due to EBCDIC */
X+#define CTRLZ  26        /* DOS & OS/2 EOF marker (used in fileio.c, vms.c) */
X+
X+#ifdef EBCDIC
X+#  define foreign(c)    ascii[(uch)(c)]
X+#  define native(c)     ebcdic[(uch)(c)]
X+#  define NATIVE        "EBCDIC"
X+#  define NOANSIFILT
X+#endif
X+
X+#ifdef VMS
X+#  define ENV_UNZIP       "UNZIP_OPTS"     /* names of environment variables */
X+#  define ENV_ZIPINFO     "ZIPINFO_OPTS"
X+#endif /* VMS */
X+#ifdef RISCOS
X+#  define ENV_UNZIP       "Unzip$Options"
X+#  define ENV_ZIPINFO     "Zipinfo$Options"
X+#  define ENV_UNZIPEXTS   "Unzip$Exts"
X+#endif /* RISCOS */
X+#ifndef ENV_UNZIP
X+#  define ENV_UNZIP       "UNZIP"          /* the standard names */
X+#  define ENV_ZIPINFO     "ZIPINFO"
X+#endif
X+#define ENV_UNZIP2        "UNZIPOPT"     /* alternate names, for zip compat. */
X+#define ENV_ZIPINFO2      "ZIPINFOOPT"
X+
X+#if (!defined(QQ) && !defined(NOQQ))
X+#  define QQ
X+#endif
X+
X+#ifdef QQ                         /* Newtware version:  no file */
X+#  define QCOND     (!uO.qflag)   /*  comments with -vq or -vqq */
X+#else                             /* Bill Davidsen version:  no way to */
X+#  define QCOND     (longhdr)     /*  kill file comments when listing */
X+#endif
X+
X+#ifdef OLD_QQ
X+#  define QCOND2    (uO.qflag < 2)
X+#else
X+#  define QCOND2    (!uO.qflag)
X+#endif
X+
X+#ifdef WILD_STOP_AT_DIR
X+#  define __WDLPRO  , int sepc
X+#  define __WDL     , sepc
X+#  define __WDLDEF  int sepc;
X+#  define WISEP     , (uO.W_flag ? '/' : '\0')
X+#else
X+#  define __WDLPRO
X+#  define __WDL
X+#  define __WDLDEF
X+#  define WISEP
X+#endif
X+
X+
X+
X+
X+/**************/
X+/*  Typedefs  */
X+/**************/
X+
X+#ifdef NO_UID_GID
X+#  ifdef UID_USHORT
X+     typedef unsigned short  uid_t;    /* TI SysV.3 */
X+     typedef unsigned short  gid_t;
X+#  else
X+     typedef unsigned int    uid_t;    /* SCO Xenix */
X+     typedef unsigned int    gid_t;
X+#  endif
X+#endif
X+
X+#if (defined(GOT_UTIMBUF) || defined(sgi) || defined(ATARI))
X+   typedef struct utimbuf ztimbuf;
X+#else
X+   typedef struct ztimbuf {
X+       time_t actime;        /* new access time */
X+       time_t modtime;       /* new modification time */
X+   } ztimbuf;
X+#endif
X+
X+typedef struct iztimes {
X+   time_t atime;             /* new access time */
X+   time_t mtime;             /* new modification time */
X+   time_t ctime;             /* used for creation time; NOT same as st_ctime */
X+} iztimes;
X+
X+#ifdef SET_DIR_ATTRIB
X+   typedef struct direntry {    /* head of system-specific struct holding */
X+       struct direntry *next;   /*  defered directory attributes info */
X+       char *fn;                /* filename of directory */
X+       char buf[1];             /* start of system-specific internal data */
X+   } direntry;
X+#endif /* SET_DIR_ATTRIB */
X+
X+#ifdef SYMLINKS
X+   typedef struct slinkentry {  /* info for deferred symlink creation */
X+       struct slinkentry *next; /* pointer to next entry in chain */
X+       extent targetlen;        /* length of target filespec */
X+       extent attriblen;        /* length of system-specific attrib data */
X+       char *target;            /* pointer to target filespec */
X+       char *fname;             /* pointer to name of link */
X+       char buf[2];             /* name of link, allocs space for 2 '\0's */
X+   } slinkentry;
X+#endif /* SYMLINKS */
X+
X+typedef struct min_info {
X+    Z_OFF_T offset;
X+    ulg compr_size;          /* compressed size (needed if extended header) */
X+    ulg uncompr_size;        /* uncompressed size (needed if extended header) */
X+    ulg crc;                 /* crc (needed if extended header) */
X+    ush diskstart;           /* no of volume where this entry starts */
X+    uch hostver;
X+    uch hostnum;
X+    unsigned file_attr;      /* local flavor, as used by creat(), chmod()... */
X+    unsigned encrypted : 1;  /* file encrypted: decrypt before uncompressing */
X+    unsigned ExtLocHdr : 1;  /* use time instead of CRC for decrypt check */
X+    unsigned textfile : 1;   /* file is text (according to zip) */
X+    unsigned textmode : 1;   /* file is to be extracted as text */
X+    unsigned lcflag : 1;     /* convert filename to lowercase */
X+    unsigned vollabel : 1;   /* "file" is an MS-DOS volume (disk) label */
X+    unsigned HasUxAtt : 1;   /* crec ext_file_attr has Unix style mode bits */
X+#ifndef SFX
X+    char Far *cfilname;      /* central header version of filename */
X+#endif
X+} min_info;
X+
X+typedef struct VMStimbuf {
X+    char *revdate;    /* (both roughly correspond to Unix modtime/st_mtime) */
X+    char *credate;
X+} VMStimbuf;
X+
X+/*---------------------------------------------------------------------------
X+    Zipfile work area declarations.
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef MALLOC_WORK
X+   union work {
X+     struct {                 /* unshrink(): */
X+       shrint *Parent;          /* pointer to (8192 * sizeof(shrint)) */
X+       uch *value;              /* pointer to 8KB char buffer */
X+       uch *Stack;              /* pointer to another 8KB char buffer */
X+     } shrink;
X+     uch *Slide;              /* explode(), inflate(), unreduce() */
X+   };
X+#else /* !MALLOC_WORK */
X+   union work {
X+     struct {                 /* unshrink(): */
X+       shrint Parent[HSIZE];    /* (8192 * sizeof(shrint)) == 16KB minimum */
X+       uch value[HSIZE];        /* 8KB */
X+       uch Stack[HSIZE];        /* 8KB */
X+     } shrink;                  /* total = 32KB minimum; 80KB on Cray/Alpha */
X+     uch Slide[WSIZE];        /* explode(), inflate(), unreduce() */
X+   };
X+#endif /* ?MALLOC_WORK */
X+
X+#define slide  G.area.Slide
X+
X+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
X+#  define redirSlide G.redirect_sldptr
X+#else
X+#  define redirSlide G.area.Slide
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Zipfile layout declarations.  If these headers ever change, make sure the
X+    xxREC_SIZE defines (above) change with them!
X+  ---------------------------------------------------------------------------*/
X+
X+   typedef uch   local_byte_hdr[ LREC_SIZE ];
X+#      define L_VERSION_NEEDED_TO_EXTRACT_0     0
X+#      define L_VERSION_NEEDED_TO_EXTRACT_1     1
X+#      define L_GENERAL_PURPOSE_BIT_FLAG        2
X+#      define L_COMPRESSION_METHOD              4
X+#      define L_LAST_MOD_DOS_DATETIME           6
X+#      define L_CRC32                           10
X+#      define L_COMPRESSED_SIZE                 14
X+#      define L_UNCOMPRESSED_SIZE               18
X+#      define L_FILENAME_LENGTH                 22
X+#      define L_EXTRA_FIELD_LENGTH              24
X+
X+   typedef uch   cdir_byte_hdr[ CREC_SIZE ];
X+#      define C_VERSION_MADE_BY_0               0
X+#      define C_VERSION_MADE_BY_1               1
X+#      define C_VERSION_NEEDED_TO_EXTRACT_0     2
X+#      define C_VERSION_NEEDED_TO_EXTRACT_1     3
X+#      define C_GENERAL_PURPOSE_BIT_FLAG        4
X+#      define C_COMPRESSION_METHOD              6
X+#      define C_LAST_MOD_DOS_DATETIME           8
X+#      define C_CRC32                           12
X+#      define C_COMPRESSED_SIZE                 16
X+#      define C_UNCOMPRESSED_SIZE               20
X+#      define C_FILENAME_LENGTH                 24
X+#      define C_EXTRA_FIELD_LENGTH              26
X+#      define C_FILE_COMMENT_LENGTH             28
X+#      define C_DISK_NUMBER_START               30
X+#      define C_INTERNAL_FILE_ATTRIBUTES        32
X+#      define C_EXTERNAL_FILE_ATTRIBUTES        34
X+#      define C_RELATIVE_OFFSET_LOCAL_HEADER    38
X+
X+   typedef uch   ec_byte_rec[ ECREC_SIZE+4 ];
X+/*     define SIGNATURE                         0   space-holder only */
X+#      define NUMBER_THIS_DISK                  4
X+#      define NUM_DISK_WITH_START_CENTRAL_DIR   6
X+#      define NUM_ENTRIES_CENTRL_DIR_THS_DISK   8
X+#      define TOTAL_ENTRIES_CENTRAL_DIR         10
X+#      define SIZE_CENTRAL_DIRECTORY            12
X+#      define OFFSET_START_CENTRAL_DIRECTORY    16
X+#      define ZIPFILE_COMMENT_LENGTH            20
X+
X+
X+/* The following structs are used to hold all header data of a zip entry.
X+   Traditionally, the structs' layouts followed the data layout of the
X+   corresponding zipfile header structures.  However, the zipfile header
X+   layouts were designed in the old ages of 16-bit CPUs, they are subject
X+   to structure padding and/or alignment issues on newer systems with a
X+   "natural word width" of more than 2 bytes.
X+   Please note that the structure members are now reordered by size
X+   (top-down), to prevent internal padding and optimize memory usage!
X+ */
X+   typedef struct local_file_header {                 /* LOCAL */
X+       ulg csize;
X+       ulg ucsize;
X+       ulg last_mod_dos_datetime;
X+       ulg crc32;
X+       uch version_needed_to_extract[2];
X+       ush general_purpose_bit_flag;
X+       ush compression_method;
X+       ush filename_length;
X+       ush extra_field_length;
X+   } local_file_hdr;
X+
X+#if 0
X+   typedef struct central_directory_file_header {     /* CENTRAL */
X+       uch version_made_by[2];
X+       uch version_needed_to_extract[2];
X+       ush general_purpose_bit_flag;
X+       ush compression_method;
X+       ulg last_mod_dos_datetime;
X+       ulg crc32;
X+       ulg csize;
X+       ulg ucsize;
X+       ush filename_length;
X+       ush extra_field_length;
X+       ush file_comment_length;
X+       ush disk_number_start;
X+       ush internal_file_attributes;
X+       ulg external_file_attributes;
X+       ulg relative_offset_local_header;
X+   } cdir_file_hdr;
X+#endif /* 0 */
X+
X+   typedef struct end_central_dir_record {            /* END CENTRAL */
X+       ush number_this_disk;
X+       ush num_disk_start_cdir;
X+       ush num_entries_centrl_dir_ths_disk;
X+       ush total_entries_central_dir;
X+       ulg size_central_directory;
X+       ulg offset_start_central_directory;
X+       ush zipfile_comment_length;
X+   } ecdir_rec;
X+
X+
X+/* Huffman code lookup table entry--this entry is four bytes for machines
X+   that have 16-bit pointers (e.g. PC's in the small or medium model).
X+   Valid extra bits are 0..16.  e == 31 is EOB (end of block), e == 32
X+   means that v is a literal, 32 < e < 64 means that v is a pointer to
X+   the next table, which codes (e & 31)  bits, and lastly e == 99 indicates
X+   an unused code.  If a code with e == 99 is looked up, this implies an
X+   error in the data. */
X+
X+struct huft {
X+    uch e;                /* number of extra bits or operation */
X+    uch b;                /* number of bits in this code or subcode */
X+    union {
X+        ush n;            /* literal, length base, or distance base */
X+        struct huft *t;   /* pointer to next level of table */
X+    } v;
X+};
X+
X+
X+typedef struct _APIDocStruct {
X+    char *compare;
X+    char *function;
X+    char *syntax;
X+    char *purpose;
X+} APIDocStruct;
X+
X+
X+
X+
X+/*************/
X+/*  Globals  */
X+/*************/
X+
X+#if (defined(OS2) && !defined(FUNZIP))
X+#  include "os2/os2data.h"
X+#endif
X+
X+#include "globals.h"
X+
X+
X+
X+/*************************/
X+/*  Function Prototypes  */
X+/*************************/
X+
X+/*---------------------------------------------------------------------------
X+    Functions in unzip.c (initialization routines):
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef WINDLL
X+   int    MAIN                   OF((int argc, char **argv));
X+   int    unzip                  OF((__GPRO__ int argc, char **argv));
X+   int    uz_opts                OF((__GPRO__ int *pargc, char ***pargv));
X+   int    usage                  OF((__GPRO__ int error));
X+#endif /* !WINDLL */
X+
X+/*---------------------------------------------------------------------------
X+    Functions in process.c (main driver routines):
X+  ---------------------------------------------------------------------------*/
X+
X+int      process_zipfiles        OF((__GPRO));
X+void     free_G_buffers          OF((__GPRO));
X+/* static int    do_seekable     OF((__GPRO__ int lastchance)); */
X+/* static int    find_ecrec      OF((__GPRO__ long searchlen)); */
X+int      uz_end_central          OF((__GPRO));
X+int      process_cdir_file_hdr   OF((__GPRO));
X+int      get_cdir_ent            OF((__GPRO));
X+int      process_local_file_hdr  OF((__GPRO));
X+unsigned ef_scan_for_izux        OF((ZCONST uch *ef_buf, unsigned ef_len,
X+                                     int ef_is_c, ulg dos_mdatetime,
X+                                     iztimes *z_utim, ush *z_uidgid));
X+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
X+   zvoid *getRISCOSexfield       OF((ZCONST uch *ef_buf, unsigned ef_len));
X+#endif
X+
X+#ifndef SFX
X+
X+/*---------------------------------------------------------------------------
X+    Functions in zipinfo.c (`zipinfo-style' listing routines):
X+  ---------------------------------------------------------------------------*/
X+
X+#ifndef NO_ZIPINFO
X+#ifndef WINDLL
X+   int   zi_opts                 OF((__GPRO__ int *pargc, char ***pargv));
X+#endif
X+int      zi_end_central          OF((__GPRO));
X+int      zipinfo                 OF((__GPRO));
X+/* static int      zi_long       OF((__GPRO__ ulg *pEndprev)); */
X+/* static int      zi_short      OF((__GPRO)); */
X+/* static char    *zi_time       OF((__GPRO__ ZCONST ulg *datetimez,
X+                                     ZCONST time_t *modtimez, char *d_t_str));*/
X+#endif /* !NO_ZIPINFO */
X+
X+/*---------------------------------------------------------------------------
X+    Functions in list.c (generic zipfile-listing routines):
X+  ---------------------------------------------------------------------------*/
X+
X+int      list_files              OF((__GPRO));
X+#ifdef TIMESTAMP
X+   int   get_time_stamp          OF((__GPRO__  time_t *last_modtime,
X+                                     ulg *nmember));
X+#endif
X+int      ratio                   OF((ulg uc, ulg c));
X+void     fnprint                 OF((__GPRO));
X+
X+#endif /* !SFX */
X+
X+/*---------------------------------------------------------------------------
X+    Functions in fileio.c:
X+  ---------------------------------------------------------------------------*/
X+
X+int      open_input_file      OF((__GPRO));
X+int      open_outfile         OF((__GPRO));                    /* also vms.c */
X+void     undefer_input        OF((__GPRO));
X+void     defer_leftover_input OF((__GPRO));
X+unsigned readbuf              OF((__GPRO__ char *buf, register unsigned len));
X+int      readbyte             OF((__GPRO));
X+int      fillinbuf            OF((__GPRO));
X+int      seek_zipf            OF((__GPRO__ Z_OFF_T abs_offset));
X+#ifdef FUNZIP
X+   int   flush                OF((__GPRO__ ulg size));  /* actually funzip.c */
X+#else
X+   int   flush                OF((__GPRO__ uch *buf, ulg size, int unshrink));
X+#endif
X+/* static int  disk_error     OF((__GPRO)); */
X+void     handler              OF((int signal));
X+time_t   dos_to_unix_time     OF((ulg dos_datetime));
X+int      check_for_newer      OF((__GPRO__ char *filename)); /* os2,vmcms,vms */
X+int      do_string            OF((__GPRO__ unsigned int length, int option));
X+ush      makeword             OF((ZCONST uch *b));
X+ulg      makelong             OF((ZCONST uch *sig));
X+#if (!defined(STR_TO_ISO) || defined(NEED_STR2ISO))
X+   char *str2iso              OF((char *dst, ZCONST char *src));
X+#endif
X+#if (!defined(STR_TO_OEM) || defined(NEED_STR2OEM))
X+   char *str2oem              OF((char *dst, ZCONST char *src));
X+#endif
X+#ifdef NO_STRNICMP
X+   int   zstrnicmp            OF((register ZCONST char *s1,
X+                                  register ZCONST char *s2,
X+                                  register unsigned n));
X+#endif
X+#ifdef REGULUS
X+   int   zstat                OF((ZCONST char *p, struct stat *s));
X+#endif
X+#ifdef ZMEM   /* MUST be ifdef'd because of conflicts with the standard def. */
X+   zvoid *memset OF((register zvoid *, register int, register unsigned int));
X+   int    memcmp OF((register ZCONST zvoid*, register ZCONST zvoid *,
X+                     register unsigned int));
X+   zvoid *memcpy OF((register zvoid *, register ZCONST zvoid *,
X+                     register unsigned int));
X+#endif
X+#ifdef NEED_UZMBSCHR
X+   unsigned char *uzmbschr  OF((ZCONST unsigned char *str, unsigned int c));
X+#endif
X+#ifdef NEED_UZMBSRCHR
X+   unsigned char *uzmbsrchr OF((ZCONST unsigned char *str, unsigned int c));
X+#endif
X+#ifdef SMALL_MEM
X+   char *fLoadFarString       OF((__GPRO__ const char Far *sz));
X+   char *fLoadFarStringSmall  OF((__GPRO__ const char Far *sz));
X+   char *fLoadFarStringSmall2 OF((__GPRO__ const char Far *sz));
X+   #ifndef zfstrcpy
X+     char Far * Far zfstrcpy  OF((char Far *s1, const char Far *s2));
X+   #endif
X+   #if (!defined(SFX) && !defined(zfstrcmp))
X+     int Far zfstrcmp         OF((const char Far *s1, const char Far *s2));
X+   #endif
X+#endif
X+
X+
X+/*---------------------------------------------------------------------------
X+    Functions in extract.c:
X+  ---------------------------------------------------------------------------*/
X+
X+int    extract_or_test_files     OF((__GPRO));
X+/* static int   store_info          OF((void)); */
X+/* static int   extract_or_test_member   OF((__GPRO)); */
X+/* static int   TestExtraField   OF((__GPRO__ uch *ef, unsigned ef_len)); */
X+/* static int   test_OS2         OF((__GPRO__ uch *eb, unsigned eb_size)); */
X+/* static int   test_NT          OF((__GPRO__ uch *eb, unsigned eb_size)); */
X+int    memextract                OF((__GPRO__ uch *tgt, ulg tgtsize,
X+                                     ZCONST uch *src, ulg srcsize));
X+int    memflush                  OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
X+#if (defined(VMS) || defined(VMS_TEXT_CONV))
X+   uch   *extract_izvms_block    OF((__GPRO__ ZCONST uch *ebdata,
X+                                     unsigned size, unsigned *retlen,
X+                                     ZCONST uch *init, unsigned needlen));
X+#endif
X+char  *fnfilter                  OF((ZCONST char *raw, uch *space));
X+
X+/*---------------------------------------------------------------------------
X+    Decompression functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#if (!defined(SFX) && !defined(FUNZIP))
X+int    explode                   OF((__GPRO));                  /* explode.c */
X+#endif
X+int    huft_free                 OF((struct huft *t));          /* inflate.c */
X+int    huft_build                OF((__GPRO__ ZCONST unsigned *b, unsigned n,
X+                                     unsigned s, ZCONST ush *d, ZCONST uch *e,
X+                                     struct huft **t, unsigned *m));
X+#ifdef USE_ZLIB
X+   int    UZinflate              OF((__GPRO__ int is_defl64));  /* inflate.c */
X+#  define inflate_free(x)        inflateEnd(&((Uz_Globs *)(&G))->dstrm)
X+#else
X+   int    inflate                OF((__GPRO__ int is_defl64));  /* inflate.c */
X+   int    inflate_free           OF((__GPRO));                  /* inflate.c */
X+#endif /* ?USE_ZLIB */
X+#if (!defined(SFX) && !defined(FUNZIP))
X+#ifndef COPYRIGHT_CLEAN
X+   int    unreduce               OF((__GPRO));                 /* unreduce.c */
X+/* static void  LoadFollowers    OF((__GPRO__ f_array *follower, uch *Slen));
X+                                                                * unreduce.c */
X+#endif /* !COPYRIGHT_CLEAN */
X+#ifndef LZW_CLEAN
X+   int    unshrink               OF((__GPRO));                 /* unshrink.c */
X+/* static void  partial_clear    OF((__GPRO));                  * unshrink.c */
X+#endif /* !LZW_CLEAN */
X+#endif /* !SFX && !FUNZIP */
X+
X+/*---------------------------------------------------------------------------
X+    Internal API functions (only included in DLL versions):
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef DLL
X+   void     setFileNotFound       OF((__GPRO));                     /* api.c */
X+   int      unzipToMemory         OF((__GPRO__ char *zip, char *file,
X+                                      UzpBuffer *retstr));          /* api.c */
X+   int      redirect_outfile      OF((__GPRO));                     /* api.c */
X+   int      writeToMemory         OF((__GPRO__ ZCONST uch *rawbuf,
X+                                      extent size));                /* api.c */
X+   int      close_redirect        OF((__GPRO));                     /* api.c */
X+   /* this obsolescent entry point kept for compatibility: */
X+   int      UzpUnzip              OF((int argc, char **argv));/* use UzpMain */
X+#ifdef OS2DLL
X+   int      varmessage            OF((__GPRO__ ZCONST uch *buf, ulg size));
X+   int      varputchar            OF((__GPRO__ int c));         /* rexxapi.c */
X+   int      finish_REXX_redirect  OF((__GPRO));                 /* rexxapi.c */
X+#endif
X+#ifdef API_DOC
X+   void     APIhelp               OF((__GPRO__ int argc, char **argv));
X+#endif                                                          /* apihelp.c */
X+#endif /* DLL */
X+
X+/*---------------------------------------------------------------------------
X+    MSDOS-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#if (defined(MSDOS) && (defined(__GO32__) || defined(__EMX__)))
X+   unsigned _dos_getcountryinfo(void *);                          /* msdos.c */
X+#if (!defined(__DJGPP__) || (__DJGPP__ < 2))
X+   unsigned _dos_setftime(int, unsigned, unsigned);               /* msdos.c */
X+   unsigned _dos_setfileattr(const char *, unsigned);             /* msdos.c */
X+   unsigned _dos_creat(const char *, unsigned, int *);            /* msdos.c */
X+   void _dos_getdrive(unsigned *);                                /* msdos.c */
X+   unsigned _dos_close(int);                                      /* msdos.c */
X+#endif /* !__DJGPP__ || (__DJGPP__ < 2) */
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    OS/2-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef OS2   /* GetFileTime conflicts with something in Win32 header files */
X+#if (defined(REENTRANT) && defined(USETHREADID))
X+   ulg   GetThreadId          OF((void));
X+#endif
X+   int   GetCountryInfo       OF((void));                           /* os2.c */
X+   long  GetFileTime          OF((ZCONST char *name));              /* os2.c */
X+/* static void  SetPathAttrTimes OF((__GPRO__ int flags, int dir));    os2.c */
X+/* static int   SetEAs        OF((__GPRO__ const char *path,
X+                                  void *eablock));                     os2.c */
X+/* static int   SetACL        OF((__GPRO__ const char *path,
X+                                  void *eablock));                     os2.c */
X+/* static int   IsFileNameValid OF((const char *name));                os2.c */
X+/* static void  map2fat       OF((char *pathcomp, char **pEndFAT));    os2.c */
X+/* static int   SetLongNameEA OF((char *name, char *longname));        os2.c */
X+/* static void  InitNLS       OF((void));                              os2.c */
X+   int   IsUpperNLS           OF((int nChr));                       /* os2.c */
X+   int   ToLowerNLS           OF((int nChr));                       /* os2.c */
X+   void  DebugMalloc          OF((void));                           /* os2.c */
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    QDOS-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef QDOS
X+   int    QMatch              (uch, uch);
X+   void   QFilename           (__GPRO__ char *);
X+   char  *Qstrfix             (char *);
X+   int    QReturn             (int zip_error);
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    TOPS20-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef TOPS20
X+   int    upper               OF((char *s));                     /* tops20.c */
X+   int    enquote             OF((char *s));                     /* tops20.c */
X+   int    dequote             OF((char *s));                     /* tops20.c */
X+   int    fnlegal             OF(()); /* error if prototyped? */ /* tops20.c */
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    VM/CMS- and MVS-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef CMS_MVS
X+   extent getVMMVSexfield     OF((char *type, uch *ef_block, unsigned datalen));
X+   FILE  *vmmvs_open_infile   OF((__GPRO));                       /* vmmvs.c */
X+   void   close_infile        OF((__GPRO));                       /* vmmvs.c */
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    VMS-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef VMS
X+   int    check_format        OF((__GPRO));                         /* vms.c */
X+/* int    open_outfile        OF((__GPRO));           * (see fileio.c) vms.c */
X+/* int    flush               OF((__GPRO__ uch *rawbuf, unsigned size,
X+                                  int final_flag));   * (see fileio.c) vms.c */
X+#ifdef RETURN_CODES
X+   void   return_VMS          OF((__GPRO__ int zip_error));         /* vms.c */
X+#else
X+   void   return_VMS          OF((int zip_error));                  /* vms.c */
X+#endif
X+#ifdef VMSCLI
X+   ulg    vms_unzip_cmdline   OF((int *, char ***));            /* cmdline.c */
X+   int    VMSCLI_usage        OF((__GPRO__ int error));         /* cmdline.c */
X+#endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    WIN32-only functions:
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef WIN32
X+   int   IsWinNT        OF((void));                               /* win32.c */
X+#ifdef NTSD_EAS
X+   void  process_defer_NT     OF((__GPRO));                       /* win32.c */
X+   int   test_NTSD      OF((__GPRO__ uch *eb, unsigned eb_size,
X+                            uch *eb_ucptr, ulg eb_ucsize));       /* win32.c */
X+#  define TEST_NTSD     test_NTSD
X+#endif
X+#ifdef W32_STAT_BANDAID
X+   int   zstat_win32    OF((__W32STAT_GLOBALS__
X+                            const char *path, struct stat *buf)); /* win32.c */
X+#endif
X+#endif
X+
X+/*---------------------------------------------------------------------------
X+    Miscellaneous/shared functions:
X+  ---------------------------------------------------------------------------*/
X+
X+Uz_Globs *globalsCtor    OF((void));                            /* globals.c */
X+
X+int      envargs         OF((int *Pargc, char ***Pargv,
X+                             ZCONST char *envstr, ZCONST char *envstr2));
X+                                                                /* envargs.c */
X+void     mksargs         OF((int *argcp, char ***argvp));       /* envargs.c */
X+
X+int      match           OF((ZCONST char *s, ZCONST char *p,
X+                             int ic __WDLPRO));                   /* match.c */
X+int      iswild          OF((ZCONST char *p));                    /* match.c */
X+
X+#ifdef DYNALLOC_CRCTAB
X+   void     free_crc_table  OF((void));                          /* crctab.c */
X+#endif
X+#ifndef USE_ZLIB
X+   ZCONST ulg near *get_crc_table  OF((void));         /* funzip.c, crctab.c */
X+   ulg      crc32           OF((ulg crc, ZCONST uch *buf, extent len));
X+#endif /* !USE_ZLIB */                        /* assembler source or crc32.c */
X+
X+int      dateformat      OF((void));                                /* local */
X+char     dateseparator   OF((void));                                /* local */
X+#ifndef WINDLL
X+   void  version         OF((__GPRO));                              /* local */
X+#endif
X+int      mapattr         OF((__GPRO));                              /* local */
X+int      mapname         OF((__GPRO__ int renamed));                /* local */
X+int      checkdir        OF((__GPRO__ char *pathcomp, int flag));   /* local */
X+char    *do_wild         OF((__GPRO__ ZCONST char *wildzipfn));     /* local */
X+char    *GetLoadPath     OF((__GPRO));                              /* local */
X+#if (defined(MORE) && (defined(ATH_BEO_UNX) || defined(QDOS) || defined(VMS)))
X+   int screensize        OF((int *tt_rows, int *tt_cols));          /* local */
X+# if defined(VMS)
X+   int screenlinewrap    OF((void));                                /* local */
X+# endif
X+#endif /* MORE && (ATH_BEO_UNX || QDOS || VMS) */
X+#ifdef OS2_W32
X+   int   SetFileSize     OF((FILE *file, ulg filesize));            /* local */
X+#endif
X+#ifndef MTS /* macro in MTS */
X+   void  close_outfile   OF((__GPRO));                              /* local */
X+#endif
X+#ifdef SET_SYMLINK_ATTRIBS
X+   int  set_symlnk_attribs  OF((__GPRO__ slinkentry *slnk_entry));  /* local */
X+#endif
X+#ifdef SET_DIR_ATTRIB
X+   int   defer_dir_attribs  OF((__GPRO__ direntry **pd));           /* local */
X+   int   set_direc_attribs  OF((__GPRO__ direntry *d));             /* local */
X+#endif
X+#ifdef TIMESTAMP
X+# ifdef WIN32
X+   int   stamp_file      OF((__GPRO__
X+                             ZCONST char *fname, time_t modtime));  /* local */
X+# else
X+   int   stamp_file      OF((ZCONST char *fname, time_t modtime));  /* local */
X+# endif
X+#endif
X+#if (defined(MALLOC_WORK) && defined(MY_ZCALLOC))
X+   zvoid far *zcalloc    OF((unsigned int, unsigned int));
X+   zvoid zcfree          OF((zvoid far *));
X+#endif /* MALLOC_WORK && MY_ZCALLOC */
X+#ifdef SYSTEM_SPECIFIC_CTOR
X+   void  SYSTEM_SPECIFIC_CTOR   OF((__GPRO));                       /* local */
X+#endif
X+#ifdef SYSTEM_SPECIFIC_DTOR
X+   void  SYSTEM_SPECIFIC_DTOR   OF((__GPRO));                       /* local */
X+#endif
X+
X+
X+
X+
X+
X+/************/
X+/*  Macros  */
X+/************/
X+
X+#ifndef MAX
X+#  define MAX(a,b)   ((a) > (b) ? (a) : (b))
X+#endif
X+#ifndef MIN
X+#  define MIN(a,b)   ((a) < (b) ? (a) : (b))
X+#endif
X+
X+#ifdef DEBUG
X+#  if (defined(THEOS) && defined(NO_BOGUS_SPC))
X+#    define NO_DEBUG_IN_MACROS
X+#    define Trace(x)   _fprintf x
X+#  else
X+#    define Trace(x)   fprintf x
X+#  endif
X+#else
X+#  define Trace(x)
X+#endif
X+
X+#ifdef DEBUG_TIME
X+#  define TTrace(x)  fprintf x
X+#else
X+#  define TTrace(x)
X+#endif
X+
X+#ifdef NO_DEBUG_IN_MACROS
X+#  define MTrace(x)
X+#else
X+#  define MTrace(x)  Trace(x)
X+#endif
X+
X+#if (defined(UNIX) || defined(T20_VMS)) /* generally old systems */
X+#  define ToLower(x)   ((char)(isupper((int)x)? tolower((int)x) : x))
X+#else
X+#  define ToLower      tolower          /* assumed "smart"; used in match() */
X+#endif
X+
X+#ifdef USE_STRM_INPUT
X+   /* ``Replace'' the unbuffered UNIX style I/O function with similar
X+    * standard C functions from <stdio.h>.
X+    */
X+#  define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
X+#  define lseek(fd,o,w) fseek((FILE *)(fd),(o),(w))
X+#  define close(fd) fclose((FILE *)(fd))
X+#endif /* USE_STRM_INPUT */
X+
X+/* The return value of the Info() "macro function" is never checked in
X+ * UnZip. Otherwise, to get the same behaviour as for (*G.message)(), the
X+ * Info() definition for "FUNZIP" would have to be corrected:
X+ * #define Info(buf,flag,sprf_arg) \
X+ *      (fprintf((flag)&1? stderr : stdout, \
X+ *               (char *)(sprintf sprf_arg, (buf))) == EOF)
X+ */
X+#ifndef Info   /* may already have been defined for redirection */
X+#  ifdef FUNZIP
X+#    define Info(buf,flag,sprf_arg) \
X+     fprintf((flag)&1? stderr : stdout, (char *)(sprintf sprf_arg, (buf)))
X+#  else
X+#    ifdef INT_SPRINTF  /* optimized version for "int sprintf()" flavour */
X+#      define Info(buf,flag,sprf_arg) \
X+       (*G.message)((zvoid *)&G, (uch *)(buf), (ulg)sprintf sprf_arg, (flag))
X+#    else          /* generic version, does not use sprintf() return value */
X+#      define Info(buf,flag,sprf_arg) \
X+       (*G.message)((zvoid *)&G, (uch *)(buf), \
X+                     (ulg)(sprintf sprf_arg, strlen((char *)(buf))), (flag))
X+#    endif
X+#  endif
X+#endif /* !Info */
X+
X+/*  The following macro wrappers around the fnfilter function are used many
X+ *  times to prepare archive entry names or name components for displaying
X+ *  listings and (warning/error) messages. They use sections in the upper half
X+ *  of 'slide' as buffer, since their output is normally fed through the
X+ *  Info() macro with 'slide' (the start of this area) as message buffer.
X+ */
X+#define FnFilter1(fname)  fnfilter((fname), slide + (WSIZE>>1))
X+#define FnFilter2(fname)  fnfilter((fname), slide + ((WSIZE>>1) + (WSIZE>>2)))
X+
X+#ifndef FUNZIP   /* used only in inflate.c */
X+#  define MESSAGE(str,len,flag)  (*G.message)((zvoid *)&G,(str),(len),(flag))
X+#endif
X+
X+#if 0            /* Optimization: use the (const) result of crc32(0L,NULL,0) */
X+#  define CRCVAL_INITIAL  crc32(0L, NULL, 0)
X+#else
X+#  define CRCVAL_INITIAL  0L
X+#endif
X+
X+#ifndef TEST_NTSD               /* "NTSD valid?" checking function */
X+#  define TEST_NTSD     NULL    /*   ... is not available */
X+#endif
X+
X+#define SKIP_(length) if(length&&((error=do_string(__G__ length,SKIP))!=0))\
X+  {error_in_archive=error; if(error>1) return error;}
X+
X+/*
X+ *  Skip a variable-length field, and report any errors.  Used in zipinfo.c
X+ *  and unzip.c in several functions.
X+ *
X+ *  macro SKIP_(length)
X+ *      ush length;
X+ *  {
X+ *      if (length && ((error = do_string(length, SKIP)) != 0)) {
X+ *          error_in_archive = error;   /-* might be warning *-/
X+ *          if (error > 1)              /-* fatal *-/
X+ *              return (error);
X+ *      }
X+ *  }
X+ *
X+ */
X+
X+
X+#ifdef FUNZIP
X+#  define FLUSH(w)  flush(__G__ (ulg)(w))
X+#  define NEXTBYTE  getc(G.in)   /* redefined in crypt.h if full version */
X+#else
X+#  define FLUSH(w)  ((G.mem_mode) ? memflush(__G__ redirSlide,(ulg)(w)) \
X+                                  : flush(__G__ redirSlide,(ulg)(w),0))
X+#  define NEXTBYTE  (G.incnt-- > 0 ? (int)(*G.inptr++) : readbyte(__G))
X+#endif
X+
X+
X+#define READBITS(nbits,zdest) {if(nbits>G.bits_left) {int temp; G.zipeof=1;\
X+  while (G.bits_left<=8*(int)(sizeof(G.bitbuf)-1) && (temp=NEXTBYTE)!=EOF) {\
X+  G.bitbuf|=(ulg)temp<<G.bits_left; G.bits_left+=8; G.zipeof=0;}}\
X+  zdest=(shrint)((unsigned)G.bitbuf&mask_bits[nbits]);G.bitbuf>>=nbits;\
X+  G.bits_left-=nbits;}
X+
X+/*
X+ * macro READBITS(nbits,zdest)    * only used by unreduce and unshrink *
X+ *  {
X+ *      if (nbits > G.bits_left) {  * fill G.bitbuf, 8*sizeof(ulg) bits *
X+ *          int temp;
X+ *
X+ *          G.zipeof = 1;
X+ *          while (G.bits_left <= 8*(int)(sizeof(G.bitbuf)-1) &&
X+ *                 (temp = NEXTBYTE) != EOF) {
X+ *              G.bitbuf |= (ulg)temp << G.bits_left;
X+ *              G.bits_left += 8;
X+ *              G.zipeof = 0;
X+ *          }
X+ *      }
X+ *      zdest = (shrint)((unsigned)G.bitbuf & mask_bits[nbits]);
X+ *      G.bitbuf >>= nbits;
X+ *      G.bits_left -= nbits;
X+ *  }
X+ *
X+ */
X+
X+
X+/* GRR:  should use StringLower for STRLOWER macro if possible */
X+
X+/*
X+ *  Copy the zero-terminated string in str1 into str2, converting any
X+ *  uppercase letters to lowercase as we go.  str2 gets zero-terminated
X+ *  as well, of course.  str1 and str2 may be the same character array.
X+ */
X+#ifdef _MBCS
X+#  define STRLOWER(str1, str2) \
X+   { \
X+       char  *p, *q, c; unsigned i; \
X+       p = (char *)(str1); \
X+       q = (char *)(str2); \
X+       while ((c = *p) != '\0') { \
X+           if ((i = CLEN(p)) > 1) { \
X+               while (i--) *q++ = *p++; \
X+           } else { \
X+               *q++ = (char)(isupper((int)(c))? tolower((int)(c)) : c); \
X+               p++; \
X+           } \
X+       } \
X+       *q = '\0'; \
X+   }
X+#else
X+#  define STRLOWER(str1, str2) \
X+   { \
X+       char  *p, *q; \
X+       p = (char *)(str1) - 1; \
X+       q = (char *)(str2); \
X+       while (*++p) \
X+           *q++ = (char)(isupper((int)(*p))? tolower((int)(*p)) : *p); \
X+       *q = '\0'; \
X+   }
X+#endif
X+/*
X+ *  NOTES:  This macro makes no assumptions about the characteristics of
X+ *    the tolower() function or macro (beyond its existence), nor does it
X+ *    make assumptions about the structure of the character set (i.e., it
X+ *    should work on EBCDIC machines, too).  The fact that either or both
X+ *    of isupper() and tolower() may be macros has been taken into account;
X+ *    watch out for "side effects" (in the C sense) when modifying this
X+ *    macro.
X+ */
X+
X+#ifndef foreign
X+#  define foreign(c)  (c)
X+#endif
X+
X+#ifndef native
X+#  define native(c)   (c)
X+#  define A_TO_N(str1)
X+#else
X+#  ifndef NATIVE
X+#    define NATIVE     "native chars"
X+#  endif
X+#  define A_TO_N(str1) {register uch *p;\
X+     for (p=(uch *)(str1); *p; p++) *p=native(*p);}
X+#endif
X+/*
X+ *  Translate the zero-terminated string in str1 from ASCII to the native
X+ *  character set. The translation is performed in-place and uses the
X+ *  "native" macro to translate each character.
X+ *
X+ *  NOTE:  Using the "native" macro means that is it the only part of unzip
X+ *    which knows which translation table (if any) is actually in use to
X+ *    produce the native character set.  This makes adding new character set
X+ *    translation tables easy, insofar as all that is needed is an appropriate
X+ *    "native" macro definition and the translation table itself.  Currently,
X+ *    the only non-ASCII native character set implemented is EBCDIC, but this
X+ *    may not always be so.
X+ */
X+
X+
X+/* default setup for internal codepage: assume ISO 8859-1 compatibility!! */
X+#if (!defined(NATIVE) && !defined(CRTL_CP_IS_ISO) && !defined(CRTL_CP_IS_OEM))
X+#  define CRTL_CP_IS_ISO
X+#endif
X+
X+
X+/*  Translate "extended ASCII" chars (OEM coding for DOS and OS/2; else
X+ *  ISO-8859-1 [ISO Latin 1, Win Ansi,...]) into the internal "native"
X+ *  code page.  As with A_TO_N(), conversion is done in place.
X+ */
X+#ifndef _ISO_INTERN
X+#  ifdef CRTL_CP_IS_OEM
X+#    ifndef IZ_ISO2OEM_ARRAY
X+#      define IZ_ISO2OEM_ARRAY
X+#    endif
X+#    define _ISO_INTERN(str1) {register uch *p;\
X+       for (p=(uch *)(str1); *p; p++)\
X+         *p = native((*p & 0x80) ? iso2oem[*p & 0x7f] : *p);}
X+#  else
X+#    define _ISO_INTERN(str1)   A_TO_N(str1)
X+#  endif
X+#endif
X+
X+#ifndef _OEM_INTERN
X+#  ifdef CRTL_CP_IS_OEM
X+#    define _OEM_INTERN(str1)   A_TO_N(str1)
X+#  else
X+#    ifndef IZ_OEM2ISO_ARRAY
X+#      define IZ_OEM2ISO_ARRAY
X+#    endif
X+#    define _OEM_INTERN(str1) {register uch *p;\
X+       for (p=(uch *)(str1); *p; p++)\
X+         *p = native((*p & 0x80) ? oem2iso[*p & 0x7f] : *p);}
X+#  endif
X+#endif
X+
X+#ifndef STR_TO_ISO
X+#  ifdef CRTL_CP_IS_ISO
X+#    define STR_TO_ISO          strcpy
X+#  else
X+#    define STR_TO_ISO          str2iso
X+#    define NEED_STR2ISO
X+#  endif
X+#endif
X+
X+#ifndef STR_TO_OEM
X+#  ifdef CRTL_CP_IS_OEM
X+#    define STR_TO_OEM          strcpy
X+#  else
X+#    define STR_TO_OEM          str2oem
X+#    define NEED_STR2OEM
X+#  endif
X+#endif
X+
X+#if (!defined(INTERN_TO_ISO) && !defined(ASCII2ISO))
X+#  ifdef CRTL_CP_IS_OEM
X+     /* know: "ASCII" is "OEM" */
X+#    define ASCII2ISO(c) (((c) & 0x80) ? oem2iso[(c) & 0x7f] : (c))
X+#    if (defined(NEED_STR2ISO) && !defined(CRYP_USES_OEM2ISO))
X+#      define CRYP_USES_OEM2ISO
X+#    endif
X+#  else
X+     /* assume: "ASCII" is "ISO-ANSI" */
X+#    define ASCII2ISO(c) (c)
X+#  endif
X+#endif
X+
X+#if (!defined(INTERN_TO_OEM) && !defined(ASCII2OEM))
X+#  ifdef CRTL_CP_IS_OEM
X+     /* know: "ASCII" is "OEM" */
X+#    define ASCII2OEM(c) (c)
X+#  else
X+     /* assume: "ASCII" is "ISO-ANSI" */
X+#    define ASCII2OEM(c) (((c) & 0x80) ? iso2oem[(c) & 0x7f] : (c))
X+#    if (defined(NEED_STR2OEM) && !defined(CRYP_USES_ISO2OEM))
X+#      define CRYP_USES_ISO2OEM
X+#    endif
X+#  endif
X+#endif
X+
X+/* codepage conversion setup for testp() in crypt.c */
X+#ifdef CRTL_CP_IS_ISO
X+#  ifndef STR_TO_CP2
X+#    define STR_TO_CP2  STR_TO_OEM
X+#  endif
X+#else
X+#  ifdef CRTL_CP_IS_OEM
X+#    ifndef STR_TO_CP2
X+#      define STR_TO_CP2  STR_TO_ISO
X+#    endif
X+#  else /* native internal CP is neither ISO nor OEM */
X+#    ifndef STR_TO_CP1
X+#      define STR_TO_CP1  STR_TO_ISO
X+#    endif
X+#    ifndef STR_TO_CP2
X+#      define STR_TO_CP2  STR_TO_OEM
X+#    endif
X+#  endif
X+#endif
X+
X+
X+/* Convert filename (and file comment string) into "internal" charset.
X+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
X+ * codepage when made on
X+ *  -> DOS (this includes 16-bit Windows 3.1)  (FS_FAT_)
X+ *  -> OS/2                                    (FS_HPFS_)
X+ *  -> Win95/WinNT with Nico Mak's WinZip      (FS_NTFS_ && hostver == "5.0")
X+ * EXCEPTIONS:
X+ *  PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
X+ *  the filename stored in the local header is coded in Windows ANSI (CP 1252
X+ *  resp. ISO 8859-1 on US and western Europe locale settings).
X+ *  Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
X+ *  filenames stored in BOTH the local and the central header are coded
X+ *  in the local system's codepage (usually ANSI codings like ISO 8859-1).
X+ *
X+ * All other ports are assumed to code zip entry filenames in ISO 8859-1.
X+ */
X+#ifndef Ext_ASCII_TO_Native
X+#  define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
X+    if (((hostnum) == FS_FAT_ && \
X+         !(((islochdr) || (isuxatt)) && \
X+           ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
X+        (hostnum) == FS_HPFS_ || \
X+        ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
X+        _OEM_INTERN((string)); \
X+    } else { \
X+        _ISO_INTERN((string)); \
X+    }
X+#endif
X+
X+
X+
X+/**********************/
X+/*  Global constants  */
X+/**********************/
X+
X+   extern ZCONST unsigned near mask_bits[17];
X+   extern ZCONST char *fnames[2];
X+
X+#ifdef EBCDIC
X+   extern ZCONST uch ebcdic[];
X+#endif
X+#ifdef IZ_ISO2OEM_ARRAY
X+   extern ZCONST uch Far iso2oem[];
X+#endif
X+#ifdef IZ_OEM2ISO_ARRAY
X+   extern ZCONST uch Far oem2iso[];
X+#endif
X+
X+   extern ZCONST char Far  VersionDate[];
X+   extern ZCONST char Far  CentSigMsg[];
X+#ifndef SFX
X+   extern ZCONST char Far  EndSigMsg[];
X+#endif
X+   extern ZCONST char Far  SeekMsg[];
X+   extern ZCONST char Far  FilenameNotMatched[];
X+   extern ZCONST char Far  ExclFilenameNotMatched[];
X+   extern ZCONST char Far  ReportMsg[];
X+
X+#ifndef SFX
X+   extern ZCONST char Far  Zipnfo[];
X+   extern ZCONST char Far  CompiledWith[];
X+#endif /* !SFX */
X+
X+
X+
X+/***********************************/
X+/*  Global (shared?) RTL variables */
X+/***********************************/
X+
X+#ifdef DECLARE_ERRNO
X+   extern int             errno;
X+#endif
X+
X+
X+#endif /* !__unzpriv_h */
Xdiff -ruN ../unzip-5.52.orig/zipinfo.c ./zipinfo.c
X--- ../unzip-5.52.orig/zipinfo.c	2005-01-27 10:02:16.000000000 +0900
X+++ ./zipinfo.c	2008-03-08 07:16:58.000000000 +0900
X@@ -482,6 +482,27 @@
X                         uO.C_flag = TRUE;
X                     break;
X #endif /* !CMS_MVS */
X+#ifdef NLS
X+		case 'E': /* -E:  character encoding for archive */
X+		  if (negative) {
X+		    uO.charenc_arch = NULL;
X+		  } else {
X+		    uO.charenc_arch = s;
X+		    if (*uO.charenc_arch == '\0') {
X+		      if (! (-- argc)) {
X+			error = TRUE;
X+			break;
X+		      }
X+		      uO.charenc_arch = *(++ argv);
X+		      if (*uO.charenc_arch == '-') {
X+			error = TRUE;
X+			break;
X+		      }
X+		    }
X+		    else while (*(++ s));
X+		  }
X+		  break;
X+#endif /* NLS */
X                 case 'h':      /* header line */
X                     if (negative)
X                         hflag_2 = hflag_slmv = FALSE, negative = 0;
Xdiff -ruN ../unzip-5.52.orig/zipinfo.c.orig ./zipinfo.c.orig
X--- ../unzip-5.52.orig/zipinfo.c.orig	1970-01-01 09:00:00.000000000 +0900
X+++ ./zipinfo.c.orig	2005-01-27 10:02:16.000000000 +0900
X@@ -0,0 +1,2235 @@
X+/*
X+  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
X+
X+  See the accompanying file LICENSE, version 2000-Apr-09 or later
X+  (the contents of which are also included in unzip.h) for terms of use.
X+  If, for some reason, all these files are missing, the Info-ZIP license
X+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
X+*/
X+/*---------------------------------------------------------------------------
X+
X+  zipinfo.c                                              Greg Roelofs et al.
X+
X+  This file contains all of the ZipInfo-specific listing routines for UnZip.
X+
X+  Contains:  zi_opts()
X+             zi_end_central()
X+             zipinfo()
X+             zi_long()
X+             zi_short()
X+             zi_time()
X+
X+  ---------------------------------------------------------------------------*/
X+
X+
X+#define UNZIP_INTERNAL
X+#include "unzip.h"
X+
X+
X+#ifndef NO_ZIPINFO  /* strings use up too much space in small-memory systems */
X+
X+/* Define OS-specific attributes for use on ALL platforms--the S_xxxx
X+ * versions of these are defined differently (or not defined) by different
X+ * compilers and operating systems. */
X+
X+#define UNX_IFMT       0170000     /* Unix file type mask */
X+#define UNX_IFREG      0100000     /* Unix regular file */
X+#define UNX_IFSOCK     0140000     /* Unix socket (BSD, not SysV or Amiga) */
X+#define UNX_IFLNK      0120000     /* Unix symbolic link (not SysV, Amiga) */
X+#define UNX_IFBLK      0060000     /* Unix block special       (not Amiga) */
X+#define UNX_IFDIR      0040000     /* Unix directory */
X+#define UNX_IFCHR      0020000     /* Unix character special   (not Amiga) */
X+#define UNX_IFIFO      0010000     /* Unix fifo    (BCC, not MSC or Amiga) */
X+#define UNX_ISUID      04000       /* Unix set user id on execution */
X+#define UNX_ISGID      02000       /* Unix set group id on execution */
X+#define UNX_ISVTX      01000       /* Unix directory permissions control */
X+#define UNX_ENFMT      UNX_ISGID   /* Unix record locking enforcement flag */
X+#define UNX_IRWXU      00700       /* Unix read, write, execute: owner */
X+#define UNX_IRUSR      00400       /* Unix read permission: owner */
X+#define UNX_IWUSR      00200       /* Unix write permission: owner */
X+#define UNX_IXUSR      00100       /* Unix execute permission: owner */
X+#define UNX_IRWXG      00070       /* Unix read, write, execute: group */
X+#define UNX_IRGRP      00040       /* Unix read permission: group */
X+#define UNX_IWGRP      00020       /* Unix write permission: group */
X+#define UNX_IXGRP      00010       /* Unix execute permission: group */
X+#define UNX_IRWXO      00007       /* Unix read, write, execute: other */
X+#define UNX_IROTH      00004       /* Unix read permission: other */
X+#define UNX_IWOTH      00002       /* Unix write permission: other */
X+#define UNX_IXOTH      00001       /* Unix execute permission: other */
X+
X+#define VMS_IRUSR      UNX_IRUSR   /* VMS read/owner */
X+#define VMS_IWUSR      UNX_IWUSR   /* VMS write/owner */
X+#define VMS_IXUSR      UNX_IXUSR   /* VMS execute/owner */
X+#define VMS_IRGRP      UNX_IRGRP   /* VMS read/group */
X+#define VMS_IWGRP      UNX_IWGRP   /* VMS write/group */
X+#define VMS_IXGRP      UNX_IXGRP   /* VMS execute/group */
X+#define VMS_IROTH      UNX_IROTH   /* VMS read/other */
X+#define VMS_IWOTH      UNX_IWOTH   /* VMS write/other */
X+#define VMS_IXOTH      UNX_IXOTH   /* VMS execute/other */
X+
X+#define AMI_IFMT       06000       /* Amiga file type mask */
X+#define AMI_IFDIR      04000       /* Amiga directory */
X+#define AMI_IFREG      02000       /* Amiga regular file */
X+#define AMI_IHIDDEN    00200       /* to be supported in AmigaDOS 3.x */
X+#define AMI_ISCRIPT    00100       /* executable script (text command file) */
X+#define AMI_IPURE      00040       /* allow loading into resident memory */
X+#define AMI_IARCHIVE   00020       /* not modified since bit was last set */
X+#define AMI_IREAD      00010       /* can be opened for reading */
X+#define AMI_IWRITE     00004       /* can be opened for writing */
X+#define AMI_IEXECUTE   00002       /* executable image, a loadable runfile */
X+#define AMI_IDELETE    00001       /* can be deleted */
X+
X+#define THS_IFMT    0xF000         /* Theos file type mask */
X+#define THS_IFIFO   0x1000         /* pipe */
X+#define THS_IFCHR   0x2000         /* char device */
X+#define THS_IFSOCK  0x3000         /* socket */
X+#define THS_IFDIR   0x4000         /* directory */
X+#define THS_IFLIB   0x5000         /* library */
X+#define THS_IFBLK   0x6000         /* block device */
X+#define THS_IFREG   0x8000         /* regular file */
X+#define THS_IFREL   0x9000         /* relative (direct) */
X+#define THS_IFKEY   0xA000         /* keyed */
X+#define THS_IFIND   0xB000         /* indexed */
X+#define THS_IFRND   0xC000         /* ???? */
X+#define THS_IFR16   0xD000         /* 16 bit real mode program */
X+#define THS_IFP16   0xE000         /* 16 bit protected mode prog */
X+#define THS_IFP32   0xF000         /* 32 bit protected mode prog */
X+#define THS_IMODF   0x0800         /* modified */
X+#define THS_INHID   0x0400         /* not hidden */
X+#define THS_IEUSR   0x0200         /* erase permission: owner */
X+#define THS_IRUSR   0x0100         /* read permission: owner */
X+#define THS_IWUSR   0x0080         /* write permission: owner */
X+#define THS_IXUSR   0x0040         /* execute permission: owner */
X+#define THS_IROTH   0x0004         /* read permission: other */
X+#define THS_IWOTH   0x0002         /* write permission: other */
X+#define THS_IXOTH   0x0001         /* execute permission: other */
X+
X+#ifdef OLD_THEOS_EXTRA
X+#  include "theos/oldstat.h"
X+#endif
X+
X+#ifndef NSK_UNSTRUCTURED
X+# define NSK_UNSTRUCTURED   0
X+#endif
X+#ifndef NSK_OBJECTFILECODE
X+# define NSK_OBJECTFILECODE 100
X+#endif
X+#ifndef NSK_EDITFILECODE
X+# define NSK_EDITFILECODE   101
X+#endif
X+
X+#define LFLAG  3   /* short "ls -l" type listing */
X+
X+static int   zi_long   OF((__GPRO__ ulg *pEndprev));
X+static int   zi_short  OF((__GPRO));
X+static void  zi_showMacTypeCreator
X+                       OF((__GPRO__ uch *ebfield));
X+static char *zi_time   OF((__GPRO__ ZCONST ulg *datetimez,
X+                           ZCONST time_t *modtimez, char *d_t_str));
X+
X+
X+/**********************************************/
X+/*  Strings used in zipinfo.c (ZipInfo half)  */
X+/**********************************************/
X+
X+static ZCONST char nullStr[] = "";
X+static ZCONST char PlurSufx[] = "s";
X+
X+static ZCONST char Far LongHeader[] = "Archive:  %s   %ld bytes   %u file%s\n";
X+static ZCONST char Far ShortHeader[] = "Archive:  %s   %ld   %u\n";
X+static ZCONST char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n";
X+static ZCONST char Far LineSeparators[] = "-------------------------------\n\n";
X+static ZCONST char Far ActOffsetCentDir[] = "\
X+  Actual offset of end-of-central-dir record:   %9ld (%.8lXh)\n\
X+  Expected offset of end-of-central-dir record: %9ld (%.8lXh)\n\
X+  (based on the length of the central directory and its expected offset)\n\n";
X+static ZCONST char Far SinglePartArchive1[] = "\
X+  This zipfile constitutes the sole disk of a single-part archive; its\n\
X+  central directory contains %u %s.  The central directory is %lu\n\
X+  (%.8lXh) bytes long, and its (expected) offset in bytes from the\n";
X+static ZCONST char Far SinglePartArchive2[] = "\
X+  beginning of the zipfile is %lu (%.8lXh).\n\n";
X+static ZCONST char Far MultiPartArchive1[] = "\
X+  This zipfile constitutes disk %u of a multi-part archive.  The central\n\
X+  directory starts on disk %u; %u of its entries %s contained within\n";
X+static ZCONST char Far MultiPartArchive2[] = "\
X+  this zipfile, out of a total of %u %s.  The entire central\n\
X+  directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n";
X+static ZCONST char Far MultiPartArchive3[] = "\
X+  the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n";
X+static ZCONST char Far NoZipfileComment[] = "  There is no zipfile comment.\n";
X+static ZCONST char Far ZipfileCommentDesc[] =
X+  "  The zipfile comment is %u bytes long and contains the following text:\n\n";
X+static ZCONST char Far ZipfileCommBegin[] =
X+ "======================== zipfile comment begins ==========================\n";
X+static ZCONST char Far ZipfileCommEnd[] =
X+ "========================= zipfile comment ends ===========================\n";
X+static ZCONST char Far ZipfileCommTrunc2[] =
X+  "\n  The zipfile comment is truncated.\n";
X+static ZCONST char Far ZipfileCommTruncMsg[] =
X+  "\ncaution:  zipfile comment truncated\n";
X+
X+static ZCONST char Far CentralDirEntry[] =
X+  "\nCentral directory entry #%lu:\n---------------------------\n\n";
X+static ZCONST char Far ZipfileStats[] =
X+  "%lu file%s, %lu bytes uncompressed, %lu bytes compressed:  %s%d.%d%%\n";
X+
X+/* zi_long() strings */
X+static ZCONST char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT";
X+static ZCONST char Far OS_Amiga[] = "Amiga";
X+static ZCONST char Far OS_VMS[] = "VMS";
X+static ZCONST char Far OS_Unix[] = "Unix";
X+static ZCONST char Far OS_VMCMS[] = "VM/CMS";
X+static ZCONST char Far OS_AtariST[] = "Atari ST";
X+static ZCONST char Far OS_HPFS[] = "OS/2 or NT HPFS";
X+static ZCONST char Far OS_Macintosh[] = "Macintosh HFS";
X+static ZCONST char Far OS_ZSystem[] = "Z-System";
X+static ZCONST char Far OS_CPM[] = "CP/M";
X+static ZCONST char Far OS_TOPS20[] = "TOPS-20";
X+static ZCONST char Far OS_NTFS[] = "NTFS";
X+static ZCONST char Far OS_QDOS[] = "SMS/QDOS";
X+static ZCONST char Far OS_Acorn[] = "Acorn RISC OS";
X+static ZCONST char Far OS_MVS[] = "MVS";
X+static ZCONST char Far OS_VFAT[] = "Win32 VFAT";
X+static ZCONST char Far OS_AtheOS[] = "AtheOS";
X+static ZCONST char Far OS_BeOS[] = "BeOS";
X+static ZCONST char Far OS_Tandem[] = "Tandem NSK";
X+static ZCONST char Far OS_Theos[] = "Theos";
X+static ZCONST char Far OS_MacDarwin[] = "Mac OS/X (Darwin)";
X+#ifdef OLD_THEOS_EXTRA
X+  static ZCONST char Far OS_TheosOld[] = "Theos (Old)";
X+#endif /* OLD_THEOS_EXTRA */
X+
X+static ZCONST char Far MthdNone[] = "none (stored)";
X+static ZCONST char Far MthdShrunk[] = "shrunk";
X+static ZCONST char Far MthdRedF1[] = "reduced (factor 1)";
X+static ZCONST char Far MthdRedF2[] = "reduced (factor 2)";
X+static ZCONST char Far MthdRedF3[] = "reduced (factor 3)";
X+static ZCONST char Far MthdRedF4[] = "reduced (factor 4)";
X+static ZCONST char Far MthdImplode[] = "imploded";
X+static ZCONST char Far MthdToken[] = "tokenized";
X+static ZCONST char Far MthdDeflate[] = "deflated";
X+static ZCONST char Far MthdDeflat64[] = "deflated (enhanced-64k)";
X+static ZCONST char Far MthdDCLImplode[] = "imploded (PK DCL)";
X+static ZCONST char Far MthdPKRes11[] = "unkn. #11 (PK reserved)";
X+static ZCONST char Far MthdBZip2[] = "bzipped";
X+
X+static ZCONST char Far DeflNorm[] = "normal";
X+static ZCONST char Far DeflMax[] = "maximum";
X+static ZCONST char Far DeflFast[] = "fast";
X+static ZCONST char Far DeflSFast[] = "superfast";
X+
X+static ZCONST char Far ExtraBytesPreceding[] =
X+  "  There are an extra %ld bytes preceding this file.\n\n";
X+
X+static ZCONST char Far UnknownNo[] = "unknown (%d)";
X+
X+static ZCONST char Far LocalHeaderOffset[] =
X+  "\n  offset of local header from start of archive:     %lu (%.8lXh) bytes\n";
X+static ZCONST char Far HostOS[] =
X+  "  file system or operating system of origin:        %s\n";
X+static ZCONST char Far EncodeSWVer[] =
X+  "  version of encoding software:                     %u.%u\n";
X+static ZCONST char Far MinOSCompReq[] =
X+  "  minimum file system compatibility required:       %s\n";
X+static ZCONST char Far MinSWVerReq[] =
X+  "  minimum software version required to extract:     %u.%u\n";
X+static ZCONST char Far CompressMethod[] =
X+  "  compression method:                               %s\n";
X+static ZCONST char Far SlideWindowSizeImplode[] =
X+  "  size of sliding dictionary (implosion):           %cK\n";
X+static ZCONST char Far ShannonFanoTrees[] =
X+  "  number of Shannon-Fano trees (implosion):         %c\n";
X+static ZCONST char Far CompressSubtype[] =
X+  "  compression sub-type (deflation):                 %s\n";
X+static ZCONST char Far FileSecurity[] =
X+  "  file security status:                             %sencrypted\n";
X+static ZCONST char Far ExtendedLocalHdr[] =
X+  "  extended local header:                            %s\n";
X+static ZCONST char Far FileModDate[] =
X+  "  file last modified on (DOS date/time):            %s\n";
X+#ifdef USE_EF_UT_TIME
X+  static ZCONST char Far UT_FileModDate[] =
X+    "  file last modified on (UT extra field modtime):   %s %s\n";
X+  static ZCONST char Far LocalTime[] = "local";
X+#ifndef NO_GMTIME
X+  static ZCONST char Far GMTime[] = "UTC";
X+#endif
X+#endif /* USE_EF_UT_TIME */
X+static ZCONST char Far CRC32Value[] =
X+  "  32-bit CRC value (hex):                           %.8lx\n";
X+static ZCONST char Far CompressedFileSize[] =
X+  "  compressed size:                                  %lu bytes\n";
X+static ZCONST char Far UncompressedFileSize[] =
X+  "  uncompressed size:                                %lu bytes\n";
X+static ZCONST char Far FilenameLength[] =
X+  "  length of filename:                               %u characters\n";
X+static ZCONST char Far ExtraFieldLength[] =
X+  "  length of extra field:                            %u bytes\n";
X+static ZCONST char Far FileCommentLength[] =
X+  "  length of file comment:                           %u characters\n";
X+static ZCONST char Far FileDiskNum[] =
X+  "  disk number on which file begins:                 disk %u\n";
X+static ZCONST char Far ApparentFileType[] =
X+  "  apparent file type:                               %s\n";
X+static ZCONST char Far VMSFileAttributes[] =
X+  "  VMS file attributes (%06o octal):               %s\n";
X+static ZCONST char Far AmigaFileAttributes[] =
X+  "  Amiga file attributes (%06o octal):             %s\n";
X+static ZCONST char Far UnixFileAttributes[] =
X+  "  Unix file attributes (%06o octal):              %s\n";
X+static ZCONST char Far NonMSDOSFileAttributes[] =
X+  "  non-MSDOS external file attributes:               %06lX hex\n";
X+static ZCONST char Far MSDOSFileAttributes[] =
X+  "  MS-DOS file attributes (%02X hex):                  none\n";
X+static ZCONST char Far MSDOSFileAttributesRO[] =
X+  "  MS-DOS file attributes (%02X hex):                  read-only\n";
X+static ZCONST char Far MSDOSFileAttributesAlpha[] =
X+  "  MS-DOS file attributes (%02X hex):                  %s%s%s%s%s%s%s%s\n";
X+static ZCONST char Far TheosFileAttributes[] =
X+  "  Theos file attributes (%04X hex):                 %s\n";
X+
X+static ZCONST char Far TheosFTypLib[] = "Library     ";
X+static ZCONST char Far TheosFTypDir[] = "Directory   ";
X+static ZCONST char Far TheosFTypReg[] = "Sequential  ";
X+static ZCONST char Far TheosFTypRel[] = "Direct      ";
X+static ZCONST char Far TheosFTypKey[] = "Keyed       ";
X+static ZCONST char Far TheosFTypInd[] = "Indexed     ";
X+static ZCONST char Far TheosFTypR16[] = " 86 program ";
X+static ZCONST char Far TheosFTypP16[] = "286 program ";
X+static ZCONST char Far TheosFTypP32[] = "386 program ";
X+static ZCONST char Far TheosFTypUkn[] = "???         ";
X+
X+static ZCONST char Far ExtraFieldTrunc[] = "\n\
X+  error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\
X+         space %u; block length has been truncated.\n";
X+static ZCONST char Far ExtraFields[] = "\n\
X+  The central-directory extra field contains:";
X+static ZCONST char Far ExtraFieldType[] = "\n\
X+  - A subfield with ID 0x%04x (%s) and %u data bytes";
X+static ZCONST char Far efPKSZ64[] = "PKWARE 64-bit sizes";
X+static ZCONST char Far efAV[] = "PKWARE AV";
X+static ZCONST char Far efOS2[] = "OS/2";
X+static ZCONST char Far efPKVMS[] = "PKWARE VMS";
X+static ZCONST char Far efPKWin32[] = "PKWARE Win32";
X+static ZCONST char Far efPKUnix[] = "PKWARE Unix";
X+static ZCONST char Far efIZVMS[] = "Info-ZIP VMS";
X+static ZCONST char Far efIZUnix[] = "old Info-ZIP Unix/OS2/NT";
X+static ZCONST char Far efIZUnix2[] = "Unix UID/GID";
X+static ZCONST char Far efTime[] = "universal time";
X+static ZCONST char Far efJLMac[] = "old Info-ZIP Macintosh";
X+static ZCONST char Far efMac3[] = "new Info-ZIP Macintosh";
X+static ZCONST char Far efZipIt[] = "ZipIt Macintosh";
X+static ZCONST char Far efSmartZip[] = "SmartZip Macintosh";
X+static ZCONST char Far efZipIt2[] = "ZipIt Macintosh (short)";
X+static ZCONST char Far efVMCMS[] = "VM/CMS";
X+static ZCONST char Far efMVS[] = "MVS";
X+static ZCONST char Far efACL[] = "OS/2 ACL";
X+static ZCONST char Far efNTSD[] = "Security Descriptor";
X+static ZCONST char Far efAtheOS[] = "AtheOS";
X+static ZCONST char Far efBeOS[] = "BeOS";
X+static ZCONST char Far efQDOS[] = "SMS/QDOS";
X+static ZCONST char Far efAOSVS[] = "AOS/VS";
X+static ZCONST char Far efSpark[] = "Acorn SparkFS";
X+static ZCONST char Far efMD5[] = "Fred Kantor MD5";
X+static ZCONST char Far efASiUnix[] = "ASi Unix";
X+static ZCONST char Far efTandem[] = "Tandem NSK";
X+static ZCONST char Far efTheos[] = "Theos";
X+static ZCONST char Far efUnknown[] = "unknown";
X+
X+static ZCONST char Far OS2EAs[] = ".\n\
X+    The local extra field has %lu bytes of OS/2 extended attributes.\n\
X+    (May not match OS/2 \"dir\" amount due to storage method)";
X+static ZCONST char Far izVMSdata[] = ".  The extra\n\
X+    field is %s and has %u bytes of VMS %s information%s";
X+static ZCONST char Far izVMSstored[] = "stored";
X+static ZCONST char Far izVMSrleenc[] = "run-length encoded";
X+static ZCONST char Far izVMSdeflat[] = "deflated";
X+static ZCONST char Far izVMScunknw[] = "compressed(?)";
X+static ZCONST char Far *izVMScomp[4] =
X+  {izVMSstored, izVMSrleenc, izVMSdeflat, izVMScunknw};
X+static ZCONST char Far ACLdata[] = ".\n\
X+    The local extra field has %lu bytes of access control list information";
X+static ZCONST char Far NTSDData[] = ".\n\
X+    The local extra field has %lu bytes of NT security descriptor data";
X+static ZCONST char Far UTdata[] = ".\n\
X+    The local extra field has UTC/GMT %s time%s";
X+static ZCONST char Far UTmodification[] = "modification";
X+static ZCONST char Far UTaccess[] = "access";
X+static ZCONST char Far UTcreation[] = "creation";
X+static ZCONST char Far ZipItFname[] = ".\n\
X+    The Mac long filename is %s";
X+static ZCONST char Far Mac3data[] = ".\n\
X+    The local extra field has %lu bytes of %scompressed Macintosh\n\
X+    finder attributes";
X+ /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */
X+static ZCONST char Far MacOSdata[] = ".\n\
X+    The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'";
X+static ZCONST char Far MacOSdata1[] = ".\n\
X+    The associated file has type code `0x%lx' and creator code `0x%lx'";
X+static ZCONST char Far MacOSJLEEflags[] = ".\n    File is marked as %s";
X+static ZCONST char Far MacOS_RF[] = "Resource-fork";
X+static ZCONST char Far MacOS_DF[] = "Data-fork";
X+static ZCONST char Far MacOSMAC3flags[] = ".\n\
X+    File is marked as %s, File Dates are in %d Bit";
X+static ZCONST char Far AtheOSdata[] = ".\n\
X+    The local extra field has %lu bytes of %scompressed AtheOS file attributes";
X+static ZCONST char Far BeOSdata[] = ".\n\
X+    The local extra field has %lu bytes of %scompressed BeOS file attributes";
X+ /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */
X+static ZCONST char Far QDOSdata[] = ".\n\
X+    The QDOS extra field subtype is `%c%c%c%c'";
X+static ZCONST char Far AOSVSdata[] = ".\n\
X+    The AOS/VS extra field revision is %d.%d";
X+static ZCONST char Far TandemUnstr[] = "Unstructured";
X+static ZCONST char Far TandemRel[]   = "Relative";
X+static ZCONST char Far TandemEntry[] = "Entry Sequenced";
X+static ZCONST char Far TandemKey[]   = "Key Sequenced";
X+static ZCONST char Far TandemEdit[]  = "Edit";
X+static ZCONST char Far TandemObj[]  = "Object";
X+static ZCONST char Far *TandemFileformat[6] =
X+  {TandemUnstr, TandemRel, TandemEntry, TandemKey, TandemEdit, TandemObj};
X+static ZCONST char Far Tandemdata[] = ".\n\
X+    The file was originally a Tandem %s file, with file code %u";
X+static ZCONST char Far MD5data[] = ".\n\
X+    The 128-bit MD5 signature is %s";
X+#ifdef CMS_MVS
X+   static ZCONST char Far VmMvsExtraField[] = ".\n\
X+    The stored file open mode (FLDATA TYPE) is \"%s\"";
X+   static ZCONST char Far VmMvsInvalid[] = "[invalid]";
X+#endif /* CMS_MVS */
X+
X+static ZCONST char Far First20[] = ".  The first\n    20 are:  ";
X+static ZCONST char Far ColonIndent[] = ":\n   ";
X+static ZCONST char Far efFormat[] = " %02x";
X+
X+static ZCONST char Far lExtraFieldType[] = "\n\
X+  There %s a local extra field with ID 0x%04x (%s) and\n\
X+  %u data bytes (%s).\n";
X+static ZCONST char Far efIZuid[] =
X+  "GMT modification/access times and Unix UID/GID";
X+static ZCONST char Far efIZnouid[] = "GMT modification/access times only";
X+
X+
X+static ZCONST char Far NoFileComment[] = "\n  There is no file comment.\n";
X+static ZCONST char Far FileCommBegin[] = "\n\
X+------------------------- file comment begins ----------------------------\n";
X+static ZCONST char Far FileCommEnd[] = "\
X+-------------------------- file comment ends -----------------------------\n";
X+
X+/* zi_time() strings */
X+static ZCONST char Far BogusFmt[] = "%03d";
X+static ZCONST char Far DMYHMTime[] = "%2u-%s-%02u %02u:%02u";
X+static ZCONST char Far YMDHMSTime[] = "%u %s %u %02u:%02u:%02u";
X+static ZCONST char Far DecimalTime[] = "%04u%02u%02u.%02u%02u%02u";
X+#ifdef USE_EF_UT_TIME
X+  static ZCONST char Far YMDHMSTimeError[] = "???? ??? ?? ??:??:??";
X+#endif
X+
X+
X+
X+
X+
X+#ifndef WINDLL
X+
X+/************************/
X+/*  Function zi_opts()  */
X+/************************/
X+
X+int zi_opts(__G__ pargc, pargv)
X+    int *pargc;
X+    char ***pargv;
X+    __GDEF
X+{
X+    char   **argv, *s;
X+    int    argc, c, error=FALSE, negative=0;
X+    int    hflag_slmv=TRUE, hflag_2=FALSE;  /* diff options => diff defaults */
X+    int    tflag_slm=TRUE, tflag_2v=FALSE;
X+    int    explicit_h=FALSE, explicit_t=FALSE;
X+
X+
X+#ifdef MACOS
X+    uO.lflag = LFLAG;         /* reset default on each call */
X+#endif
X+    G.extract_flag = FALSE;   /* zipinfo does not extract to disk */
X+    argc = *pargc;
X+    argv = *pargv;
X+
X+    while (--argc > 0 && (*++argv)[0] == '-') {
X+        s = argv[0] + 1;
X+        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
X+            switch (c) {
X+                case '-':
X+                    ++negative;
X+                    break;
X+                case '1':      /* shortest listing:  JUST filenames */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 1;
X+                    break;
X+                case '2':      /* just filenames, plus headers if specified */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 2;
X+                    break;
X+#ifndef CMS_MVS
X+                case ('C'):    /* -C:  match filenames case-insensitively */
X+                    if (negative)
X+                        uO.C_flag = FALSE, negative = 0;
X+                    else
X+                        uO.C_flag = TRUE;
X+                    break;
X+#endif /* !CMS_MVS */
X+                case 'h':      /* header line */
X+                    if (negative)
X+                        hflag_2 = hflag_slmv = FALSE, negative = 0;
X+                    else {
X+                        hflag_2 = hflag_slmv = explicit_h = TRUE;
X+                        if (uO.lflag == -1)
X+                            uO.lflag = 0;
X+                    }
X+                    break;
X+                case 'l':      /* longer form of "ls -l" type listing */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 5;
X+                    break;
X+                case 'm':      /* medium form of "ls -l" type listing */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 4;
X+                    break;
X+#ifdef MORE
X+                case 'M':      /* send output through built-in "more" */
X+                    if (negative)
X+                        G.M_flag = FALSE, negative = 0;
X+                    else
X+                        G.M_flag = TRUE;
X+                    break;
X+#endif
X+                case 's':      /* default:  shorter "ls -l" type listing */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 3;
X+                    break;
X+                case 't':      /* totals line */
X+                    if (negative)
X+                        tflag_2v = tflag_slm = FALSE, negative = 0;
X+                    else {
X+                        tflag_2v = tflag_slm = explicit_t = TRUE;
X+                        if (uO.lflag == -1)
X+                            uO.lflag = 0;
X+                    }
X+                    break;
X+                case ('T'):    /* use (sortable) decimal time format */
X+                    if (negative)
X+                        uO.T_flag = FALSE, negative = 0;
X+                    else
X+                        uO.T_flag = TRUE;
X+                    break;
X+                case 'v':      /* turbo-verbose listing */
X+                    if (negative)
X+                        uO.lflag = -2, negative = 0;
X+                    else
X+                        uO.lflag = 10;
X+                    break;
X+#ifdef WILD_STOP_AT_DIR
X+                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
X+                    if (negative)
X+                        uO.W_flag = FALSE, negative = 0;
X+                    else
X+                        uO.W_flag = TRUE;
X+                    break;
X+#endif /* WILD_STOP_AT_DIR */
X+                case 'z':      /* print zipfile comment */
X+                    if (negative)
X+                        uO.zflag = negative = 0;
X+                    else
X+                        uO.zflag = 1;
X+                    break;
X+                case 'Z':      /* ZipInfo mode:  ignore */
X+                    break;
X+                default:
X+                    error = TRUE;
X+                    break;
X+            }
X+        }
X+    }
X+    if ((argc-- == 0) || error) {
X+        *pargc = argc;
X+        *pargv = argv;
X+        return USAGE(error);
X+    }
X+
X+#ifdef MORE
X+    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func useless */
X+        G.M_flag = 0;
X+#endif
X+
X+    /* if no listing options given (or all negated), or if only -h/-t given
X+     * with individual files specified, use default listing format */
X+    if ((uO.lflag < 0) || ((argc > 0) && (uO.lflag == 0)))
X+        uO.lflag = LFLAG;
X+
X+    /* set header and totals flags to default or specified values */
X+    switch (uO.lflag) {
X+        case 0:   /* 0:  can only occur if either -t or -h explicitly given; */
X+        case 2:   /*  therefore set both flags equal to normally false value */
X+            uO.hflag = hflag_2;
X+            uO.tflag = tflag_2v;
X+            break;
X+        case 1:   /* only filenames, *always* */
X+            uO.hflag = FALSE;
X+            uO.tflag = FALSE;
X+            uO.zflag = FALSE;
X+            break;
X+        case 3:
X+        case 4:
X+        case 5:
X+            uO.hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
X+            uO.tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
X+            break;
X+        case 10:
X+            uO.hflag = hflag_slmv;
X+            uO.tflag = tflag_2v;
X+            break;
X+    }
X+
X+    *pargc = argc;
X+    *pargv = argv;
X+    return 0;
X+
X+} /* end function zi_opts() */
X+
X+#endif /* !WINDLL */
X+
X+
X+
X+
X+
X+/*******************************/
X+/*  Function zi_end_central()  */
X+/*******************************/
X+
X+int zi_end_central(__G)   /* return PK-type error code */
X+    __GDEF
X+{
X+    int  error = PK_COOL;
X+
X+
X+/*---------------------------------------------------------------------------
X+    Print out various interesting things about the zipfile.
X+  ---------------------------------------------------------------------------*/
X+
X+    /* header fits on one line, for anything up to 10GB and 10000 files: */
X+    if (uO.hflag)
X+        Info(slide, 0, ((char *)slide, ((int)strlen(G.zipfn) < 39)?
X+          LoadFarString(LongHeader) : LoadFarString(ShortHeader), G.zipfn,
X+          (long)G.ziplen, G.ecrec.total_entries_central_dir,
X+          (G.ecrec.total_entries_central_dir==1)?
X+          nullStr : PlurSufx));
X+
X+    /* verbose format */
X+    if (uO.lflag > 9) {
X+        Info(slide, 0, ((char *)slide, LoadFarString(EndCentDirRec)));
X+        Info(slide, 0, ((char *)slide, LoadFarString(LineSeparators)));
X+
X+        Info(slide, 0, ((char *)slide, LoadFarString(ActOffsetCentDir),
X+          (long)G.real_ecrec_offset, (long)G.real_ecrec_offset,
X+          (long)G.expect_ecrec_offset, (long)G.expect_ecrec_offset));
X+
X+        if (G.ecrec.number_this_disk == 0) {
X+            Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive1),
X+              G.ecrec.total_entries_central_dir,
X+              (G.ecrec.total_entries_central_dir == 1)? "entry" : "entries",
X+              G.ecrec.size_central_directory,
X+              G.ecrec.size_central_directory));
X+            Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive2),
X+              G.ecrec.offset_start_central_directory,
X+              G.ecrec.offset_start_central_directory));
X+        } else {
X+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive1),
X+              G.ecrec.number_this_disk + 1,
X+              G.ecrec.num_disk_start_cdir + 1,
X+              G.ecrec.num_entries_centrl_dir_ths_disk,
X+              (G.ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are"));
X+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive2),
X+              G.ecrec.total_entries_central_dir,
X+              (G.ecrec.total_entries_central_dir == 1) ? "entry" : "entries",
X+              G.ecrec.size_central_directory,
X+              G.ecrec.size_central_directory));
X+            Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive3),
X+              G.ecrec.offset_start_central_directory,
X+              G.ecrec.offset_start_central_directory));
X+        }
X+
X+    /*-----------------------------------------------------------------------
X+        Get the zipfile comment, if any, and print it out.  (Comment may be
X+        up to 64KB long.  May the fleas of a thousand camels infest the arm-
X+        pits of anyone who actually takes advantage of this fact.)
X+      -----------------------------------------------------------------------*/
X+
X+        if (!G.ecrec.zipfile_comment_length)
X+            Info(slide, 0, ((char *)slide, LoadFarString(NoZipfileComment)));
X+        else {
X+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommentDesc),
X+              G.ecrec.zipfile_comment_length));
X+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommBegin)));
X+            if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY))
X+                error = PK_WARN;
X+            Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommEnd)));
X+            if (error)
X+                Info(slide, 0, ((char *)slide,
X+                  LoadFarString(ZipfileCommTrunc2)));
X+        } /* endif (comment exists) */
X+
X+    /* non-verbose mode:  print zipfile comment only if requested */
X+    } else if (uO.zflag && G.ecrec.zipfile_comment_length) {
X+        if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) {
X+            Info(slide, 0x401, ((char *)slide,
X+              LoadFarString(ZipfileCommTruncMsg)));
X+            error = PK_WARN;
X+        }
X+    } /* endif (verbose) */
X+
X+    return error;
X+
X+} /* end function zi_end_central() */
X+
X+
X+
X+
X+
X+/************************/
X+/*  Function zipinfo()  */
X+/************************/
X+
X+int zipinfo(__G)   /* return PK-type error code */
X+    __GDEF
X+{
X+    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
X+    int *fn_matched=NULL, *xn_matched=NULL;
X+    ulg j, members=0L;
X+    ulg tot_csize=0L, tot_ucsize=0L;
X+    ulg endprev;   /* buffers end of previous entry for zi_long()'s check
X+                    *  of extra bytes */
X+
X+
X+/*---------------------------------------------------------------------------
X+    Malloc space for check on unmatched filespecs (no big deal if one or both
X+    are NULL).
X+  ---------------------------------------------------------------------------*/
X+
X+    if (G.filespecs > 0  &&
X+        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != NULL)
X+        for (j = 0;  j < G.filespecs;  ++j)
X+            fn_matched[j] = FALSE;
X+
X+    if (G.xfilespecs > 0  &&
X+        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != NULL)
X+        for (j = 0;  j < G.xfilespecs;  ++j)
X+            xn_matched[j] = FALSE;
X+
X+/*---------------------------------------------------------------------------
X+    Set file pointer to start of central directory, then loop through cen-
X+    tral directory entries.  Check that directory-entry signature bytes are
X+    actually there (just a precaution), then process the entry.  We know
X+    the entire central directory is on this disk:  we wouldn't have any of
X+    this information unless the end-of-central-directory record was on this
X+    disk, and we wouldn't have gotten to this routine unless this is also
X+    the disk on which the central directory starts.  In practice, this had
X+    better be the *only* disk in the archive, but maybe someday we'll add
X+    multi-disk support.
X+  ---------------------------------------------------------------------------*/
X+
X+    uO.L_flag = FALSE;      /* zipinfo mode: never convert name to lowercase */
X+    G.pInfo = G.info;       /* (re-)initialize, (just to make sure) */
X+    G.pInfo->textmode = 0;  /* so one can read on screen (is this ever used?) */
X+
X+    /* reset endprev for new zipfile; account for multi-part archives (?) */
X+    endprev = (G.crec.relative_offset_local_header == 4L)? 4L : 0L;
X+
X+
X+    for (j = 1L;; j++) {
X+        if (readbuf(__G__ G.sig, 4) == 0)
X+            return PK_EOF;
X+        if (strncmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
X+            if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
X+                (unsigned)G.ecrec.total_entries_central_dir) {
X+                /* "j modulus 64k" matches the reported 16-bit-unsigned
X+                 * number of directory entries -> probably, the regular
X+                 * end of the central directory has been reached
X+                 */
X+                break;
X+            } else {
X+                Info(slide, 0x401,
X+                     ((char *)slide, LoadFarString(CentSigMsg), j));
X+                Info(slide, 0x401,
X+                     ((char *)slide, LoadFarString(ReportMsg)));
X+                return PK_BADERR;   /* sig not found */
X+            }
X+        }
X+        /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
X+        if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
X+            return error;       /* only PK_EOF defined */
X+
X+        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
X+             PK_COOL)
X+        {
X+          error_in_archive = error;   /* might be warning */
X+          if (error > PK_WARN)        /* fatal */
X+              return error;
X+        }
X+
X+        if (!G.process_all_files) {   /* check if specified on command line */
X+            unsigned i;
X+
X+            if (G.filespecs == 0)
X+                do_this_file = TRUE;
X+            else {  /* check if this entry matches an `include' argument */
X+                do_this_file = FALSE;
X+                for (i = 0; i < G.filespecs; i++)
X+                    if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
X+                        do_this_file = TRUE;
X+                        if (fn_matched)
X+                            fn_matched[i] = TRUE;
X+                        break;       /* found match, so stop looping */
X+                    }
X+            }
X+            if (do_this_file) {  /* check if this is an excluded file */
X+                for (i = 0; i < G.xfilespecs; i++)
X+                    if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
X+                        do_this_file = FALSE;  /* ^-- ignore case in match */
X+                        if (xn_matched)
X+                            xn_matched[i] = TRUE;
X+                        break;
X+                    }
X+            }
X+        }
X+
X+    /*-----------------------------------------------------------------------
X+        If current file was specified on command line, or if no names were
X+        specified, do the listing for this file.  Otherwise, get rid of the
X+        file comment and go back for the next file.
X+      -----------------------------------------------------------------------*/
X+
X+        if (G.process_all_files || do_this_file) {
X+
X+            switch (uO.lflag) {
X+                case 1:
X+                case 2:
X+                    fnprint(__G);
X+                    SKIP_(G.crec.extra_field_length)
X+                    SKIP_(G.crec.file_comment_length)
X+                    break;
X+
X+                case 3:
X+                case 4:
X+                case 5:
X+                    if ((error = zi_short(__G)) != PK_COOL) {
X+                        error_in_archive = error;   /* might be warning */
X+                        if (error > PK_WARN)        /* fatal */
X+                            return error;
X+                    }
X+                    break;
X+
X+                case 10:
X+                    Info(slide, 0, ((char *)slide,
X+                      LoadFarString(CentralDirEntry), j));
X+                    if ((error = zi_long(__G__ &endprev)) != PK_COOL) {
X+                        error_in_archive = error;   /* might be warning */
X+                        if (error > PK_WARN)        /* fatal */
X+                            return error;
X+                    }
X+                    break;
X+
X+                default:
X+                    SKIP_(G.crec.extra_field_length)
X+                    SKIP_(G.crec.file_comment_length)
X+                    break;
X+
X+            } /* end switch (lflag) */
X+
X+            tot_csize += G.crec.csize;
X+            tot_ucsize += G.crec.ucsize;
X+            if (G.crec.general_purpose_bit_flag & 1)
X+                tot_csize -= 12;   /* don't count encryption header */
X+            ++members;
X+
X+#ifdef DLL
X+            if ((G.statreportcb != NULL) &&
X+                (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
X+                                  G.filename, (zvoid *)&G.crec.ucsize)) {
X+                if (fn_matched)
X+                    free((zvoid *)fn_matched);
X+                if (xn_matched)
X+                    free((zvoid *)xn_matched);
X+                return IZ_CTRLC;        /* cancel operation by user request */
X+            }
X+#endif
X+#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
X+            UserStop();
X+#endif
X+
X+        } else {        /* not listing this file */
X+            SKIP_(G.crec.extra_field_length)
X+            SKIP_(G.crec.file_comment_length)
X+
X+        } /* end if (list member?) */
X+
X+    } /* end for-loop (j: member files) */
X+
X+/*---------------------------------------------------------------------------
X+    Check that we actually found requested files; if so, print totals.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (uO.tflag) {
X+        char *sgn = "";
X+        int cfactor = ratio(tot_ucsize, tot_csize);
X+
X+        if (cfactor < 0) {
X+            sgn = "-";
X+            cfactor = -cfactor;
X+        }
X+        Info(slide, 0, ((char *)slide, LoadFarString(ZipfileStats),
X+          members, (members==1L)? nullStr:PlurSufx, tot_ucsize,
X+          tot_csize, sgn, cfactor/10, cfactor%10));
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Check for unmatched filespecs on command line and print warning if any
X+    found.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (fn_matched) {
X+        for (j = 0;  j < G.filespecs;  ++j)
X+            if (!fn_matched[j])
X+                Info(slide, 0x401, ((char *)slide,
X+                  LoadFarString(FilenameNotMatched), G.pfnames[j]));
X+        free((zvoid *)fn_matched);
X+    }
X+    if (xn_matched) {
X+        for (j = 0;  j < G.xfilespecs;  ++j)
X+            if (!xn_matched[j])
X+                Info(slide, 0x401, ((char *)slide,
X+                  LoadFarString(ExclFilenameNotMatched), G.pxnames[j]));
X+        free((zvoid *)xn_matched);
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Double check that we're back at the end-of-central-directory record.
X+  ---------------------------------------------------------------------------*/
X+
X+    if (strncmp(G.sig, end_central_sig, 4)) {   /* just to make sure again */
X+        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
X+        error_in_archive = PK_WARN;   /* didn't find sig */
X+    }
X+    if (members == 0 && error_in_archive <= PK_WARN)
X+        error_in_archive = PK_FIND;
X+
X+    if (uO.lflag >= 10)
X+        (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
X+
X+    return error_in_archive;
X+
X+} /* end function zipinfo() */
X+
X+
X+
X+
X+
X+/************************/
X+/*  Function zi_long()  */
X+/************************/
X+
X+static int zi_long(__G__ pEndprev)   /* return PK-type error code */
X+    __GDEF
X+    ulg *pEndprev;                   /* for zi_long() check of extra bytes */
X+{
X+#ifdef USE_EF_UT_TIME
X+    iztimes z_utime;
X+#endif
X+    int  error, error_in_archive=PK_COOL;
X+    unsigned  hostnum, hostver, extnum, extver, methnum, xattr;
X+    char workspace[12], attribs[22];
X+    ZCONST char *varmsg_str;
X+    char unkn[16];
X+    static ZCONST char Far *os[NUM_HOSTS] = {
X+        OS_FAT, OS_Amiga, OS_VMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS,
X+        OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS,
X+        OS_Acorn, OS_VFAT, OS_MVS, OS_BeOS, OS_Tandem, OS_Theos, OS_MacDarwin,
X+        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
X+        OS_AtheOS
X+    };
X+    static ZCONST char Far *method[NUM_METHODS] = {
X+        MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4,
X+        MthdImplode, MthdToken, MthdDeflate, MthdDeflat64, MthdDCLImplode,
X+        MthdPKRes11, MthdBZip2
X+    };
X+    static ZCONST char Far *dtypelng[4] = {
X+        DeflNorm, DeflMax, DeflFast, DeflSFast
X+    };
X+
X+
X+/*---------------------------------------------------------------------------
X+    Check whether there's any extra space inside the zipfile.  If *pEndprev is
X+    zero, it's probably a signal that OS/2 extra fields are involved (with
X+    unknown compressed size).  We won't worry about prepended junk here...
X+  ---------------------------------------------------------------------------*/
X+
X+    if (G.crec.relative_offset_local_header != *pEndprev && *pEndprev > 0L) {
X+        /*  GRR DEBUG
X+        Info(slide, 0, ((char *)slide,
X+          "  [crec.relative_offset_local_header = %lu, endprev = %lu]\n",
X+          G.crec.relative_offset_local_header, *pEndprev));
X+         */
X+        Info(slide, 0, ((char *)slide, LoadFarString(ExtraBytesPreceding),
X+          (long)G.crec.relative_offset_local_header - (long)(*pEndprev)));
X+    }
X+
X+    /* calculate endprev for next time around (problem:  extra fields may
X+     * differ in length between local and central-directory records) */
X+    *pEndprev = G.crec.relative_offset_local_header + (4L + LREC_SIZE) +
X+      G.crec.filename_length + G.crec.extra_field_length + G.crec.csize;
X+
X+/*---------------------------------------------------------------------------
X+    Read the extra field, if any. It may be used to get UNIX style modtime.
X+  ---------------------------------------------------------------------------*/
X+
X+    if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD)) != 0)
X+    {
X+        if (G.extra_field != NULL) {
X+            free(G.extra_field);
X+            G.extra_field = NULL;
X+        }
X+        error_in_archive = error;
X+        /* The premature return in case of a "fatal" error (PK_EOF) is
X+         * delayed until we analyze the extra field contents.
X+         * This allows us to display all the other info that has been
X+         * successfully read in.
X+         */
X+    }
X+
X+/*---------------------------------------------------------------------------
X+    Print out various interesting things about the compressed file.
X+  ---------------------------------------------------------------------------*/
X+
X+    hostnum = (unsigned)(G.pInfo->hostnum);
X+    hostver = (unsigned)(G.pInfo->hostver);
X+    extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
X+    extver = (unsigned)G.crec.version_needed_to_extract[0];
X+    methnum = (unsigned)MIN(G.crec.compression_method, NUM_METHODS);
X+
X+    (*G.message)((zvoid *)&G, (uch *)"  ", 2L, 0);  fnprint(__G);
X+
X+    Info(slide, 0, ((char *)slide, LoadFarString(LocalHeaderOffset),
X+      G.crec.relative_offset_local_header,
X+      G.crec.relative_offset_local_header));
X+
X+    if (hostnum >= NUM_HOSTS) {
X+        sprintf(unkn, LoadFarString(UnknownNo),
X+                (int)G.crec.version_made_by[1]);
X+        varmsg_str = unkn;
X+    } else {
X+        varmsg_str = LoadFarStringSmall(os[hostnum]);
X+#ifdef OLD_THEOS_EXTRA
X+        if (hostnum == FS_VFAT_ && hostver == 20) {
X+            /* entry made by old non-official THEOS port zip archive */
X+            varmsg_str = LoadFarStringSmall(OS_TheosOld);
X+        }
X+#endif /* OLD_THEOS_EXTRA */
X+    }
X+    Info(slide, 0, ((char *)slide, LoadFarString(HostOS), varmsg_str));
X+    Info(slide, 0, ((char *)slide, LoadFarString(EncodeSWVer), hostver/10,
X+      hostver%10));
X+
X+    if ((extnum >= NUM_HOSTS) || (os[extnum] == NULL)) {
X+        sprintf(unkn, LoadFarString(UnknownNo),
X+                (int)G.crec.version_needed_to_extract[1]);
X+        varmsg_str = unkn;
X+    } else {
X+        varmsg_str = LoadFarStringSmall(os[extnum]);
X+    }
X+    Info(slide, 0, ((char *)slide, LoadFarString(MinOSCompReq), varmsg_str));
X+    Info(slide, 0, ((char *)slide, LoadFarString(MinSWVerReq), extver/10,
X+      extver%10));
X+
X+    if (methnum >= NUM_METHODS) {
X+        sprintf(unkn, LoadFarString(UnknownNo), G.crec.compression_method);
X+        varmsg_str = unkn;
X+    } else {
X+        varmsg_str = LoadFarStringSmall(method[methnum]);
X+    }
X+    Info(slide, 0, ((char *)slide, LoadFarString(CompressMethod), varmsg_str));
X+    if (methnum == IMPLODED) {
X+        Info(slide, 0, ((char *)slide, LoadFarString(SlideWindowSizeImplode),
X+          (G.crec.general_purpose_bit_flag & 2)? '8' : '4'));
X+        Info(slide, 0, ((char *)slide, LoadFarString(ShannonFanoTrees),
X+          (G.crec.general_purpose_bit_flag & 4)? '3' : '2'));
X+    } else if (methnum == DEFLATED || methnum == ENHDEFLATED) {
X+        ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
X+
X+        Info(slide, 0, ((char *)slide, LoadFarString(CompressSubtype),
X+          LoadFarStringSmall(dtypelng[dnum])));
X+    }
X+
X+    Info(slide, 0, ((char *)slide, LoadFarString(FileSecurity),
X+      (G.crec.general_purpose_bit_flag & 1) ? nullStr : "not "));
X+    Info(slide, 0, ((char *)slide, LoadFarString(ExtendedLocalHdr),
X+      (G.crec.general_purpose_bit_flag & 8) ? "yes" : "no"));
X+    /* print upper 3 bits for amusement? */
X+
X+    /* For printing of date & time, a "char d_t_buf[21]" is required.
X+     * To save stack space, we reuse the "char attribs[22]" buffer which
X+     * is not used yet.
X+     */
X+#   define d_t_buf attribs
X+
X+    zi_time(__G__ &G.crec.last_mod_dos_datetime, NULL, d_t_buf);
X+    Info(slide, 0, ((char *)slide, LoadFarString(FileModDate), d_t_buf));
X+#ifdef USE_EF_UT_TIME
X+    if (G.extra_field &&
X+#ifdef IZ_CHECK_TZ
X+        G.tz_is_valid &&
X+#endif
X+        (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
X+                          G.crec.last_mod_dos_datetime, &z_utime, NULL)
X+         & EB_UT_FL_MTIME))
X+    {
X+        TIMET_TO_NATIVE(z_utime.mtime)   /* NOP unless MSC 7.0 or Macintosh */
X+        d_t_buf[0] = (char)0;               /* signal "show local time" */
X+        zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
X+        Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
X+          d_t_buf, LoadFarStringSmall(LocalTime)));
X+#ifndef NO_GMTIME
X+        d_t_buf[0] = (char)1;           /* signal "show UTC (GMT) time" */
X+        zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
X+        Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
X+          d_t_buf, LoadFarStringSmall(GMTime)));
X+#endif /* !NO_GMTIME */
X+    }
X+#endif /* USE_EF_UT_TIME */
X+
X+    Info(slide, 0, ((char *)slide, LoadFarString(CRC32Value), G.crec.crc32));
X+    Info(slide, 0, ((char *)slide, LoadFarString(CompressedFileSize),
X+      G.crec.csize));
X+    Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize),
X+      G.crec.ucsize));
X+    Info(slide, 0, ((char *)slide, LoadFarString(FilenameLength),
X+      G.crec.filename_length));
X+    Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldLength),
X+      G.crec.extra_field_length));
X+    Info(slide, 0, ((char *)slide, LoadFarString(FileCommentLength),
X+      G.crec.file_comment_length));
X+    Info(slide, 0, ((char *)slide, LoadFarString(FileDiskNum),
X+      G.crec.disk_number_start + 1));
X+    Info(slide, 0, ((char *)slide, LoadFarString(ApparentFileType),
X+      (G.crec.internal_file_attributes & 1)? "text"
X+         : (G.crec.internal_file_attributes & 2)? "ebcdic"
X+              : "binary"));             /* changed to accept EBCDIC */
X+#ifdef ATARI
X+    printf("  external file attributes (hex):                   %.8lx\n",
X+      G.crec.external_file_attributes);
X+#endif
X+    xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
X+    if (hostnum == VMS_) {
X+        char   *p=attribs, *q=attribs+1;
X+        int    i, j, k;
X+
X+        for (k = 0;  k < 12;  ++k)
X+            workspace[k] = 0;
X+        if (xattr & VMS_IRUSR)
X+            workspace[0] = 'R';
X+        if (xattr & VMS_IWUSR) {
X+            workspace[1] = 'W';
X+            workspace[3] = 'D';
X+        }
X+        if (xattr & VMS_IXUSR)
X+            workspace[2] = 'E';
X+        if (xattr & VMS_IRGRP)
X+            workspace[4] = 'R';
X+        if (xattr & VMS_IWGRP) {
X+            workspace[5] = 'W';
X+            workspace[7] = 'D';
X+        }
X+        if (xattr & VMS_IXGRP)
X+            workspace[6] = 'E';
X+        if (xattr & VMS_IROTH)
X+            workspace[8] = 'R';
X+        if (xattr & VMS_IWOTH) {
X+            workspace[9] = 'W';
X+            workspace[11] = 'D';
X+        }
X+        if (xattr & VMS_IXOTH)
X+            workspace[10] = 'E';
X+
X+        *p++ = '(';
X+        for (k = j = 0;  j < 3;  ++j) {    /* loop over groups of permissions */
X+            for (i = 0;  i < 4;  ++i, ++k)  /* loop over perms within a group */
X+                if (workspace[k])
X+                    *p++ = workspace[k];
X+            *p++ = ',';                       /* group separator */
X+            if (j == 0)
X+                while ((*p++ = *q++) != ',')
X+                    ;                         /* system, owner perms are same */
X+        }
X+        *p-- = '\0';
X+        *p = ')';   /* overwrite last comma */
X+        Info(slide, 0, ((char *)slide, LoadFarString(VMSFileAttributes), xattr,
X+          attribs));
X+
X+    } else if (hostnum == AMIGA_) {
X+        switch (xattr & AMI_IFMT) {
X+            case AMI_IFDIR:  attribs[0] = 'd';  break;
X+            case AMI_IFREG:  attribs[0] = '-';  break;
X+            default:         attribs[0] = '?';  break;
X+        }
X+        attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
X+        attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
X+        attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
X+        attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
X+        attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
X+        attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
X+        attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
X+        attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
X+        attribs[9] = 0;   /* better dlm the string */
X+        Info(slide, 0, ((char *)slide, LoadFarString(AmigaFileAttributes),
X+          xattr, attribs));
X+
X+    } else if (hostnum == THEOS_) {
X+        ZCONST char Far *fpFtyp;
X+
X+        switch (xattr & THS_IFMT) {
X+            case THS_IFLIB:  fpFtyp = TheosFTypLib;  break;
X+            case THS_IFDIR:  fpFtyp = TheosFTypDir;  break;
X+            case THS_IFREG:  fpFtyp = TheosFTypReg;  break;
X+            case THS_IFREL:  fpFtyp = TheosFTypRel;  break;
X+            case THS_IFKEY:  fpFtyp = TheosFTypKey;  break;
X+            case THS_IFIND:  fpFtyp = TheosFTypInd;  break;
X+            case THS_IFR16:  fpFtyp = TheosFTypR16;  break;
X+            case THS_IFP16:  fpFtyp = TheosFTypP16;  break;
X+            case THS_IFP32:  fpFtyp = TheosFTypP32;  break;
X+            default:         fpFtyp = TheosFTypUkn;  break;
X+        }
X+        strcpy(attribs, LoadFarStringSmall(fpFtyp));
X+        attribs[12] = (xattr & THS_INHID) ? '.' : 'H';
X+        attribs[13] = (xattr & THS_IMODF) ? '.' : 'M';
X+        attribs[14] = (xattr & THS_IWOTH) ? '.' : 'W';
X+        attribs[15] = (xattr & THS_IROTH) ? '.' : 'R';
X+        attribs[16] = (xattr & THS_IEUSR) ? '.' : 'E';
X+        attribs[17] = (xattr & THS_IXUSR) ? '.' : 'X';
X+        attribs[18] = (xattr & THS_IWUSR) ? '.' : 'W';
X+        attribs[19] = (xattr & THS_IRUSR) ? '.' : 'R';
X+        attribs[20] = 0;
X+        Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
X+          xattr, attribs));
X+
X+#ifdef OLD_THEOS_EXTRA
X+    } else if (hostnum == FS_VFAT_ && hostver == 20) {
X+        /* process old non-official THEOS port zip archive */
X+        ZCONST char Far *fpFtyp;
X+
X+        switch (xattr & _THS_IFMT) {
X+            case _THS_IFLIB:  fpFtyp = TheosFTypLib;  break;
X+            case _THS_IFDIR:  fpFtyp = TheosFTypDir;  break;
X+            case _THS_IFREG:  fpFtyp = TheosFTypReg;  break;
X+            case _THS_IODRC:  fpFtyp = TheosFTypRel;  break;
X+            case _THS_IOKEY:  fpFtyp = TheosFTypKey;  break;
X+            case _THS_IOIND:  fpFtyp = TheosFTypInd;  break;
X+            case _THS_IOPRG:  fpFtyp = TheosFTypR16;  break;
X+            case _THS_IO286:  fpFtyp = TheosFTypP16;  break;
X+            case _THS_IO386:  fpFtyp = TheosFTypP32;  break;
X+            default:         fpFtyp = TheosFTypUkn;  break;
X+        }
X+        strcpy(attribs, LoadFarStringSmall(fpFtyp));
X+        attribs[12] = (xattr & _THS_HIDDN) ? 'H' : '.';
X+        attribs[13] = (xattr & _THS_IXOTH) ? '.' : 'X';
X+        attribs[14] = (xattr & _THS_IWOTH) ? '.' : 'W';
X+        attribs[15] = (xattr & _THS_IROTH) ? '.' : 'R';
X+        attribs[16] = (xattr & _THS_IEUSR) ? '.' : 'E';
X+        attribs[17] = (xattr & _THS_IXUSR) ? '.' : 'X';
X+        attribs[18] = (xattr & _THS_IWUSR) ? '.' : 'W';
X+        attribs[19] = (xattr & _THS_IRUSR) ? '.' : 'R';
X+        attribs[20] = 0;
X+        Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
X+          xattr, attribs));
X+#endif /* OLD_THEOS_EXTRA */
X+
X+    } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) &&
X+               (hostnum != FS_NTFS_) && (hostnum != FS_VFAT_) &&
X+               (hostnum != ACORN_) &&
X+               (hostnum != VM_CMS_) && (hostnum != MVS_))
X+    {                                 /* assume Unix-like */
X+        switch ((unsigned)(xattr & UNX_IFMT)) {
X+            case (unsigned)UNX_IFDIR:   attribs[0] = 'd';  break;
X+            case (unsigned)UNX_IFREG:   attribs[0] = '-';  break;
X+            case (unsigned)UNX_IFLNK:   attribs[0] = 'l';  break;
X+            case (unsigned)UNX_IFBLK:   attribs[0] = 'b';  break;
X+            case (unsigned)UNX_IFCHR:   attribs[0] = 'c';  break;
X+            case (unsigned)UNX_IFIFO:   attribs[0] = 'p';  break;
X+            case (unsigned)UNX_IFSOCK:  attribs[0] = 's';  break;
X+            default:          attribs[0] = '?';  break;
X+        }
X+        attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
X+        attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
X+        attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
X+
X+        attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
X+        attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
X+        attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
X+
X+        if (xattr & UNX_IXUSR)
X+            attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
X+        else
X+            attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';   /* S = undefined */
X+        if (xattr & UNX_IXGRP)
X+            attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';   /* == UNX_ENFMT */
X+        else
X+            attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
X+        if (xattr & UNX_IXOTH)
X+            attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';   /* "sticky bit" */
X+        else
X+            attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';   /* T = undefined */
X+        attribs[10] = 0;
X+
X+        Info(slide, 0, ((char *)slide, LoadFarString(UnixFileAttributes), xattr,
X+          attribs));
X+
X+    } else {
X+        Info(slide, 0, ((char *)slide, LoadFarString(NonMSDOSFileAttributes),
X+            G.crec.external_file_attributes >> 8));
X+
X+    } /* endif (hostnum: external attributes format) */
X+
X+    if ((xattr=(unsigned)(G.crec.external_file_attributes & 0xFF)) == 0)
X+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributes),
X+          xattr));
X+    else if (xattr == 1)
X+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesRO),
X+          xattr));
X+    else
X+        Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesAlpha),
X+          xattr, (xattr&1)? "rdo " : nullStr,
X+          (xattr&2)? "hid " : nullStr,
X+          (xattr&4)? "sys " : nullStr,
X+          (xattr&8)? "lab " : nullStr,
X+          (xattr&16)? "dir " : nullStr,
X+          (xattr&32)? "arc " : nullStr,
X+          (xattr&64)? "lnk " : nullStr,
X+          (xattr&128)? "exe" : nullStr));
X+
X+/*---------------------------------------------------------------------------
X+    Analyze the extra field, if any, and print the file comment, if any (the
X+    filename has already been printed, above).  That finishes up this file
X+    entry...
X+  ---------------------------------------------------------------------------*/
X+
X+    if (G.crec.extra_field_length > 0) {
X+        uch *ef_ptr = G.extra_field;
X+        ush ef_len = G.crec.extra_field_length;
X+        ush eb_id, eb_datalen;
X+        ZCONST char Far *ef_fieldname;
X+
X+        if (error_in_archive > PK_WARN)   /* fatal:  can't continue */
X+            /* delayed "fatal error" return from extra field reading */
X+            return error;
X+        if (G.extra_field == (uch *)NULL)
X+            return PK_ERR;   /* not consistent with crec length */
X+
X+        Info(slide, 0, ((char *)slide, LoadFarString(ExtraFields)));
X+
X+        while (ef_len >= EB_HEADSIZE) {
X+            eb_id = makeword(&ef_ptr[EB_ID]);
X+            eb_datalen = makeword(&ef_ptr[EB_LEN]);
X+            ef_ptr += EB_HEADSIZE;
X+            ef_len -= EB_HEADSIZE;
X+
X+            if (eb_datalen > (ush)ef_len) {
X+                Info(slide, 0x421, ((char *)slide,
X+                  LoadFarString(ExtraFieldTrunc), eb_id, eb_datalen, ef_len));
X+                eb_datalen = ef_len;
X+            }
X+
X+            switch (eb_id) {
X+                case EF_PKSZ64:
X+                    ef_fieldname = efPKSZ64;
X+                    break;
X+                case EF_AV:
X+                    ef_fieldname = efAV;
X+                    break;
X+                case EF_OS2:
X+                    ef_fieldname = efOS2;
X+                    break;
X+                case EF_ACL:
X+                    ef_fieldname = efACL;
X+                    break;
X+                case EF_NTSD:
X+                    ef_fieldname = efNTSD;
X+                    break;
X+                case EF_PKVMS:
X+                    ef_fieldname = efPKVMS;
X+                    break;
X+                case EF_IZVMS:
X+                    ef_fieldname = efIZVMS;
X+                    break;
X+                case EF_PKW32:
X+                    ef_fieldname = efPKWin32;
X+                    break;
X+                case EF_PKUNIX:
X+                    ef_fieldname = efPKUnix;
X+                    break;
X+                case EF_IZUNIX:
X+                    ef_fieldname = efIZUnix;
X+                    if (hostnum == UNIX_ && *pEndprev > 0L)
X+                        *pEndprev += 4L;  /* also have UID/GID in local copy */
X+                    break;
X+                case EF_IZUNIX2:
X+                    ef_fieldname = efIZUnix2;
X+                    if (*pEndprev > 0L)
X+                        *pEndprev += 4L;  /* 4 byte UID/GID in local copy */
X+                    break;
X+                case EF_TIME:
X+                    ef_fieldname = efTime;
X+                    break;
X+                case EF_MAC3:
X+                    ef_fieldname = efMac3;
X+                    break;
X+                case EF_JLMAC:
X+                    ef_fieldname = efJLMac;
X+                    break;
X+                case EF_ZIPIT:
X+                    ef_fieldname = efZipIt;
X+                    break;
X+                case EF_ZIPIT2:
X+                    ef_fieldname = efZipIt2;
X+                    break;
X+                case EF_VMCMS:
X+                    ef_fieldname = efVMCMS;
X+                    break;
X+                case EF_MVS:
X+                    ef_fieldname = efMVS;
X+                    break;
X+                case EF_ATHEOS:
X+                    ef_fieldname = efAtheOS;
X+                    break;
X+                case EF_BEOS:
X+                    ef_fieldname = efBeOS;
X+                    break;
X+                case EF_QDOS:
X+                    ef_fieldname = efQDOS;
X+                    break;
X+                case EF_AOSVS:
X+                    ef_fieldname = efAOSVS;
X+                    break;
X+                case EF_SPARK:   /* from RISC OS */
X+                    ef_fieldname = efSpark;
X+                    break;
X+                case EF_MD5:
X+                    ef_fieldname = efMD5;
X+                    break;
X+                case EF_ASIUNIX:
X+                    ef_fieldname = efASiUnix;
X+                    break;
X+                case EF_TANDEM:
X+                    ef_fieldname = efTandem;
X+                    break;
X+                case EF_SMARTZIP:
X+                    ef_fieldname = efSmartZip;
X+                    break;
X+                case EF_THEOS:
X+#ifdef OLD_THEOS_EXTRA
X+                case EF_THEOSO:
X+#endif
X+                    ef_fieldname = efTheos;
X+                    break;
X+                default:
X+                    ef_fieldname = efUnknown;
X+                    break;
X+            }
X+            Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldType),
X+                 eb_id, LoadFarStringSmall(ef_fieldname), eb_datalen));
X+
X+            /* additional, field-specific information: */
X+            switch (eb_id) {
X+                case EF_OS2:
X+                case EF_ACL:
X+                    if (eb_datalen >= EB_OS2_HLEN) {
X+                        if (eb_id == EF_OS2)
X+                            ef_fieldname = OS2EAs;
X+                        else
X+                            ef_fieldname = ACLdata;
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(ef_fieldname), makelong(ef_ptr)));
X+                        *pEndprev = 0L;   /* no clue about csize of local */
X+                    }
X+                    break;
X+                case EF_NTSD:
X+                    if (eb_datalen >= EB_NTSD_C_LEN) {
X+                        Info(slide, 0, ((char *)slide, LoadFarString(NTSDData),
X+                          makelong(ef_ptr)));
X+                        *pEndprev = 0L;   /* no clue about csize of local */
X+                    }
X+                    break;
X+                case EF_IZVMS:
X+                    if (eb_datalen >= 8) {
X+                        char *p, q[8];
X+                        unsigned compr = makeword(ef_ptr+EB_IZVMS_FLGS)
X+                                        & EB_IZVMS_BCMASK;
X+
X+                        *q = '\0';
X+                        if (compr > 3)
X+                            compr = 3;
X+                        switch (makelong(ef_ptr)) {
X+                            case 0x42414656: /* "VFAB" */
X+                                p = "FAB"; break;
X+                            case 0x4C4C4156: /* "VALL" */
X+                                p = "XABALL"; break;
X+                            case 0x43484656: /* "VFHC" */
X+                                p = "XABFHC"; break;
X+                            case 0x54414456: /* "VDAT" */
X+                                p = "XABDAT"; break;
X+                            case 0x54445256: /* "VRDT" */
X+                                p = "XABRDT"; break;
X+                            case 0x4F525056: /* "VPRO" */
X+                                p = "XABPRO"; break;
X+                            case 0x59454B56: /* "VKEY" */
X+                                p = "XABKEY"; break;
X+                            case 0x56534D56: /* "VMSV" */
X+                                p = "version";
X+                                if (eb_datalen >= 16) {
X+                                    /* put termitation first, for A_TO_N() */
X+                                    q[7] = '\0';
X+                                    q[0] = ' ';
X+                                    q[1] = '(';
X+                                    strncpy(q+2,
X+                                            (char *)ef_ptr+EB_IZVMS_HLEN, 4);
X+                                    A_TO_N(q+2);
X+                                    q[6] = ')';
X+                                }
X+                                break;
X+                            default:
X+                                p = "unknown";
X+                        }
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(izVMSdata),
X+                          LoadFarStringSmall(izVMScomp[compr]),
X+                          makeword(ef_ptr+EB_IZVMS_UCSIZ), p, q));
X+                    }
X+                    break;
X+                case EF_TIME:
X+                    if (eb_datalen >= 1) {
X+                        char types[80];
X+                        int num = 0, len;
X+
X+                        *types = '\0';
X+                        if (*ef_ptr & 1) {
X+                            strcpy(types, LoadFarString(UTmodification));
X+                            ++num;
X+                        }
X+                        if (*ef_ptr & 2) {
X+                            len = strlen(types);
X+                            if (num)
X+                                types[len++] = '/';
X+                            strcpy(types+len, LoadFarString(UTaccess));
X+                            ++num;
X+                            if (*pEndprev > 0L)
X+                                *pEndprev += 4L;
X+                        }
X+                        if (*ef_ptr & 4) {
X+                            len = strlen(types);
X+                            if (num)
X+                                types[len++] = '/';
X+                            strcpy(types+len, LoadFarString(UTcreation));
X+                            ++num;
X+                            if (*pEndprev > 0L)
X+                                *pEndprev += 4L;
X+                        }
X+                        if (num > 0)
X+                            Info(slide, 0, ((char *)slide,
X+                              LoadFarString(UTdata), types,
X+                              num == 1? nullStr : PlurSufx));
X+                    }
X+                    break;
X+                case EF_MAC3:
X+                    if (eb_datalen >= EB_MAC3_HLEN) {
X+                        ulg eb_uc = makelong(ef_ptr);
X+                        unsigned mac3_flgs = makeword(ef_ptr+EB_FLGS_OFFS);
X+                        unsigned eb_is_uc = mac3_flgs & EB_M3_FL_UNCMPR;
X+
X+                        Info(slide, 0, ((char *)slide, LoadFarString(Mac3data),
X+                          eb_uc, eb_is_uc ? "un" : nullStr));
X+                        if (eb_is_uc) {
X+                            if (*pEndprev > 0L)
X+                                *pEndprev += makelong(ef_ptr);
X+                        } else {
X+                            *pEndprev = 0L; /* no clue about csize of local */
X+                        }
X+
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(MacOSMAC3flags),
X+                          LoadFarStringSmall(mac3_flgs & EB_M3_FL_DATFRK ?
X+                                             MacOS_DF : MacOS_RF),
X+                          (mac3_flgs & EB_M3_FL_TIME64 ? 64 : 32)));
X+                        zi_showMacTypeCreator(__G__ &ef_ptr[6]);
X+                    }
X+                    break;
X+                case EF_ZIPIT2:
X+                    if (eb_datalen >= 5 &&
X+                        makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
X+
X+                        if (eb_datalen >= 12) {
X+                            zi_showMacTypeCreator(__G__ &ef_ptr[4]);
X+                        }
X+                    }
X+                    break;
X+                case EF_ZIPIT:
X+                    if (eb_datalen >= 5 &&
X+                        makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
X+                        unsigned fnlen = ef_ptr[4];
X+
X+                        if ((unsigned)eb_datalen >= fnlen + (5 + 8)) {
X+                            uch nullchar = ef_ptr[fnlen+5];
X+
X+                            ef_ptr[fnlen+5] = '\0'; /* terminate filename */
X+                            A_TO_N(ef_ptr+5);
X+                            Info(slide, 0, ((char *)slide,
X+                              LoadFarString(ZipItFname), (char *)ef_ptr+5));
X+                            ef_ptr[fnlen+5] = nullchar;
X+                            zi_showMacTypeCreator(__G__ &ef_ptr[fnlen+5]);
X+                        }
X+                    }
X+                    break;
X+                case EF_JLMAC:
X+                    if (eb_datalen >= 40 &&
X+                        makelong(ef_ptr) == 0x45454C4A /* "JLEE" */)
X+                    {
X+                        zi_showMacTypeCreator(__G__ &ef_ptr[4]);
X+
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(MacOSJLEEflags),
X+                          LoadFarStringSmall(ef_ptr[31] & 1 ?
X+                                             MacOS_DF : MacOS_RF)));
X+                    }
X+                    break;
X+                case EF_SMARTZIP:
X+                    if ((eb_datalen == EB_SMARTZIP_HLEN) &&
X+                        makelong(ef_ptr) == 0x70695A64 /* "dZip" */) {
X+                        char filenameBuf[32];
X+                        zi_showMacTypeCreator(__G__ &ef_ptr[4]);
X+                        memcpy(filenameBuf, &ef_ptr[33], 31);
X+                        filenameBuf[ef_ptr[32]] = '\0';
X+                        A_TO_N(filenameBuf);
X+                        Info(slide, 0, ((char *)slide,
X+                             LoadFarString(ZipItFname), filenameBuf));
X+                    }
X+                    break;
X+#ifdef CMS_MVS
X+                case EF_VMCMS:
X+                case EF_MVS:
X+                    {
X+                        char type[100];
X+
X+                        Info(slide, 0, ((char *)slide,
X+                             LoadFarString(VmMvsExtraField),
X+                             (getVMMVSexfield(type, ef_ptr-EB_HEADSIZE,
X+                             (unsigned)eb_datalen) > 0)?
X+                             type : LoadFarStringSmall(VmMvsInvalid)));
X+                    }
X+                    break;
X+#endif /* CMS_MVS */
X+                case EF_ATHEOS:
X+                case EF_BEOS:
X+                    if (eb_datalen >= EB_BEOS_HLEN) {
X+                        ulg eb_uc = makelong(ef_ptr);
X+                        unsigned eb_is_uc =
X+                          *(ef_ptr+EB_FLGS_OFFS) & EB_BE_FL_UNCMPR;
X+
X+                        if (eb_id == EF_ATHEOS)
X+                            ef_fieldname = AtheOSdata;
X+                        else
X+                            ef_fieldname = BeOSdata;
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(ef_fieldname),
X+                          eb_uc, eb_is_uc ? "un" : nullStr));
X+                        if (eb_is_uc) {
X+                            if (*pEndprev > 0L)
X+                                *pEndprev += makelong(ef_ptr);
X+                        } else {
X+                            *pEndprev = 0L; /* no clue about csize of local */
X+                        }
X+                    }
X+                    break;
X+                case EF_QDOS:
X+                    if (eb_datalen >= 4) {
X+                        Info(slide, 0, ((char *)slide, LoadFarString(QDOSdata),
X+                          ef_ptr[0], ef_ptr[1], ef_ptr[2], ef_ptr[3]));
X+                    }
X+                    break;
X+                case EF_AOSVS:
X+                    if (eb_datalen >= 5) {
X+                        Info(slide, 0, ((char *)slide, LoadFarString(AOSVSdata),
X+                          ((int)(uch)ef_ptr[4])/10, ((int)(uch)ef_ptr[4])%10));
X+                    }
X+                    break;
X+                case EF_TANDEM:
X+                    if (eb_datalen == 20) {
X+                        unsigned type, code;
X+
X+                        type = (ef_ptr[18] & 0x60) >> 5;
X+                        code = makeword(ef_ptr);
X+                        /* Arrg..., Tandem e.f. uses BigEndian byte-order */
X+                        code = ((code << 8) & 0xff00) | ((code >> 8) & 0x00ff);
X+                        if (type == NSK_UNSTRUCTURED) {
X+                            if (code == NSK_EDITFILECODE)
X+                                type = 4;
X+                            else if (code == NSK_OBJECTFILECODE)
X+                                type = 5;
X+                        }
X+                        Info(slide, 0, ((char *)slide,
X+                          LoadFarString(Tandemdata),
X+                          LoadFarStringSmall(TandemFileformat[type]),
X+                          code));
X+                    }
X+                    break;
X+                case EF_MD5:
X+                    if (eb_datalen >= 19) {
X+                        char md5[33];
X+                        int i;
X+
X+                        for (i = 0;  i < 16;  ++i)
X+                            sprintf(&md5[i<<1], "%02x", ef_ptr[15-i]);
X+                        md5[32] = '\0';
X+                        Info(slide, 0, ((char *)slide, LoadFarString(MD5data),
X+                          md5));
X+                        break;
X+                    }   /* else: fall through !! */
X+                default:
X+                    if (eb_datalen > 0) {
X+                        ush i, n;
X+
X+                        if (eb_datalen <= 24) {
X+                            Info(slide, 0, ((char *)slide,
X+                                 LoadFarString(ColonIndent)));
X+                            n = eb_datalen;
X+                        } else {
X+                            Info(slide, 0, ((char *)slide,
X+                                 LoadFarString(First20)));
X+                            n = 20;
X+                        }
X+                        for (i = 0;  i < n;  ++i)
X+                            Info(slide, 0, ((char *)slide,
X+                                 LoadFarString(efFormat), ef_ptr[i]));
X+                    }
X+                    break;
X+            }
X+            (*G.message)((zvoid *)&G, (uch *)".", 1L, 0);
X+
X+            ef_ptr += eb_datalen;
X+            ef_len -= eb_datalen;
X+        }
X+        (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
X+    }
X+
X+    /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */
X+    if ((xattr = (unsigned)((G.crec.external_file_attributes & 0xC000) >> 12))
X+        & 8)
X+    {
X+        if (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)
X+        {
X+            Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
X+              "is", EF_IZUNIX, LoadFarStringSmall(efIZUnix),
X+              (unsigned)(xattr&12), (xattr&4)? efIZuid : efIZnouid));
X+            if (*pEndprev > 0L)
X+                *pEndprev += (ulg)(xattr&12);
X+        }
X+        else if (hostnum == FS_FAT_ && !(xattr&4))
X+            Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
X+              "may be", EF_IZUNIX, LoadFarStringSmall(efIZUnix), 8,
X+              efIZnouid));
X+    }
X+
X+    if (!G.crec.file_comment_length)
X+        Info(slide, 0, ((char *)slide, LoadFarString(NoFileComment)));
X+    else {
X+        Info(slide, 0, ((char *)slide, LoadFarString(FileCommBegin)));
X+        if ((error = do_string(__G__ G.crec.file_comment_length, DISPL_8)) !=
X+            PK_COOL)
X+        {
X+            error_in_archive = error;   /* might be warning */
X+            if (error > PK_WARN)   /* fatal */
X+                return error;
X+        }
X+        Info(slide, 0, ((char *)slide, LoadFarString(FileCommEnd)));
X+    }
X+
X+    return error_in_archive;
X+
X+} /* end function zi_long() */
X+
X+
X+
X+
X+
X+/*************************/
X+/*  Function zi_short()  */
X+/*************************/
X+
X+static int zi_short(__G)   /* return PK-type error code */
X+    __GDEF
X+{
X+#ifdef USE_EF_UT_TIME
X+    iztimes     z_utime;
X+    time_t      *z_modtim;
X+#endif
X+    int         k, error, error_in_archive=PK_COOL;
X+    unsigned    hostnum, hostver, methnum, xattr;
X+    char        *p, workspace[12], attribs[16];
X+    char        methbuf[5];
X+    static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
X+    static ZCONST char Far os[NUM_HOSTS+1][4] = {
X+        "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
X+        "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk",
X+        "ths", "osx", "???", "???", "???", "???", "???", "???", "???",
X+        "???", "???", "???", "ath", "???"
X+    };
X+#ifdef OLD_THEOS_EXTRA
X+    static ZCONST char Far os_TheosOld[] = "tho";
X+#endif
X+    static ZCONST char Far method[NUM_METHODS+1][5] = {
X+        "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn",
X+        "def#", "d64#", "dcli", "u011", "bzp2", "u###"
X+    };
X+
X+
X+/*---------------------------------------------------------------------------
X+    Print out various interesting things about the compressed file.
X+  ---------------------------------------------------------------------------*/
X+
X+    methnum = (unsigned)MIN(G.crec.compression_method, NUM_METHODS);
X+    hostnum = (unsigned)(G.pInfo->hostnum);
X+    hostver = (unsigned)(G.pInfo->hostver);
X+/*
X+    extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
X+    extver = (unsigned)G.crec.version_needed_to_extract[0];
X+ */
X+
X+    zfstrcpy(methbuf, method[methnum]);
X+    if (methnum == IMPLODED) {
X+        methbuf[1] = (char)((G.crec.general_purpose_bit_flag & 2)? '8' : '4');
X+        methbuf[3] = (char)((G.crec.general_purpose_bit_flag & 4)? '3' : '2');
X+    } else if (methnum == DEFLATED || methnum == ENHDEFLATED) {
X+        ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
X+        methbuf[3] = dtype[dnum];
X+    } else if (methnum >= NUM_METHODS) {   /* unknown */
X+        sprintf(&methbuf[1], "%03u", G.crec.compression_method);
X+    }
X+
X+    for (k = 0;  k < 15;  ++k)
X+        attribs[k] = ' ';
X+    attribs[15] = 0;
X+
X+    xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
X+    switch (hostnum) {
X+        case VMS_:
X+            {   int    i, j;
X+
X+                for (k = 0;  k < 12;  ++k)
X+                    workspace[k] = 0;
X+                if (xattr & VMS_IRUSR)
X+                    workspace[0] = 'R';
X+                if (xattr & VMS_IWUSR) {
X+                    workspace[1] = 'W';
X+                    workspace[3] = 'D';
X+                }
X+                if (xattr & VMS_IXUSR)
X+                    workspace[2] = 'E';
X+                if (xattr & VMS_IRGRP)
X+                    workspace[4] = 'R';
X+                if (xattr & VMS_IWGRP) {
X+                    workspace[5] = 'W';
X+                    workspace[7] = 'D';
X+                }
X+                if (xattr & VMS_IXGRP)
X+                  workspace[6] = 'E';
X+                if (xattr & VMS_IROTH)
X+                    workspace[8] = 'R';
X+                if (xattr & VMS_IWOTH) {
X+                    workspace[9] = 'W';
X+                    workspace[11] = 'D';
X+                }
X+                if (xattr & VMS_IXOTH)
X+                    workspace[10] = 'E';
X+
X+                p = attribs;
X+                for (k = j = 0;  j < 3;  ++j) {     /* groups of permissions */
X+                    for (i = 0;  i < 4;  ++i, ++k)  /* perms within a group */
X+                        if (workspace[k])
X+                            *p++ = workspace[k];
X+                    *p++ = ',';                     /* group separator */
X+                }
X+                *--p = ' ';   /* overwrite last comma */
X+                if ((p - attribs) < 12)
X+                    sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
X+            }
X+            break;
X+
X+        case AMIGA_:
X+            switch (xattr & AMI_IFMT) {
X+                case AMI_IFDIR:  attribs[0] = 'd';  break;
X+                case AMI_IFREG:  attribs[0] = '-';  break;
X+                default:         attribs[0] = '?';  break;
X+            }
X+            attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
X+            attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
X+            attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
X+            attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
X+            attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
X+            attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
X+            attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
X+            attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
X+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
X+            break;
X+
X+        case THEOS_:
X+            switch (xattr & THS_IFMT) {
X+                case THS_IFLIB: *attribs = 'L'; break;
X+                case THS_IFDIR: *attribs = 'D'; break;
X+                case THS_IFCHR: *attribs = 'C'; break;
X+                case THS_IFREG: *attribs = 'S'; break;
X+                case THS_IFREL: *attribs = 'R'; break;
X+                case THS_IFKEY: *attribs = 'K'; break;
X+                case THS_IFIND: *attribs = 'I'; break;
X+                case THS_IFR16: *attribs = 'P'; break;
X+                case THS_IFP16: *attribs = '2'; break;
X+                case THS_IFP32: *attribs = '3'; break;
X+                default:        *attribs = '?'; break;
X+            }
X+            attribs[1] = (xattr & THS_INHID) ? '.' : 'H';
X+            attribs[2] = (xattr & THS_IMODF) ? '.' : 'M';
X+            attribs[3] = (xattr & THS_IWOTH) ? '.' : 'W';
X+            attribs[4] = (xattr & THS_IROTH) ? '.' : 'R';
X+            attribs[5] = (xattr & THS_IEUSR) ? '.' : 'E';
X+            attribs[6] = (xattr & THS_IXUSR) ? '.' : 'X';
X+            attribs[7] = (xattr & THS_IWUSR) ? '.' : 'W';
X+            attribs[8] = (xattr & THS_IRUSR) ? '.' : 'R';
X+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
X+            break;
X+
X+        case FS_VFAT_:
X+#ifdef OLD_THEOS_EXTRA
X+            if (hostver == 20) {
X+                switch (xattr & _THS_IFMT) {
X+                    case _THS_IFLIB: *attribs = 'L'; break;
X+                    case _THS_IFDIR: *attribs = 'd'; break;
X+                    case _THS_IFCHR: *attribs = 'c'; break;
X+                    case _THS_IFREG: *attribs = 'S'; break;
X+                    case _THS_IODRC: *attribs = 'D'; break;
X+                    case _THS_IOKEY: *attribs = 'K'; break;
X+                    case _THS_IOIND: *attribs = 'I'; break;
X+                    case _THS_IOPRG: *attribs = 'P'; break;
X+                    case _THS_IO286: *attribs = '2'; break;
X+                    case _THS_IO386: *attribs = '3'; break;
X+                    default:         *attribs = '?'; break;
X+                }
X+                attribs[1] = (xattr & _THS_HIDDN) ? 'H' : '.';
X+                attribs[2] = (xattr & _THS_IXOTH) ? '.' : 'X';
X+                attribs[3] = (xattr & _THS_IWOTH) ? '.' : 'W';
X+                attribs[4] = (xattr & _THS_IROTH) ? '.' : 'R';
X+                attribs[5] = (xattr & _THS_IEUSR) ? '.' : 'E';
X+                attribs[6] = (xattr & _THS_IXUSR) ? '.' : 'X';
X+                attribs[7] = (xattr & _THS_IWUSR) ? '.' : 'W';
X+                attribs[8] = (xattr & _THS_IRUSR) ? '.' : 'R';
X+                sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
X+                break;
X+            } /* else: fall through! */
X+#endif /* OLD_THEOS_EXTRA */
X+
X+        case FS_FAT_:
X+        case FS_HPFS_:
X+        case FS_NTFS_:
X+        case VM_CMS_:
X+        case MVS_:
X+        case ACORN_:
X+            if (hostnum != FS_FAT_ ||
X+                (unsigned)(xattr & 0700) !=
X+                 ((unsigned)0400 |
X+                  ((unsigned)!(G.crec.external_file_attributes & 1) << 7) |
X+                  ((unsigned)(G.crec.external_file_attributes & 0x10) << 2))
X+               )
X+            {
X+                xattr = (unsigned)(G.crec.external_file_attributes & 0xFF);
X+                sprintf(attribs, ".r.-...     %u.%u", hostver/10, hostver%10);
X+                attribs[2] = (xattr & 0x01)? '-' : 'w';
X+                attribs[5] = (xattr & 0x02)? 'h' : '-';
X+                attribs[6] = (xattr & 0x04)? 's' : '-';
X+                attribs[4] = (xattr & 0x20)? 'a' : '-';
X+                if (xattr & 0x10) {
X+                    attribs[0] = 'd';
X+                    attribs[3] = 'x';
X+                } else
X+                    attribs[0] = '-';
X+                if (IS_VOLID(xattr))
X+                    attribs[0] = 'V';
X+                else if ((p = MBSRCHR(G.filename, '.')) != (char *)NULL) {
X+                    ++p;
X+                    if (STRNICMP(p, "com", 3) == 0 ||
X+                        STRNICMP(p, "exe", 3) == 0 ||
X+                        STRNICMP(p, "btm", 3) == 0 ||
X+                        STRNICMP(p, "cmd", 3) == 0 ||
X+                        STRNICMP(p, "bat", 3) == 0)
X+                        attribs[3] = 'x';
X+                }
X+                break;
X+            } /* else: fall through! */
X+
X+        default:   /* assume Unix-like */
X+            switch ((unsigned)(xattr & UNX_IFMT)) {
X+                case (unsigned)UNX_IFDIR:   attribs[0] = 'd';  break;
X+                case (unsigned)UNX_IFREG:   attribs[0] = '-';  break;
X+                case (unsigned)UNX_IFLNK:   attribs[0] = 'l';  break;
X+                case (unsigned)UNX_IFBLK:   attribs[0] = 'b';  break;
X+                case (unsigned)UNX_IFCHR:   attribs[0] = 'c';  break;
X+                case (unsigned)UNX_IFIFO:   attribs[0] = 'p';  break;
X+                case (unsigned)UNX_IFSOCK:  attribs[0] = 's';  break;
X+                default:          attribs[0] = '?';  break;
X+            }
X+            attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
X+            attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
X+            attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
X+            attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
X+            attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
X+            attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
X+
X+            if (xattr & UNX_IXUSR)
X+                attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
X+            else
X+                attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';  /* S==undefined */
X+            if (xattr & UNX_IXGRP)
X+                attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';  /* == UNX_ENFMT */
X+            else
X+                /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';  real 4.3BSD */
X+                attribs[6] = (xattr & UNX_ISGID)? 'S' : '-';  /* SunOS 4.1.x */
X+            if (xattr & UNX_IXOTH)
X+                attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';  /* "sticky bit" */
X+            else
X+                attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';  /* T==undefined */
X+
X+            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
X+            break;
X+
X+    } /* end switch (hostnum: external attributes format) */
X+
X+#ifdef OLD_THEOS_EXTRA
X+    Info(slide, 0, ((char *)slide, "%s %s %8lu ", attribs,
X+      LoadFarStringSmall(((hostnum == FS_VFAT_ && hostver == 20) ?
X+                          os_TheosOld :
X+                          os[hostnum])),
X+      G.crec.ucsize));
X+#else
X+    Info(slide, 0, ((char *)slide, "%s %s %8lu ", attribs,
X+      LoadFarStringSmall(os[hostnum]),
X+      G.crec.ucsize));
X+#endif
X+    Info(slide, 0, ((char *)slide, "%c",
X+      (G.crec.general_purpose_bit_flag & 1)?
X+      ((G.crec.internal_file_attributes & 1)? 'T' : 'B') :  /* encrypted */
X+      ((G.crec.internal_file_attributes & 1)? 't' : 'b'))); /* plaintext */
X+    k = (G.crec.extra_field_length ||
X+         /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */
X+         ((G.crec.external_file_attributes & 0x8000) &&
X+          (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)));
X+    Info(slide, 0, ((char *)slide, "%c", k?
X+      ((G.crec.general_purpose_bit_flag & 8)? 'X' : 'x') :  /* extra field */
X+      ((G.crec.general_purpose_bit_flag & 8)? 'l' : '-'))); /* no extra field */
X+      /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */
X+
X+    if (uO.lflag == 4) {
X+        ulg csiz = G.crec.csize;
X+
X+        if (G.crec.general_purpose_bit_flag & 1)
X+            csiz -= 12;    /* if encrypted, don't count encryption header */
X+        Info(slide, 0, ((char *)slide, "%3d%%",
X+          (ratio(G.crec.ucsize,csiz)+5)/10));
X+    } else if (uO.lflag == 5)
X+        Info(slide, 0, ((char *)slide, " %8lu", G.crec.csize));
X+
X+    /* Read the extra field, if any.  The extra field info may be used
X+     * in the file modification time section, below.
X+     */
X+    if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD)) != 0)
X+    {
X+        if (G.extra_field != NULL) {
X+            free(G.extra_field);
X+            G.extra_field = NULL;
X+        }
X+        error_in_archive = error;
X+        /* We do not return prematurely in case of a "fatal" error (PK_EOF).
X+         * This does not hurt here, because we do not need to read from the
X+         * zipfile again before the end of this function.
X+         */
X+    }
X+
X+    /* For printing of date & time, a "char d_t_buf[16]" is required.
X+     * To save stack space, we reuse the "char attribs[16]" buffer whose
X+     * content is no longer needed.
X+     */
X+#   define d_t_buf attribs
X+#ifdef USE_EF_UT_TIME
X+    z_modtim = G.extra_field &&
X+#ifdef IZ_CHECK_TZ
X+               G.tz_is_valid &&
X+#endif
X+               (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
X+                                 G.crec.last_mod_dos_datetime, &z_utime, NULL)
X+                & EB_UT_FL_MTIME)
X+              ? &z_utime.mtime : NULL;
X+    TIMET_TO_NATIVE(z_utime.mtime)     /* NOP unless MSC 7.0 or Macintosh */
X+    d_t_buf[0] = (char)0;              /* signal "show local time" */
X+#else
X+#   define z_modtim NULL
X+#endif
X+    Info(slide, 0, ((char *)slide, " %s %s ", methbuf,
X+      zi_time(__G__ &G.crec.last_mod_dos_datetime, z_modtim, d_t_buf)));
X+    fnprint(__G);
X+
X+/*---------------------------------------------------------------------------
X+    Skip the file comment, if any (the filename has already been printed,
X+    above).  That finishes up this file entry...
X+  ---------------------------------------------------------------------------*/
X+
X+    SKIP_(G.crec.file_comment_length)
X+
X+    return error_in_archive;
X+
X+} /* end function zi_short() */
X+
X+
X+
X+
X+
X+/**************************************/
X+/*  Function zi_showMacTypeCreator()  */
X+/**************************************/
X+
X+static void zi_showMacTypeCreator(__G__ ebfield)
X+    __GDEF
X+    uch *ebfield;
X+{
X+    /* not every Type / Creator character is printable */
X+    if (isprint(native(ebfield[0])) && isprint(native(ebfield[1])) &&
X+        isprint(native(ebfield[2])) && isprint(native(ebfield[3])) &&
X+        isprint(native(ebfield[4])) && isprint(native(ebfield[5])) &&
X+        isprint(native(ebfield[6])) && isprint(native(ebfield[7]))) {
X+       Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata),
X+            native(ebfield[0]), native(ebfield[1]),
X+            native(ebfield[2]), native(ebfield[3]),
X+            native(ebfield[4]), native(ebfield[5]),
X+            native(ebfield[6]), native(ebfield[7])));
X+    } else {
X+       Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata1),
X+            (((ulg)ebfield[0]) << 24) +
X+            (((ulg)ebfield[1]) << 16) +
X+            (((ulg)ebfield[2]) << 8)  +
X+            ((ulg)ebfield[3]),
X+            (((ulg)ebfield[4]) << 24) +
X+            (((ulg)ebfield[5]) << 16) +
X+            (((ulg)ebfield[6]) << 8)  +
X+            ((ulg)ebfield[7])));
X+    }
X+} /* end function zi_showMacTypeCreator() */
X+
X+
X+
X+
X+
X+/************************/
X+/*  Function zi_time()  */
X+/************************/
X+
X+static char *zi_time(__G__ datetimez, modtimez, d_t_str)
X+    __GDEF
X+    ZCONST ulg *datetimez;
X+    ZCONST time_t *modtimez;
X+    char *d_t_str;
X+{
X+    unsigned yr, mo, dy, hh, mm, ss;
X+    char monthbuf[4];
X+    ZCONST char *monthstr;
X+    static ZCONST char Far month[12][4] = {
X+        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
X+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
X+    };
X+#ifdef USE_EF_UT_TIME
X+    struct tm *t;
X+#endif
X+
X+
X+
X+/*---------------------------------------------------------------------------
X+    Convert the file-modification date and time info to a string of the form
X+    "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending
X+    on values of lflag and T_flag.  If using Unix-time extra fields, convert
X+    to local time or not, depending on value of first character in d_t_str[].
X+  ---------------------------------------------------------------------------*/
X+
X+#ifdef USE_EF_UT_TIME
X+    if (modtimez != NULL) {
X+#ifndef NO_GMTIME
X+        /* check for our secret message from above... */
X+        t = (d_t_str[0] == (char)1)? gmtime(modtimez) : localtime(modtimez);
X+#else
X+        t = localtime(modtimez);
X+#endif
X+        if (uO.lflag > 9 && t == (struct tm *)NULL)
X+            /* time conversion error in verbose listing format,
X+             * return string with '?' instead of data
X+             */
X+            return (strcpy(d_t_str, LoadFarString(YMDHMSTimeError)));
X+    } else
X+        t = (struct tm *)NULL;
X+    if (t != (struct tm *)NULL) {
X+        mo = (unsigned)(t->tm_mon + 1);
X+        dy = (unsigned)(t->tm_mday);
X+        yr = (unsigned)(t->tm_year);
X+
X+        hh = (unsigned)(t->tm_hour);
X+        mm = (unsigned)(t->tm_min);
X+        ss = (unsigned)(t->tm_sec);
X+    } else
X+#endif /* USE_EF_UT_TIME */
X+    {
X+        yr = ((unsigned)(*datetimez >> 25) & 0x7f) + 80;
X+        mo = ((unsigned)(*datetimez >> 21) & 0x0f);
X+        dy = ((unsigned)(*datetimez >> 16) & 0x1f);
X+
X+        hh = (((unsigned)*datetimez >> 11) & 0x1f);
X+        mm = (((unsigned)*datetimez >> 5) & 0x3f);
X+        ss = (((unsigned)*datetimez << 1) & 0x3e);
X+    }
X+
X+    if (mo == 0 || mo > 12) {
X+        sprintf(monthbuf, LoadFarString(BogusFmt), mo);
X+        monthstr = monthbuf;
X+    } else
X+        monthstr = LoadFarStringSmall(month[mo-1]);
X+
X+    if (uO.lflag > 9)   /* verbose listing format */
X+        sprintf(d_t_str, LoadFarString(YMDHMSTime), yr+1900, monthstr, dy, hh,
X+          mm, ss);
X+    else if (uO.T_flag)
X+        sprintf(d_t_str, LoadFarString(DecimalTime), yr+1900, mo, dy, hh, mm,
X+          ss);
X+    else   /* was:  if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
X+        sprintf(d_t_str, LoadFarString(DMYHMTime), dy, monthstr, yr%100, hh,
X+          mm);
X+
X+    return d_t_str;
X+
X+} /* end function zi_time() */
X+
X+#endif /* !NO_ZIPINFO */
X--- unix/Makefile-p1	2008-03-08 07:42:03.000000000 +0900
X+++ unix/Makefile	2008-03-08 07:42:16.000000000 +0900
X@@ -728,7 +728,7 @@
X freebsd:		unix_make
X 	@echo 'NOTE:  use bsd target for non-Intel FreeBSD compiles (if any).'
X 	$(MAKE) unzips CC="$(CC)" LD="$(CC)" AS="$(CC)"\
X-	 CF="-Wall -I. -DASM_CRC -DUNIX -DBSD $(LOC)"\
X+	 CF="-Wall -I. -DASM_CRC -DUNIX -DBSD -I/usr/local/include -DNLS $(LOC)" LF="-o unzip -L/usr/local/lib -liconv" SL="-o unzipsfx -L/usr/local/lib -liconv"\
X 	 AF="-Di386 $(AF)" CRC32=crc_gcc
X 
X # Generic BSDish Unix gcc.  ``The -O3 only works with later versions of gcc;
0588af1d819e734dc985a056f2d05bf8
echo x - japanese/unzip/Makefile
sed 's/^X//' >japanese/unzip/Makefile << 'ef28c3c2993ba7a9af96a53f627cb676'
X# New ports collection makefile for:	unzip
X# Date created:		17 October 1994
X# Whom:			jmz
X#
X# $FreeBSD: ports/archivers/unzip/Makefile,v 1.64 2009/08/22 00:12:55 amdmi3 Exp $
X#
X
XPORTNAME=	unzip
XPORTVERSION=	5.52
XPORTREVISION=	6
XCATEGORIES?=	japanese archivers
XMASTER_SITES=	SF/infozip/UnZip%205.x%20and%20earlier/${PORTVERSION}
XDISTNAME=	${PORTNAME}552
X
XMAINTAINER?=	hashiz at meridiani.jp
XCOMMENT?=	List, test and extract compressed files in a ZIP archive \
X		with NLS patch
X
XWRKSRC=		${WRKDIR}/${PORTNAME}-${PORTVERSION}
XMAKEFILE=	unix/Makefile
X.if defined(INSTALL_AS_INFOUNZIP)
XUNZIP_NAME=	info-unzip
X.else
XUNZIP_NAME=	unzip
X.endif
XPLIST_FILES=	bin/${UNZIP_NAME} bin/funzip bin/unzipsfx bin/zipgrep bin/zipinfo
XPORTDOCS=	README WHERE
XMAN1=		${UNZIP_NAME}.1 funzip.1 unzipsfx.1 zipgrep.1 zipinfo.1
XCONFLICTS=	unzip-*
X
XCFLAGS+=	-D_FILE_OFFSET_BITS=64
XLOCAL_UNZIP=	${CFLAGS} -DACORN_FTYPE_NFS -DWILD_STOP_AT_DIR
X
X.if defined(WITH_UNZIP_UNREDUCE)
XDISTFILES=	${DISTNAME}${EXTRACT_SUFX} unreduce_full.zip
XEXTRACT_ONLY=	${PORTNAME}552.tar.gz
XLOCAL_UNZIP+=	-DUSE_SMITH_CODE
X.endif
X
XMAKE_ENV=	LOCAL_UNZIP="${LOCAL_UNZIP}"
X
X.ifdef USE_UNZIP
X.error You have `USE_UNZIP' variable defined either in environment or in make(1) arguments. Please undefine and try again.
X.endif
X
X.include <bsd.port.pre.mk>
X
X.if ${ARCH} == "i386"
XALL_TARGET=	freebsd
X.else
XALL_TARGET=	bsd
X.endif
X
X.if !defined(INSTALL_AS_INFOUNZIP)
Xpre-fetch:
X	@${ECHO} ""
X	@${ECHO} "Use INSTALL_AS_INFOUNZIP=yes to install Info Unzip as ${PREFIX}/bin/info-unzip"
X	@${ECHO} ""
X.endif
X
X.if defined(WITH_UNZIP_UNREDUCE)
Xpre-build:
X	@(cd ${BUILD_WRKSRC}; ${MAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} unzip)
X	@(cd ${WRKSRC}; \
X		./unzip -o ${_DISTDIR}unreduce_full.zip; \
X		${MV} unreduce_full.c unreduce.c)
X	@(cd ${BUILD_WRKSRC}; ${MAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} clean)
X.endif
X
Xdo-install:
X	${INSTALL_PROGRAM} ${WRKSRC}/unzip ${PREFIX}/bin/${UNZIP_NAME}
X.for file in funzip unzipsfx
X	${INSTALL_PROGRAM} ${WRKSRC}/${file} ${PREFIX}/bin
X.endfor
X	${LN} -sf ${UNZIP_NAME} ${PREFIX}/bin/zipinfo
X	${INSTALL_SCRIPT} ${WRKSRC}/unix/zipgrep ${PREFIX}/bin
X	${INSTALL_MAN} ${WRKSRC}/man/unzip.1 ${MAN1PREFIX}/man/man1/${UNZIP_NAME}.1
X.for f in ${MAN1:Nunzip.1:Ninfo-unzip.1}
X	${INSTALL_MAN} ${WRKSRC}/man/${f} ${MAN1PREFIX}/man/man1
X.endfor
X.if !defined(NOPORTDOCS)
X	@${MKDIR} ${DOCSDIR}
X.for f in ${PORTDOCS}
X	${INSTALL_DATA} ${WRKSRC}/${f} ${DOCSDIR}
X.endfor
X.endif
X
X.include <bsd.port.post.mk>
ef28c3c2993ba7a9af96a53f627cb676
echo x - japanese/unzip/distinfo
sed 's/^X//' >japanese/unzip/distinfo << '2bfbf1a6b7fd895f28b590a63f77c263'
XMD5 (unzip552.tar.gz) = 9d23919999d6eac9217d1f41472034a9
XSHA256 (unzip552.tar.gz) = 145d95e2ef1ef9add2e3c97d1340907e33ab8749eb1235372e7f0b7af600a8e9
XSIZE (unzip552.tar.gz) = 1140291
XMD5 (unreduce_full.zip) = b7cde206d69b403e7551b9b0c25bd345
XSHA256 (unreduce_full.zip) = 1f4d93d2250dc1a1d1d2b8aac09d9989d4f9dd2cb0967373bf41fdf5f108cec1
XSIZE (unreduce_full.zip) = 2849
2bfbf1a6b7fd895f28b590a63f77c263
echo x - japanese/unzip/pkg-descr
sed 's/^X//' >japanese/unzip/pkg-descr << '0957b64fe15f9fdfdc95087be2243636'
XNLS patched unzip.
X
XThis patch import from Ubuntu japan.
X
XUnzip will list, test, or extract files from a ZIP archive, commonly
Xfound on MS-DOS systems.  The default behavior (with no options) is to
Xextract into the current directory (and subdirectories below it) all
Xfiles from the specified ZIP archive. Unzip is compatible with
Xarchives created by PKWARE's PKZIP, but in many cases the program
Xoptions or default behaviors differ.
X
XZipinfo lists technical information about files in a ZIP archive, most
Xcommonly found on MS-DOS systems.  Such information includes file access
Xpermissions, encryption status, type of compression, version and operating
Xsystem or file system of compressing program, and the like.  
X
XFunzip acts as a filter; that is, it assumes that a ZIP archive is
Xbeing piped into standard input, and it extracts the first member from
Xthe archive to stdout.  If there is an argument, then the input comes
Xfrom the specified file instead of from stdin.
X
XUnzipsfx may be used to create self-extracting ZIP archives from previously
Xcreated ZIP archives.
X
XWWW: http://www.info-zip.org/UnZip.html
0957b64fe15f9fdfdc95087be2243636
exit
--- unzip-nls.shar ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list