Radix cross Linux

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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