Index: Makefile
===================================================================
--- Makefile (nonexistent)
+++ Makefile (revision 5)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../../build-system/core.mk
+
+
+download_clean:
+ @true
+
+.PHONY: download_clean
Index: unzip/Makefile
===================================================================
--- unzip/Makefile (nonexistent)
+++ unzip/Makefile (revision 5)
@@ -0,0 +1,57 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url = $(DOWNLOAD_SERVER)/sources/packages/a/infozip/unzip60
+
+versions = 60
+pkgname = unzip
+suffix = tar.gz
+
+tarballs = $(addsuffix .$(suffix), $(addprefix $(pkgname), $(versions)))
+sha1s = $(addsuffix .sha1sum, $(tarballs))
+
+
+patches = $(CURDIR)/patches/unzip-6.0-slackware.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+ @echo -e "\n======= Downloading source tarballs =======" ; \
+ for tarball in $(tarballs) ; do \
+ echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+ done ; wait
+
+$(sha1s): $(tarballs)
+ @for sha in $@ ; do \
+ echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+ echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+ touch $$sha ; \
+ echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+ sha1sum --check $$sha ; ret="$$?" ; \
+ if [ "$$ret" == "1" ]; then \
+ echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+ exit 1 ; \
+ fi ; \
+ done
+
+$(patches): $(sha1s)
+ @echo -e "\n======= Create Patches =======\n" ; \
+ ( cd create-6.0-slackware-patch ; ./create.patch.sh ) ; \
+ echo -e "\n"
+
+download_clean:
+ @rm -f $(tarballs) $(sha1s) $(patches)
Index: unzip/create-6.0-slackware-patch/create.patch.sh
===================================================================
--- unzip/create-6.0-slackware-patch/create.patch.sh (nonexistent)
+++ unzip/create-6.0-slackware-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=6.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../unzip${version}.tar.gz
+mv unzip${version} unzip${version}-orig
+
+cp -rf ./unzip${version}-new ./unzip${version}
+
+diff --unified -Nr unzip${version}-orig unzip${version} > unzip-${VERSION}-slackware.patch
+
+mv unzip-${VERSION}-slackware.patch ../patches
+
+rm -rf ./unzip${version}
+rm -rf ./unzip${version}-orig
Property changes on: unzip/create-6.0-slackware-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: unzip/create-6.0-slackware-patch/file.list
===================================================================
--- unzip/create-6.0-slackware-patch/file.list (nonexistent)
+++ unzip/create-6.0-slackware-patch/file.list (revision 5)
@@ -0,0 +1,14 @@
+unzip60/crc_i386.S
+unzip60/crypt.c
+unzip60/extract.c
+unzip60/fileio.c
+unzip60/list.c
+unzip60/man/unzip.1
+unzip60/match.c
+unzip60/process.c
+unzip60/unix/configure
+unzip60/unix/unix.c
+unzip60/unix/unxcfg.h
+unzip60/unzip.c
+unzip60/unzpriv.h
+unzip60/zipinfo.c
Index: unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/crc_i386.S (revision 5)
@@ -0,0 +1,307 @@
+/*
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * crc_i386.S, optimized CRC calculation function for Zip and UnZip,
+ * created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007.
+ *
+ * GRR 961110: incorporated Scott Field optimizations from win32/crc_i386.asm
+ * => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
+ *
+ * SPC 970402: revised for Rodney Brown's optimizations (32-bit-wide
+ * aligned reads for most of the data from buffer), can be
+ * disabled by defining the macro NO_32_BIT_LOADS
+ *
+ * SPC 971012: added Rodney Brown's additional tweaks for 32-bit-optimized
+ * CPUs (like the Pentium Pro, Pentium II, and probably some
+ * Pentium clones). This optimization is controlled by the
+ * preprocessor switch "__686" and is disabled by default.
+ * (This default is based on the assumption that most users
+ * do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * COS 050116: Enabled the 686 build by default, because there are hardly any
+ * pre-686 CPUs in serious use nowadays. (See SPC 970402 above.)
+ *
+ * SPC 060103: Updated code to incorporate newer optimizations found in zlib.
+ *
+ * SPC 070107: Added conditional switch to deactivate crc32() compilation.
+ *
+ * FLAT memory model assumed. Calling interface:
+ * - args are pushed onto the stack from right to left,
+ * - return value is given in the EAX register,
+ * - all other registers (with exception of EFLAGS) are preserved. (With
+ * GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
+ * them nevertheless adds only 4 single byte instructions.)
+ *
+ * This source generates the function
+ * ulg crc32(ulg crc, ZCONST uch *buf, extent len).
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ */
+
+/* This file is NOT used in conjunction with zlib, or when only creation of
+ * the basic CRC_32_Table (for other purpose) is requested.
+ */
+#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+# define _crc32 crc32
+# define _get_crc_table get_crc_table
+#endif
+/* Use 16-byte alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+# define ALIGNMENT .align 4,0x90
+#endif
+
+#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
+
+/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to use the C version,
+ * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
+ */
+
+ .file "crc_i386.S"
+
+#if !defined(PRE_686) && !defined(__686)
+ /* Optimize for Pentium Pro and compatible CPUs by default. */
+# define __686
+#endif
+
+#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
+# undef USE_STACKFRAME
+#else
+ /* The default is to use standard stack frame entry, because it
+ * results in smaller code!
+ */
+# ifndef USE_STD_STACKFRAME
+# define USE_STD_STACKFRAME
+# endif
+#endif
+
+#ifdef USE_STD_STACKFRAME
+# define _STD_ENTRY pushl %ebp ; movl %esp,%ebp
+# define arg1 8(%ebp)
+# define arg2 12(%ebp)
+# define arg3 16(%ebp)
+# define _STD_LEAVE popl %ebp
+#else /* !USE_STD_STACKFRAME */
+# define _STD_ENTRY
+# define arg1 24(%esp)
+# define arg2 28(%esp)
+# define arg3 32(%esp)
+# define _STD_LEAVE
+#endif /* ?USE_STD_STACKFRAME */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ * eax : crc value "c"
+ * esi : pointer to next data byte (or lword) "buf++"
+ * registers read:
+ * edi : pointer to base of crc_table array
+ * scratch registers:
+ * ebx : index into crc_table array
+ * (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686 /* optimize for 386, 486, Pentium */
+#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
+ movb %al, %bl ;/* tmp = c & 0xFF */\
+ shrl $8, %eax ;/* c = (c >> 8) */\
+ xorl (%edi, %ebx, 4), %eax ;/* c ^= table[tmp] */
+#else /* __686 : optimize for Pentium Pro and compatible CPUs */
+#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
+ movzbl %al, %ebx ;/* tmp = c & 0xFF */\
+ shrl $8, %eax ;/* c = (c >> 8) */\
+ xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */
+#endif /* ?__686 */
+
+#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+ xorb (%esi), %al ;/* c ^= *buf */\
+ incl %esi ;/* buf++ */\
+ Do_CRC
+
+#define Do_CRC_byteof(ofs) /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+ xorb ofs(%esi), %al ;/* c ^= *buf */\
+ incl %esi ;/* buf++ */\
+ Do_CRC
+
+#ifndef NO_32_BIT_LOADS
+# ifdef IZ_CRCOPTIM_UNFOLDTBL
+ /* the edx register is needed in crc calculation */
+# define SavLen arg3
+# define UpdCRC_lword \
+ movzbl %al, %ebx ; \
+ movl 3072(%edi,%ebx,4), %edx ; \
+ movzbl %ah, %ebx ; \
+ shrl $16, %eax ; \
+ xor 2048(%edi,%ebx,4), %edx ; \
+ movzbl %al, %ebx ; \
+ shrl $8,%eax ; \
+ xorl 1024(%edi,%ebx,4), %edx ; \
+ movl (%edi,%eax,4), %eax ; \
+ xorl %edx,%eax ;
+# define UpdCRC_lword_sh(dwPtrIncr) \
+ movzbl %al, %ebx ; \
+ movl 3072(%edi,%ebx,4), %edx ; \
+ movzbl %ah, %ebx ; \
+ shrl $16, %eax ; \
+ xor 2048(%edi,%ebx,4), %edx ; \
+ movzbl %al, %ebx ; \
+ addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)+=dwPtrIncr */\
+ shrl $8,%eax ; \
+ xorl 1024(%edi,%ebx,4), %edx ; \
+ movl (%edi,%eax,4),%eax ; \
+ xorl %edx,%eax ;
+# else /* !IZ_CRCOPTIM_UNFOLDTBL */
+ /* the edx register is not needed anywhere else */
+# define SavLen %edx
+# define UpdCRC_lword \
+ Do_CRC \
+ Do_CRC \
+ Do_CRC \
+ Do_CRC
+# define UpdCRC_lword_sh(dwPtrIncr) \
+ Do_CRC \
+ Do_CRC \
+ addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)++ */\
+ Do_CRC \
+ Do_CRC
+# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+#define Do_CRC_lword \
+ xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
+ UpdCRC_lword_sh(1) /* ... ((ulg *)buf)++ */
+#define Do_CRC_4lword \
+ xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
+ UpdCRC_lword \
+ xorl 4(%esi), %eax ;/* c ^= *((ulg *)buf+1) */\
+ UpdCRC_lword \
+ xorl 8(%esi), %eax ;/* c ^= *((ulg *)buf+2) */\
+ UpdCRC_lword \
+ xorl 12(%esi), %eax ;/* c ^= *((ulg *)buf]+3 */\
+ UpdCRC_lword_sh(4) /* ... ((ulg *)buf)+=4 */
+#endif /* !NO_32_BIT_LOADS */
+
+
+ .text
+
+ .globl _crc32
+
+_crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */
+ _STD_ENTRY
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %edx
+ pushl %ecx
+
+ movl arg2, %esi /* 2nd arg: uch *buf */
+ subl %eax, %eax /* > if (!buf) */
+ testl %esi, %esi /* > return 0; */
+ jz .L_fine /* > else { */
+ call _get_crc_table
+ movl %eax, %edi
+ movl arg1, %eax /* 1st arg: ulg crc */
+#ifndef __686
+ subl %ebx, %ebx /* ebx=0; bl usable as dword */
+#endif
+ movl arg3, %ecx /* 3rd arg: extent len */
+ notl %eax /* > c = ~crc; */
+
+ testl %ecx, %ecx
+#ifndef NO_UNROLLED_LOOPS
+ jz .L_bail
+# ifndef NO_32_BIT_LOADS
+ /* Assert now have positive length */
+.L_align_loop:
+ testl $3, %esi /* Align buf on lword boundary */
+ jz .L_aligned_now
+ Do_CRC_byte
+ decl %ecx
+ jnz .L_align_loop
+.L_aligned_now:
+# endif /* !NO_32_BIT_LOADS */
+ movl %ecx, SavLen /* save current value of len */
+ shrl $4, %ecx /* ecx = len / 16 */
+ jz .L_No_Sixteens
+/* align loop head at start of 486 internal cache line !! */
+ ALIGNMENT
+.L_Next_Sixteen:
+# ifndef NO_32_BIT_LOADS
+ Do_CRC_4lword
+# else /* NO_32_BIT_LOADS */
+ Do_CRC_byteof(0)
+ Do_CRC_byteof(1)
+ Do_CRC_byteof(2)
+ Do_CRC_byteof(3)
+ Do_CRC_byteof(4)
+ Do_CRC_byteof(5)
+ Do_CRC_byteof(6)
+ Do_CRC_byteof(7)
+ Do_CRC_byteof(8)
+ Do_CRC_byteof(9)
+ Do_CRC_byteof(10)
+ Do_CRC_byteof(11)
+ Do_CRC_byteof(12)
+ Do_CRC_byteof(13)
+ Do_CRC_byteof(14)
+ Do_CRC_byteof(15)
+ addl $16,%esi ;/* buf += 16 */
+# endif /* ?NO_32_BIT_LOADS */
+ decl %ecx
+ jnz .L_Next_Sixteen
+
+.L_No_Sixteens:
+ movl SavLen, %ecx
+ andl $15, %ecx /* ecx = len % 16 */
+# ifndef NO_32_BIT_LOADS
+ shrl $2,%ecx /* ecx = len / 4 */
+ jz .L_No_Fours
+.L_Next_Four:
+ Do_CRC_lword
+ decl %ecx
+ jnz .L_Next_Four
+.L_No_Fours:
+ movl SavLen,%ecx
+ andl $3,%ecx /* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
+#endif /* !NO_UNROLLED_LOOPS */
+ jz .L_bail /* > if (len) */
+/* align loop head at start of 486 internal cache line !! */
+ ALIGNMENT
+.L_loupe: /* > do { */
+ Do_CRC_byte /* c = CRC32(c,*buf++,crctab);*/
+ decl %ecx /* > } while (--len); */
+ jnz .L_loupe
+
+.L_bail: /* > } */
+ notl %eax /* > return ~c; */
+.L_fine:
+ popl %ecx
+ popl %edx
+ popl %ebx
+ popl %esi
+ popl %edi
+ _STD_LEAVE
+ ret
+
+#else
+ error: this asm version is for 386 only
+#endif /* i386 || _i386 || _I386 || __i386 */
+
+#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: unzip/create-6.0-slackware-patch/unzip60-new/crypt.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/crypt.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/crypt.c (revision 5)
@@ -0,0 +1,663 @@
+/*
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2005-Feb-10 or later
+ (the contents of which are also included in (un)zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ The main encryption/decryption source code for Info-Zip software was
+ originally written in Europe. To the best of our knowledge, it can
+ be freely distributed in both source and object forms from any country,
+ including the USA under License Exception TSU of the U.S. Export
+ Administration Regulations (section 740.13(e)) of 6 June 2002.
+
+ NOTE on copyright history:
+ Previous versions of this source package (up to version 2.8) were
+ not copyrighted and put in the public domain. If you cannot comply
+ with the Info-Zip LICENSE, you may want to look for one of those
+ public domain versions.
+ */
+
+/*
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+ */
+
+#define ZCRYPT_INTERNAL
+#include "zip.h"
+#include "crypt.h"
+#include "ttyio.h"
+
+#if CRYPT
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifdef ZIP
+ /* For the encoding task used in Zip (and ZipCloak), we want to initialize
+ the crypt algorithm with some reasonably unpredictable bytes, see
+ the crypthead() function. The standard rand() library function is
+ used to supply these `random' bytes, which in turn is initialized by
+ a srand() call. The srand() function takes an "unsigned" (at least 16bit)
+ seed value as argument to determine the starting point of the rand()
+ pseudo-random number generator.
+ This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
+ Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
+ as some (hopefully) nondeterministic bitmask. On many (most) systems,
+ we use some "process specific" number, as the PID or something similar,
+ but when nothing unpredictable is available, a fixed number may be
+ sufficient.
+ NOTE:
+ 1.) This implementation requires the availability of the following
+ standard UNIX C runtime library functions: time(), rand(), srand().
+ On systems where some of them are missing, the environment that
+ incorporates the crypt routines must supply suitable replacement
+ functions.
+ 2.) It is a very bad idea to use a second call to time() to set the
+ "Seed2" number! In this case, both "Seed1" and "Seed2" would be
+ (almost) identical, resulting in a (mostly) "zero" constant seed
+ number passed to srand().
+
+ The implementation environment defined in the "zip.h" header should
+ supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
+ most implementations of rand() and srand(), only the lower 16 bits are
+ significant!). An example that works on many systems would be
+ "#define ZCR_SEED2 (unsigned)getpid()".
+ The default definition for ZCR_SEED2 supplied below should be regarded
+ as a fallback to allow successful compilation in "beta state"
+ environments.
+ */
+# include <time.h> /* time() function supplies first part of crypt seed */
+ /* "last resort" source for second part of crypt seed pattern */
+# ifndef ZCR_SEED2
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
+# endif
+# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
+# undef GLOBAL
+# endif
+# define GLOBAL(g) g
+#else /* !ZIP */
+# define GLOBAL(g) G.g
+#endif /* ?ZIP */
+
+
+#ifdef UNZIP
+ /* char *key = (char *)NULL; moved to globals.h */
+# ifndef FUNZIP
+ local int testp OF((__GPRO__ ZCONST uch *h));
+ local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
+# endif
+#endif /* UNZIP */
+
+#ifndef UNZIP /* moved to globals.h for UnZip */
+# ifndef Z_UINT4_DEFINED
+# if !defined(NO_LIMITS_H)
+# if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
+ typedef unsigned int z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
+ typedef unsigned long z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
+ typedef unsigned short z_uint4;
+# define Z_UINT4_DEFINED
+# endif
+# endif
+# endif
+# endif /* !NO_LIMITS_H */
+# endif /* !Z_UINT4_DEFINED */
+# ifndef Z_UINT4_DEFINED
+ typedef ulg z_uint4;
+# define Z_UINT4_DEFINED
+# endif
+ local z_uint4 keys[3]; /* keys defining the pseudo-random sequence */
+#endif /* !UNZIP */
+
+#ifndef Trace
+# ifdef CRYPT_DEBUG
+# define Trace(x) fprintf x
+# else
+# define Trace(x)
+# endif
+#endif
+
+#include "crc32.h"
+
+#ifdef IZ_CRC_BE_OPTIMIZ
+ local z_uint4 near crycrctab[256];
+ local z_uint4 near *cry_crctb_p = NULL;
+ local z_uint4 near *crytab_init OF((__GPRO));
+# define CRY_CRC_TAB cry_crctb_p
+# undef CRC32
+# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+#else
+# define CRY_CRC_TAB CRC_32_TAB
+#endif /* ?IZ_CRC_BE_OPTIMIZ */
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+int decrypt_byte(__G)
+ __GDEF
+{
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ * unpredictable manner on 16-bit systems; not a problem
+ * with any known compiler so far, though */
+
+ temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+int update_keys(__G__ c)
+ __GDEF
+ int c; /* byte of plain text */
+{
+ GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB);
+ GLOBAL(keys[1]) = (GLOBAL(keys[1])
+ + (GLOBAL(keys[0]) & 0xff))
+ * 134775813L + 1;
+ {
+ register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
+ GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
+ }
+ return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+void init_keys(__G__ passwd)
+ __GDEF
+ ZCONST char *passwd; /* password string with which to modify keys */
+{
+#ifdef IZ_CRC_BE_OPTIMIZ
+ if (cry_crctb_p == NULL) {
+ cry_crctb_p = crytab_init(__G);
+ }
+#endif
+ GLOBAL(keys[0]) = 305419896L;
+ GLOBAL(keys[1]) = 591751049L;
+ GLOBAL(keys[2]) = 878082192L;
+ while (*passwd != '\0') {
+ update_keys(__G__ (int)*passwd);
+ passwd++;
+ }
+}
+
+
+/***********************************************************************
+ * Initialize the local copy of the table of precomputed crc32 values.
+ * Whereas the public crc32-table is optimized for crc32 calculations
+ * on arrays of bytes, the crypt code needs the crc32 values in an
+ * byte-order-independent form as 32-bit unsigned numbers. On systems
+ * with Big-Endian byte order using the optimized crc32 code, this
+ * requires inverting the byte-order of the values in the
+ * crypt-crc32-table.
+ */
+#ifdef IZ_CRC_BE_OPTIMIZ
+local z_uint4 near *crytab_init(__G)
+ __GDEF
+{
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ crycrctab[i] = REV_BE(CRC_32_TAB[i]);
+ }
+ return crycrctab;
+}
+#endif
+
+
+#ifdef ZIP
+
+/***********************************************************************
+ * Write encryption header to file zfile using the password passwd
+ * and the cyclic redundancy check crc.
+ */
+void crypthead(passwd, crc, zfile)
+ ZCONST char *passwd; /* password string */
+ ulg crc; /* crc of file being encrypted */
+ FILE *zfile; /* where to write header */
+{
+ int n; /* index in random header */
+ int t; /* temporary */
+ int c; /* random byte */
+ uch header[RAND_HEAD_LEN]; /* random header */
+ static unsigned calls = 0; /* ensure different random header each time */
+
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ * output of rand() to get less predictability, since rand() is
+ * often poorly implemented.
+ */
+ if (++calls == 1) {
+ srand((unsigned)time(NULL) ^ ZCR_SEED2);
+ }
+ init_keys(passwd);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+ c = (rand() >> 7) & 0xff;
+ header[n] = (uch)zencode(c, t);
+ }
+ /* Encrypt random header (last two bytes is high word of crc) */
+ init_keys(passwd);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+ header[n] = (uch)zencode(header[n], t);
+ }
+ header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t);
+ header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t);
+ fwrite(header, 1, RAND_HEAD_LEN, f);
+}
+
+
+#ifdef UTIL
+
+/***********************************************************************
+ * Encrypt the zip entry described by z from file source to file dest
+ * using the password passwd. Return an error code in the ZE_ class.
+ */
+int zipcloak(z, source, dest, passwd)
+ struct zlist far *z; /* zip entry to encrypt */
+ FILE *source, *dest; /* source and destination files */
+ ZCONST char *passwd; /* password string */
+{
+ int c; /* input byte */
+ int res; /* result code */
+ ulg n; /* holds offset and counts size */
+ ush flag; /* previous flags */
+ int t; /* temporary */
+ int ztemp; /* temporary storage for zencode value */
+
+ /* Set encrypted bit, clear extended local header bit and write local
+ header to output file */
+ if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+ z->off = n;
+ flag = z->flg;
+ z->flg |= 1, z->flg &= ~8;
+ z->lflg |= 1, z->lflg &= ~8;
+ z->siz += RAND_HEAD_LEN;
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+ /* Initialize keys with password and write random header */
+ crypthead(passwd, z->crc, dest);
+
+ /* Skip local header in input file */
+ if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
+ SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+
+ /* Encrypt data */
+ for (n = z->siz - RAND_HEAD_LEN; n; n--) {
+ if ((c = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ ztemp = zencode(c, t);
+ putc(ztemp, dest);
+ }
+ /* Skip extended local header in input file if there is one */
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if (fflush(dest) == EOF) return ZE_TEMP;
+
+ /* Update number of bytes written to output file */
+ tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
+
+ return ZE_OK;
+}
+
+/***********************************************************************
+ * Decrypt the zip entry described by z from file source to file dest
+ * using the password passwd. Return an error code in the ZE_ class.
+ */
+int zipbare(z, source, dest, passwd)
+ struct zlist far *z; /* zip entry to encrypt */
+ FILE *source, *dest; /* source and destination files */
+ ZCONST char *passwd; /* password string */
+{
+#ifdef ZIP10
+ int c0 /* byte preceding the last input byte */
+#endif
+ int c1; /* last input byte */
+ ulg offset; /* used for file offsets */
+ ulg size; /* size of input data */
+ int r; /* size of encryption header */
+ int res; /* return code */
+ ush flag; /* previous flags */
+
+ /* Save position and skip local header in input file */
+ if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
+ fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
+ SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ /* Initialize keys with password */
+ init_keys(passwd);
+
+ /* Decrypt encryption header, save last two bytes */
+ c1 = 0;
+ for (r = RAND_HEAD_LEN; r; r--) {
+#ifdef ZIP10
+ c0 = c1;
+#endif
+ if ((c1 = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ Trace((stdout, " (%02x)", c1));
+ zdecode(c1);
+ Trace((stdout, " %02x", c1));
+ }
+ Trace((stdout, "\n"));
+
+ /* If last two bytes of header don't match crc (or file time in the
+ * case of an extended local header), back up and just copy. For
+ * pkzip 2.0, the check has been reduced to one byte only.
+ */
+#ifdef ZIP10
+ if ((ush)(c0 | (c1<<8)) !=
+ (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
+#else
+ if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
+#endif
+ if (fseek(source, offset, SEEK_SET)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
+ return ZE_MISS;
+ }
+
+ /* Clear encrypted bit and local header bit, and write local header to
+ output file */
+ if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+ z->off = offset;
+ flag = z->flg;
+ z->flg &= ~9;
+ z->lflg &= ~9;
+ z->siz -= RAND_HEAD_LEN;
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+ /* Decrypt data */
+ for (size = z->siz; size; size--) {
+ if ((c1 = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ zdecode(c1);
+ putc(c1, dest);
+ }
+ /* Skip extended local header in input file if there is one */
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if (fflush(dest) == EOF) return ZE_TEMP;
+
+ /* Update number of bytes written to output file */
+ tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
+
+ return ZE_OK;
+}
+
+
+#else /* !UTIL */
+
+/***********************************************************************
+ * If requested, encrypt the data in buf, and in any case call fwrite()
+ * with the arguments to zfwrite(). Return what fwrite() returns.
+ *
+ * A bug has been found when encrypting large files. See trees.c
+ * for details and the fix.
+ */
+unsigned zfwrite(buf, item_size, nb, f)
+ zvoid *buf; /* data buffer */
+ extent item_size; /* size of each item in bytes */
+ extent nb; /* number of items */
+ FILE *f; /* file to write to */
+{
+ int t; /* temporary */
+
+ if (key != (char *)NULL) { /* key is the global password pointer */
+ ulg size; /* buffer size */
+ char *p = (char*)buf; /* steps through buffer */
+
+ /* Encrypt data in buffer */
+ for (size = item_size*(ulg)nb; size != 0; p++, size--) {
+ *p = (char)zencode(*p, t);
+ }
+ }
+ /* Write the buffer out */
+ return fwrite(buf, item_size, nb, f);
+}
+
+#endif /* ?UTIL */
+#endif /* ZIP */
+
+
+#if (defined(UNZIP) && !defined(FUNZIP))
+
+/***********************************************************************
+ * Get the password and set up keys for current zipfile member.
+ * Return PK_ class error.
+ */
+int decrypt(__G__ passwrd)
+ __GDEF
+ ZCONST char *passwrd;
+{
+ ush b;
+ int n, r;
+ uch h[RAND_HEAD_LEN];
+
+ Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
+
+ /* get header once (turn off "encrypted" flag temporarily so we don't
+ * try to decrypt the same data twice) */
+ GLOBAL(pInfo->encrypted) = FALSE;
+ defer_leftover_input(__G);
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
+ /* 2012-11-23 SMS. (OUSPG report.)
+ * Quit early if compressed size < HEAD_LEN. The resulting
+ * error message ("unable to get password") could be improved,
+ * but it's better than trying to read nonexistent data, and
+ * then continuing with a negative G.csize. (See
+ * fileio.c:readbyte()).
+ */
+ if ((b = NEXTBYTE) == (ush)EOF)
+ {
+ return PK_ERR;
+ }
+ h[n] = (uch)b;
+ Trace((stdout, " (%02x)", h[n]));
+ }
+ undefer_input(__G);
+ GLOBAL(pInfo->encrypted) = TRUE;
+
+ if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
+ GLOBAL(newzip) = FALSE;
+ if (passwrd != (char *)NULL) { /* user gave password on command line */
+ if (!GLOBAL(key)) {
+ if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
+ (char *)NULL)
+ return PK_MEM2;
+ strcpy(GLOBAL(key), passwrd);
+ GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
+ }
+ } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
+ free(GLOBAL(key));
+ GLOBAL(key) = (char *)NULL;
+ }
+ }
+
+ /* if have key already, test it; else allocate memory for it */
+ if (GLOBAL(key)) {
+ if (!testp(__G__ h))
+ return PK_COOL; /* existing password OK (else prompt for new) */
+ else if (GLOBAL(nopwd))
+ return PK_WARN; /* user indicated no more prompting */
+ } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
+ return PK_MEM2;
+
+ /* try a few keys */
+ n = 0;
+ do {
+ r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
+ GLOBAL(zipfn), GLOBAL(filename));
+ if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
+ free (GLOBAL(key));
+ GLOBAL(key) = NULL;
+ return PK_MEM2;
+ }
+ if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
+ *GLOBAL(key) = '\0'; /* We try the NIL password, ... */
+ n = 0; /* and cancel fetch for this item. */
+ }
+ if (!testp(__G__ h))
+ return PK_COOL;
+ if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
+ GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
+ } while (n > 0);
+
+ return PK_WARN;
+
+} /* end function decrypt() */
+
+
+
+/***********************************************************************
+ * Test the password. Return -1 if bad, 0 if OK.
+ */
+local int testp(__G__ h)
+ __GDEF
+ ZCONST uch *h;
+{
+ int r;
+ char *key_translated;
+
+ /* On systems with "obscure" native character coding (e.g., EBCDIC),
+ * the first test translates the password to the "main standard"
+ * character coding. */
+
+#ifdef STR_TO_CP1
+ /* allocate buffer for translated password */
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+ return -1;
+ /* first try, test password translated "standard" charset */
+ r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
+#else /* !STR_TO_CP1 */
+ /* first try, test password as supplied on the extractor's host */
+ r = testkey(__G__ h, GLOBAL(key));
+#endif /* ?STR_TO_CP1 */
+
+#ifdef STR_TO_CP2
+ if (r != 0) {
+#ifndef STR_TO_CP1
+ /* now prepare for second (and maybe third) test with translated pwd */
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+ return -1;
+#endif
+ /* second try, password translated to alternate ("standard") charset */
+ r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
+#ifdef STR_TO_CP3
+ if (r != 0)
+ /* third try, password translated to another "standard" charset */
+ r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
+#endif
+#ifndef STR_TO_CP1
+ free(key_translated);
+#endif
+ }
+#endif /* STR_TO_CP2 */
+
+#ifdef STR_TO_CP1
+ free(key_translated);
+ if (r != 0) {
+ /* last resort, test password as supplied on the extractor's host */
+ r = testkey(__G__ h, GLOBAL(key));
+ }
+#endif /* STR_TO_CP1 */
+
+ return r;
+
+} /* end function testp() */
+
+
+local int testkey(__G__ h, key)
+ __GDEF
+ ZCONST uch *h; /* decrypted header */
+ ZCONST char *key; /* decryption password to test */
+{
+ ush b;
+#ifdef ZIP10
+ ush c;
+#endif
+ int n;
+ uch *p;
+ uch hh[RAND_HEAD_LEN]; /* decrypted header */
+
+ /* set keys and save the encrypted header */
+ init_keys(__G__ key);
+ memcpy(hh, h, RAND_HEAD_LEN);
+
+ /* check password */
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
+ zdecode(hh[n]);
+ Trace((stdout, " %02x", hh[n]));
+ }
+
+ Trace((stdout,
+ "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
+ GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
+ GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
+ Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
+ GLOBAL(incnt),
+ GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
+
+ /* same test as in zipbare(): */
+
+#ifdef ZIP10 /* check two bytes */
+ c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
+ Trace((stdout,
+ " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
+ (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
+ if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
+ (ush)(GLOBAL(lrec.crc32) >> 16)))
+ return -1; /* bad */
+#else
+ b = hh[RAND_HEAD_LEN-1];
+ Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
+ b, (ush)(GLOBAL(lrec.crc32) >> 24),
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
+ if (b != (GLOBAL(pInfo->ExtLocHdr) ?
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
+ (ush)(GLOBAL(lrec.crc32) >> 24)))
+ return -1; /* bad */
+#endif
+ /* password OK: decrypt current buffer contents before leaving */
+ for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
+ (int)GLOBAL(csize) : GLOBAL(incnt),
+ p = GLOBAL(inptr); n--; p++)
+ zdecode(*p);
+ return 0; /* OK */
+
+} /* end function testkey() */
+
+#endif /* UNZIP && !FUNZIP */
+
+#else /* !CRYPT */
+
+/* something "externally visible" to shut up compiler/linker warnings */
+int zcr_dummy;
+
+#endif /* ?CRYPT */
Index: unzip/create-6.0-slackware-patch/unzip60-new/extract.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/extract.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/extract.c (revision 5)
@@ -0,0 +1,3031 @@
+/*
+ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ extract.c
+
+ This file contains the high-level routines ("driver routines") for extrac-
+ ting and testing zipfile members. It calls the low-level routines in files
+ explode.c, inflate.c, unreduce.c and unshrink.c.
+
+ Contains: extract_or_test_files()
+ store_info()
+ find_compr_idx()
+ extract_or_test_entrylist()
+ extract_or_test_member()
+ TestExtraField()
+ test_compr_eb()
+ memextract()
+ memflush()
+ extract_izvms_block() (VMS or VMS_TEXT_CONV)
+ set_deferred_symlink() (SYMLINKS only)
+ fnfilter()
+ dircomp() (SET_DIR_ATTRIB only)
+ UZbunzip2() (USE_BZIP2 only)
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __EXTRACT_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+#endif
+#include "crc32.h"
+#include "crypt.h"
+#include <wctype.h>
+
+#define GRRDUMP(buf,len) { \
+ int i, j; \
+ \
+ for (j = 0; j < (len)/16; ++j) { \
+ printf(" "); \
+ for (i = 0; i < 16; ++i) \
+ printf("%02x ", (uch)(buf)[i+(j<<4)]); \
+ printf("\n "); \
+ for (i = 0; i < 16; ++i) { \
+ char c = (char)(buf)[i+(j<<4)]; \
+ \
+ if (c == '\n') \
+ printf("\\n "); \
+ else if (c == '\r') \
+ printf("\\r "); \
+ else \
+ printf(" %c ", c); \
+ } \
+ printf("\n"); \
+ } \
+ if ((len) % 16) { \
+ printf(" "); \
+ for (i = j<<4; i < (len); ++i) \
+ printf("%02x ", (uch)(buf)[i]); \
+ printf("\n "); \
+ for (i = j<<4; i < (len); ++i) { \
+ char c = (char)(buf)[i]; \
+ \
+ if (c == '\n') \
+ printf("\\n "); \
+ else if (c == '\r') \
+ printf("\\r "); \
+ else \
+ printf(" %c ", c); \
+ } \
+ printf("\n"); \
+ } \
+}
+
+static int store_info OF((__GPRO));
+#ifdef SET_DIR_ATTRIB
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+ ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
+ unsigned *pnum_dirs, direntry **pdirlist,
+ int error_in_archive));
+#else
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+ ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
+ int error_in_archive));
+#endif
+static int extract_or_test_member OF((__GPRO));
+#ifndef SFX
+ static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
+ static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
+ unsigned compr_offset,
+ int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize)));
+#endif
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+ static void decompress_bits OF((uch *outptr, unsigned needlen,
+ ZCONST uch *bitptr));
+#endif
+#ifdef SYMLINKS
+ static void set_deferred_symlink OF((__GPRO__ slinkentry *slnk_entry));
+#endif
+#ifdef SET_DIR_ATTRIB
+ static int Cdecl dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
+#endif
+
+
+
+/*******************************/
+/* Strings used in extract.c */
+/*******************************/
+
+static ZCONST char Far VersionMsg[] =
+ " skipping: %-22s need %s compat. v%u.%u (can do v%u.%u)\n";
+static ZCONST char Far ComprMsgNum[] =
+ " skipping: %-22s unsupported compression method %u\n";
+#ifndef SFX
+ static ZCONST char Far ComprMsgName[] =
+ " skipping: %-22s `%s' method not supported\n";
+ static ZCONST char Far CmprNone[] = "store";
+ static ZCONST char Far CmprShrink[] = "shrink";
+ static ZCONST char Far CmprReduce[] = "reduce";
+ static ZCONST char Far CmprImplode[] = "implode";
+ static ZCONST char Far CmprTokenize[] = "tokenize";
+ static ZCONST char Far CmprDeflate[] = "deflate";
+ static ZCONST char Far CmprDeflat64[] = "deflate64";
+ static ZCONST char Far CmprDCLImplode[] = "DCL implode";
+ static ZCONST char Far CmprBzip[] = "bzip2";
+ static ZCONST char Far CmprLZMA[] = "LZMA";
+ static ZCONST char Far CmprIBMTerse[] = "IBM/Terse";
+ static ZCONST char Far CmprIBMLZ77[] = "IBM LZ77";
+ static ZCONST char Far CmprWavPack[] = "WavPack";
+ static ZCONST char Far CmprPPMd[] = "PPMd";
+ static ZCONST char Far *ComprNames[NUM_METHODS] = {
+ CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
+ CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode,
+ CmprBzip, CmprLZMA, CmprIBMTerse, CmprIBMLZ77, CmprWavPack, CmprPPMd
+ };
+ static ZCONST unsigned ComprIDs[NUM_METHODS] = {
+ STORED, SHRUNK, REDUCED1, REDUCED2, REDUCED3, REDUCED4,
+ IMPLODED, TOKENIZED, DEFLATED, ENHDEFLATED, DCLIMPLODED,
+ BZIPPED, LZMAED, IBMTERSED, IBMLZ77ED, WAVPACKED, PPMDED
+ };
+#endif /* !SFX */
+static ZCONST char Far FilNamMsg[] =
+ "%s: bad filename length (%s)\n";
+#ifndef SFX
+ static ZCONST char Far WarnNoMemCFName[] =
+ "%s: warning, no memory for comparison with local header\n";
+ static ZCONST char Far LvsCFNamMsg[] =
+ "%s: mismatching \"local\" filename (%s),\n\
+ continuing with \"central\" filename version\n";
+#endif /* !SFX */
+#if (!defined(SFX) && defined(UNICODE_SUPPORT))
+ static ZCONST char Far GP11FlagsDiffer[] =
+ "file #%lu (%s):\n\
+ mismatch between local and central GPF bit 11 (\"UTF-8\"),\n\
+ continuing with central flag (IsUTF8 = %d)\n";
+#endif /* !SFX && UNICODE_SUPPORT */
+static ZCONST char Far WrnStorUCSizCSizDiff[] =
+ "%s: ucsize %s <> csize %s for STORED entry\n\
+ continuing with \"compressed\" size value\n";
+static ZCONST char Far ExtFieldMsg[] =
+ "%s: bad extra field length (%s)\n";
+static ZCONST char Far OffsetMsg[] =
+ "file #%lu: bad zipfile offset (%s): %ld\n";
+static ZCONST char Far ExtractMsg[] =
+ "%8sing: %-22s %s%s";
+#ifndef SFX
+ static ZCONST char Far LengthMsg[] =
+ "%s %s: %s bytes required to uncompress to %s bytes;\n %s\
+ supposed to require %s bytes%s%s%s\n";
+#endif
+
+static ZCONST char Far BadFileCommLength[] = "%s: bad file comment length\n";
+static ZCONST char Far LocalHdrSig[] = "local header sig";
+static ZCONST char Far BadLocalHdr[] = "file #%lu: bad local header\n";
+static ZCONST char Far AttemptRecompensate[] =
+ " (attempting to re-compensate)\n";
+#ifndef SFX
+ static ZCONST char Far BackslashPathSep[] =
+ "warning: %s appears to use backslashes as path separators\n";
+#endif
+static ZCONST char Far AbsolutePathWarning[] =
+ "warning: stripped absolute path spec from %s\n";
+static ZCONST char Far SkipVolumeLabel[] =
+ " skipping: %-22s %svolume label\n";
+
+#ifdef SET_DIR_ATTRIB /* messages of code for setting directory attributes */
+ static ZCONST char Far DirlistEntryNoMem[] =
+ "warning: cannot alloc memory for dir times/permissions/UID/GID\n";
+ static ZCONST char Far DirlistSortNoMem[] =
+ "warning: cannot alloc memory to sort dir times/perms/etc.\n";
+ static ZCONST char Far DirlistSetAttrFailed[] =
+ "warning: set times/attribs failed for %s\n";
+ static ZCONST char Far DirlistFailAttrSum[] =
+ " failed setting times/attribs for %lu dir entries";
+#endif
+
+#ifdef SYMLINKS /* messages of the deferred symlinks handler */
+ static ZCONST char Far SymLnkWarnNoMem[] =
+ "warning: deferred symlink (%s) failed:\n\
+ out of memory\n";
+ static ZCONST char Far SymLnkWarnInvalid[] =
+ "warning: deferred symlink (%s) failed:\n\
+ invalid placeholder file\n";
+ static ZCONST char Far SymLnkDeferred[] =
+ "finishing deferred symbolic links:\n";
+ static ZCONST char Far SymLnkFinish[] =
+ " %-22s -> %s\n";
+#endif
+
+#ifndef WINDLL
+ static ZCONST char Far ReplaceQuery[] =
+# ifdef VMS
+ "new version of %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
+# else
+ "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
+# endif
+ static ZCONST char Far AssumeNone[] =
+ " NULL\n(EOF or read error, treating as \"[N]one\" ...)\n";
+ static ZCONST char Far NewNameQuery[] = "new name: ";
+ static ZCONST char Far InvalidResponse[] =
+ "error: invalid response [%s]\n";
+#endif /* !WINDLL */
+
+static ZCONST char Far ErrorInArchive[] =
+ "At least one %serror was detected in %s.\n";
+static ZCONST char Far ZeroFilesTested[] =
+ "Caution: zero files tested in %s.\n";
+
+#ifndef VMS
+ static ZCONST char Far VMSFormatQuery[] =
+ "\n%s: stored in VMS format. Extract anyway? (y/n) ";
+#endif
+
+#if CRYPT
+ static ZCONST char Far SkipCannotGetPasswd[] =
+ " skipping: %-22s unable to get password\n";
+ static ZCONST char Far SkipIncorrectPasswd[] =
+ " skipping: %-22s incorrect password\n";
+ static ZCONST char Far FilesSkipBadPasswd[] =
+ "%lu file%s skipped because of incorrect password.\n";
+ static ZCONST char Far MaybeBadPasswd[] =
+ " (may instead be incorrect password)\n";
+#else
+ static ZCONST char Far SkipEncrypted[] =
+ " skipping: %-22s encrypted (not supported)\n";
+#endif
+
+static ZCONST char Far NoErrInCompData[] =
+ "No errors detected in compressed data of %s.\n";
+static ZCONST char Far NoErrInTestedFiles[] =
+ "No errors detected in %s for the %lu file%s tested.\n";
+static ZCONST char Far FilesSkipped[] =
+ "%lu file%s skipped because of unsupported compression or encoding.\n";
+
+static ZCONST char Far ErrUnzipFile[] = " error: %s%s %s\n";
+static ZCONST char Far ErrUnzipNoFile[] = "\n error: %s%s\n";
+static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
+static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
+static ZCONST char Far Inflate[] = "inflate";
+#ifdef USE_BZIP2
+ static ZCONST char Far BUnzip[] = "bunzip";
+#endif
+
+#ifndef SFX
+ static ZCONST char Far Explode[] = "explode";
+#ifndef LZW_CLEAN
+ static ZCONST char Far Unshrink[] = "unshrink";
+#endif
+#endif
+
+#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
+ static ZCONST char Far FileTruncated[] =
+ "warning: %s is probably truncated\n";
+#endif
+
+static ZCONST char Far FileUnknownCompMethod[] =
+ "%s: unknown compression method\n";
+static ZCONST char Far BadCRC[] = " bad CRC %08lx (should be %08lx)\n";
+
+ /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
+char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
+char ZCONST Far TruncNTSD[] =
+ " compressed WinNT security data missing (%d bytes)%s";
+
+#ifndef SFX
+ static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
+ EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
+ static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
+ EF block length (%u bytes) invalid (< %d)\n";
+ static ZCONST char Far InvalidComprDataEAs[] =
+ " invalid compressed data for EAs\n";
+# if (defined(WIN32) && defined(NTSD_EAS))
+ static ZCONST char Far InvalidSecurityEAs[] =
+ " EAs fail security check\n";
+# endif
+ static ZCONST char Far UnsuppNTSDVersEAs[] =
+ " unsupported NTSD EAs version %d\n";
+ static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
+ static ZCONST char Far UnknComprMethodEAs[] =
+ " unknown compression method for EAs (%u)\n";
+ static ZCONST char Far NotEnoughMemEAs[] =
+ " out of memory while inflating EAs\n";
+ static ZCONST char Far UnknErrorEAs[] =
+ " unknown error on extended attributes\n";
+#endif /* !SFX */
+
+static ZCONST char Far UnsupportedExtraField[] =
+ "\nerror: unsupported extra-field compression type (%u)--skipping\n";
+static ZCONST char Far BadExtraFieldCRC[] =
+ "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
+
+
+
+
+
+/**************************************/
+/* Function extract_or_test_files() */
+/**************************************/
+
+int extract_or_test_files(__G) /* return PK-type error code */
+ __GDEF
+{
+ unsigned i, j;
+ zoff_t cd_bufstart;
+ uch *cd_inptr;
+ int cd_incnt;
+ ulg filnum=0L, blknum=0L;
+ int reached_end;
+#ifndef SFX
+ int no_endsig_found;
+#endif
+ int error, error_in_archive=PK_COOL;
+ int *fn_matched=NULL, *xn_matched=NULL;
+ zucn_t members_processed;
+ ulg num_skipped=0L, num_bad_pwd=0L;
+ zoff_t old_extra_bytes = 0L;
+#ifdef SET_DIR_ATTRIB
+ unsigned num_dirs=0;
+ direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
+#endif
+
+ /*
+ * First, two general initializations are applied. These have been moved
+ * here from process_zipfiles() because they are only needed for accessing
+ * and/or extracting the data content of the zip archive.
+ */
+
+ /* a) initialize the CRC table pointer (once) */
+ if (CRC_32_TAB == NULL) {
+ if ((CRC_32_TAB = get_crc_table()) == NULL) {
+ return PK_MEM;
+ }
+ }
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ /* b) check out if specified extraction root directory exists */
+ if (uO.exdir != (char *)NULL && G.extract_flag) {
+ G.create_dirs = !uO.fflag;
+ if ((error = checkdir(__G__ uO.exdir, ROOT)) > MPN_INF_SKIP) {
+ /* out of memory, or file in way */
+ return (error == MPN_NOMEM ? PK_MEM : PK_ERR);
+ }
+ }
+#endif /* !SFX || SFX_EXDIR */
+
+/*---------------------------------------------------------------------------
+ The basic idea of this function is as follows. Since the central di-
+ rectory lies at the end of the zipfile and the member files lie at the
+ beginning or middle or wherever, it is not very desirable to simply
+ read a central directory entry, jump to the member and extract it, and
+ then jump back to the central directory. In the case of a large zipfile
+ this would lead to a whole lot of disk-grinding, especially if each mem-
+ ber file is small. Instead, we read from the central directory the per-
+ tinent information for a block of files, then go extract/test the whole
+ block. Thus this routine contains two small(er) loops within a very
+ large outer loop: the first of the small ones reads a block of files
+ from the central directory; the second extracts or tests each file; and
+ the outer one loops over blocks. There's some file-pointer positioning
+ stuff in between, but that's about it. Btw, it's because of this jump-
+ ing around that we can afford to be lenient if an error occurs in one of
+ the member files: we should still be able to go find the other members,
+ since we know the offset of each from the beginning of the zipfile.
+ ---------------------------------------------------------------------------*/
+
+ G.pInfo = G.info;
+
+#if CRYPT
+ G.newzip = TRUE;
+#endif
+#ifndef SFX
+ G.reported_backslash = FALSE;
+#endif
+
+ /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
+ if (G.filespecs > 0 &&
+ (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
+ for (i = 0; i < G.filespecs; ++i)
+ fn_matched[i] = FALSE;
+ if (G.xfilespecs > 0 &&
+ (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
+ for (i = 0; i < G.xfilespecs; ++i)
+ xn_matched[i] = FALSE;
+
+/*---------------------------------------------------------------------------
+ Begin main loop over blocks of member files. We know the entire central
+ directory is on this disk: we would not have any of this information un-
+ less the end-of-central-directory record was on this disk, and we would
+ not have gotten to this routine unless this is also the disk on which
+ the central directory starts. In practice, this had better be the ONLY
+ disk in the archive, but we'll add multi-disk support soon.
+ ---------------------------------------------------------------------------*/
+
+ members_processed = 0;
+#ifndef SFX
+ no_endsig_found = FALSE;
+#endif
+ reached_end = FALSE;
+ while (!reached_end) {
+ j = 0;
+#ifdef AMIGA
+ memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
+#endif
+
+ /*
+ * Loop through files in central directory, storing offsets, file
+ * attributes, case-conversion and text-conversion flags until block
+ * size is reached.
+ */
+
+ while ((j < DIR_BLKSIZ)) {
+ G.pInfo = &G.info[j];
+
+ if (readbuf(__G__ G.sig, 4) == 0) {
+ error_in_archive = PK_EOF;
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a new entry? */
+ /* no new central directory entry
+ * -> is the number of processed entries compatible with the
+ * number of entries as stored in the end_central record?
+ */
+ if ((members_processed
+ & (G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+ == G.ecrec.total_entries_central_dir) {
+#ifndef SFX
+ /* yes, so look if we ARE back at the end_central record
+ */
+ no_endsig_found =
+ ( (memcmp(G.sig,
+ (G.ecrec.have_ecr64 ?
+ end_central64_sig : end_central_sig),
+ 4) != 0)
+ && (!G.ecrec.is_zip64_archive)
+ && (memcmp(G.sig, end_central_sig, 4) != 0)
+ );
+#endif /* !SFX */
+ } else {
+ /* no; we have found an error in the central directory
+ * -> report it and stop searching for more Zip entries
+ */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
+ error_in_archive = PK_BADERR;
+ }
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
+ if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
+ error_in_archive = error; /* only PK_EOF defined */
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+ PK_COOL)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal: no more left to do */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilNamMsg),
+ FnFilter1(G.filename), "central"));
+ reached_end = TRUE;
+ break;
+ }
+ }
+ if ((error = do_string(__G__ G.crec.extra_field_length,
+ EXTRA_FIELD)) != 0)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtFieldMsg),
+ FnFilter1(G.filename), "central"));
+ reached_end = TRUE;
+ break;
+ }
+ }
+#ifdef AMIGA
+ G.filenote_slot = j;
+ if ((error = do_string(__G__ G.crec.file_comment_length,
+ uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
+#else
+ if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
+ != PK_COOL)
+#endif
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal */
+ Info(slide, 0x421, ((char *)slide,
+ LoadFarString(BadFileCommLength),
+ FnFilter1(G.filename)));
+ reached_end = TRUE;
+ break;
+ }
+ }
+ if (G.process_all_files) {
+ if (store_info(__G))
+ ++j; /* file is OK; info[] stored; continue with next */
+ else
+ ++num_skipped;
+ } else {
+ int do_this_file;
+
+ if (G.filespecs == 0)
+ do_this_file = TRUE;
+ else { /* check if this entry matches an `include' argument */
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+ do_this_file = TRUE; /* ^-- ignore case or not? */
+ if (fn_matched)
+ fn_matched[i] = TRUE;
+ break; /* found match, so stop looping */
+ }
+ }
+ if (do_this_file) { /* check if this is an excluded file */
+ for (i = 0; i < G.xfilespecs; i++)
+ if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+ do_this_file = FALSE; /* ^-- ignore case or not? */
+ if (xn_matched)
+ xn_matched[i] = TRUE;
+ break;
+ }
+ }
+ if (do_this_file) {
+ if (store_info(__G))
+ ++j; /* file is OK */
+ else
+ ++num_skipped; /* unsupp. compression or encryption */
+ }
+ } /* end if (process_all_files) */
+
+ members_processed++;
+
+ } /* end while-loop (adding files to current block) */
+
+ /* save position in central directory so can come back later */
+ cd_bufstart = G.cur_zipfile_bufstart;
+ cd_inptr = G.inptr;
+ cd_incnt = G.incnt;
+
+ /*-----------------------------------------------------------------------
+ Second loop: process files in current block, extracting or testing
+ each one.
+ -----------------------------------------------------------------------*/
+
+ error = extract_or_test_entrylist(__G__ j,
+ &filnum, &num_bad_pwd, &old_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+ &num_dirs, &dirlist,
+#endif
+ error_in_archive);
+ if (error != PK_COOL) {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ /* ...and keep going (unless disk full or user break) */
+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+ /* clear reached_end to signal premature stop ... */
+ reached_end = FALSE;
+ /* ... and cancel scanning the central directory */
+ break;
+ }
+ }
+
+
+ /*
+ * Jump back to where we were in the central directory, then go and do
+ * the next batch of files.
+ */
+
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, cd_bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart =
+ zlseek(G.zipfd, cd_bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ read(G.zipfd, (char *)G.inbuf, INBUFSIZ); /* been here before... */
+ G.inptr = cd_inptr;
+ G.incnt = cd_incnt;
+ ++blknum;
+
+#ifdef TEST
+ printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
+ printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
+ cur_zipfile_bufstart);
+ printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
+ printf("incnt = %d\n\n", G.incnt);
+#endif
+
+ } /* end while-loop (blocks of files in central directory) */
+
+/*---------------------------------------------------------------------------
+ Process the list of deferred symlink extractions and finish up
+ the symbolic links.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SYMLINKS
+ if (G.slink_last != NULL) {
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, LoadFarString(SymLnkDeferred)));
+ while (G.slink_head != NULL) {
+ set_deferred_symlink(__G__ G.slink_head);
+ /* remove the processed entry from the chain and free its memory */
+ G.slink_last = G.slink_head;
+ G.slink_head = G.slink_last->next;
+ free(G.slink_last);
+ }
+ G.slink_last = NULL;
+ }
+#endif /* SYMLINKS */
+
+/*---------------------------------------------------------------------------
+ Go back through saved list of directories, sort and set times/perms/UIDs
+ and GIDs from the deepest level on up.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SET_DIR_ATTRIB
+ if (num_dirs > 0) {
+ sorted_dirlist = (direntry **)malloc(num_dirs*sizeof(direntry *));
+ if (sorted_dirlist == (direntry **)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(DirlistSortNoMem)));
+ while (dirlist != (direntry *)NULL) {
+ direntry *d = dirlist;
+
+ dirlist = dirlist->next;
+ free(d);
+ }
+ } else {
+ ulg ndirs_fail = 0;
+
+ if (num_dirs == 1)
+ sorted_dirlist[0] = dirlist;
+ else {
+ for (i = 0; i < num_dirs; ++i) {
+ sorted_dirlist[i] = dirlist;
+ dirlist = dirlist->next;
+ }
+ qsort((char *)sorted_dirlist, num_dirs, sizeof(direntry *),
+ dircomp);
+ }
+
+ Trace((stderr, "setting directory times/perms/attributes\n"));
+ for (i = 0; i < num_dirs; ++i) {
+ direntry *d = sorted_dirlist[i];
+
+ Trace((stderr, "dir = %s\n", d->fn));
+ if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
+ ndirs_fail++;
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(DirlistSetAttrFailed), d->fn));
+ if (!error_in_archive)
+ error_in_archive = error;
+ }
+ free(d);
+ }
+ free(sorted_dirlist);
+ if (!uO.tflag && QCOND2) {
+ if (ndirs_fail > 0)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(DirlistFailAttrSum), ndirs_fail));
+ }
+ }
+ }
+#endif /* SET_DIR_ATTRIB */
+
+/*---------------------------------------------------------------------------
+ Check for unmatched filespecs on command line and print warning if any
+ found. Free allocated memory. (But suppress check when central dir
+ scan was interrupted prematurely.)
+ ---------------------------------------------------------------------------*/
+
+ if (fn_matched) {
+ if (reached_end) for (i = 0; i < G.filespecs; ++i)
+ if (!fn_matched[i]) {
+#ifdef DLL
+ if (!G.redirect_data && !G.redirect_text)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameNotMatched), G.pfnames[i]));
+ else
+ setFileNotFound(__G);
+#else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(FilenameNotMatched), G.pfnames[i]));
+#endif
+ if (error_in_archive <= PK_WARN)
+ error_in_archive = PK_FIND; /* some files not found */
+ }
+ free((zvoid *)fn_matched);
+ }
+ if (xn_matched) {
+ if (reached_end) for (i = 0; i < G.xfilespecs; ++i)
+ if (!xn_matched[i])
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
+ free((zvoid *)xn_matched);
+ }
+
+/*---------------------------------------------------------------------------
+ Now, all locally allocated memory has been released. When the central
+ directory processing has been interrupted prematurely, it is safe to
+ return immediately. All completeness checks and summary messages are
+ skipped in this case.
+ ---------------------------------------------------------------------------*/
+ if (!reached_end)
+ return error_in_archive;
+
+/*---------------------------------------------------------------------------
+ Double-check that we're back at the end-of-central-directory record, and
+ print quick summary of results, if we were just testing the archive. We
+ send the summary to stdout so that people doing the testing in the back-
+ ground and redirecting to a file can just do a "tail" on the output file.
+ ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+ if (no_endsig_found) { /* just to make sure */
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(ReportMsg)));
+ if (!error_in_archive) /* don't overwrite stronger error */
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ if (uO.tflag) {
+ ulg num = filnum - num_bad_pwd;
+
+ if (uO.qflag < 2) { /* GRR 930710: was (uO.qflag == 1) */
+ if (error_in_archive)
+ Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
+ (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
+ else if (num == 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
+ G.zipfn));
+ else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
+ Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
+ G.zipfn));
+ else
+ Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
+ , G.zipfn, num, (num==1L)? "":"s"));
+ if (num_skipped > 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
+ num_skipped, (num_skipped==1L)? "":"s"));
+#if CRYPT
+ if (num_bad_pwd > 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
+ , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
+#endif /* CRYPT */
+ }
+ }
+
+ /* give warning if files not tested or extracted (first condition can still
+ * happen if zipfile is empty and no files specified on command line) */
+
+ if ((filnum == 0) && error_in_archive <= PK_WARN) {
+ if (num_skipped > 0L)
+ error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
+ else
+ error_in_archive = PK_FIND; /* no files found at all */
+ }
+#if CRYPT
+ else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
+ error_in_archive = IZ_BADPWD; /* bad passwd => all files skipped */
+#endif
+ else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
+ error_in_archive = IZ_UNSUP; /* was PK_WARN; Jean-loup complained */
+#if CRYPT
+ else if ((num_bad_pwd > 0L) && !error_in_archive)
+ error_in_archive = PK_WARN;
+#endif
+
+ return error_in_archive;
+
+} /* end function extract_or_test_files() */
+
+
+
+
+
+/***************************/
+/* Function store_info() */
+/***************************/
+
+static int store_info(__G) /* return 0 if skipping, 1 if OK */
+ __GDEF
+{
+#ifdef USE_BZIP2
+# define UNKN_BZ2 (G.crec.compression_method!=BZIPPED)
+#else
+# define UNKN_BZ2 TRUE /* bzip2 unknown */
+#endif
+
+#ifdef USE_LZMA
+# define UNKN_LZMA (G.crec.compression_method!=LZMAED)
+#else
+# define UNKN_LZMA TRUE /* LZMA unknown */
+#endif
+
+#ifdef USE_WAVP
+# define UNKN_WAVP (G.crec.compression_method!=WAVPACKED)
+#else
+# define UNKN_WAVP TRUE /* WavPack unknown */
+#endif
+
+#ifdef USE_PPMD
+# define UNKN_PPMD (G.crec.compression_method!=PPMDED)
+#else
+# define UNKN_PPMD TRUE /* PPMd unknown */
+#endif
+
+#ifdef SFX
+# ifdef USE_DEFLATE64
+# define UNKN_COMPR \
+ (G.crec.compression_method!=STORED && G.crec.compression_method<DEFLATED \
+ && G.crec.compression_method>ENHDEFLATED \
+ && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
+# else
+# define UNKN_COMPR \
+ (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED\
+ && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
+# endif
+#else
+# ifdef COPYRIGHT_CLEAN /* no reduced files */
+# define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
+ G.crec.compression_method <= REDUCED4)
+# else
+# define UNKN_RED FALSE /* reducing not unknown */
+# endif
+# ifdef LZW_CLEAN /* no shrunk files */
+# define UNKN_SHR (G.crec.compression_method == SHRUNK)
+# else
+# define UNKN_SHR FALSE /* unshrinking not unknown */
+# endif
+# ifdef USE_DEFLATE64
+# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+ G.crec.compression_method==TOKENIZED || \
+ (G.crec.compression_method>ENHDEFLATED && UNKN_BZ2 && UNKN_LZMA \
+ && UNKN_WAVP && UNKN_PPMD))
+# else
+# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+ G.crec.compression_method==TOKENIZED || \
+ (G.crec.compression_method>DEFLATED && UNKN_BZ2 && UNKN_LZMA \
+ && UNKN_WAVP && UNKN_PPMD))
+# endif
+#endif
+
+#if (defined(USE_BZIP2) && (UNZIP_VERSION < UNZIP_BZ2VERS))
+ int unzvers_support = (UNKN_BZ2 ? UNZIP_VERSION : UNZIP_BZ2VERS);
+# define UNZVERS_SUPPORT unzvers_support
+#else
+# define UNZVERS_SUPPORT UNZIP_VERSION
+#endif
+
+/*---------------------------------------------------------------------------
+ Check central directory info for version/compatibility requirements.
+ ---------------------------------------------------------------------------*/
+
+ G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1; /* bit field */
+ G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8; /* bit */
+ G.pInfo->textfile = G.crec.internal_file_attributes & 1; /* bit field */
+ G.pInfo->crc = G.crec.crc32;
+ G.pInfo->compr_size = G.crec.csize;
+ G.pInfo->uncompr_size = G.crec.ucsize;
+
+ switch (uO.aflag) {
+ case 0:
+ G.pInfo->textmode = FALSE; /* bit field */
+ break;
+ case 1:
+ G.pInfo->textmode = G.pInfo->textfile; /* auto-convert mode */
+ break;
+ default: /* case 2: */
+ G.pInfo->textmode = TRUE;
+ break;
+ }
+
+ if (G.crec.version_needed_to_extract[1] == VMS_) {
+ if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+ FnFilter1(G.filename), "VMS",
+ G.crec.version_needed_to_extract[0] / 10,
+ G.crec.version_needed_to_extract[0] % 10,
+ VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
+ return 0;
+ }
+#ifndef VMS /* won't be able to use extra field, but still have data */
+ else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
+ Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
+ FnFilter1(G.filename)));
+ fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
+ if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
+ return 0;
+ }
+#endif /* !VMS */
+ /* usual file type: don't need VMS to extract */
+ } else if (G.crec.version_needed_to_extract[0] > UNZVERS_SUPPORT) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+ FnFilter1(G.filename), "PK",
+ G.crec.version_needed_to_extract[0] / 10,
+ G.crec.version_needed_to_extract[0] % 10,
+ UNZVERS_SUPPORT / 10, UNZVERS_SUPPORT % 10));
+ return 0;
+ }
+
+ if (UNKN_COMPR) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
+#ifndef SFX
+ unsigned cmpridx;
+
+ if ((cmpridx = find_compr_idx(G.crec.compression_method))
+ < NUM_METHODS)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
+ FnFilter1(G.filename),
+ LoadFarStringSmall(ComprNames[cmpridx])));
+ else
+#endif
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
+ FnFilter1(G.filename),
+ G.crec.compression_method));
+ }
+ return 0;
+ }
+#if (!CRYPT)
+ if (G.pInfo->encrypted) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
+ FnFilter1(G.filename)));
+ return 0;
+ }
+#endif /* !CRYPT */
+
+#ifndef SFX
+ /* store a copy of the central header filename for later comparison */
+ if ((G.pInfo->cfilname = zfmalloc(strlen(G.filename) + 1)) == NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(WarnNoMemCFName),
+ FnFilter1(G.filename)));
+ } else
+ zfstrcpy(G.pInfo->cfilname, G.filename);
+#endif /* !SFX */
+
+ /* map whatever file attributes we have into the local format */
+ mapattr(__G); /* GRR: worry about return value later */
+
+ G.pInfo->diskstart = G.crec.disk_number_start;
+ G.pInfo->offset = (zoff_t)G.crec.relative_offset_local_header;
+ return 1;
+
+} /* end function store_info() */
+
+
+
+
+
+#ifndef SFX
+/*******************************/
+/* Function find_compr_idx() */
+/*******************************/
+
+unsigned find_compr_idx(compr_methodnum)
+ unsigned compr_methodnum;
+{
+ unsigned i;
+
+ for (i = 0; i < NUM_METHODS; i++) {
+ if (ComprIDs[i] == compr_methodnum) break;
+ }
+ return i;
+}
+#endif /* !SFX */
+
+
+
+
+
+/******************************************/
+/* Function extract_or_test_entrylist() */
+/******************************************/
+
+static int extract_or_test_entrylist(__G__ numchunk,
+ pfilnum, pnum_bad_pwd, pold_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+ pnum_dirs, pdirlist,
+#endif
+ error_in_archive) /* return PK-type error code */
+ __GDEF
+ unsigned numchunk;
+ ulg *pfilnum;
+ ulg *pnum_bad_pwd;
+ zoff_t *pold_extra_bytes;
+#ifdef SET_DIR_ATTRIB
+ unsigned *pnum_dirs;
+ direntry **pdirlist;
+#endif
+ int error_in_archive;
+{
+ unsigned i;
+ int renamed, query;
+ int skip_entry;
+ zoff_t bufstart, inbuf_offset, request;
+ int error, errcode;
+
+/* possible values for local skip_entry flag: */
+#define SKIP_NO 0 /* do not skip this entry */
+#define SKIP_Y_EXISTING 1 /* skip this entry, do not overwrite file */
+#define SKIP_Y_NONEXIST 2 /* skip this entry, do not create new file */
+
+ /*-----------------------------------------------------------------------
+ Second loop: process files in current block, extracting or testing
+ each one.
+ -----------------------------------------------------------------------*/
+
+ for (i = 0; i < numchunk; ++i) {
+ (*pfilnum)++; /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
+ G.pInfo = &G.info[i];
+#ifdef NOVELL_BUG_FAILSAFE
+ G.dne = FALSE; /* assume file exists until stat() says otherwise */
+#endif
+
+ /* if the target position is not within the current input buffer
+ * (either haven't yet read far enough, or (maybe) skipping back-
+ * ward), skip to the target position and reset readbuf(). */
+
+ /* seek_zipf(__G__ pInfo->offset); */
+ request = G.pInfo->offset + G.extra_bytes;
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+
+ Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
+ (long)request, (long)inbuf_offset));
+ Trace((stderr,
+ "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+ (long)bufstart, (long)G.cur_zipfile_bufstart));
+ if (request < 0) {
+ Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ error_in_archive = PK_ERR;
+ if (*pfilnum == 1 && G.extra_bytes != 0L) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AttemptRecompensate)));
+ *pold_extra_bytes = G.extra_bytes;
+ G.extra_bytes = 0L;
+ request = G.pInfo->offset; /* could also check if != 0 */
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+ Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
+ (long)request, (long)inbuf_offset));
+ Trace((stderr,
+ "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+ (long)bufstart, (long)G.cur_zipfile_bufstart));
+ /* try again */
+ if (request < 0) {
+ Trace((stderr,
+ "debug: recompensated request still < 0\n"));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ error_in_archive = PK_BADERR;
+ continue;
+ }
+ } else {
+ error_in_archive = PK_BADERR;
+ continue; /* this one hosed; try next */
+ }
+ }
+
+ if (bufstart != G.cur_zipfile_bufstart) {
+ Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart =
+ zlseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, "lseek", (long)bufstart));
+ error_in_archive = PK_BADERR;
+ continue; /* can still do next file */
+ }
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ G.incnt -= (int)inbuf_offset;
+ } else {
+ G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ }
+
+ /* should be in proper position now, so check for sig */
+ if (readbuf(__G__ G.sig, 4) == 0) { /* bad offset */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, "EOF", (long)request));
+ error_in_archive = PK_BADERR;
+ continue; /* but can still try next one */
+ }
+ if (memcmp(G.sig, local_hdr_sig, 4)) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, LoadFarStringSmall(LocalHdrSig), (long)request));
+ /*
+ GRRDUMP(G.sig, 4)
+ GRRDUMP(local_hdr_sig, 4)
+ */
+ error_in_archive = PK_ERR;
+ if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
+ (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AttemptRecompensate)));
+ if (G.extra_bytes) {
+ *pold_extra_bytes = G.extra_bytes;
+ G.extra_bytes = 0L;
+ } else
+ G.extra_bytes = *pold_extra_bytes; /* third attempt */
+ if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
+ (readbuf(__G__ G.sig, 4) == 0)) { /* bad offset */
+ if (error != PK_BADERR)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OffsetMsg), *pfilnum, "EOF",
+ (long)request));
+ error_in_archive = PK_BADERR;
+ continue; /* but can still try next one */
+ }
+ if (memcmp(G.sig, local_hdr_sig, 4)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OffsetMsg), *pfilnum,
+ LoadFarStringSmall(LocalHdrSig), (long)request));
+ error_in_archive = PK_BADERR;
+ continue;
+ }
+ } else
+ continue; /* this one hosed; try next */
+ }
+ if ((error = process_local_file_hdr(__G)) != PK_COOL) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
+ *pfilnum));
+ error_in_archive = error; /* only PK_EOF defined */
+ continue; /* can still try next one */
+ }
+#if (!defined(SFX) && defined(UNICODE_SUPPORT))
+ if (((G.lrec.general_purpose_bit_flag & (1 << 11)) == (1 << 11))
+ != (G.pInfo->GPFIsUTF8 != 0)) {
+ if (QCOND2) {
+# ifdef SMALL_MEM
+ char *temp_cfilnam = slide + (7 * (WSIZE>>3));
+
+ zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
+# define cFile_PrintBuf temp_cfilnam
+# else
+# define cFile_PrintBuf G.pInfo->cfilname
+# endif
+ Info(slide, 0x421, ((char *)slide,
+ LoadFarStringSmall2(GP11FlagsDiffer),
+ *pfilnum, FnFilter1(cFile_PrintBuf), G.pInfo->GPFIsUTF8));
+# undef cFile_PrintBuf
+ }
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX && UNICODE_SUPPORT */
+ if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
+ PK_COOL)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
+ FnFilter1(G.filename), "local"));
+ continue; /* go on to next one */
+ }
+ }
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+ if ((error =
+ do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtFieldMsg),
+ FnFilter1(G.filename), "local"));
+ continue; /* go on */
+ }
+ }
+#ifndef SFX
+ /* Filename consistency checks must come after reading in the local
+ * extra field, so that a UTF-8 entry name e.f. block has already
+ * been processed.
+ */
+ if (G.pInfo->cfilname != (char Far *)NULL) {
+ if (zfstrcmp(G.pInfo->cfilname, G.filename) != 0) {
+# ifdef SMALL_MEM
+ char *temp_cfilnam = slide + (7 * (WSIZE>>3));
+
+ zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
+# define cFile_PrintBuf temp_cfilnam
+# else
+# define cFile_PrintBuf G.pInfo->cfilname
+# endif
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall2(LvsCFNamMsg),
+ FnFilter2(cFile_PrintBuf), FnFilter1(G.filename)));
+# undef cFile_PrintBuf
+ zfstrcpy(G.filename, G.pInfo->cfilname);
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+ zffree(G.pInfo->cfilname);
+ G.pInfo->cfilname = (char Far *)NULL;
+ }
+#endif /* !SFX */
+ /* Size consistency checks must come after reading in the local extra
+ * field, so that any Zip64 extension local e.f. block has already
+ * been processed.
+ */
+ if (G.lrec.compression_method == STORED) {
+ zusz_t csiz_decrypted = G.lrec.csize;
+
+ if (G.pInfo->encrypted) {
+ if (csiz_decrypted < 12) {
+ /* handle the error now to prevent unsigned overflow */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile),
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ return PK_ERR;
+ }
+ csiz_decrypted -= 12;
+ }
+ if (G.lrec.ucsize != csiz_decrypted) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall2(WrnStorUCSizCSizDiff),
+ FnFilter1(G.filename),
+ FmZofft(G.lrec.ucsize, NULL, "u"),
+ FmZofft(csiz_decrypted, NULL, "u")));
+ G.lrec.ucsize = csiz_decrypted;
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+ }
+
+#if CRYPT
+ if (G.pInfo->encrypted &&
+ (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
+ if (error == PK_WARN) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipIncorrectPasswd),
+ FnFilter1(G.filename)));
+ ++(*pnum_bad_pwd);
+ } else { /* (error > PK_WARN) */
+ if (error > error_in_archive)
+ error_in_archive = error;
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipCannotGetPasswd),
+ FnFilter1(G.filename)));
+ }
+ continue; /* go on to next file */
+ }
+#endif /* CRYPT */
+
+ /*
+ * just about to extract file: if extracting to disk, check if
+ * already exists, and if so, take appropriate action according to
+ * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
+ * loop because we don't store the possibly renamed filename[] in
+ * info[])
+ */
+#ifdef DLL
+ if (!uO.tflag && !uO.cflag && !G.redirect_data)
+#else
+ if (!uO.tflag && !uO.cflag)
+#endif
+ {
+ renamed = FALSE; /* user hasn't renamed output file yet */
+
+startover:
+ query = FALSE;
+ skip_entry = SKIP_NO;
+ /* for files from DOS FAT, check for use of backslash instead
+ * of slash as directory separator (bug in some zipper(s); so
+ * far, not a problem in HPFS, NTFS or VFAT systems)
+ */
+#ifndef SFX
+ if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
+ char *p=G.filename;
+
+ if (*p) do {
+ if (*p == '\\') {
+ if (!G.reported_backslash) {
+ Info(slide, 0x21, ((char *)slide,
+ LoadFarString(BackslashPathSep), G.zipfn));
+ G.reported_backslash = TRUE;
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ }
+ *p = '/';
+ }
+ } while (*PREINCSTR(p));
+ }
+#endif /* !SFX */
+
+ if (!renamed) {
+ /* remove absolute path specs */
+ if (G.filename[0] == '/') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AbsolutePathWarning),
+ FnFilter1(G.filename)));
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ do {
+ char *p = G.filename + 1;
+ do {
+ *(p-1) = *p;
+ } while (*p++ != '\0');
+ } while (G.filename[0] == '/');
+ }
+ }
+
+ /* mapname can create dirs if not freshening or if renamed */
+ error = mapname(__G__ renamed);
+ if ((errcode = error & ~MPN_MASK) != PK_OK &&
+ error_in_archive < errcode)
+ error_in_archive = errcode;
+ if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
+ if (errcode == MPN_CREATED_DIR) {
+#ifdef SET_DIR_ATTRIB
+ direntry *d_entry;
+
+ error = defer_dir_attribs(__G__ &d_entry);
+ if (d_entry == (direntry *)NULL) {
+ /* There may be no dir_attribs info available, or
+ * we have encountered a mem allocation error.
+ * In case of an error, report it and set program
+ * error state to warning level.
+ */
+ if (error) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(DirlistEntryNoMem)));
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ }
+ } else {
+ d_entry->next = (*pdirlist);
+ (*pdirlist) = d_entry;
+ ++(*pnum_dirs);
+ }
+#endif /* SET_DIR_ATTRIB */
+ } else if (errcode == MPN_VOL_LABEL) {
+#ifdef DOS_OS2_W32
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipVolumeLabel),
+ FnFilter1(G.filename),
+ uO.volflag? "hard disk " : ""));
+#else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(SkipVolumeLabel),
+ FnFilter1(G.filename), ""));
+#endif
+ } else if (errcode > MPN_INF_SKIP &&
+ error_in_archive < PK_ERR)
+ error_in_archive = PK_ERR;
+ Trace((stderr, "mapname(%s) returns error code = %d\n",
+ FnFilter1(G.filename), error));
+ continue; /* go on to next file */
+ }
+
+#ifdef QDOS
+ QFilename(__G__ G.filename);
+#endif
+ switch (check_for_newer(__G__ G.filename)) {
+ case DOES_NOT_EXIST:
+#ifdef NOVELL_BUG_FAILSAFE
+ G.dne = TRUE; /* stat() says file DOES NOT EXIST */
+#endif
+ /* freshen (no new files): skip unless just renamed */
+ if (uO.fflag && !renamed)
+ skip_entry = SKIP_Y_NONEXIST;
+ break;
+ case EXISTS_AND_OLDER:
+#ifdef UNIXBACKUP
+ if (!uO.B_flag)
+#endif
+ {
+ if (IS_OVERWRT_NONE)
+ /* never overwrite: skip file */
+ skip_entry = SKIP_Y_EXISTING;
+ else if (!IS_OVERWRT_ALL)
+ query = TRUE;
+ }
+ break;
+ case EXISTS_AND_NEWER: /* (or equal) */
+#ifdef UNIXBACKUP
+ if ((!uO.B_flag && IS_OVERWRT_NONE) ||
+#else
+ if (IS_OVERWRT_NONE ||
+#endif
+ (uO.uflag && !renamed)) {
+ /* skip if update/freshen & orig name */
+ skip_entry = SKIP_Y_EXISTING;
+ } else {
+#ifdef UNIXBACKUP
+ if (!IS_OVERWRT_ALL && !uO.B_flag)
+#else
+ if (!IS_OVERWRT_ALL)
+#endif
+ query = TRUE;
+ }
+ break;
+ }
+#ifdef VMS
+ /* 2008-07-24 SMS.
+ * On VMS, if the file name includes a version number,
+ * and "-V" ("retain VMS version numbers", V_flag) is in
+ * effect, then the VMS-specific code will handle any
+ * conflicts with an existing file, making this query
+ * redundant. (Implicit "y" response here.)
+ */
+ if (query && uO.V_flag) {
+ /* Not discarding file versions. Look for one. */
+ int cndx = strlen(G.filename) - 1;
+
+ while ((cndx > 0) && (isdigit(G.filename[cndx])))
+ cndx--;
+ if (G.filename[cndx] == ';')
+ /* File version found; skip the generic query,
+ * proceeding with its default response "y".
+ */
+ query = FALSE;
+ }
+#endif /* VMS */
+ if (query) {
+#ifdef WINDLL
+ switch (G.lpUserFunctions->replace != NULL ?
+ (*G.lpUserFunctions->replace)(G.filename, FILNAMSIZ) :
+ IDM_REPLACE_NONE) {
+ case IDM_REPLACE_RENAME:
+ _ISO_INTERN(G.filename);
+ renamed = TRUE;
+ goto startover;
+ case IDM_REPLACE_ALL:
+ G.overwrite_mode = OVERWRT_ALWAYS;
+ /* FALL THROUGH, extract */
+ case IDM_REPLACE_YES:
+ break;
+ case IDM_REPLACE_NONE:
+ G.overwrite_mode = OVERWRT_NEVER;
+ /* FALL THROUGH, skip */
+ case IDM_REPLACE_NO:
+ skip_entry = SKIP_Y_EXISTING;
+ break;
+ }
+#else /* !WINDLL */
+ extent fnlen;
+reprompt:
+ Info(slide, 0x81, ((char *)slide,
+ LoadFarString(ReplaceQuery),
+ FnFilter1(G.filename)));
+ if (fgets(G.answerbuf, sizeof(G.answerbuf), stdin)
+ == (char *)NULL) {
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(AssumeNone)));
+ *G.answerbuf = 'N';
+ if (!error_in_archive)
+ error_in_archive = 1; /* not extracted: warning */
+ }
+ switch (*G.answerbuf) {
+ case 'r':
+ case 'R':
+ do {
+ Info(slide, 0x81, ((char *)slide,
+ LoadFarString(NewNameQuery)));
+ fgets(G.filename, FILNAMSIZ, stdin);
+ /* usually get \n here: better check for it */
+ fnlen = strlen(G.filename);
+ if (lastchar(G.filename, fnlen) == '\n')
+ G.filename[--fnlen] = '\0';
+ } while (fnlen == 0);
+#ifdef WIN32 /* WIN32 fgets( ... , stdin) returns OEM coded strings */
+ _OEM_INTERN(G.filename);
+#endif
+ renamed = TRUE;
+ goto startover; /* sorry for a goto */
+ case 'A': /* dangerous option: force caps */
+ G.overwrite_mode = OVERWRT_ALWAYS;
+ /* FALL THROUGH, extract */
+ case 'y':
+ case 'Y':
+ break;
+ case 'N':
+ G.overwrite_mode = OVERWRT_NEVER;
+ /* FALL THROUGH, skip */
+ case 'n':
+ /* skip file */
+ skip_entry = SKIP_Y_EXISTING;
+ break;
+ case '\n':
+ case '\r':
+ /* Improve echo of '\n' and/or '\r'
+ (sizeof(G.answerbuf) == 10 (see globals.h), so
+ there is enough space for the provided text...) */
+ strcpy(G.answerbuf, "{ENTER}");
+ /* fall through ... */
+ default:
+ /* usually get \n here: remove it for nice display
+ (fnlen can be re-used here, we are outside the
+ "enter new filename" loop) */
+ fnlen = strlen(G.answerbuf);
+ if (lastchar(G.answerbuf, fnlen) == '\n')
+ G.answerbuf[--fnlen] = '\0';
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidResponse), G.answerbuf));
+ goto reprompt; /* yet another goto? */
+ } /* end switch (*answerbuf) */
+#endif /* ?WINDLL */
+ } /* end if (query) */
+ if (skip_entry != SKIP_NO) {
+#ifdef WINDLL
+ if (skip_entry == SKIP_Y_EXISTING) {
+ /* report skipping of an existing entry */
+ Info(slide, 0, ((char *)slide,
+ ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
+ "Target file exists. Skipping %s\n" :
+ "Target file newer. Skipping %s\n"),
+ FnFilter1(G.filename)));
+ }
+#endif /* WINDLL */
+ continue;
+ }
+ } /* end if (extracting to disk) */
+
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
+ G.filename, NULL)) {
+ return IZ_CTRLC; /* cancel operation by user request */
+ }
+#endif
+#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+#endif
+#ifdef AMIGA
+ G.filenote_slot = i;
+#endif
+ G.disk_full = 0;
+ if ((error = extract_or_test_member(__G)) != PK_COOL) {
+ if (error > error_in_archive)
+ error_in_archive = error; /* ...and keep going */
+#ifdef DLL
+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+#else
+ if (G.disk_full > 1) {
+#endif
+ return error_in_archive; /* (unless disk full) */
+ }
+ }
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
+ G.filename, (zvoid *)&G.lrec.ucsize)) {
+ return IZ_CTRLC; /* cancel operation by user request */
+ }
+#endif
+#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+#endif
+ } /* end for-loop (i: files in current block) */
+
+ return error_in_archive;
+
+} /* end function extract_or_test_entrylist() */
+
+
+
+
+
+/* wsize is used in extract_or_test_member() and UZbunzip2() */
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+# define wsize G._wsize /* wsize is a variable */
+#else
+# define wsize WSIZE /* wsize is a constant */
+#endif
+
+/***************************************/
+/* Function extract_or_test_member() */
+/***************************************/
+
+static int extract_or_test_member(__G) /* return PK-type error code */
+ __GDEF
+{
+ char *nul="[empty] ", *txt="[text] ", *bin="[binary]";
+#ifdef CMS_MVS
+ char *ebc="[ebcdic]";
+#endif
+ register int b;
+ int r, error=PK_COOL;
+
+
+/*---------------------------------------------------------------------------
+ Initialize variables, buffers, etc.
+ ---------------------------------------------------------------------------*/
+
+ G.bits_left = 0;
+ G.bitbuf = 0L; /* unreduce and unshrink only */
+ G.zipeof = 0;
+ G.newfile = TRUE;
+ G.crc32val = CRCVAL_INITIAL;
+
+#ifdef SYMLINKS
+ /* If file is a (POSIX-compatible) symbolic link and we are extracting
+ * to disk, prepare to restore the link. */
+ G.symlnk = (G.pInfo->symlink &&
+ !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0));
+#endif /* SYMLINKS */
+
+ if (uO.tflag) {
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
+ FnFilter1(G.filename), "", ""));
+ } else {
+#ifdef DLL
+ if (uO.cflag && !G.redirect_data)
+#else
+ if (uO.cflag)
+#endif
+ {
+#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
+ G.outfile = freopen("", "wb", stdout); /* VAC++ ignores setmode */
+#else
+ G.outfile = stdout;
+#endif
+#ifdef DOS_FLX_NLM_OS2_W32
+#if (defined(__HIGHC__) && !defined(FLEXOS))
+ setmode(G.outfile, _BINARY);
+#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
+ setmode(fileno(G.outfile), O_BINARY);
+#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
+# define NEWLINE "\r\n"
+#else /* !DOS_FLX_NLM_OS2_W32 */
+# define NEWLINE "\n"
+#endif /* ?DOS_FLX_NLM_OS2_W32 */
+#ifdef VMS
+ /* VMS: required even for stdout! */
+ if ((r = open_outfile(__G)) != 0)
+ switch (r) {
+ case OPENOUT_SKIPOK:
+ return PK_OK;
+ case OPENOUT_SKIPWARN:
+ return PK_WARN;
+ default:
+ return PK_DISK;
+ }
+ } else if ((r = open_outfile(__G)) != 0)
+ switch (r) {
+ case OPENOUT_SKIPOK:
+ return PK_OK;
+ case OPENOUT_SKIPWARN:
+ return PK_WARN;
+ default:
+ return PK_DISK;
+ }
+#else /* !VMS */
+ } else if (open_outfile(__G))
+ return PK_DISK;
+#endif /* ?VMS */
+ }
+
+/*---------------------------------------------------------------------------
+ Unpack the file.
+ ---------------------------------------------------------------------------*/
+
+ defer_leftover_input(__G); /* so NEXTBYTE bounds check will work */
+ switch (G.lrec.compression_method) {
+ case STORED:
+ if (!uO.tflag && QCOND2) {
+#ifdef SYMLINKS
+ if (G.symlnk) /* can also be deflated, but rarer... */
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "link", FnFilter1(G.filename), "", ""));
+ else
+#endif /* SYMLINKS */
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "extract", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
+ bin)), uO.cflag? NEWLINE : ""));
+ }
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide) {
+ wsize = G.redirect_size; redirSlide = G.redirect_buffer;
+ } else {
+ wsize = WSIZE; redirSlide = slide;
+ }
+#endif
+ G.outptr = redirSlide;
+ G.outcnt = 0L;
+ while ((b = NEXTBYTE) != EOF) {
+ *G.outptr++ = (uch)b;
+ if (++G.outcnt == wsize) {
+ error = flush(__G__ redirSlide, G.outcnt, 0);
+ G.outptr = redirSlide;
+ G.outcnt = 0L;
+ if (error != PK_COOL || G.disk_full) break;
+ }
+ }
+ if (G.outcnt) { /* flush final (partial) buffer */
+ r = flush(__G__ redirSlide, G.outcnt, 0);
+ if (error < r) error = r;
+ }
+ break;
+
+#ifndef SFX
+#ifndef LZW_CLEAN
+ case SHRUNK:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = unshrink(__G)) != PK_COOL) {
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == PK_MEM3 ?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Unshrink),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == PK_MEM3 ?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Unshrink)));
+ }
+ error = r;
+ }
+ break;
+#endif /* !LZW_CLEAN */
+
+#ifndef COPYRIGHT_CLEAN
+ case REDUCED1:
+ case REDUCED2:
+ case REDUCED3:
+ case REDUCED4:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "unreduc", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = unreduce(__G)) != PK_COOL) {
+ /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
+ error = r;
+ }
+ break;
+#endif /* !COPYRIGHT_CLEAN */
+
+ case IMPLODED:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "explod", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = explode(__G)) != 0) {
+ if (r == 5) { /* treat 5 specially */
+ int warning = ((zusz_t)G.used_csize <= G.lrec.csize);
+
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(LengthMsg),
+ "", warning ? "warning" : "error",
+ FmZofft(G.used_csize, NULL, NULL),
+ FmZofft(G.lrec.ucsize, NULL, "u"),
+ warning ? " " : "",
+ FmZofft(G.lrec.csize, NULL, "u"),
+ " [", FnFilter1(G.filename), "]"));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(LengthMsg),
+ "\n", warning ? "warning" : "error",
+ FmZofft(G.used_csize, NULL, NULL),
+ FmZofft(G.lrec.ucsize, NULL, "u"),
+ warning ? " " : "",
+ FmZofft(G.lrec.csize, NULL, "u"),
+ "", "", "."));
+ error = warning ? PK_WARN : PK_ERR;
+ } else if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Explode),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Explode)));
+ error = ((r == 3) ? PK_MEM3 : PK_ERR);
+ } else {
+ error = r;
+ }
+ }
+ break;
+#endif /* !SFX */
+
+ case DEFLATED:
+#ifdef USE_DEFLATE64
+ case ENHDEFLATED:
+#endif
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "inflat", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+#ifndef USE_ZLIB /* zlib's function is called inflate(), too */
+# define UZinflate inflate
+#endif
+ if ((r = UZinflate(__G__
+ (G.lrec.compression_method == ENHDEFLATED)))
+ != 0) {
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ error = ((r == 3) ? PK_MEM3 : PK_ERR);
+ } else {
+ error = r;
+ }
+ }
+ break;
+
+#ifdef USE_BZIP2
+ case BZIPPED:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "bunzipp", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = UZbunzip2(__G)) != 0) {
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(BUnzip),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(BUnzip)));
+ error = ((r == 3) ? PK_MEM3 : PK_ERR);
+ } else {
+ error = r;
+ }
+ }
+ break;
+#endif /* USE_BZIP2 */
+
+ default: /* should never get to this point */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
+ /* close and delete file before return? */
+ undefer_input(__G);
+ return PK_WARN;
+
+ } /* end switch (compression method) */
+
+/*---------------------------------------------------------------------------
+ Close the file and set its date and time (not necessarily in that order),
+ and make sure the CRC checked out OK. Logical-AND the CRC for 64-bit
+ machines (redundant on 32-bit machines).
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS /* VMS: required even for stdout! (final flush) */
+ if (!uO.tflag) /* don't close NULL file */
+ error = close_outfile(__G);
+#else
+#ifdef DLL
+ if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
+ if (G.redirect_data)
+ FINISH_REDIRECT();
+ else
+ error = close_outfile(__G);
+ }
+#else
+ if (!uO.tflag && !uO.cflag) /* don't close NULL file or stdout */
+ error = close_outfile(__G);
+#endif
+#endif /* VMS */
+
+ if (G.disk_full) { /* set by flush() */
+ if (G.disk_full > 1) {
+#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
+ /* delete the incomplete file if we can */
+ if (unlink(G.filename) != 0)
+ Trace((stderr, "extract.c: could not delete %s\n",
+ FnFilter1(G.filename)));
+#else
+ /* warn user about the incomplete file */
+ Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
+ FnFilter1(G.filename)));
+#endif
+ error = PK_DISK;
+ } else {
+ error = PK_WARN;
+ }
+ }
+
+ if (error > PK_WARN) {/* don't print redundant CRC error if error already */
+ undefer_input(__G);
+ return error;
+ }
+ if (G.crc32val != G.lrec.crc32) {
+ /* if quiet enough, we haven't output the filename yet: do it */
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
+ G.lrec.crc32));
+#if CRYPT
+ if (G.pInfo->encrypted)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
+#endif
+ error = PK_ERR;
+ } else if (uO.tflag) {
+#ifndef SFX
+ if (G.extra_field) {
+ if ((r = TestExtraField(__G__ G.extra_field,
+ G.lrec.extra_field_length)) > error)
+ error = r;
+ } else
+#endif /* !SFX */
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, " OK\n"));
+ } else {
+ if (QCOND2 && !error) /* GRR: is stdout reset to text mode yet? */
+ Info(slide, 0, ((char *)slide, "\n"));
+ }
+
+ undefer_input(__G);
+ return error;
+
+} /* end function extract_or_test_member() */
+
+
+
+
+
+#ifndef SFX
+
+/*******************************/
+/* Function TestExtraField() */
+/*******************************/
+
+static int TestExtraField(__G__ ef, ef_len)
+ __GDEF
+ uch *ef;
+ unsigned ef_len;
+{
+ ush ebID;
+ unsigned ebLen;
+ unsigned eb_cmpr_offs = 0;
+ int r;
+
+ /* we know the regular compressed file data tested out OK, or else we
+ * wouldn't be here ==> print filename if any extra-field errors found
+ */
+ while (ef_len >= EB_HEADSIZE) {
+ ebID = makeword(ef);
+ ebLen = (unsigned)makeword(ef+EB_LEN);
+
+ if (ebLen > (ef_len - EB_HEADSIZE))
+ {
+ /* Discovered some extra field inconsistency! */
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
+ ebLen, (ef_len - EB_HEADSIZE)));
+ return PK_ERR;
+ }
+
+ switch (ebID) {
+ case EF_OS2:
+ case EF_ACL:
+ case EF_MAC3:
+ case EF_BEOS:
+ case EF_ATHEOS:
+ switch (ebID) {
+ case EF_OS2:
+ case EF_ACL:
+ eb_cmpr_offs = EB_OS2_HLEN;
+ break;
+ case EF_MAC3:
+ if (ebLen >= EB_MAC3_HLEN &&
+ (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
+ & EB_M3_FL_UNCMPR) &&
+ (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
+ eb_cmpr_offs = 0;
+ else
+ eb_cmpr_offs = EB_MAC3_HLEN;
+ break;
+ case EF_BEOS:
+ case EF_ATHEOS:
+ if (ebLen >= EB_BEOS_HLEN &&
+ (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
+ (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
+ eb_cmpr_offs = 0;
+ else
+ eb_cmpr_offs = EB_BEOS_HLEN;
+ break;
+ }
+ if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
+ != PK_OK) {
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ switch (r) {
+ case IZ_EF_TRUNC:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(TruncEAs),
+ ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
+ break;
+ case PK_ERR:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidComprDataEAs)));
+ break;
+ case PK_MEM3:
+ case PK_MEM4:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(NotEnoughMemEAs)));
+ break;
+ default:
+ if ((r & 0xff) != PK_ERR)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknErrorEAs)));
+ else {
+ ush m = (ush)(r >> 8);
+ if (m == DEFLATED) /* GRR KLUDGE! */
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknComprMethodEAs), m));
+ }
+ break;
+ }
+ return r;
+ }
+ break;
+
+ case EF_NTSD:
+ Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
+ r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
+ ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
+ (PK_WARN | 0x4000) :
+ test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
+ if (r != PK_OK) {
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ switch (r) {
+ case IZ_EF_TRUNC:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(TruncNTSD),
+ ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
+ break;
+#if (defined(WIN32) && defined(NTSD_EAS))
+ case PK_WARN:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidSecurityEAs)));
+ break;
+#endif
+ case PK_ERR:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidComprDataEAs)));
+ break;
+ case PK_MEM3:
+ case PK_MEM4:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(NotEnoughMemEAs)));
+ break;
+ case (PK_WARN | 0x4000):
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnsuppNTSDVersEAs),
+ (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
+ r = PK_WARN;
+ break;
+ default:
+ if ((r & 0xff) != PK_ERR)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknErrorEAs)));
+ else {
+ ush m = (ush)(r >> 8);
+ if (m == DEFLATED) /* GRR KLUDGE! */
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknComprMethodEAs), m));
+ }
+ break;
+ }
+ return r;
+ }
+ break;
+ case EF_PKVMS:
+ /* 2015-01-30 SMS. Added sufficient-bytes test/message
+ * here. (Removed defective ebLen test above.)
+ *
+ * If sufficient bytes (EB_PKVMS_MINLEN) are available,
+ * then compare the stored CRC value with the calculated
+ * CRC for the remainder of the data (and complain about
+ * a mismatch).
+ */
+ if (ebLen < EB_PKVMS_MINLEN)
+ {
+ /* Insufficient bytes available. */
+ Info( slide, 1,
+ ((char *)slide, LoadFarString( TooSmallEBlength),
+ ebLen, EB_PKVMS_MINLEN));
+ }
+ else if (makelong(ef+ EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL,
+ (ef+ EB_HEADSIZE+ EB_PKVMS_MINLEN),
+ (extent)(ebLen- EB_PKVMS_MINLEN)))
+ {
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ }
+ break;
+ case EF_PKW32:
+ case EF_PKUNIX:
+ case EF_ASIUNIX:
+ case EF_IZVMS:
+ case EF_IZUNIX:
+ case EF_VMCMS:
+ case EF_MVS:
+ case EF_SPARK:
+ case EF_TANDEM:
+ case EF_THEOS:
+ case EF_AV:
+ default:
+ break;
+ }
+ ef_len -= (ebLen + EB_HEADSIZE);
+ ef += (ebLen + EB_HEADSIZE);
+ }
+
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, " OK\n"));
+
+ return PK_COOL;
+
+} /* end function TestExtraField() */
+
+
+
+
+
+/******************************/
+/* Function test_compr_eb() */
+/******************************/
+
+#ifdef PROTO
+static int test_compr_eb(
+ __GPRO__
+ uch *eb,
+ unsigned eb_size,
+ unsigned compr_offset,
+ int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize))
+#else /* !PROTO */
+static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
+ __GDEF
+ uch *eb;
+ unsigned eb_size;
+ unsigned compr_offset;
+ int (*test_uc_ebdata)();
+#endif /* ?PROTO */
+{
+ ulg eb_ucsize;
+ uch *eb_ucptr;
+ int r;
+ ush method;
+
+ if (compr_offset < 4) /* field is not compressed: */
+ return PK_OK; /* do nothing and signal OK */
+
+ /* Return no/bad-data error status if any problem is found:
+ * 1. eb_size is too small to hold the uncompressed size
+ * (eb_ucsize). (Else extract eb_ucsize.)
+ * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS.
+ * 3. eb_ucsize is positive, but eb_size is too small to hold
+ * the compressed data header.
+ */
+ if ((eb_size < (EB_UCSIZE_P + 4)) ||
+ ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
+ ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
+ return IZ_EF_TRUNC; /* no/bad compressed data! */
+
+ method = makeword(eb + (EB_HEADSIZE + compr_offset));
+ if ((method == STORED) && (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
+ return PK_ERR; /* compressed & uncompressed
+ * should match in STORED
+ * method */
+
+ if (
+#ifdef INT_16BIT
+ (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
+#endif
+ (eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
+ return PK_MEM4;
+
+ r = memextract(__G__ eb_ucptr, eb_ucsize,
+ eb + (EB_HEADSIZE + compr_offset),
+ (ulg)(eb_size - compr_offset));
+
+ if (r == PK_OK && test_uc_ebdata != NULL)
+ r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
+
+ free(eb_ucptr);
+ return r;
+
+} /* end function test_compr_eb() */
+
+#endif /* !SFX */
+
+
+
+
+
+/***************************/
+/* Function memextract() */
+/***************************/
+
+int memextract(__G__ tgt, tgtsize, src, srcsize) /* extract compressed */
+ __GDEF /* extra field block; */
+ uch *tgt; /* return PK-type error */
+ ulg tgtsize; /* level */
+ ZCONST uch *src;
+ ulg srcsize;
+{
+ zoff_t old_csize=G.csize;
+ uch *old_inptr=G.inptr;
+ int old_incnt=G.incnt;
+ int r, error=PK_OK;
+ ush method;
+ ulg extra_field_crc;
+
+
+ method = makeword(src);
+ extra_field_crc = makelong(src+2);
+
+ /* compressed extra field exists completely in memory at this location: */
+ G.inptr = (uch *)src + (2 + 4); /* method and extra_field_crc */
+ G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
+ G.mem_mode = TRUE;
+ G.outbufptr = tgt;
+ G.outsize = tgtsize;
+
+ switch (method) {
+ case STORED:
+ memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
+ G.outcnt = (ulg)G.csize; /* for CRC calculation */
+ break;
+ case DEFLATED:
+#ifdef USE_DEFLATE64
+ case ENHDEFLATED:
+#endif
+ G.outcnt = 0L;
+ if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
+ if (!uO.tflag)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ error = (r == 3)? PK_MEM3 : PK_ERR;
+ }
+ if (G.outcnt == 0L) /* inflate's final FLUSH sets outcnt */
+ break;
+ break;
+ default:
+ if (uO.tflag)
+ error = PK_ERR | ((int)method << 8);
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UnsupportedExtraField), method));
+ error = PK_ERR; /* GRR: should be passed on up via SetEAs() */
+ }
+ break;
+ }
+
+ G.inptr = old_inptr;
+ G.incnt = old_incnt;
+ G.csize = old_csize;
+ G.mem_mode = FALSE;
+
+ if (!error) {
+ register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
+
+ if (crcval != extra_field_crc) {
+ if (uO.tflag)
+ error = PK_ERR | (DEFLATED << 8); /* kludge for now */
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
+ extra_field_crc));
+ error = PK_ERR;
+ }
+ }
+ }
+ return error;
+
+} /* end function memextract() */
+
+
+
+
+
+/*************************/
+/* Function memflush() */
+/*************************/
+
+int memflush(__G__ rawbuf, size)
+ __GDEF
+ ZCONST uch *rawbuf;
+ ulg size;
+{
+ if (size > G.outsize)
+ /* Here, PK_DISK is a bit off-topic, but in the sense of marking
+ "overflow of output space", its use may be tolerated. */
+ return PK_DISK; /* more data than output buffer can hold */
+
+
+
+ memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
+ G.outbufptr += (unsigned int)size;
+ G.outsize -= size;
+ G.outcnt += size;
+
+ return 0;
+
+} /* end function memflush() */
+
+
+
+
+
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+
+/************************************/
+/* Function extract_izvms_block() */
+/************************************/
+
+/*
+ * Extracts block from p. If resulting length is less than needed, fill
+ * extra space with corresponding bytes from 'init'.
+ * Currently understands 3 formats of block compression:
+ * - Simple storing
+ * - Compression of zero bytes to zero bits
+ * - Deflation (see memextract())
+ * The IZVMS block data is returned in malloc'd space.
+ */
+uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
+ __GDEF
+ ZCONST uch *ebdata;
+ unsigned size;
+ unsigned *retlen;
+ ZCONST uch *init;
+ unsigned needlen;
+{
+ uch *ucdata; /* Pointer to block allocated */
+ int cmptype;
+ unsigned usiz, csiz;
+
+ cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
+ csiz = size - EB_IZVMS_HLEN;
+ usiz = (cmptype == EB_IZVMS_BCSTOR ?
+ csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
+
+ if (retlen)
+ *retlen = usiz;
+
+ if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
+ return NULL;
+
+ if (init && (usiz < needlen))
+ memcpy((char *)ucdata, (ZCONST char *)init, needlen);
+
+ switch (cmptype)
+ {
+ case EB_IZVMS_BCSTOR: /* The simplest case */
+ memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
+ break;
+ case EB_IZVMS_BC00:
+ decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
+ break;
+ case EB_IZVMS_BCDEFL:
+ memextract(__G__ ucdata, (ulg)usiz,
+ ebdata+EB_IZVMS_HLEN, (ulg)csiz);
+ break;
+ default:
+ free(ucdata);
+ ucdata = NULL;
+ }
+ return ucdata;
+
+} /* end of extract_izvms_block */
+
+
+
+
+
+/********************************/
+/* Function decompress_bits() */
+/********************************/
+/*
+ * Simple uncompression routine. The compression uses bit stream.
+ * Compression scheme:
+ *
+ * if (byte!=0)
+ * putbit(1),putbyte(byte)
+ * else
+ * putbit(0)
+ */
+static void decompress_bits(outptr, needlen, bitptr)
+ uch *outptr; /* Pointer into output block */
+ unsigned needlen; /* Size of uncompressed block */
+ ZCONST uch *bitptr; /* Pointer into compressed data */
+{
+ ulg bitbuf = 0;
+ int bitcnt = 0;
+
+#define _FILL { bitbuf |= (*bitptr++) << bitcnt;\
+ bitcnt += 8; \
+ }
+
+ while (needlen--)
+ {
+ if (bitcnt <= 0)
+ _FILL;
+
+ if (bitbuf & 1)
+ {
+ bitbuf >>= 1;
+ if ((bitcnt -= 1) < 8)
+ _FILL;
+ *outptr++ = (uch)bitbuf;
+ bitcnt -= 8;
+ bitbuf >>= 8;
+ }
+ else
+ {
+ *outptr++ = '\0';
+ bitcnt -= 1;
+ bitbuf >>= 1;
+ }
+ }
+} /* end function decompress_bits() */
+
+#endif /* VMS || VMS_TEXT_CONV */
+
+
+
+
+
+#ifdef SYMLINKS
+/***********************************/
+/* Function set_deferred_symlink() */
+/***********************************/
+
+static void set_deferred_symlink(__G__ slnk_entry)
+ __GDEF
+ slinkentry *slnk_entry;
+{
+ extent ucsize = slnk_entry->targetlen;
+ char *linkfname = slnk_entry->fname;
+ char *linktarget = (char *)malloc(ucsize+1);
+
+ if (!linktarget) {
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
+ return;
+ }
+ linktarget[ucsize] = '\0';
+ G.outfile = zfopen(linkfname, FOPR); /* open link placeholder for reading */
+ /* Check that the following conditions are all fulfilled:
+ * a) the placeholder file exists,
+ * b) the placeholder file contains exactly "ucsize" bytes
+ * (read the expected placeholder content length + 1 extra byte, this
+ * should return the expected content length),
+ * c) the placeholder content matches the link target specification as
+ * stored in the symlink control structure.
+ */
+ if (!G.outfile ||
+ fread(linktarget, 1, ucsize+1, G.outfile) != ucsize ||
+ strcmp(slnk_entry->target, linktarget))
+ {
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(SymLnkWarnInvalid), FnFilter1(linkfname)));
+ free(linktarget);
+ if (G.outfile)
+ fclose(G.outfile);
+ return;
+ }
+ fclose(G.outfile); /* close "data" file for good... */
+ unlink(linkfname); /* ...and delete it */
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
+ FnFilter1(linkfname), FnFilter2(linktarget)));
+ if (symlink(linktarget, linkfname)) /* create the real link */
+ perror("symlink error");
+ free(linktarget);
+#ifdef SET_SYMLINK_ATTRIBS
+ set_symlnk_attribs(__G__ slnk_entry);
+#endif
+ return; /* can't set time on symlinks */
+
+} /* end function set_deferred_symlink() */
+#endif /* SYMLINKS */
+
+/*
+ * If Unicode is supported, assume we have what we need to do this
+ * check using wide characters, avoiding MBCS issues.
+ */
+
+#ifndef UZ_FNFILTER_REPLACECHAR
+ /* A convenient choice for the replacement of unprintable char codes is
+ * the "single char wildcard", as this character is quite unlikely to
+ * appear in filenames by itself. The following default definition
+ * sets the replacement char to a question mark as the most common
+ * "single char wildcard"; this setting should be overridden in the
+ * appropiate system-specific configuration header when needed.
+ */
+# define UZ_FNFILTER_REPLACECHAR '?'
+#endif
+
+/*************************/
+/* Function fnfilter() */ /* here instead of in list.c for SFX */
+/*************************/
+
+char *fnfilter(raw, space, size) /* convert name to safely printable form */
+ ZCONST char *raw;
+ uch *space;
+ extent size;
+{
+#ifndef NATIVE /* ASCII: filter ANSI escape codes, etc. */
+ ZCONST uch *r; // =(ZCONST uch *)raw;
+ uch *s=space;
+ uch *slim=NULL;
+ uch *se=NULL;
+ int have_overflow = FALSE;
+
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+/* If Unicode support is enabled, and we have multi-byte characters,
+ * then do the isprint() checks by first converting to wide characters
+ * and checking those. This avoids our having to parse multi-byte
+ * characters for ourselves. After the wide-char replacements have been
+ * made, the wide string is converted back to the local character set.
+ */
+ wchar_t *wstring; /* wchar_t version of raw */
+ size_t wslen; /* length of wstring */
+ wchar_t *wostring; /* wchar_t version of output string */
+ size_t woslen; /* length of wostring */
+ char *newraw; /* new raw */
+
+ /* 2012-11-06 SMS.
+ * Changed to check the value returned by mbstowcs(), and bypass the
+ * Unicode processing if it fails. This seems to fix a problem
+ * reported in the SourceForge forum, but it's not clear that we
+ * should be doing any Unicode processing without some evidence that
+ * the name actually is Unicode. (Check bit 11 in the flags before
+ * coming here?)
+ * http://sourceforge.net/p/infozip/bugs/40/
+ */
+
+ if (MB_CUR_MAX <= 1)
+ {
+ /* There's no point to converting multi-byte chars if there are
+ * no multi-byte chars.
+ */
+ wslen = (size_t)-1;
+ }
+ else
+ {
+ /* Get Unicode wide character count (for storage allocation). */
+ wslen = mbstowcs( NULL, raw, 0);
+ }
+
+ if (wslen != (size_t)-1)
+ {
+ /* Apparently valid Unicode. Allocate wide-char storage. */
+ wstring = (wchar_t *)malloc((wslen + 1) * sizeof(wchar_t));
+ if (wstring == NULL) {
+ strcpy( (char *)space, raw);
+ return (char *)space;
+ }
+ wostring = (wchar_t *)malloc(2 * (wslen + 1) * sizeof(wchar_t));
+ if (wostring == NULL) {
+ free(wstring);
+ strcpy( (char *)space, raw);
+ return (char *)space;
+ }
+
+ /* Convert the multi-byte Unicode to wide chars. */
+ wslen = mbstowcs(wstring, raw, wslen + 1);
+
+ /* Filter the wide-character string. */
+ fnfilterw( wstring, wostring, (2 * (wslen + 1) * sizeof(wchar_t)));
+
+ /* Convert filtered wide chars back to multi-byte. */
+ woslen = wcstombs( NULL, wostring, 0);
+ if ((newraw = malloc(woslen + 1)) == NULL) {
+ free(wstring);
+ free(wostring);
+ strcpy( (char *)space, raw);
+ return (char *)space;
+ }
+ woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1);
+
+ if (size > 0) {
+ slim = space + size - 4;
+ }
+ r = (ZCONST uch *)newraw;
+ while (*r) {
+ if (size > 0 && s >= slim && se == NULL) {
+ se = s;
+ }
+# ifdef QDOS
+ if (qlflag & 2) {
+ if (*r == '/' || *r == '.') {
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ ++r;
+ *s++ = '_';
+ continue;
+ }
+ } else
+# endif
+ {
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = *r++;
+ }
+ }
+ if (have_overflow) {
+ strcpy((char *)se, "...");
+ } else {
+ *s = '\0';
+ }
+
+ free(wstring);
+ free(wostring);
+ free(newraw);
+ }
+ else
+# endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+ {
+ /* No Unicode support, or apparently invalid Unicode. */
+ r = (ZCONST uch *)raw;
+
+ if (size > 0) {
+ slim = space + size
+#ifdef _MBCS
+ - (MB_CUR_MAX - 1)
+#endif
+ - 4;
+ }
+ while (*r) {
+ if (size > 0 && s >= slim && se == NULL) {
+ se = s;
+ }
+#ifdef QDOS
+ if (qlflag & 2) {
+ if (*r == '/' || *r == '.') {
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ ++r;
+ *s++ = '_';
+ continue;
+ }
+ } else
+#endif
+#ifdef HAVE_WORKING_ISPRINT
+ if (!isprint(*r)) {
+ if (*r < 32) {
+ /* ASCII control codes are escaped as "^{letter}". */
+ if (se != NULL && (s > (space + (size-4)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = '^', *s++ = (uch)(64 + *r++);
+ } else {
+ /* Other unprintable codes are replaced by the
+ * placeholder character. */
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = UZ_FNFILTER_REPLACECHAR;
+ INCSTR(r);
+ }
+#else /* !HAVE_WORKING_ISPRINT */
+ if (*r < 32) {
+ /* ASCII control codes are escaped as "^{letter}". */
+ if (se != NULL && (s > (space + (size-4)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = '^', *s++ = (uch)(64 + *r++);
+#endif /* ?HAVE_WORKING_ISPRINT */
+ } else {
+#ifdef _MBCS
+ unsigned i = CLEN(r);
+ if (se != NULL && (s > (space + (size-i-2)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ for (; i > 0; i--)
+ *s++ = *r++;
+#else
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = *r++;
+#endif
+ }
+ }
+ if (have_overflow) {
+ strcpy((char *)se, "...");
+ } else {
+ *s = '\0';
+ }
+ }
+
+#ifdef WINDLL
+ INTERN_TO_ISO((char *)space, (char *)space); /* translate to ANSI */
+#else
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM((char *)space, (char *)space);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+
+ return (char *)space;
+
+#else /* NATIVE: EBCDIC or whatever */
+ return (char *)raw;
+#endif
+
+} /* end function fnfilter() */
+
+
+#if defined( UNICODE_SUPPORT) && defined( _MBCS)
+
+/****************************/
+/* Function fnfilter[w]() */ /* (Here instead of in list.c for SFX.) */
+/****************************/
+
+/* fnfilterw() - Convert wide name to safely printable form. */
+
+/* fnfilterw() - Convert wide-character name to safely printable form. */
+
+wchar_t *fnfilterw( src, dst, siz)
+ ZCONST wchar_t *src; /* Pointer to source char (string). */
+ wchar_t *dst; /* Pointer to destination char (string). */
+ extent siz; /* Not used (!). */
+{
+ wchar_t *dsx = dst;
+
+ /* Filter the wide chars. */
+ while (*src)
+ {
+ if (iswprint( *src))
+ {
+ /* Printable code. Copy it. */
+ *dst++ = *src;
+ }
+ else
+ {
+ /* Unprintable code. Substitute something printable for it. */
+ if (*src < 32)
+ {
+ /* Replace ASCII control code with "^{letter}". */
+ *dst++ = (wchar_t)'^';
+ *dst++ = (wchar_t)(64 + *src);
+ }
+ else
+ {
+ /* Replace other unprintable code with the placeholder. */
+ *dst++ = (wchar_t)UZ_FNFILTER_REPLACECHAR;
+ }
+ }
+ src++;
+ }
+ *dst = (wchar_t)0; /* NUL-terminate the destination string. */
+ return dsx;
+} /* fnfilterw(). */
+
+#endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+
+
+#ifdef SET_DIR_ATTRIB
+/* must sort saved directories so can set perms from bottom up */
+
+/************************/
+/* Function dircomp() */
+/************************/
+
+static int Cdecl dircomp(a, b) /* used by qsort(); swiped from Zip */
+ ZCONST zvoid *a, *b;
+{
+ /* order is significant: this sorts in reverse order (deepest first) */
+ return strcmp((*(direntry **)b)->fn, (*(direntry **)a)->fn);
+ /* return namecmp((*(direntry **)b)->fn, (*(direntry **)a)->fn); */
+}
+
+#endif /* SET_DIR_ATTRIB */
+
+
+#ifdef USE_BZIP2
+
+/**************************/
+/* Function UZbunzip2() */
+/**************************/
+
+int UZbunzip2(__G)
+__GDEF
+/* decompress a bzipped entry using the libbz2 routines */
+{
+ int retval = 0; /* return code: 0 = "no error" */
+ int err=BZ_OK;
+ int repeated_buf_err;
+ bz_stream bstrm;
+
+ if (G.incnt <= 0 && G.csize <= 0L) {
+ /* avoid an infinite loop */
+ Trace((stderr, "UZbunzip2() got empty input\n"));
+ return 2;
+ }
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide)
+ wsize = G.redirect_size, redirSlide = G.redirect_buffer;
+ else
+ wsize = WSIZE, redirSlide = slide;
+#endif
+
+ bstrm.next_out = (char *)redirSlide;
+ bstrm.avail_out = wsize;
+
+ bstrm.next_in = (char *)G.inptr;
+ bstrm.avail_in = G.incnt;
+
+ {
+ /* local buffer for efficiency */
+ /* $TODO Check for BZIP LIB version? */
+
+ bstrm.bzalloc = NULL;
+ bstrm.bzfree = NULL;
+ bstrm.opaque = NULL;
+
+ Trace((stderr, "initializing bzlib()\n"));
+ err = BZ2_bzDecompressInit(&bstrm, 0, 0);
+
+ if (err == BZ_MEM_ERROR)
+ return 3;
+ else if (err != BZ_OK)
+ Trace((stderr, "oops! (BZ2_bzDecompressInit() err = %d)\n", err));
+ }
+
+#ifdef FUNZIP
+ while (err != BZ_STREAM_END) {
+#else /* !FUNZIP */
+ while (G.csize > 0) {
+ Trace((stderr, "first loop: G.csize = %ld\n", G.csize));
+#endif /* ?FUNZIP */
+ while (bstrm.avail_out > 0) {
+ err = BZ2_bzDecompress(&bstrm);
+
+ if (err == BZ_DATA_ERROR) {
+ retval = 2; goto uzbunzip_cleanup_exit;
+ } else if (err == BZ_MEM_ERROR) {
+ retval = 3; goto uzbunzip_cleanup_exit;
+ } else if (err != BZ_OK && err != BZ_STREAM_END)
+ Trace((stderr, "oops! (bzip(first loop) err = %d)\n", err));
+
+#ifdef FUNZIP
+ if (err == BZ_STREAM_END) /* "END-of-entry-condition" ? */
+#else /* !FUNZIP */
+ if (G.csize <= 0L) /* "END-of-entry-condition" ? */
+#endif /* ?FUNZIP */
+ break;
+
+ if (bstrm.avail_in == 0) {
+ if (fillinbuf(__G) == 0) {
+ /* no "END-condition" yet, but no more data */
+ retval = 2; goto uzbunzip_cleanup_exit;
+ }
+
+ bstrm.next_in = (char *)G.inptr;
+ bstrm.avail_in = G.incnt;
+ }
+ Trace((stderr, " avail_in = %u\n", bstrm.avail_in));
+ }
+ /* flush slide[] */
+ if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
+ goto uzbunzip_cleanup_exit;
+ Trace((stderr, "inside loop: flushing %ld bytes (ptr diff = %ld)\n",
+ (long)(wsize - bstrm.avail_out),
+ (long)(bstrm.next_out-(char *)redirSlide)));
+ bstrm.next_out = (char *)redirSlide;
+ bstrm.avail_out = wsize;
+ }
+
+ /* no more input, so loop until we have all output */
+ Trace((stderr, "beginning final loop: err = %d\n", err));
+ repeated_buf_err = FALSE;
+ while (err != BZ_STREAM_END) {
+ err = BZ2_bzDecompress(&bstrm);
+ if (err == BZ_DATA_ERROR) {
+ retval = 2; goto uzbunzip_cleanup_exit;
+ } else if (err == BZ_MEM_ERROR) {
+ retval = 3; goto uzbunzip_cleanup_exit;
+ } else if (err != BZ_OK && err != BZ_STREAM_END) {
+ Trace((stderr, "oops! (bzip(final loop) err = %d)\n", err));
+ DESTROYGLOBALS();
+ EXIT(PK_MEM3);
+ }
+ /* final flush of slide[] */
+ if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
+ goto uzbunzip_cleanup_exit;
+ Trace((stderr, "final loop: flushing %ld bytes (ptr diff = %ld)\n",
+ (long)(wsize - bstrm.avail_out),
+ (long)(bstrm.next_out-(char *)redirSlide)));
+ bstrm.next_out = (char *)redirSlide;
+ bstrm.avail_out = wsize;
+ }
+#ifdef LARGE_FILE_SUPPORT
+ Trace((stderr, "total in = %llu, total out = %llu\n",
+ (zusz_t)(bstrm.total_in_lo32) + ((zusz_t)(bstrm.total_in_hi32))<<32,
+ (zusz_t)(bstrm.total_out_lo32) + ((zusz_t)(bstrm.total_out_hi32))<<32));
+#else
+ Trace((stderr, "total in = %lu, total out = %lu\n", bstrm.total_in_lo32,
+ bstrm.total_out_lo32));
+#endif
+
+ G.inptr = (uch *)bstrm.next_in;
+ G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
+
+uzbunzip_cleanup_exit:
+ err = BZ2_bzDecompressEnd(&bstrm);
+ if (err != BZ_OK)
+ Trace((stderr, "oops! (BZ2_bzDecompressEnd() err = %d)\n", err));
+
+ return retval;
+} /* end function UZbunzip2() */
+#endif /* USE_BZIP2 */
Index: unzip/create-6.0-slackware-patch/unzip60-new/fileio.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/fileio.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/fileio.c (revision 5)
@@ -0,0 +1,2889 @@
+/*
+ Copyright (c) 1990-2017 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ fileio.c
+
+ This file contains routines for doing direct but relatively generic input/
+ output, file-related sorts of things, plus some miscellaneous stuff. Most
+ of the stuff has to do with opening, closing, reading and/or writing files.
+
+ Contains: open_input_file()
+ open_outfile() (not: VMS, AOS/VS, CMSMVS, MACOS, TANDEM)
+ undefer_input()
+ defer_leftover_input()
+ readbuf()
+ readbyte()
+ fillinbuf()
+ seek_zipf()
+ flush() (non-VMS)
+ is_vms_varlen_txt() (non-VMS, VMS_TEXT_CONV only)
+ disk_error() (non-VMS)
+ UzpMessagePrnt()
+ UzpMessageNull() (DLL only)
+ UzpInput()
+ UzpMorePause()
+ UzpPassword() (non-WINDLL)
+ handler()
+ dos_to_unix_time() (non-VMS, non-VM/CMS, non-MVS)
+ check_for_newer() (non-VMS, non-OS/2, non-VM/CMS, non-MVS)
+ do_string()
+ makeword()
+ makelong()
+ makeint64()
+ fzofft()
+ str2iso() (CRYPT && NEED_STR2ISO, only)
+ str2oem() (CRYPT && NEED_STR2OEM, only)
+ memset() (ZMEM only)
+ memcpy() (ZMEM only)
+ zstrnicmp() (NO_STRNICMP only)
+ zstat() (REGULUS only)
+ plastchar() (_MBCS only)
+ uzmbclen() (_MBCS && NEED_UZMBCLEN, only)
+ uzmbschr() (_MBCS && NEED_UZMBSCHR, only)
+ uzmbsrchr() (_MBCS && NEED_UZMBSRCHR, only)
+ fLoadFarString() (SMALL_MEM only)
+ fLoadFarStringSmall() (SMALL_MEM only)
+ fLoadFarStringSmall2() (SMALL_MEM only)
+ zfstrcpy() (SMALL_MEM only)
+ zfstrcmp() (SMALL_MEM && !(SFX || FUNZIP) only)
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __FILEIO_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+# include <setjmp.h>
+#endif
+#include "crc32.h"
+#include "crypt.h"
+#include "ttyio.h"
+
+/* setup of codepage conversion for decryption passwords */
+#if CRYPT
+# if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY))
+# define IZ_ISO2OEM_ARRAY /* pull in iso2oem[] table */
+# endif
+# if (defined(CRYP_USES_OEM2ISO) && !defined(IZ_OEM2ISO_ARRAY))
+# define IZ_OEM2ISO_ARRAY /* pull in oem2iso[] table */
+# endif
+#endif
+#include "ebcdic.h" /* definition/initialization of ebcdic[] */
+
+
+/*
+ Note: Under Windows, the maximum size of the buffer that can be used
+ with any of the *printf calls is 16,384, so win_fprintf was used to
+ feed the fprintf clone no more than 16K chunks at a time. This should
+ be valid for anything up to 64K (and probably beyond, assuming your
+ buffers are that big).
+*/
+#ifdef WINDLL
+# define WriteError(buf,len,strm) \
+ (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len))
+#else /* !WINDLL */
+# ifdef USE_FWRITE
+# define WriteError(buf,len,strm) \
+ ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
+# else
+# define WriteError(buf,len,strm) \
+ ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
+# endif
+#endif /* ?WINDLL */
+
+/*
+ 2005-09-16 SMS.
+ On VMS, when output is redirected to a file, as in a command like
+ "PIPE UNZIP -v > X.OUT", the output file is created with VFC record
+ format, and multiple calls to write() or fwrite() will produce multiple
+ records, even when there's no newline terminator in the buffer.
+ The result is unsightly output with spurious newlines. Using fprintf()
+ instead of write() here, and disabling a fflush(stdout) in UzpMessagePrnt()
+ below, together seem to solve the problem.
+
+ According to the C RTL manual, "The write and decc$record_write
+ functions always generate at least one record." Also, "[T]he fwrite
+ function always generates at least <number_items> records." So,
+ "fwrite(buf, len, 1, strm)" is much better ("1" record) than
+ "fwrite(buf, 1, len, strm)" ("len" (1-character) records, _really_
+ ugly), but neither is better than write(). Similarly, "The fflush
+ function always generates a record if there is unwritten data in the
+ buffer." Apparently fprintf() buffers the stuff somewhere, and puts
+ out a record (only) when it sees a newline.
+*/
+#ifdef VMS
+# define WriteTxtErr(buf,len,strm) \
+ ((extent)fprintf(strm, "%.*s", len, buf) != (extent)(len))
+#else
+# define WriteTxtErr(buf,len,strm) WriteError(buf,len,strm)
+#endif
+
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+static int partflush OF((__GPRO__ uch *rawbuf, ulg size, int unshrink));
+#endif
+#ifdef VMS_TEXT_CONV
+static int is_vms_varlen_txt OF((__GPRO__ uch *ef_buf, unsigned ef_len));
+#endif
+static int disk_error OF((__GPRO));
+
+
+/****************************/
+/* Strings used in fileio.c */
+/****************************/
+
+static ZCONST char Far CannotOpenZipfile[] =
+ "error: cannot open zipfile [ %s ]\n %s\n";
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+#if (defined(ATH_BEO_THS_UNX) || defined(DOS_FLX_NLM_OS2_W32))
+ static ZCONST char Far CannotDeleteOldFile[] =
+ "error: cannot delete old %s\n %s\n";
+#ifdef UNIXBACKUP
+ static ZCONST char Far CannotRenameOldFile[] =
+ "error: cannot rename old %s\n %s\n";
+ static ZCONST char Far BackupSuffix[] = "~";
+#endif
+#endif /* ATH_BEO_THS_UNX || DOS_FLX_NLM_OS2_W32 */
+#ifdef NOVELL_BUG_FAILSAFE
+ static ZCONST char Far NovellBug[] =
+ "error: %s: stat() says does not exist, but fopen() found anyway\n";
+#endif
+ static ZCONST char Far CannotCreateFile[] =
+ "error: cannot create %s\n %s\n";
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+static ZCONST char Far ReadError[] = "error: zipfile read error\n";
+static ZCONST char Far FilenameTooLongTrunc[] =
+ "warning: filename too long--truncating.\n";
+#ifdef UNICODE_SUPPORT
+ static ZCONST char Far UFilenameCorrupt[] =
+ "error: Unicode filename corrupt.\n";
+ static ZCONST char Far UFilenameTooLongTrunc[] =
+ "warning: Converted unicode filename too long--truncating.\n";
+#endif
+static ZCONST char Far ExtraFieldTooLong[] =
+ "warning: extra field too long (%d). Ignoring...\n";
+static ZCONST char Far ExtraFieldCorrupt[] =
+ "warning: extra field (type: 0x%04x) corrupt. Continuing...\n";
+
+#ifdef WINDLL
+ static ZCONST char Far DiskFullQuery[] =
+ "%s: write error (disk full?).\n";
+#else
+ static ZCONST char Far DiskFullQuery[] =
+ "%s: write error (disk full?). Continue? (y/n/^C) ";
+ static ZCONST char Far ZipfileCorrupt[] =
+ "error: zipfile probably corrupt (%s)\n";
+# ifdef SYMLINKS
+ static ZCONST char Far FileIsSymLink[] =
+ "%s exists and is a symbolic link%s.\n";
+# endif
+# ifdef MORE
+ static ZCONST char Far MorePrompt[] = "--More--(%lu)";
+# endif
+ static ZCONST char Far QuitPrompt[] =
+ "--- Press `Q' to quit, or any other key to continue ---";
+ static ZCONST char Far HidePrompt[] = /* "\r \r"; */
+ "\r \r";
+# if CRYPT
+# ifdef MACOS
+ /* SPC: are names on MacOS REALLY so much longer than elsewhere ??? */
+ static ZCONST char Far PasswPrompt[] = "[%s]\n %s password: ";
+# else
+ static ZCONST char Far PasswPrompt[] = "[%s] %s password: ";
+# endif
+ static ZCONST char Far PasswPrompt2[] = "Enter password: ";
+ static ZCONST char Far PasswRetry[] = "password incorrect--reenter: ";
+# endif /* CRYPT */
+#endif /* !WINDLL */
+
+
+
+
+
+/******************************/
+/* Function open_input_file() */
+/******************************/
+
+int open_input_file(__G) /* return 1 if open failed */
+ __GDEF
+{
+ /*
+ * open the zipfile for reading and in BINARY mode to prevent cr/lf
+ * translation, which would corrupt the bitstreams
+ */
+
+#ifdef VMS
+ G.zipfd = open(G.zipfn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
+#else /* !VMS */
+#ifdef MACOS
+ G.zipfd = open(G.zipfn, 0);
+#else /* !MACOS */
+#ifdef CMS_MVS
+ G.zipfd = vmmvs_open_infile(__G);
+#else /* !CMS_MVS */
+#ifdef USE_STRM_INPUT
+ G.zipfd = fopen(G.zipfn, FOPR);
+#else /* !USE_STRM_INPUT */
+ G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);
+#endif /* ?USE_STRM_INPUT */
+#endif /* ?CMS_MVS */
+#endif /* ?MACOS */
+#endif /* ?VMS */
+
+#ifdef USE_STRM_INPUT
+ if (G.zipfd == NULL)
+#else
+ /* if (G.zipfd < 0) */ /* no good for Windows CE port */
+ if (G.zipfd == -1)
+#endif
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile),
+ G.zipfn, strerror(errno)));
+ return 1;
+ }
+ return 0;
+
+} /* end function open_input_file() */
+
+
+
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+
+/***************************/
+/* Function open_outfile() */
+/***************************/
+
+int open_outfile(__G) /* return 1 if fail */
+ __GDEF
+{
+#ifdef DLL
+ if (G.redirect_data)
+ return (redirect_outfile(__G) == FALSE);
+#endif
+#ifdef QDOS
+ QFilename(__G__ G.filename);
+#endif
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_THS_UNX))
+#ifdef BORLAND_STAT_BUG
+ /* Borland 5.0's stat() barfs if the filename has no extension and the
+ * file doesn't exist. */
+ if (access(G.filename, 0) == -1) {
+ FILE *tmp = fopen(G.filename, "wb+");
+
+ /* file doesn't exist, so create a dummy file to keep stat() from
+ * failing (will be over-written anyway) */
+ fputc('0', tmp); /* just to have something in the file */
+ fclose(tmp);
+ }
+#endif /* BORLAND_STAT_BUG */
+#ifdef SYMLINKS
+ if (SSTAT(G.filename, &G.statbuf) == 0 ||
+ lstat(G.filename, &G.statbuf) == 0)
+#else
+ if (SSTAT(G.filename, &G.statbuf) == 0)
+#endif /* ?SYMLINKS */
+ {
+ Trace((stderr, "open_outfile: stat(%s) returns 0: file exists\n",
+ FnFilter1(G.filename)));
+#ifdef UNIXBACKUP
+ if (uO.B_flag) { /* do backup */
+ char *tname;
+ z_stat tmpstat;
+ int blen, flen, tlen;
+
+ blen = strlen(BackupSuffix);
+ flen = strlen(G.filename);
+ tlen = flen + blen + 6; /* includes space for 5 digits */
+ if (tlen >= FILNAMSIZ) { /* in case name is too long, truncate */
+ tname = (char *)malloc(FILNAMSIZ);
+ if (tname == NULL)
+ return 1; /* in case we run out of space */
+ tlen = FILNAMSIZ - 1 - blen;
+ strcpy(tname, G.filename); /* make backup name */
+ tname[tlen] = '\0';
+ if (flen > tlen) flen = tlen;
+ tlen = FILNAMSIZ;
+ } else {
+ tname = (char *)malloc(tlen);
+ if (tname == NULL)
+ return 1; /* in case we run out of space */
+ strcpy(tname, G.filename); /* make backup name */
+ }
+ strcpy(tname+flen, BackupSuffix);
+
+ if (IS_OVERWRT_ALL) {
+ /* If there is a previous backup file, delete it,
+ * otherwise the following rename operation may fail.
+ */
+ if (SSTAT(tname, &tmpstat) == 0)
+ unlink(tname);
+ } else {
+ /* Check if backupname exists, and, if it's true, try
+ * appending numbers of up to 5 digits (or the maximum
+ * "unsigned int" number on 16-bit systems) to the
+ * BackupSuffix, until an unused name is found.
+ */
+ unsigned maxtail, i;
+ char *numtail = tname + flen + blen;
+
+ /* take account of the "unsigned" limit on 16-bit systems: */
+ maxtail = ( ((~0) >= 99999L) ? 99999 : (~0) );
+ switch (tlen - flen - blen - 1) {
+ case 4: maxtail = 9999; break;
+ case 3: maxtail = 999; break;
+ case 2: maxtail = 99; break;
+ case 1: maxtail = 9; break;
+ case 0: maxtail = 0; break;
+ }
+ /* while filename exists */
+ for (i = 0; (i < maxtail) && (SSTAT(tname, &tmpstat) == 0);)
+ sprintf(numtail,"%u", ++i);
+ }
+
+ if (rename(G.filename, tname) != 0) { /* move file */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotRenameOldFile),
+ FnFilter1(G.filename), strerror(errno)));
+ free(tname);
+ return 1;
+ }
+ Trace((stderr, "open_outfile: %s now renamed into %s\n",
+ FnFilter1(G.filename), FnFilter2(tname)));
+ free(tname);
+ } else
+#endif /* UNIXBACKUP */
+ {
+#ifdef DOS_FLX_OS2_W32
+ if (!(G.statbuf.st_mode & S_IWRITE)) {
+ Trace((stderr,
+ "open_outfile: existing file %s is read-only\n",
+ FnFilter1(G.filename)));
+ chmod(G.filename, S_IREAD | S_IWRITE);
+ Trace((stderr, "open_outfile: %s now writable\n",
+ FnFilter1(G.filename)));
+ }
+#endif /* DOS_FLX_OS2_W32 */
+#ifdef NLM
+ /* Give the file read/write permission (non-POSIX shortcut) */
+ chmod(G.filename, 0);
+#endif /* NLM */
+ if (unlink(G.filename) != 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotDeleteOldFile),
+ FnFilter1(G.filename), strerror(errno)));
+ return 1;
+ }
+ Trace((stderr, "open_outfile: %s now deleted\n",
+ FnFilter1(G.filename)));
+ }
+ }
+#endif /* DOS_FLX_NLM_OS2_W32 || ATH_BEO_THS_UNX */
+#ifdef RISCOS
+ if (SWI_OS_File_7(G.filename,0xDEADDEAD,0xDEADDEAD,G.lrec.ucsize)!=NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename), strerror(errno)));
+ return 1;
+ }
+#endif /* RISCOS */
+#ifdef TOPS20
+ char *tfilnam;
+
+ if ((tfilnam = (char *)malloc(2*strlen(G.filename)+1)) == (char *)NULL)
+ return 1;
+ strcpy(tfilnam, G.filename);
+ upper(tfilnam);
+ enquote(tfilnam);
+ if ((G.outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ tfilnam, strerror(errno)));
+ free(tfilnam);
+ return 1;
+ }
+ free(tfilnam);
+#else /* !TOPS20 */
+#ifdef MTS
+ if (uO.aflag)
+ G.outfile = zfopen(G.filename, FOPWT);
+ else
+ G.outfile = zfopen(G.filename, FOPW);
+ if (G.outfile == (FILE *)NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename), strerror(errno)));
+ return 1;
+ }
+#else /* !MTS */
+#ifdef DEBUG
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: doing fopen(%s) for reading\n", FnFilter1(G.filename)));
+ if ((G.outfile = zfopen(G.filename, FOPR)) == (FILE *)NULL)
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: fopen(%s) for reading failed: does not exist\n",
+ FnFilter1(G.filename)));
+ else {
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: fopen(%s) for reading succeeded: file exists\n",
+ FnFilter1(G.filename)));
+ fclose(G.outfile);
+ }
+#endif /* DEBUG */
+#ifdef NOVELL_BUG_FAILSAFE
+ if (G.dne && ((G.outfile = zfopen(G.filename, FOPR)) != (FILE *)NULL)) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NovellBug),
+ FnFilter1(G.filename)));
+ fclose(G.outfile);
+ return 1; /* with "./" fix in checkdir(), should never reach here */
+ }
+#endif /* NOVELL_BUG_FAILSAFE */
+ Trace((stderr, "open_outfile: doing fopen(%s) for writing\n",
+ FnFilter1(G.filename)));
+ {
+#if defined(ATH_BE_UNX) || defined(AOS_VS) || defined(QDOS) || defined(TANDEM)
+ mode_t umask_sav = umask(0077);
+#endif
+#if defined(SYMLINKS) || defined(QLZIP)
+ /* These features require the ability to re-read extracted data from
+ the output files. Output files are created with Read&Write access.
+ */
+ G.outfile = zfopen(G.filename, FOPWR);
+#else
+ G.outfile = zfopen(G.filename, FOPW);
+#endif
+#if defined(ATH_BE_UNX) || defined(AOS_VS) || defined(QDOS) || defined(TANDEM)
+ umask(umask_sav);
+#endif
+ }
+ if (G.outfile == (FILE *)NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename), strerror(errno)));
+ return 1;
+ }
+ Trace((stderr, "open_outfile: fopen(%s) for writing succeeded\n",
+ FnFilter1(G.filename)));
+#endif /* !MTS */
+#endif /* !TOPS20 */
+
+#ifdef USE_FWRITE
+#ifdef DOS_NLM_OS2_W32
+ /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE): bogus */
+ setbuf(G.outfile, (char *)NULL); /* make output unbuffered */
+#else /* !DOS_NLM_OS2_W32 */
+#ifndef RISCOS
+#ifdef _IOFBF /* make output fully buffered (works just about like write()) */
+ setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);
+#else
+ setbuf(G.outfile, (char *)slide);
+#endif
+#endif /* !RISCOS */
+#endif /* ?DOS_NLM_OS2_W32 */
+#endif /* USE_FWRITE */
+#ifdef OS2_W32
+ /* preallocate the final file size to prevent file fragmentation */
+ SetFileSize(G.outfile, G.lrec.ucsize);
+#endif
+ return 0;
+
+} /* end function open_outfile() */
+
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+
+
+
+
+/*
+ * These functions allow NEXTBYTE to function without needing two bounds
+ * checks. Call defer_leftover_input() if you ever have filled G.inbuf
+ * by some means other than readbyte(), and you then want to start using
+ * NEXTBYTE. When going back to processing bytes without NEXTBYTE, call
+ * undefer_input(). For example, extract_or_test_member brackets its
+ * central section that does the decompression with these two functions.
+ * If you need to check the number of bytes remaining in the current
+ * file while using NEXTBYTE, check (G.csize + G.incnt), not G.csize.
+ */
+
+/****************************/
+/* function undefer_input() */
+/****************************/
+
+void undefer_input(__G)
+ __GDEF
+{
+ if (G.incnt > 0)
+ G.csize += G.incnt;
+ if (G.incnt_leftover > 0) {
+ /* We know that "(G.csize < MAXINT)" so we can cast G.csize to int:
+ * This condition was checked when G.incnt_leftover was set > 0 in
+ * defer_leftover_input(), and it is NOT allowed to touch G.csize
+ * before calling undefer_input() when (G.incnt_leftover > 0)
+ * (single exception: see read_byte()'s "G.csize <= 0" handling) !!
+ */
+ G.incnt = G.incnt_leftover + (int)G.csize;
+ G.inptr = G.inptr_leftover - (int)G.csize;
+ G.incnt_leftover = 0;
+ } else if (G.incnt < 0)
+ G.incnt = 0;
+} /* end function undefer_input() */
+
+
+
+
+
+/***********************************/
+/* function defer_leftover_input() */
+/***********************************/
+
+void defer_leftover_input(__G)
+ __GDEF
+{
+ if ((zoff_t)G.incnt > G.csize) {
+ /* (G.csize < MAXINT), we can safely cast it to int !! */
+ if (G.csize < 0L)
+ G.csize = 0L;
+ G.inptr_leftover = G.inptr + (int)G.csize;
+ G.incnt_leftover = G.incnt - (int)G.csize;
+ G.incnt = (int)G.csize;
+ } else
+ G.incnt_leftover = 0;
+ G.csize -= G.incnt;
+} /* end function defer_leftover_input() */
+
+
+
+
+
+/**********************/
+/* Function readbuf() */
+/**********************/
+
+unsigned readbuf(__G__ buf, size) /* return number of bytes read into buf */
+ __GDEF
+ char *buf;
+ register unsigned size;
+{
+ register unsigned count;
+ unsigned n;
+
+ n = size;
+ while (size) {
+ if (G.incnt <= 0) {
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
+ return (n-size);
+ else if (G.incnt < 0) {
+ /* another hack, but no real harm copying same thing twice */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError), /* CANNOT use slide */
+ (ulg)strlen(LoadFarString(ReadError)), 0x401);
+ return 0; /* discarding some data; better than lock-up */
+ }
+ /* buffer ALWAYS starts on a block boundary: */
+ G.cur_zipfile_bufstart += INBUFSIZ;
+ G.inptr = G.inbuf;
+ }
+ count = MIN(size, (unsigned)G.incnt);
+ memcpy(buf, G.inptr, count);
+ buf += count;
+ G.inptr += count;
+ G.incnt -= count;
+ size -= count;
+ }
+ return n;
+
+} /* end function readbuf() */
+
+
+
+
+
+/***********************/
+/* Function readbyte() */
+/***********************/
+
+int readbyte(__G) /* refill inbuf and return a byte if available, else EOF */
+ __GDEF
+{
+ if (G.mem_mode)
+ return EOF;
+ if (G.csize <= 0) {
+ G.csize--; /* for tests done after exploding */
+ G.incnt = 0;
+ return EOF;
+ }
+ if (G.incnt <= 0) {
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) {
+ return EOF;
+ } else if (G.incnt < 0) { /* "fail" (abort, retry, ...) returns this */
+ /* another hack, but no real harm copying same thing twice */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError),
+ (ulg)strlen(LoadFarString(ReadError)), 0x401);
+ echon();
+#ifdef WINDLL
+ longjmp(dll_error_return, 1);
+#else
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR); /* totally bailing; better than lock-up */
+#endif
+ }
+ G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on block bndry */
+ G.inptr = G.inbuf;
+ defer_leftover_input(__G); /* decrements G.csize */
+ }
+
+#if CRYPT
+ if (G.pInfo->encrypted) {
+ uch *p;
+ int n;
+
+ /* This was previously set to decrypt one byte beyond G.csize, when
+ * incnt reached that far. GRR said, "but it's required: why?" This
+ * was a bug in fillinbuf() -- was it also a bug here?
+ */
+ for (n = G.incnt, p = G.inptr; n--; p++)
+ zdecode(*p);
+ }
+#endif /* CRYPT */
+
+ --G.incnt;
+ return *G.inptr++;
+
+} /* end function readbyte() */
+
+
+
+
+
+#if defined(USE_ZLIB) || defined(USE_BZIP2)
+
+/************************/
+/* Function fillinbuf() */
+/************************/
+
+int fillinbuf(__G) /* like readbyte() except returns number of bytes in inbuf */
+ __GDEF
+{
+ if (G.mem_mode ||
+ (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ return 0;
+ G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on a block boundary */
+ G.inptr = G.inbuf;
+ defer_leftover_input(__G); /* decrements G.csize */
+
+#if CRYPT
+ if (G.pInfo->encrypted) {
+ uch *p;
+ int n;
+
+ for (n = G.incnt, p = G.inptr; n--; p++)
+ zdecode(*p);
+ }
+#endif /* CRYPT */
+
+ return G.incnt;
+
+} /* end function fillinbuf() */
+
+#endif /* USE_ZLIB || USE_BZIP2 */
+
+
+
+
+
+/************************/
+/* Function seek_zipf() */
+/************************/
+
+int seek_zipf(__G__ abs_offset)
+ __GDEF
+ zoff_t abs_offset;
+{
+/*
+ * Seek to the block boundary of the block which includes abs_offset,
+ * then read block into input buffer and set pointers appropriately.
+ * If block is already in the buffer, just set the pointers. This function
+ * is used by do_seekable (process.c), extract_or_test_entrylist (extract.c)
+ * and do_string (fileio.c). Also, a slightly modified version is embedded
+ * within extract_or_test_entrylist (extract.c). readbyte() and readbuf()
+ * (fileio.c) are compatible. NOTE THAT abs_offset is intended to be the
+ * "proper offset" (i.e., if there were no extra bytes prepended);
+ * cur_zipfile_bufstart contains the corrected offset.
+ *
+ * Since seek_zipf() is never used during decompression, it is safe to
+ * use the slide[] buffer for the error message.
+ *
+ * returns PK error codes:
+ * PK_BADERR if effective offset in zipfile is negative
+ * PK_EOF if seeking past end of zipfile
+ * PK_OK when seek was successful
+ */
+ zoff_t request = abs_offset + G.extra_bytes;
+ zoff_t inbuf_offset = request % INBUFSIZ;
+ zoff_t bufstart = request - inbuf_offset;
+
+ if (request < 0) {
+ Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ return(PK_BADERR);
+ } else if (bufstart != G.cur_zipfile_bufstart) {
+ Trace((stderr,
+ "fpos_zip: abs_offset = %s, G.extra_bytes = %s\n",
+ FmZofft(abs_offset, NULL, NULL),
+ FmZofft(G.extra_bytes, NULL, NULL)));
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = zlseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ Trace((stderr,
+ " request = %s, (abs+extra) = %s, inbuf_offset = %s\n",
+ FmZofft(request, NULL, NULL),
+ FmZofft((abs_offset+G.extra_bytes), NULL, NULL),
+ FmZofft(inbuf_offset, NULL, NULL)));
+ Trace((stderr, " bufstart = %s, cur_zipfile_bufstart = %s\n",
+ FmZofft(bufstart, NULL, NULL),
+ FmZofft(G.cur_zipfile_bufstart, NULL, NULL)));
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ return(PK_EOF);
+ G.incnt -= (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ } else {
+ G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ }
+ return(PK_OK);
+} /* end function seek_zipf() */
+
+
+
+
+
+#ifndef VMS /* for VMS use code in vms.c */
+
+/********************/
+/* Function flush() */ /* returns PK error codes: */
+/********************/ /* if tflag => always 0; PK_DISK if write error */
+
+int flush(__G__ rawbuf, size, unshrink)
+ __GDEF
+ uch *rawbuf;
+ ulg size;
+ int unshrink;
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+{
+ int ret;
+
+ /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions
+ * cannot handle writes of 64k blocks at once. For these systems, the
+ * blocks to flush are split into pieces of 32k or less.
+ */
+ while (size > 0x8000L) {
+ ret = partflush(__G__ rawbuf, 0x8000L, unshrink);
+ if (ret != PK_OK)
+ return ret;
+ size -= 0x8000L;
+ rawbuf += (extent)0x8000;
+ }
+ return partflush(__G__ rawbuf, size, unshrink);
+} /* end function flush() */
+
+
+/************************/
+/* Function partflush() */ /* returns PK error codes: */
+/************************/ /* if tflag => always 0; PK_DISK if write error */
+
+static int partflush(__G__ rawbuf, size, unshrink)
+ __GDEF
+ uch *rawbuf; /* cannot be ZCONST, gets passed to (*G.message)() */
+ ulg size;
+ int unshrink;
+#endif /* USE_DEFLATE64 && __16BIT__ */
+{
+ register uch *p;
+ register uch *q;
+ uch *transbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ ulg transbufsiz;
+#endif
+ /* static int didCRlast = FALSE; moved to globals.h */
+
+
+/*---------------------------------------------------------------------------
+ Compute the CRC first; if testing or if disk is full, that's it.
+ ---------------------------------------------------------------------------*/
+
+ G.crc32val = crc32(G.crc32val, rawbuf, (extent)size);
+
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_IN_PROGRESS, G.zipfn, G.filename, NULL))
+ return IZ_CTRLC; /* cancel operation by user request */
+#endif
+
+ if (uO.tflag || size == 0L) /* testing or nothing to write: all done */
+ return PK_OK;
+
+ if (G.disk_full)
+ return PK_DISK; /* disk already full: ignore rest of file */
+
+/*---------------------------------------------------------------------------
+ Write the bytes rawbuf[0..size-1] to the output device, first converting
+ end-of-lines and ASCII/EBCDIC as needed. If SMALL_MEM or MED_MEM are NOT
+ defined, outbuf is assumed to be at least as large as rawbuf and is not
+ necessarily checked for overflow.
+ ---------------------------------------------------------------------------*/
+
+ if (!G.pInfo->textmode) { /* write raw binary data */
+ /* GRR: note that for standard MS-DOS compilers, size argument to
+ * fwrite() can never be more than 65534, so WriteError macro will
+ * have to be rewritten if size can ever be that large. For now,
+ * never more than 32K. Also note that write() returns an int, which
+ * doesn't necessarily limit size to 32767 bytes if write() is used
+ * on 16-bit systems but does make it more of a pain; however, because
+ * at least MSC 5.1 has a lousy implementation of fwrite() (as does
+ * DEC Ultrix cc), write() is used anyway.
+ */
+#ifdef DLL
+ if (G.redirect_data) {
+#ifdef NO_SLIDE_REDIR
+ if (writeToMemory(__G__ rawbuf, (extent)size)) return PK_ERR;
+#else
+ writeToMemory(__G__ rawbuf, (extent)size);
+#endif
+ } else
+#endif
+ if (!uO.cflag && WriteError(rawbuf, size, G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G, rawbuf, size, 0))
+ return PK_OK;
+ } else { /* textmode: aflag is true */
+ if (unshrink) {
+ /* rawbuf = outbuf */
+ transbuf = G.outbuf2;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ transbufsiz = TRANSBUFSIZ;
+#endif
+ } else {
+ /* rawbuf = slide */
+ transbuf = G.outbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ transbufsiz = OUTBUFSIZ;
+ Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n",
+ (unsigned)OUTBUFSIZ));
+#endif
+ }
+ if (G.newfile) {
+#ifdef VMS_TEXT_CONV
+ if (G.pInfo->hostnum == VMS_ && G.extra_field &&
+ is_vms_varlen_txt(__G__ G.extra_field,
+ G.lrec.extra_field_length))
+ G.VMS_line_state = 0; /* 0: ready to read line length */
+ else
+ G.VMS_line_state = -1; /* -1: don't treat as VMS text */
+#endif
+ G.didCRlast = FALSE; /* no previous buffers written */
+ G.newfile = FALSE;
+ }
+
+#ifdef VMS_TEXT_CONV
+ if (G.VMS_line_state >= 0)
+ {
+ p = rawbuf;
+ q = transbuf;
+ while ((extent)(p-rawbuf) < (extent)size) {
+ switch (G.VMS_line_state) {
+
+ /* 0: ready to read line length */
+ case 0:
+ G.VMS_line_length = 0;
+ if ((extent)(p-rawbuf) == (extent)size-1) {
+ /* last char */
+ G.VMS_line_length = (unsigned)(*p++);
+ G.VMS_line_state = 1;
+ } else {
+ G.VMS_line_length = makeword(p);
+ p += 2;
+ G.VMS_line_state = 2;
+ }
+ G.VMS_line_pad =
+ ((G.VMS_line_length & 1) != 0); /* odd */
+ break;
+
+ /* 1: read one byte of length, need second */
+ case 1:
+ G.VMS_line_length += ((unsigned)(*p++) << 8);
+ G.VMS_line_state = 2;
+ break;
+
+ /* 2: ready to read VMS_line_length chars */
+ case 2:
+ {
+ extent remaining = (extent)size+(rawbuf-p);
+ extent outroom;
+
+ if (G.VMS_line_length < remaining) {
+ remaining = G.VMS_line_length;
+ G.VMS_line_state = 3;
+ }
+
+ outroom = transbuf+(extent)transbufsiz-q;
+ if (remaining >= outroom) {
+ remaining -= outroom;
+ for (;outroom > 0; p++, outroom--)
+ *q++ = native(*p);
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf,
+ (extent)(q-transbuf))) return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag && WriteError(transbuf,
+ (extent)(q-transbuf), G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ /* fall through to normal case */
+ }
+ G.VMS_line_length -= remaining;
+ for (;remaining > 0; p++, remaining--)
+ *q++ = native(*p);
+ }
+ break;
+
+ /* 3: ready to PutNativeEOL */
+ case 3:
+ if (q > transbuf+(extent)transbufsiz-lenEOL) {
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf,
+ (extent)(q-transbuf))) return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag &&
+ WriteError(transbuf, (extent)(q-transbuf),
+ G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ }
+ PutNativeEOL
+ G.VMS_line_state = G.VMS_line_pad ? 4 : 0;
+ break;
+
+ /* 4: ready to read pad byte */
+ case 4:
+ ++p;
+ G.VMS_line_state = 0;
+ break;
+ }
+ } /* end while */
+
+ } else
+#endif /* VMS_TEXT_CONV */
+
+ /*-----------------------------------------------------------------------
+ Algorithm: CR/LF => native; lone CR => native; lone LF => native.
+ This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
+ stream-oriented files, not record-oriented).
+ -----------------------------------------------------------------------*/
+
+ /* else not VMS text */ {
+ p = rawbuf;
+ if (*p == LF && G.didCRlast)
+ ++p;
+ G.didCRlast = FALSE;
+ for (q = transbuf; (extent)(p-rawbuf) < (extent)size; ++p) {
+ if (*p == CR) { /* lone CR or CR/LF: treat as EOL */
+ PutNativeEOL
+ if ((extent)(p-rawbuf) == (extent)size-1)
+ /* last char in buffer */
+ G.didCRlast = TRUE;
+ else if (p[1] == LF) /* get rid of accompanying LF */
+ ++p;
+ } else if (*p == LF) /* lone LF */
+ PutNativeEOL
+ else
+#ifndef DOS_FLX_OS2_W32
+ if (*p != CTRLZ) /* lose all ^Z's */
+#endif
+ *q++ = native(*p);
+
+#if (defined(SMALL_MEM) || defined(MED_MEM))
+# if (lenEOL == 1) /* don't check unshrink: both buffers small but equal */
+ if (!unshrink)
+# endif
+ /* check for danger of buffer overflow and flush */
+ if (q > transbuf+(extent)transbufsiz-lenEOL) {
+ Trace((stderr,
+ "p - rawbuf = %u q-transbuf = %u size = %lu\n",
+ (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+ if (!uO.cflag && WriteError(transbuf,
+ (extent)(q-transbuf), G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ continue;
+ }
+#endif /* SMALL_MEM || MED_MEM */
+ }
+ }
+
+ /*-----------------------------------------------------------------------
+ Done translating: write whatever we've got to file (or screen).
+ -----------------------------------------------------------------------*/
+
+ Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n",
+ (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+ if (q > transbuf) {
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf, (extent)(q-transbuf)))
+ return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf),
+ G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf,
+ (ulg)(q-transbuf), 0))
+ return PK_OK;
+ }
+ }
+
+ return PK_OK;
+
+} /* end function flush() [resp. partflush() for 16-bit Deflate64 support] */
+
+
+
+
+
+#ifdef VMS_TEXT_CONV
+
+/********************************/
+/* Function is_vms_varlen_txt() */
+/********************************/
+
+static int is_vms_varlen_txt(__G__ ef_buf, ef_len)
+ __GDEF
+ uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+ uch *eb_data;
+ unsigned eb_datlen;
+#define VMSREC_C_UNDEF 0
+#define VMSREC_C_VAR 2
+ uch vms_rectype = VMSREC_C_UNDEF;
+ /* uch vms_fileorg = 0; */ /* currently, fileorg is not used... */
+
+#define VMSPK_ITEMID 0
+#define VMSPK_ITEMLEN 2
+#define VMSPK_ITEMHEADSZ 4
+
+#define VMSATR_C_RECATTR 4
+#define VMS_FABSIG 0x42414656 /* "VFAB" */
+/* offsets of interesting fields in VMS fabdef structure */
+#define VMSFAB_B_RFM 31 /* record format byte */
+#define VMSFAB_B_ORG 29 /* file organization byte */
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return FALSE;
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "is_vms_varlen_txt: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id) {
+ case EF_PKVMS:
+ /* The PKVMS e.f. raw data part consists of:
+ * a) 4 bytes CRC checksum
+ * b) list of uncompressed variable-length data items
+ * Each data item is introduced by a fixed header
+ * - 2 bytes data type ID
+ * - 2 bytes <size> of data
+ * - <size> bytes of actual attribute data
+ */
+
+ /* get pointer to start of data and its total length */
+ eb_data = ef_buf+(EB_HEADSIZE+4);
+ eb_datlen = eb_len-4;
+
+ /* test the CRC checksum */
+ if (makelong(ef_buf+EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL, eb_data, (extent)eb_datlen))
+ {
+ Info(slide, 1, ((char *)slide,
+ "[Warning: CRC error, discarding PKWARE extra field]\n"));
+ /* skip over the data analysis code */
+ break;
+ }
+
+ /* scan through the attribute data items */
+ while (eb_datlen > 4)
+ {
+ unsigned fldsize = makeword(&eb_data[VMSPK_ITEMLEN]);
+
+ /* check the item type word */
+ switch (makeword(&eb_data[VMSPK_ITEMID])) {
+ case VMSATR_C_RECATTR:
+ /* we have found the (currently only) interesting
+ * data item */
+ if (fldsize >= 1) {
+ vms_rectype = eb_data[VMSPK_ITEMHEADSZ] & 15;
+ /* vms_fileorg = eb_data[VMSPK_ITEMHEADSZ] >> 4; */
+ }
+ break;
+ default:
+ break;
+ }
+ /* skip to next data item */
+ eb_datlen -= fldsize + VMSPK_ITEMHEADSZ;
+ eb_data += fldsize + VMSPK_ITEMHEADSZ;
+ }
+ break;
+
+ case EF_IZVMS:
+ if (makelong(ef_buf+EB_HEADSIZE) == VMS_FABSIG) {
+ if ((eb_data = extract_izvms_block(__G__
+ ef_buf+EB_HEADSIZE, eb_len,
+ &eb_datlen, NULL, 0))
+ != NULL)
+ {
+ if (eb_datlen >= VMSFAB_B_RFM+1) {
+ vms_rectype = eb_data[VMSFAB_B_RFM] & 15;
+ /* vms_fileorg = eb_data[VMSFAB_B_ORG] >> 4; */
+ }
+ free(eb_data);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return (vms_rectype == VMSREC_C_VAR);
+
+} /* end function is_vms_varlen_txtfile() */
+
+#endif /* VMS_TEXT_CONV */
+
+
+
+
+/*************************/
+/* Function disk_error() */
+/*************************/
+
+static int disk_error(__G)
+ __GDEF
+{
+ /* OK to use slide[] here because this file is finished regardless */
+ Info(slide, 0x4a1, ((char *)slide, LoadFarString(DiskFullQuery),
+ FnFilter1(G.filename)));
+
+#ifndef WINDLL
+ fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
+ if (*G.answerbuf == 'y') /* stop writing to this file */
+ G.disk_full = 1; /* (outfile bad?), but new OK */
+ else
+#endif
+ G.disk_full = 2; /* no: exit program */
+
+ return PK_DISK;
+
+} /* end function disk_error() */
+
+#endif /* !VMS */
+
+
+
+
+
+/*****************************/
+/* Function UzpMessagePrnt() */
+/*****************************/
+
+int UZ_EXP UzpMessagePrnt(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ ulg size; /* length of string (may include nulls) */
+ int flag; /* flag bits */
+{
+ /* IMPORTANT NOTE:
+ * The name of the first parameter of UzpMessagePrnt(), which passes
+ * the "Uz_Globs" address, >>> MUST <<< be identical to the string
+ * expansion of the __G__ macro in the REENTRANT case (see globals.h).
+ * This name identity is mandatory for the LoadFarString() macro
+ * (in the SMALL_MEM case) !!!
+ */
+ int error;
+ uch *q=buf, *endbuf=buf+(unsigned)size;
+#ifdef MORE
+ uch *p=buf;
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ int islinefeed = FALSE;
+#endif
+#endif
+ FILE *outfp;
+
+
+/*---------------------------------------------------------------------------
+ These tests are here to allow fine-tuning of UnZip's output messages,
+ but none of them will do anything without setting the appropriate bit
+ in the flag argument of every Info() statement which is to be turned
+ *off*. That is, all messages are currently turned on for all ports.
+ To turn off *all* messages, use the UzpMessageNull() function instead
+ of this one.
+ ---------------------------------------------------------------------------*/
+
+#if (defined(OS2) && defined(DLL))
+ if (MSG_NO_DLL2(flag)) /* if OS/2 DLL bit is set, do NOT print this msg */
+ return 0;
+#endif
+#ifdef WINDLL
+ if (MSG_NO_WDLL(flag))
+ return 0;
+#endif
+#ifdef WINDLL
+ if (MSG_NO_WGUI(flag))
+ return 0;
+#endif
+/*
+#ifdef ACORN_GUI
+ if (MSG_NO_AGUI(flag))
+ return 0;
+#endif
+ */
+#ifdef DLL /* don't display message if data is redirected */
+ if (((Uz_Globs *)pG)->redirect_data &&
+ !((Uz_Globs *)pG)->redirect_text)
+ return 0;
+#endif
+
+ if (MSG_STDERR(flag) && !((Uz_Globs *)pG)->UzO.tflag)
+ outfp = (FILE *)stderr;
+ else
+ outfp = (FILE *)stdout;
+
+#ifdef QUERY_TRNEWLN
+ /* some systems require termination of query prompts with '\n' to force
+ * immediate display */
+ if (MSG_MNEWLN(flag)) { /* assumes writable buffer (e.g., slide[]) */
+ *endbuf++ = '\n'; /* with room for one more char at end of buf */
+ ++size; /* (safe assumption: only used for four */
+ } /* short queries in extract.c and fileio.c) */
+#endif
+
+ if (MSG_TNEWLN(flag)) { /* again assumes writable buffer: fragile... */
+ if ((!size && !((Uz_Globs *)pG)->sol) ||
+ (size && (endbuf[-1] != '\n')))
+ {
+ *endbuf++ = '\n';
+ ++size;
+ }
+ }
+
+#ifdef MORE
+# ifdef SCREENSIZE
+ /* room for --More-- and one line of overlap: */
+# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ SCREENSIZE(&((Uz_Globs *)pG)->height, &((Uz_Globs *)pG)->width);
+# else
+ SCREENSIZE(&((Uz_Globs *)pG)->height, (int *)NULL);
+# endif
+ ((Uz_Globs *)pG)->height -= 2;
+# else
+ /* room for --More-- and one line of overlap: */
+ ((Uz_Globs *)pG)->height = SCREENLINES - 2;
+# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ ((Uz_Globs *)pG)->width = SCREENWIDTH;
+# endif
+# endif
+#endif /* MORE */
+
+ if (MSG_LNEWLN(flag) && !((Uz_Globs *)pG)->sol) {
+ /* not at start of line: want newline */
+#ifdef OS2DLL
+ if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+ putc('\n', outfp);
+ fflush(outfp);
+#ifdef MORE
+ if (((Uz_Globs *)pG)->M_flag)
+ {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ ((Uz_Globs *)pG)->chars = 0;
+#endif
+ ++((Uz_Globs *)pG)->numlines;
+ ++((Uz_Globs *)pG)->lines;
+ if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+ (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+ LoadFarString(MorePrompt), 1);
+ }
+#endif /* MORE */
+ if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+ !isatty(1) && isatty(2))
+ {
+ /* error output from testing redirected: also send to stderr */
+ putc('\n', stderr);
+ fflush(stderr);
+ }
+#ifdef OS2DLL
+ } else
+ REDIRECTC('\n');
+#endif
+ ((Uz_Globs *)pG)->sol = TRUE;
+ }
+
+ /* put zipfile name, filename and/or error/warning keywords here */
+
+#ifdef MORE
+ if (((Uz_Globs *)pG)->M_flag
+#ifdef OS2DLL
+ && !((Uz_Globs *)pG)->redirect_text
+#endif
+ )
+ {
+ while (p < endbuf) {
+ if (*p == '\n') {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ islinefeed = TRUE;
+ } else if (SCREENLWRAP) {
+ if (*p == '\r') {
+ ((Uz_Globs *)pG)->chars = 0;
+ } else {
+# ifdef TABSIZE
+ if (*p == '\t')
+ ((Uz_Globs *)pG)->chars +=
+ (TABSIZE - (((Uz_Globs *)pG)->chars % TABSIZE));
+ else
+# endif
+ ++((Uz_Globs *)pG)->chars;
+
+ if (((Uz_Globs *)pG)->chars >= ((Uz_Globs *)pG)->width)
+ islinefeed = TRUE;
+ }
+ }
+ if (islinefeed) {
+ islinefeed = FALSE;
+ ((Uz_Globs *)pG)->chars = 0;
+#endif /* (SCREENWIDTH && SCREEN_LWRAP) */
+ ++((Uz_Globs *)pG)->numlines;
+ ++((Uz_Globs *)pG)->lines;
+ if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+ {
+ if ((error = WriteTxtErr(q, p-q+1, outfp)) != 0)
+ return error;
+ fflush(outfp);
+ ((Uz_Globs *)pG)->sol = TRUE;
+ q = p + 1;
+ (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+ LoadFarString(MorePrompt), 1);
+ }
+ }
+ INCSTR(p);
+ } /* end while */
+ size = (ulg)(p - q); /* remaining text */
+ }
+#endif /* MORE */
+
+ if (size) {
+#ifdef OS2DLL
+ if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+ if ((error = WriteTxtErr(q, size, outfp)) != 0)
+ return error;
+#ifndef VMS /* 2005-09-16 SMS. See note at "WriteTxtErr()", above. */
+ fflush(outfp);
+#endif
+ if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+ !isatty(1) && isatty(2))
+ {
+ /* error output from testing redirected: also send to stderr */
+ if ((error = WriteTxtErr(q, size, stderr)) != 0)
+ return error;
+ fflush(stderr);
+ }
+#ifdef OS2DLL
+ } else { /* GRR: this is ugly: hide with macro */
+ if ((error = REDIRECTPRINT(q, size)) != 0)
+ return error;
+ }
+#endif /* OS2DLL */
+ ((Uz_Globs *)pG)->sol = (endbuf[-1] == '\n');
+ }
+ return 0;
+
+} /* end function UzpMessagePrnt() */
+
+
+
+
+
+#ifdef DLL
+
+/*****************************/
+/* Function UzpMessageNull() */ /* convenience routine for no output at all */
+/*****************************/
+
+int UZ_EXP UzpMessageNull(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ ulg size; /* length of string (may include nulls) */
+ int flag; /* flag bits */
+{
+ return 0;
+
+} /* end function UzpMessageNull() */
+
+#endif /* DLL */
+
+
+
+
+
+/***********************/
+/* Function UzpInput() */ /* GRR: this is a placeholder for now */
+/***********************/
+
+int UZ_EXP UzpInput(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ int *size; /* (address of) size of buf and of returned string */
+ int flag; /* flag bits (bit 0: no echo) */
+{
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG; buf = buf; flag = flag;
+
+ *size = 0;
+ return 0;
+
+} /* end function UzpInput() */
+
+
+
+
+
+#if (!defined(WINDLL) && !defined(MACOS))
+
+/***************************/
+/* Function UzpMorePause() */
+/***************************/
+
+void UZ_EXP UzpMorePause(pG, prompt, flag)
+ zvoid *pG; /* globals struct: always passed */
+ ZCONST char *prompt; /* "--More--" prompt */
+ int flag; /* 0 = any char OK; 1 = accept only '\n', ' ', q */
+{
+ uch c;
+
+/*---------------------------------------------------------------------------
+ Print a prompt and wait for the user to press a key, then erase prompt
+ if possible.
+ ---------------------------------------------------------------------------*/
+
+ if (!((Uz_Globs *)pG)->sol)
+ fprintf(stderr, "\n");
+ /* numlines may or may not be used: */
+ fprintf(stderr, prompt, ((Uz_Globs *)pG)->numlines);
+ fflush(stderr);
+ if (flag & 1) {
+ do {
+ c = (uch)FGETCH(0);
+ } while (
+#ifdef THEOS
+ c != 17 && /* standard QUIT key */
+#endif
+ c != '\r' && c != '\n' && c != ' ' && c != 'q' && c != 'Q');
+ } else
+ c = (uch)FGETCH(0);
+
+ /* newline was not echoed, so cover up prompt line */
+ fprintf(stderr, LoadFarString(HidePrompt));
+ fflush(stderr);
+
+ if (
+#ifdef THEOS
+ (c == 17) || /* standard QUIT key */
+#endif
+ (ToLower(c) == 'q')) {
+ DESTROYGLOBALS();
+ EXIT(PK_COOL);
+ }
+
+ ((Uz_Globs *)pG)->sol = TRUE;
+
+#ifdef MORE
+ /* space for another screen, enter for another line. */
+ if ((flag & 1) && c == ' ')
+ ((Uz_Globs *)pG)->lines = 0;
+#endif /* MORE */
+
+} /* end function UzpMorePause() */
+
+#endif /* !WINDLL && !MACOS */
+
+
+
+
+#ifndef WINDLL
+
+/**************************/
+/* Function UzpPassword() */
+/**************************/
+
+int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, efn)
+ zvoid *pG; /* pointer to UnZip's internal global vars */
+ int *rcnt; /* retry counter */
+ char *pwbuf; /* buffer for password */
+ int size; /* size of password buffer */
+ ZCONST char *zfn; /* name of zip archive */
+ ZCONST char *efn; /* name of archive entry being processed */
+{
+#if CRYPT
+ int r = IZ_PW_ENTERED;
+ char *m;
+ char *prompt;
+ char *ep;
+ char *zp;
+
+#ifndef REENTRANT
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG;
+#endif
+
+ if (*rcnt == 0) { /* First call for current entry */
+ *rcnt = 2;
+ zp = FnFilter1( zfn);
+ ep = FnFilter2( efn);
+ prompt = (char *)malloc( /* Slightly too long (2* "%s"). */
+ sizeof( PasswPrompt)+ strlen( zp)+ strlen( ep));
+ if (prompt != (char *)NULL) {
+ sprintf(prompt, LoadFarString(PasswPrompt), zp, ep);
+ m = prompt;
+ } else
+ m = (char *)LoadFarString(PasswPrompt2);
+ } else { /* Retry call, previous password was wrong */
+ (*rcnt)--;
+ prompt = NULL;
+ m = (char *)LoadFarString(PasswRetry);
+ }
+
+ m = getp(__G__ m, pwbuf, size);
+ if (prompt != (char *)NULL) {
+ free(prompt);
+ }
+ if (m == (char *)NULL) {
+ r = IZ_PW_ERROR;
+ }
+ else if (*pwbuf == '\0') {
+ r = IZ_PW_CANCELALL;
+ }
+ return r;
+
+#else /* !CRYPT */
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG; rcnt = rcnt; pwbuf = pwbuf; size = size; zfn = zfn; efn = efn;
+
+ return IZ_PW_ERROR; /* internal error; function should never get called */
+#endif /* ?CRYPT */
+
+} /* end function UzpPassword() */
+
+
+
+
+
+/**********************/
+/* Function handler() */
+/**********************/
+
+void handler(signal) /* upon interrupt, turn on echo and exit cleanly */
+ int signal;
+{
+ GETGLOBALS();
+
+#if !(defined(SIGBUS) || defined(SIGSEGV)) /* add a newline if not at */
+ (*G.message)((zvoid *)&G, slide, 0L, 0x41); /* start of line (to stderr; */
+#endif /* slide[] should be safe) */
+
+ echon();
+
+#ifdef SIGBUS
+ if (signal == SIGBUS) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+ "bus error"));
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR);
+ }
+#endif /* SIGBUS */
+
+#ifdef SIGILL
+ if (signal == SIGILL) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+ "illegal instruction"));
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR);
+ }
+#endif /* SIGILL */
+
+#ifdef SIGSEGV
+ if (signal == SIGSEGV) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+ "segmentation violation"));
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR);
+ }
+#endif /* SIGSEGV */
+
+ /* probably ctrl-C */
+ DESTROYGLOBALS();
+#if defined(AMIGA) && defined(__SASC)
+ _abort();
+#endif
+ EXIT(IZ_CTRLC); /* was EXIT(0), then EXIT(PK_ERR) */
+}
+
+#endif /* !WINDLL */
+
+
+
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+#if (!defined(OS2) || defined(TIMESTAMP))
+
+#if (!defined(HAVE_MKTIME) || defined(WIN32))
+/* also used in amiga/filedate.c and win32/win32.c */
+ZCONST ush ydays[] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+#endif
+
+/*******************************/
+/* Function dos_to_unix_time() */ /* used for freshening/updating/timestamps */
+/*******************************/
+
+time_t dos_to_unix_time(dosdatetime)
+ ulg dosdatetime;
+{
+ time_t m_time;
+
+#ifdef HAVE_MKTIME
+
+ ZCONST time_t now = time(NULL);
+ struct tm *tm;
+# define YRBASE 1900
+
+ tm = localtime(&now);
+ tm->tm_isdst = -1; /* let mktime determine if DST is in effect */
+
+ /* dissect date */
+ tm->tm_year = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+ tm->tm_mon = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+ tm->tm_mday = ((int)(dosdatetime >> 16) & 0x1f);
+
+ /* dissect time */
+ tm->tm_hour = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+ tm->tm_min = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+ tm->tm_sec = (int)((unsigned)dosdatetime << 1) & 0x3e;
+
+ m_time = mktime(tm);
+ NATIVE_TO_TIMET(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ TTrace((stderr, " final m_time = %lu\n", (ulg)m_time));
+
+#else /* !HAVE_MKTIME */
+
+ int yr, mo, dy, hh, mm, ss;
+#ifdef TOPS20
+# define YRBASE 1900
+ struct tmx *tmx;
+ char temp[20];
+#else /* !TOPS20 */
+# define YRBASE 1970
+ int leap;
+ unsigned days;
+ struct tm *tm;
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res;
+#else /* ! WIN32 */
+#ifndef BSD4_4 /* GRR: change to !defined(MODERN) ? */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+ struct timeb tbp;
+#else /* !(BSD || MTS || __GO32__) */
+#ifdef DECLARE_TIMEZONE
+ extern time_t timezone;
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* !BSD4_4 */
+#endif /* ?WIN32 */
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+
+ /* dissect date */
+ yr = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+ mo = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+ dy = ((int)(dosdatetime >> 16) & 0x1f) - 1;
+
+ /* dissect time */
+ hh = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+ mm = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+ ss = (int)((unsigned)dosdatetime & 0x1f) * 2;
+
+#ifdef TOPS20
+ tmx = (struct tmx *)malloc(sizeof(struct tmx));
+ sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
+ time_parse(temp, tmx, (char *)0);
+ m_time = time_make(tmx);
+ free(tmx);
+
+#else /* !TOPS20 */
+
+/*---------------------------------------------------------------------------
+ Calculate the number of seconds since the epoch, usually 1 January 1970.
+ ---------------------------------------------------------------------------*/
+
+ /* leap = # of leap yrs from YRBASE up to but not including current year */
+ leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
+
+ /* calculate days from BASE to this year and add expired days this year */
+ days = (yr * 365) + (leap - 492) + ydays[mo];
+
+ /* if year is a leap year and month is after February, add another day */
+ if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
+ ++days; /* OK through 2199 */
+
+ /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
+ m_time = (time_t)((unsigned long)(days + dy) * 86400L +
+ (unsigned long)hh * 3600L +
+ (unsigned long)(mm * 60 + ss));
+ /* - 1; MS-DOS times always rounded up to nearest even second */
+ TTrace((stderr, "dos_to_unix_time:\n"));
+ TTrace((stderr, " m_time before timezone = %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+ Adjust for local standard timezone offset.
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+ /* account for timezone differences */
+ res = GetTimeZoneInformation(&tzinfo);
+ if (res != TIME_ZONE_ID_INVALID)
+ {
+ m_time += 60*(tzinfo.Bias);
+#else /* !WIN32 */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+#ifdef BSD4_4
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+ if ((tm = localtime(&m_time)) != (struct tm *)NULL)
+ m_time -= tm->tm_gmtoff; /* sec. EAST of GMT: subtr. */
+#else /* !(BSD4_4 */
+ ftime(&tbp); /* get `timezone' */
+ m_time += tbp.timezone * 60L; /* seconds WEST of GMT: add */
+#endif /* ?(BSD4_4 || __EMX__) */
+#else /* !(BSD || MTS || __GO32__) */
+ /* tzset was already called at start of process_zipfiles() */
+ /* tzset(); */ /* set `timezone' variable */
+#ifndef __BEOS__ /* BeOS DR8 has no timezones... */
+ m_time += timezone; /* seconds WEST of GMT: add */
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* ?WIN32 */
+ TTrace((stderr, " m_time after timezone = %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+ Adjust for local daylight savings (summer) time.
+ ---------------------------------------------------------------------------*/
+
+#ifndef BSD4_4 /* (DST already added to tm_gmtoff, so skip tm_isdst) */
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+ TIMET_TO_NATIVE(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ if (((tm = localtime((time_t *)&m_time)) != NULL) && tm->tm_isdst)
+#ifdef WIN32
+ m_time += 60L * tzinfo.DaylightBias; /* adjust with DST bias */
+ else
+ m_time += 60L * tzinfo.StandardBias; /* add StdBias (normally 0) */
+#else
+ m_time -= 60L * 60L; /* adjust for daylight savings time */
+#endif
+ NATIVE_TO_TIMET(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ TTrace((stderr, " m_time after DST = %lu\n", (ulg)m_time));
+#endif /* !BSD4_4 */
+#ifdef WIN32
+ }
+#endif
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+#endif /* ?HAVE_MKTIME */
+
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+
+ return m_time;
+
+} /* end function dos_to_unix_time() */
+
+#endif /* !OS2 || TIMESTAMP */
+#endif /* !VMS && !CMS_MVS */
+
+
+
+#if (!defined(VMS) && !defined(OS2) && !defined(CMS_MVS))
+
+/******************************/
+/* Function check_for_newer() */ /* used for overwriting/freshening/updating */
+/******************************/
+
+int check_for_newer(__G__ filename) /* return 1 if existing file is newer */
+ __GDEF /* or equal; 0 if older; -1 if doesn't */
+ char *filename; /* exist yet */
+{
+ time_t existing, archive;
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+#endif
+#ifdef AOS_VS
+ long dyy, dmm, ddd, dhh, dmin, dss;
+
+
+ dyy = (lrec.last_mod_dos_datetime >> 25) + 1980;
+ dmm = (lrec.last_mod_dos_datetime >> 21) & 0x0f;
+ ddd = (lrec.last_mod_dos_datetime >> 16) & 0x1f;
+ dhh = (lrec.last_mod_dos_datetime >> 11) & 0x1f;
+ dmin = (lrec.last_mod_dos_datetime >> 5) & 0x3f;
+ dss = (lrec.last_mod_dos_datetime & 0x1f) * 2;
+
+ /* under AOS/VS, file times can only be set at creation time,
+ * with the info in a special DG format. Make sure we can create
+ * it here - we delete it later & re-create it, whether or not
+ * it exists now.
+ */
+ if (!zvs_create(filename, (((ulg)dgdate(dmm, ddd, dyy)) << 16) |
+ (dhh*1800L + dmin*30L + dss/2L), -1L, -1L, (char *) -1, -1, -1, -1))
+ return DOES_NOT_EXIST;
+#endif /* AOS_VS */
+
+ Trace((stderr, "check_for_newer: doing stat(%s)\n", FnFilter1(filename)));
+ if (SSTAT(filename, &G.statbuf)) {
+ Trace((stderr,
+ "check_for_newer: stat(%s) returns %d: file does not exist\n",
+ FnFilter1(filename), SSTAT(filename, &G.statbuf)));
+#ifdef SYMLINKS
+ Trace((stderr, "check_for_newer: doing lstat(%s)\n",
+ FnFilter1(filename)));
+ /* GRR OPTION: could instead do this test ONLY if G.symlnk is true */
+ if (lstat(filename, &G.statbuf) == 0) {
+ Trace((stderr,
+ "check_for_newer: lstat(%s) returns 0: symlink does exist\n",
+ FnFilter1(filename)));
+ if (QCOND2 && !IS_OVERWRT_ALL)
+ Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+ FnFilter1(filename), " with no real file"));
+ return EXISTS_AND_OLDER; /* symlink dates are meaningless */
+ }
+#endif /* SYMLINKS */
+ return DOES_NOT_EXIST;
+ }
+ Trace((stderr, "check_for_newer: stat(%s) returns 0: file exists\n",
+ FnFilter1(filename)));
+
+#ifdef SYMLINKS
+ /* GRR OPTION: could instead do this test ONLY if G.symlnk is true */
+ if (lstat(filename, &G.statbuf) == 0 && S_ISLNK(G.statbuf.st_mode)) {
+ Trace((stderr, "check_for_newer: %s is a symbolic link\n",
+ FnFilter1(filename)));
+ if (QCOND2 && !IS_OVERWRT_ALL)
+ Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+ FnFilter1(filename), ""));
+ return EXISTS_AND_OLDER; /* symlink dates are meaningless */
+ }
+#endif /* SYMLINKS */
+
+ NATIVE_TO_TIMET(G.statbuf.st_mtime) /* NOP unless MSC 7.0 or Macintosh */
+
+#ifdef USE_EF_UT_TIME
+ /* The `Unix extra field mtime' should be used for comparison with the
+ * time stamp of the existing file >>>ONLY<<< when the EF info is also
+ * used to set the modification time of the extracted file.
+ */
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
+ G.lrec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME))
+ {
+ TTrace((stderr, "check_for_newer: using Unix extra field mtime\n"));
+ existing = G.statbuf.st_mtime;
+ archive = z_utime.mtime;
+ } else {
+ /* round up existing filetime to nearest 2 seconds for comparison,
+ * but saturate in case of arithmetic overflow
+ */
+ existing = ((G.statbuf.st_mtime & 1) &&
+ (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+ G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+ archive = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+ }
+#else /* !USE_EF_UT_TIME */
+ /* round up existing filetime to nearest 2 seconds for comparison,
+ * but saturate in case of arithmetic overflow
+ */
+ existing = ((G.statbuf.st_mtime & 1) &&
+ (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+ G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+ archive = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+#endif /* ?USE_EF_UT_TIME */
+
+ TTrace((stderr, "check_for_newer: existing %lu, archive %lu, e-a %ld\n",
+ (ulg)existing, (ulg)archive, (long)(existing-archive)));
+
+ return (existing >= archive);
+
+} /* end function check_for_newer() */
+
+#endif /* !VMS && !OS2 && !CMS_MVS */
+
+
+
+
+
+/************************/
+/* Function do_string() */
+/************************/
+
+int do_string(__G__ length, option) /* return PK-type error code */
+ __GDEF
+ unsigned int length; /* without prototype, ush converted to this */
+ int option;
+{
+ unsigned comment_bytes_left;
+ unsigned int block_len;
+ int error=PK_OK;
+ unsigned int length2;
+#ifdef AMIGA
+ char tmp_fnote[2 * AMIGA_FILENOTELEN]; /* extra room for squozen chars */
+#endif
+
+
+/*---------------------------------------------------------------------------
+ This function processes arbitrary-length (well, usually) strings. Four
+ major options are allowed: SKIP, wherein the string is skipped (pretty
+ logical, eh?); DISPLAY, wherein the string is printed to standard output
+ after undergoing any necessary or unnecessary character conversions;
+ DS_FN, wherein the string is put into the filename[] array after under-
+ going appropriate conversions (including case-conversion, if that is
+ indicated: see the global variable pInfo->lcflag); and EXTRA_FIELD,
+ wherein the `string' is assumed to be an extra field and is copied to
+ the (freshly malloced) buffer G.extra_field. The third option should
+ be OK since filename is dimensioned at 1025, but we check anyway.
+
+ The string, by the way, is assumed to start at the current file-pointer
+ position; its length is given by 'length'. So start off by checking the
+ length of the string: if zero, we're already done.
+ ---------------------------------------------------------------------------*/
+
+ if (!length)
+ return PK_COOL;
+
+ switch (option) {
+
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ /*
+ * Special case: See if the comment begins with an autorun command line.
+ * Save that and display (or skip) the remainder.
+ */
+
+ case CHECK_AUTORUN:
+ case CHECK_AUTORUN_Q:
+ comment_bytes_left = length;
+ if (length >= 10)
+ {
+ block_len = readbuf(__G__ (char *)G.outbuf, 10);
+ if (block_len == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+ G.outbuf[block_len] = '\0';
+ if (!strcmp((char *)G.outbuf, "$AUTORUN$>")) {
+ char *eol;
+ length -= 10;
+ block_len = readbuf(__G__ G.autorun_command,
+ MIN(length, sizeof(G.autorun_command)-1));
+ if (block_len == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+ G.autorun_command[block_len] = '\0';
+ A_TO_N(G.autorun_command);
+ eol = strchr(G.autorun_command, '\n');
+ if (!eol)
+ eol = G.autorun_command + strlen(G.autorun_command) - 1;
+ length -= eol + 1 - G.autorun_command;
+ while (eol >= G.autorun_command && isspace(*eol))
+ *eol-- = '\0';
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM(G.autorun_command, G.autorun_command);
+#endif /* (WIN32 && !_WIN32_WCE) */
+ }
+ }
+ if (option == CHECK_AUTORUN_Q) /* don't display the remainder */
+ length = 0;
+ /* seek to beginning of remaining part of comment -- rewind if */
+ /* displaying entire comment, or skip to end if discarding it */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr - G.inbuf) + comment_bytes_left - length);
+ if (!length)
+ break;
+ /* FALL THROUGH... */
+#endif /* SFX && CHEAP_SFX_AUTORUN */
+
+ /*
+ * First normal case: print string on standard output. First set loop
+ * variables, then loop through the comment in chunks of OUTBUFSIZ bytes,
+ * converting formats and printing as we go. The second half of the
+ * loop conditional was added because the file might be truncated, in
+ * which case comment_bytes_left will remain at some non-zero value for
+ * all time. outbuf and slide are used as scratch buffers because they
+ * are available (we should be either before or in between any file pro-
+ * cessing).
+ */
+
+ case DISPLAY:
+ case DISPL_8:
+ comment_bytes_left = length;
+ block_len = OUTBUFSIZ; /* for the while statement, first time */
+ while (comment_bytes_left > 0 && block_len > 0) {
+ register uch *p = G.outbuf;
+ register uch *q = G.outbuf;
+
+ if ((block_len = readbuf(__G__ (char *)G.outbuf,
+ MIN((unsigned)OUTBUFSIZ, comment_bytes_left))) == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+
+ /* this is why we allocated an extra byte for outbuf: terminate
+ * with zero (ASCIIZ) */
+ G.outbuf[block_len] = '\0';
+
+ /* remove all ASCII carriage returns from comment before printing
+ * (since used before A_TO_N(), check for CR instead of '\r')
+ */
+ while (*p) {
+ while (*p == CR)
+ ++p;
+ *q++ = *p++;
+ }
+ /* could check whether (p - outbuf) == block_len here */
+ *q = '\0';
+
+ if (option == DISPL_8) {
+ /* translate the text coded in the entry's host-dependent
+ "extended ASCII" charset into the compiler's (system's)
+ internal text code page */
+ Ext_ASCII_TO_Native((char *)G.outbuf, G.pInfo->hostnum,
+ G.pInfo->hostver, G.pInfo->HasUxAtt,
+ FALSE);
+#ifdef WINDLL
+ /* translate to ANSI (RTL internal codepage may be OEM) */
+ INTERN_TO_ISO((char *)G.outbuf, (char *)G.outbuf);
+#else /* !WINDLL */
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM((char *)G.outbuf, (char *)G.outbuf);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+ } else {
+ A_TO_N(G.outbuf); /* translate string to native */
+ }
+
+#ifdef WINDLL
+ /* ran out of local mem -- had to cheat */
+ win_fprintf((zvoid *)&G, stdout, (extent)(q-G.outbuf),
+ (char *)G.outbuf);
+ win_fprintf((zvoid *)&G, stdout, 2, (char *)"\n\n");
+#else /* !WINDLL */
+#ifdef NOANSIFILT /* GRR: can ANSI be used with EBCDIC? */
+ (*G.message)((zvoid *)&G, G.outbuf, (ulg)(q-G.outbuf), 0);
+#else /* ASCII, filter out ANSI escape sequences and handle ^S (pause) */
+ p = G.outbuf - 1;
+ q = slide;
+ while (*++p) {
+ int pause = FALSE;
+
+ if (*p == 0x1B) { /* ASCII escape char */
+ *q++ = '^';
+ *q++ = '[';
+ } else if (*p == 0x13) { /* ASCII ^S (pause) */
+ pause = TRUE;
+ if (p[1] == LF) /* ASCII LF */
+ *q++ = *++p;
+ else if (p[1] == CR && p[2] == LF) { /* ASCII CR LF */
+ *q++ = *++p;
+ *q++ = *++p;
+ }
+ } else
+ *q++ = *p;
+ if ((unsigned)(q-slide) > WSIZE-3 || pause) { /* flush */
+ (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+ q = slide;
+ if (pause && G.extract_flag) /* don't pause for list/test */
+ (*G.mpause)((zvoid *)&G, LoadFarString(QuitPrompt), 0);
+ }
+ }
+ (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+#endif /* ?NOANSIFILT */
+#endif /* ?WINDLL */
+ }
+ /* add '\n' if not at start of line */
+ (*G.message)((zvoid *)&G, slide, 0L, 0x40);
+ break;
+
+ /*
+ * Second case: read string into filename[] array. The filename should
+ * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
+ * just to be sure.
+ */
+
+ case DS_FN:
+ case DS_FN_L:
+#ifdef UNICODE_SUPPORT
+ /* get the whole filename as need it for Unicode checksum */
+ if (G.fnfull_bufsize <= length) {
+ extent fnbufsiz = FILNAMSIZ;
+
+ if (fnbufsiz <= length)
+ fnbufsiz = length + 1;
+ if (G.filename_full)
+ free(G.filename_full);
+ G.filename_full = malloc(fnbufsiz);
+ if (G.filename_full == NULL)
+ return PK_MEM;
+ G.fnfull_bufsize = fnbufsiz;
+ }
+ if (readbuf(__G__ G.filename_full, length) == 0)
+ return PK_EOF;
+ G.filename_full[length] = '\0'; /* terminate w/zero: ASCIIZ */
+
+ /* if needed, chop off end so standard filename is a valid length */
+ if (length >= FILNAMSIZ) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameTooLongTrunc)));
+ error = PK_WARN;
+ length = FILNAMSIZ - 1;
+ }
+ /* no excess size */
+ block_len = 0;
+ strncpy(G.filename, G.filename_full, length);
+ G.filename[length] = '\0'; /* terminate w/zero: ASCIIZ */
+#else /* !UNICODE_SUPPORT */
+ if (length >= FILNAMSIZ) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameTooLongTrunc)));
+ error = PK_WARN;
+ /* remember excess length in block_len */
+ block_len = length - (FILNAMSIZ - 1);
+ length = FILNAMSIZ - 1;
+ } else
+ /* no excess size */
+ block_len = 0;
+ if (readbuf(__G__ G.filename, length) == 0)
+ return PK_EOF;
+ G.filename[length] = '\0'; /* terminate w/zero: ASCIIZ */
+#endif /* ?UNICODE_SUPPORT */
+
+ /* translate the Zip entry filename coded in host-dependent "extended
+ ASCII" into the compiler's (system's) internal text code page */
+ Ext_ASCII_TO_Native(G.filename, G.pInfo->hostnum, G.pInfo->hostver,
+ G.pInfo->HasUxAtt, (option == DS_FN_L));
+
+ if (G.pInfo->lcflag) /* replace with lowercase filename */
+ STRLOWER(G.filename, G.filename);
+
+ if (G.pInfo->vollabel && length > 8 && G.filename[8] == '.') {
+ char *p = G.filename+8;
+ while (*p++)
+ p[-1] = *p; /* disk label, and 8th char is dot: remove dot */
+ }
+
+ if (!block_len) /* no overflow, we're done here */
+ break;
+
+ /*
+ * We truncated the filename, so print what's left and then fall
+ * through to the SKIP routine.
+ */
+ Info(slide, 0x401, ((char *)slide, "[ %s ]\n", FnFilter1(G.filename)));
+ length = block_len; /* SKIP the excess bytes... */
+ /* FALL THROUGH... */
+
+ /*
+ * Third case: skip string, adjusting readbuf's internal variables
+ * as necessary (and possibly skipping to and reading a new block of
+ * data).
+ */
+
+ case SKIP:
+ /* cur_zipfile_bufstart already takes account of extra_bytes, so don't
+ * correct for it twice: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr-G.inbuf) + length);
+ break;
+
+ /*
+ * Fourth case: assume we're at the start of an "extra field"; malloc
+ * storage for it and read data into the allocated space.
+ */
+
+ case EXTRA_FIELD:
+ if (G.extra_field != (uch *)NULL)
+ free(G.extra_field);
+ if ((G.extra_field = (uch *)malloc(length)) == (uch *)NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ExtraFieldTooLong),
+ length));
+ /* cur_zipfile_bufstart already takes account of extra_bytes,
+ * so don't correct for it twice: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr-G.inbuf) + length);
+ } else {
+ if ((length2 = readbuf(__G__ (char *)G.extra_field, length)) == 0)
+ return PK_EOF;
+ if(length2 < length) {
+ memset (__G__ (char *)G.extra_field+length2, 0 , length-length2);
+ length = length2;
+ }
+ /* Looks like here is where extra fields are read */
+ if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
+ error = PK_WARN;
+ }
+
+#ifdef UNICODE_SUPPORT
+ G.unipath_filename = NULL;
+ if (G.UzO.U_flag < 2) {
+ /* check if GPB11 (General Purpuse Bit 11) is set indicating
+ the standard path and comment are UTF-8 */
+ if (G.pInfo->GPFIsUTF8) {
+ /* if GPB11 set then filename_full is untruncated UTF-8 */
+ G.unipath_filename = G.filename_full;
+ } else {
+ /* Get the Unicode fields if exist */
+ getUnicodeData(__G__ G.extra_field, length);
+ if (G.unipath_filename && strlen(G.unipath_filename) == 0) {
+ /* the standard filename field is UTF-8 */
+ free(G.unipath_filename);
+ G.unipath_filename = G.filename_full;
+ }
+ }
+ if (G.unipath_filename) {
+# ifdef UTF8_MAYBE_NATIVE
+ if (G.native_is_utf8
+# ifdef UNICODE_WCHAR
+ && (!G.unicode_escape_all)
+# endif
+ ) {
+ strncpy(G.filename, G.unipath_filename, FILNAMSIZ - 1);
+ /* make sure filename is short enough */
+ if (strlen(G.unipath_filename) >= FILNAMSIZ) {
+ G.filename[FILNAMSIZ - 1] = '\0';
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UFilenameTooLongTrunc)));
+ error = PK_WARN;
+ }
+ }
+# ifdef UNICODE_WCHAR
+ else
+# endif
+# endif /* UTF8_MAYBE_NATIVE */
+# ifdef UNICODE_WCHAR
+ {
+ char *fn;
+
+ /* convert UTF-8 to local character set */
+ fn = utf8_to_local_string(G.unipath_filename,
+ G.unicode_escape_all);
+
+ /* 2022-07-22 SMS, et al. CVE-2022-0530
+ * Detect conversion failure, emit message.
+ * Continue with unconverted name.
+ */
+ if (fn == NULL)
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UFilenameCorrupt)));
+ error = PK_ERR;
+ }
+ else
+ {
+ /* make sure filename is short enough */
+ if (strlen(fn) >= FILNAMSIZ) {
+ fn[FILNAMSIZ - 1] = '\0';
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UFilenameTooLongTrunc)));
+ error = PK_WARN;
+ }
+ /* replace filename with converted UTF-8 */
+ strcpy(G.filename, fn);
+ free(fn);
+ }
+ }
+# endif /* UNICODE_WCHAR */
+ if (G.unipath_filename != G.filename_full)
+ free(G.unipath_filename);
+ G.unipath_filename = NULL;
+ }
+ }
+#endif /* UNICODE_SUPPORT */
+ }
+ break;
+
+#ifdef AMIGA
+ /*
+ * Fifth case, for the Amiga only: take the comment that would ordinarily
+ * be skipped over, and turn it into a 79 character string that will be
+ * attached to the file as a "filenote" after it is extracted.
+ */
+
+ case FILENOTE:
+ if ((block_len = readbuf(__G__ tmp_fnote, (unsigned)
+ MIN(length, 2 * AMIGA_FILENOTELEN - 1))) == 0)
+ return PK_EOF;
+ if ((length -= block_len) > 0) /* treat remainder as in case SKIP: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes
+ + (G.inptr - G.inbuf) + length);
+ /* convert multi-line text into single line with no ctl-chars: */
+ tmp_fnote[block_len] = '\0';
+ while ((short int) --block_len >= 0)
+ if ((unsigned) tmp_fnote[block_len] < ' ')
+ if (tmp_fnote[block_len+1] == ' ') /* no excess */
+ strcpy(tmp_fnote+block_len, tmp_fnote+block_len+1);
+ else
+ tmp_fnote[block_len] = ' ';
+ tmp_fnote[AMIGA_FILENOTELEN - 1] = '\0';
+ if (G.filenotes[G.filenote_slot])
+ free(G.filenotes[G.filenote_slot]); /* should not happen */
+ G.filenotes[G.filenote_slot] = NULL;
+ if (tmp_fnote[0]) {
+ if (!(G.filenotes[G.filenote_slot] = malloc(strlen(tmp_fnote)+1)))
+ return PK_MEM;
+ strcpy(G.filenotes[G.filenote_slot], tmp_fnote);
+ }
+ break;
+#endif /* AMIGA */
+
+ } /* end switch (option) */
+
+ return error;
+
+} /* end function do_string() */
+
+
+
+
+
+/***********************/
+/* Function makeword() */
+/***********************/
+
+ush makeword(b)
+ ZCONST uch *b;
+{
+ /*
+ * Convert Intel style 'short' integer to non-Intel non-16-bit
+ * host format. This routine also takes care of byte-ordering.
+ */
+ return (ush)((b[1] << 8) | b[0]);
+}
+
+
+
+
+
+/***********************/
+/* Function makelong() */
+/***********************/
+
+ulg makelong(sig)
+ ZCONST uch *sig;
+{
+ /*
+ * Convert intel style 'long' variable to non-Intel non-16-bit
+ * host format. This routine also takes care of byte-ordering.
+ */
+ return (((ulg)sig[3]) << 24)
+ + (((ulg)sig[2]) << 16)
+ + (ulg)((((unsigned)sig[1]) << 8)
+ + ((unsigned)sig[0]));
+}
+
+
+
+
+
+/************************/
+/* Function makeint64() */
+/************************/
+
+zusz_t makeint64(sig)
+ ZCONST uch *sig;
+{
+#ifdef LARGE_FILE_SUPPORT
+ /*
+ * Convert intel style 'int64' variable to non-Intel non-16-bit
+ * host format. This routine also takes care of byte-ordering.
+ */
+ return (((zusz_t)sig[7]) << 56)
+ + (((zusz_t)sig[6]) << 48)
+ + (((zusz_t)sig[4]) << 32)
+ + (zusz_t)((((ulg)sig[3]) << 24)
+ + (((ulg)sig[2]) << 16)
+ + (((unsigned)sig[1]) << 8)
+ + (sig[0]));
+
+#else /* !LARGE_FILE_SUPPORT */
+
+ if ((sig[7] | sig[6] | sig[5] | sig[4]) != 0)
+ return (zusz_t)0xffffffffL;
+ else
+ return (zusz_t)((((ulg)sig[3]) << 24)
+ + (((ulg)sig[2]) << 16)
+ + (((unsigned)sig[1]) << 8)
+ + (sig[0]));
+
+#endif /* ?LARGE_FILE_SUPPORT */
+}
+
+
+
+
+
+/*********************/
+/* Function fzofft() */
+/*********************/
+
+/* Format a zoff_t value in a cylindrical buffer set. */
+char *fzofft(__G__ val, pre, post)
+ __GDEF
+ zoff_t val;
+ ZCONST char *pre;
+ ZCONST char *post;
+{
+ /* Storage cylinder. (now in globals.h) */
+ /*static char fzofft_buf[FZOFFT_NUM][FZOFFT_LEN];*/
+ /*static int fzofft_index = 0;*/
+
+ /* Temporary format string storage. */
+ char fmt[16];
+
+ /* Assemble the format string. */
+ fmt[0] = '%';
+ fmt[1] = '\0'; /* Start after initial "%". */
+ if (pre == FZOFFT_HEX_WID) /* Special hex width. */
+ {
+ strcat(fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+ {
+ strcat(fmt, ".");
+ strcat(fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre != NULL) /* Caller's prefix (width). */
+ {
+ strcat(fmt, pre);
+ }
+
+ strcat(fmt, FZOFFT_FMT); /* Long or long-long or whatever. */
+
+ if (post == NULL)
+ strcat(fmt, "d"); /* Default radix = decimal. */
+ else
+ strcat(fmt, post); /* Caller's radix. */
+
+ /* Advance the cylinder. */
+ G.fzofft_index = (G.fzofft_index + 1) % FZOFFT_NUM;
+
+ /* Write into the current chamber. */
+ sprintf(G.fzofft_buf[G.fzofft_index], fmt, val);
+
+ /* Return a pointer to this chamber. */
+ return G.fzofft_buf[G.fzofft_index];
+}
+
+
+
+
+#if CRYPT
+
+#ifdef NEED_STR2ISO
+/**********************/
+/* Function str2iso() */
+/**********************/
+
+char *str2iso(dst, src)
+ char *dst; /* destination buffer */
+ register ZCONST char *src; /* source string */
+{
+#ifdef INTERN_TO_ISO
+ INTERN_TO_ISO(src, dst);
+#else
+ register uch c;
+ register char *dstp = dst;
+
+ do {
+ c = (uch)foreign(*src++);
+ *dstp++ = (char)ASCII2ISO(c);
+ } while (c != '\0');
+#endif
+
+ return dst;
+}
+#endif /* NEED_STR2ISO */
+
+
+#ifdef NEED_STR2OEM
+/**********************/
+/* Function str2oem() */
+/**********************/
+
+char *str2oem(dst, src)
+ char *dst; /* destination buffer */
+ register ZCONST char *src; /* source string */
+{
+#ifdef INTERN_TO_OEM
+ INTERN_TO_OEM(src, dst);
+#else
+ register uch c;
+ register char *dstp = dst;
+
+ do {
+ c = (uch)foreign(*src++);
+ *dstp++ = (char)ASCII2OEM(c);
+ } while (c != '\0');
+#endif
+
+ return dst;
+}
+#endif /* NEED_STR2OEM */
+
+#endif /* CRYPT */
+
+
+#ifdef ZMEM /* memset/memcmp/memcpy for systems without either them or */
+ /* bzero/bcmp/bcopy */
+ /* (no known systems as of 960211) */
+
+/*********************/
+/* Function memset() */
+/*********************/
+
+zvoid *memset(buf, init, len)
+ register zvoid *buf; /* buffer location */
+ register int init; /* initializer character */
+ register unsigned int len; /* length of the buffer */
+{
+ zvoid *start;
+
+ start = buf;
+ while (len--)
+ *((char *)buf++) = (char)init;
+ return start;
+}
+
+
+
+/*********************/
+/* Function memcmp() */
+/*********************/
+
+int memcmp(b1, b2, len)
+ register ZCONST zvoid *b1;
+ register ZCONST zvoid *b2;
+ register unsigned int len;
+{
+ register int c;
+
+ if (len > 0) do {
+ if ((c = (int)(*((ZCONST unsigned char *)b1)++) -
+ (int)(*((ZCONST unsigned char *)b2)++)) != 0)
+ return c;
+ } while (--len > 0)
+ return 0;
+}
+
+
+
+/*********************/
+/* Function memcpy() */
+/*********************/
+
+zvoid *memcpy(dst, src, len)
+ register zvoid *dst;
+ register ZCONST zvoid *src;
+ register unsigned int len;
+{
+ zvoid *start;
+
+ start = dst;
+ while (len-- > 0)
+ *((char *)dst)++ = *((ZCONST char *)src)++;
+ return start;
+}
+
+#endif /* ZMEM */
+
+
+
+
+#ifdef NO_STRNICMP
+
+/************************/
+/* Function zstrnicmp() */
+/************************/
+
+int zstrnicmp(s1, s2, n)
+ register ZCONST char *s1, *s2;
+ register unsigned n;
+{
+ for (; n > 0; --n, ++s1, ++s2) {
+
+ if (ToLower(*s1) != ToLower(*s2))
+ /* test includes early termination of one string */
+ return ((uch)ToLower(*s1) < (uch)ToLower(*s2))? -1 : 1;
+
+ if (*s1 == '\0') /* both strings terminate early */
+ return 0;
+ }
+ return 0;
+}
+
+#endif /* NO_STRNICMP */
+
+
+
+
+#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */
+# undef stat
+
+/********************/
+/* Function zstat() */
+/********************/
+
+int zstat(p, s)
+ ZCONST char *p;
+ struct stat *s;
+{
+ return (stat((char *)p,s) >= 0? 0 : (-1));
+}
+
+#endif /* REGULUS */
+
+
+
+
+#ifdef _MBCS
+
+/* DBCS support for Info-ZIP's zip (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ * This code is public domain! Date: 1998/12/20
+ */
+
+/************************/
+/* Function plastchar() */
+/************************/
+
+char *plastchar(ptr, len)
+ ZCONST char *ptr;
+ extent len;
+{
+ unsigned clen;
+ ZCONST char *oldptr = ptr;
+ while(*ptr != '\0' && len > 0){
+ oldptr = ptr;
+ clen = CLEN(ptr);
+ ptr += clen;
+ len -= clen;
+ }
+ return (char *)oldptr;
+}
+
+
+#ifdef NEED_UZMBCLEN
+/***********************/
+/* Function uzmbclen() */
+/***********************/
+
+extent uzmbclen(ptr)
+ ZCONST unsigned char *ptr;
+{
+ int mbl;
+
+ mbl = mblen((ZCONST char *)ptr, MB_CUR_MAX);
+ /* For use in code scanning through MBCS strings, we need a strictly
+ positive "MB char bytes count". For our scanning purpose, it is not
+ not relevant whether the MB character is valid or not. And, the NUL
+ char '\0' has a byte count of 1, but mblen() returns 0. So, we make
+ sure that the uzmbclen() return value is not less than 1.
+ */
+ return (extent)(mbl > 0 ? mbl : 1);
+}
+#endif /* NEED_UZMBCLEN */
+
+
+#ifdef NEED_UZMBSCHR
+/***********************/
+/* Function uzmbschr() */
+/***********************/
+
+unsigned char *uzmbschr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ while(*str != '\0'){
+ if (*str == c) {return (unsigned char *)str;}
+ INCSTR(str);
+ }
+ return NULL;
+}
+#endif /* NEED_UZMBSCHR */
+
+
+#ifdef NEED_UZMBSRCHR
+/************************/
+/* Function uzmbsrchr() */
+/************************/
+
+unsigned char *uzmbsrchr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ unsigned char *match = NULL;
+ while(*str != '\0'){
+ if (*str == c) {match = (unsigned char *)str;}
+ INCSTR(str);
+ }
+ return match;
+}
+#endif /* NEED_UZMBSRCHR */
+#endif /* _MBCS */
+
+
+
+
+
+#ifdef SMALL_MEM
+
+/*******************************/
+/* Function fLoadFarString() */ /* (and friends...) */
+/*******************************/
+
+char *fLoadFarString(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchBigBuffer, sz);
+ return G.rgchBigBuffer;
+}
+
+char *fLoadFarStringSmall(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchSmallBuffer, sz);
+ return G.rgchSmallBuffer;
+}
+
+char *fLoadFarStringSmall2(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchSmallBuffer2, sz);
+ return G.rgchSmallBuffer2;
+}
+
+
+
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+/*************************/
+/* Function zfstrcpy() */ /* portable clone of _fstrcpy() */
+/*************************/
+
+char Far * Far zfstrcpy(char Far *s1, const char Far *s2)
+{
+ char Far *p = s1;
+
+ while ((*s1++ = *s2++) != '\0');
+ return p;
+}
+
+#if (!(defined(SFX) || defined(FUNZIP)))
+/*************************/
+/* Function zfstrcmp() */ /* portable clone of _fstrcmp() */
+/*************************/
+
+int Far zfstrcmp(const char Far *s1, const char Far *s2)
+{
+ int ret;
+
+ while ((ret = (int)(uch)*s1 - (int)(uch)*s2) == 0
+ && *s2 != '\0') {
+ ++s2; ++s1;
+ }
+ return ret;
+}
+#endif /* !(SFX || FUNZIP) */
+#endif /* !_MSC_VER || (_MSC_VER < 600) */
+
+#endif /* SMALL_MEM */
Index: unzip/create-6.0-slackware-patch/unzip60-new/list.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/list.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/list.c (revision 5)
@@ -0,0 +1,746 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ list.c
+
+ This file contains the non-ZipInfo-specific listing routines for UnZip.
+
+ Contains: list_files()
+ get_time_stamp() [optional feature]
+ ratio()
+ fnprint()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+#endif
+
+
+#ifdef TIMESTAMP
+ static int fn_is_dir OF((__GPRO));
+#endif
+
+#ifndef WINDLL
+ static ZCONST char Far CompFactorStr[] = "%c%d%%";
+ static ZCONST char Far CompFactor100[] = "100%%";
+
+#ifdef OS2_EAS
+ static ZCONST char Far HeadersS[] =
+ " Length EAs ACLs Date Time Name";
+ static ZCONST char Far HeadersS1[] =
+ "--------- --- ---- ---------- ----- ----";
+#else
+ static ZCONST char Far HeadersS[] =
+ " Length Date Time Name";
+ static ZCONST char Far HeadersS1[] =
+ "--------- ---------- ----- ----";
+#endif
+
+ static ZCONST char Far HeadersL[] =
+ " Length Method Size Cmpr Date Time CRC-32 Name";
+ static ZCONST char Far HeadersL1[] =
+ "-------- ------ ------- ---- ---------- ----- -------- ----";
+ static ZCONST char Far *Headers[][2] =
+ { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
+
+ static ZCONST char Far CaseConversion[] =
+ "%s (\"^\" ==> case\n%s conversion)\n";
+ static ZCONST char Far LongHdrStats[] =
+ "%s %-7s%s %4s %02u%c%02u%c%02u %02u:%02u %08lx %c";
+ static ZCONST char Far LongFileTrailer[] =
+ "-------- ------- --- \
+ -------\n%s %s %4s %lu file%s\n";
+#ifdef OS2_EAS
+ static ZCONST char Far ShortHdrStats[] =
+ "%s %6lu %6lu %02u%c%02u%c%02u %02u:%02u %c";
+ static ZCONST char Far ShortFileTrailer[] =
+ "--------- ----- ----- \
+ -------\n%s %6lu %6lu %lu file%s\n";
+ static ZCONST char Far OS2ExtAttrTrailer[] =
+ "%lu file%s %lu bytes of OS/2 extended attributes attached.\n";
+ static ZCONST char Far OS2ACLTrailer[] =
+ "%lu file%s %lu bytes of access control lists attached.\n";
+#else
+ static ZCONST char Far ShortHdrStats[] =
+ "%s %02u%c%02u%c%02u %02u:%02u %c";
+ static ZCONST char Far ShortFileTrailer[] =
+ "--------- -------\n%s\
+ %lu file%s\n";
+#endif /* ?OS2_EAS */
+#endif /* !WINDLL */
+
+
+
+
+
+/*************************/
+/* Function list_files() */
+/*************************/
+
+int list_files(__G) /* return PK-type error code */
+ __GDEF
+{
+ int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
+#ifndef WINDLL
+ char sgn, cfactorstr[1+10+1+1]; /* <sgn><int>%NUL */
+ int longhdr=(uO.vflag>1);
+#endif
+ int date_format;
+ char dt_sepchar;
+ ulg members=0L;
+ zusz_t j;
+ unsigned methnum;
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+ struct tm *t;
+#endif
+ unsigned yr, mo, dy, hh, mm;
+ zusz_t csiz, tot_csize=0L, tot_ucsize=0L;
+#ifdef OS2_EAS
+ ulg ea_size, tot_easize=0L, tot_eafiles=0L;
+ ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
+#endif
+ min_info info;
+ char methbuf[8];
+ static ZCONST char dtype[]="NXFS"; /* see zi_short() */
+ static ZCONST char Far method[NUM_METHODS+1][8] =
+ {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
+ "Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "BZip2",
+ "LZMA", "Terse", "IBMLZ77", "WavPack", "PPMd", "Unk:###"};
+
+
+
+/*---------------------------------------------------------------------------
+ Unlike extract_or_test_files(), this routine confines itself to the cen-
+ tral directory. Thus its structure is somewhat simpler, since we can do
+ just a single loop through the entire directory, listing files as we go.
+
+ So to start off, print the heading line and then begin main loop through
+ the central directory. The results will look vaguely like the following:
+
+ Length Method Size Ratio Date Time CRC-32 Name ("^" ==> case
+-------- ------ ------- ----- ---- ---- ------ ---- conversion)
+ 44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
+ 3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 ^dos-file.ext
+ 16717 Defl:X 5252 69% 11-03-97 06:40 1ce0f189 WHERE
+-------- ------- --- -------
+ 64159 20502 68% 3 files
+ ---------------------------------------------------------------------------*/
+
+ G.pInfo = &info;
+ date_format = DATE_FORMAT;
+ dt_sepchar = DATE_SEPCHAR;
+
+#ifndef WINDLL
+ if (uO.qflag < 2) {
+ if (uO.L_flag)
+ Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
+ LoadFarStringSmall(Headers[longhdr][0]),
+ LoadFarStringSmall2(Headers[longhdr][1])));
+ else
+ Info(slide, 0, ((char *)slide, "%s\n%s\n",
+ LoadFarString(Headers[longhdr][0]),
+ LoadFarStringSmall(Headers[longhdr][1])));
+ }
+#endif /* !WINDLL */
+
+ for (j = 1L;;j++) {
+
+ if (readbuf(__G__ G.sig, 4) == 0)
+ return PK_EOF;
+ if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a CentDir entry? */
+ /* no new central directory entry
+ * -> is the number of processed entries compatible with the
+ * number of entries as stored in the end_central record?
+ */
+ if (((j - 1) &
+ (ulg)(G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+ == (ulg)G.ecrec.total_entries_central_dir)
+ {
+ /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
+ * number of directory entries -> probably, the regular
+ * end of the central directory has been reached
+ */
+ break;
+ } else {
+ Info(slide, 0x401,
+ ((char *)slide, LoadFarString(CentSigMsg), j));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
+ return PK_BADERR; /* sig not found */
+ }
+ }
+ /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
+ if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
+ return error; /* only PK_EOF defined */
+
+ /*
+ * We could DISPLAY the filename instead of storing (and possibly trun-
+ * cating, in the case of a very long name) and printing it, but that
+ * has the disadvantage of not allowing case conversion--and it's nice
+ * to be able to see in the listing precisely how you have to type each
+ * filename in order for unzip to consider it a match. Speaking of
+ * which, if member names were specified on the command line, check in
+ * with match() to see if the current file is one of them, and make a
+ * note of it if it is.
+ */
+
+ if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+ PK_COOL) /* ^--(uses pInfo->lcflag) */
+ {
+ error_in_archive = error;
+ if (error > PK_WARN) /* fatal: can't continue */
+ return error;
+ }
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+ if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
+ != 0)
+ {
+ error_in_archive = error;
+ if (error > PK_WARN) /* fatal */
+ return error;
+ }
+ if (!G.process_all_files) { /* check if specified on command line */
+ unsigned i;
+
+ if (G.filespecs == 0)
+ do_this_file = TRUE;
+ else { /* check if this entry matches an `include' argument */
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+ do_this_file = TRUE;
+ break; /* found match, so stop looping */
+ }
+ }
+ if (do_this_file) { /* check if this is an excluded file */
+ for (i = 0; i < G.xfilespecs; i++)
+ if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+ do_this_file = FALSE; /* ^-- ignore case in match */
+ break;
+ }
+ }
+ }
+ /*
+ * If current file was specified on command line, or if no names were
+ * specified, do the listing for this file. Otherwise, get rid of the
+ * file comment and go back for the next file.
+ */
+
+ if (G.process_all_files || do_this_file) {
+
+#ifdef OS2DLL
+ /* this is used by UzpFileTree() to allow easy processing of lists
+ * of zip directory contents */
+ if (G.processExternally) {
+ if ((G.processExternally)(G.filename, &G.crec))
+ break;
+ ++members;
+ } else {
+#endif
+#ifdef OS2_EAS
+ {
+ uch *ef_ptr = G.extra_field;
+ int ef_size, ef_len = G.crec.extra_field_length;
+ ea_size = acl_size = 0;
+
+ while (ef_len >= EB_HEADSIZE) {
+ ef_size = makeword(&ef_ptr[EB_LEN]);
+ switch (makeword(&ef_ptr[EB_ID])) {
+ case EF_OS2:
+ ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
+ break;
+ case EF_ACL:
+ acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
+ break;
+ }
+ ef_ptr += (ef_size + EB_HEADSIZE);
+ ef_len -= (ef_size + EB_HEADSIZE);
+ }
+ }
+#endif
+#ifdef USE_EF_UT_TIME
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+ G.crec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME))
+ {
+ TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0, Mac */
+ t = localtime(&(z_utime.mtime));
+ } else
+ t = (struct tm *)NULL;
+ if (t != (struct tm *)NULL) {
+ mo = (unsigned)(t->tm_mon + 1);
+ dy = (unsigned)(t->tm_mday);
+ yr = (unsigned)(t->tm_year + 1900);
+ hh = (unsigned)(t->tm_hour);
+ mm = (unsigned)(t->tm_min);
+ } else
+#endif /* USE_EF_UT_TIME */
+ {
+ yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
+ + 1980));
+ mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
+ dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
+ hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
+ mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
+ }
+ /* permute date so it displays according to nat'l convention
+ * ('methnum' is not yet set, it is used as temporary buffer) */
+ switch (date_format) {
+ case DF_YMD:
+ methnum = mo;
+ mo = yr; yr = dy; dy = methnum;
+ break;
+ case DF_DMY:
+ methnum = mo;
+ mo = dy; dy = methnum;
+ }
+
+ csiz = G.crec.csize;
+ if (G.crec.general_purpose_bit_flag & 1)
+ csiz -= 12; /* if encrypted, don't count encryption header */
+ if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
+#ifndef WINDLL
+ sgn = '-';
+#endif
+ cfactor = (-cfactor + 5) / 10;
+ } else {
+#ifndef WINDLL
+ sgn = ' ';
+#endif
+ cfactor = (cfactor + 5) / 10;
+ }
+
+ methnum = find_compr_idx(G.crec.compression_method);
+ zfstrcpy(methbuf, method[methnum]);
+ if (G.crec.compression_method == DEFLATED ||
+ G.crec.compression_method == ENHDEFLATED) {
+ methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
+ } else if (methnum >= NUM_METHODS) {
+ /* 2013-02-26 SMS.
+ * http://sourceforge.net/tracker/?func=detail
+ * &aid=2861648&group_id=118012&atid=679786
+ * Unexpectedly large compression methods overflow
+ * &methbuf[]. Use the old, three-digit decimal format
+ * for values which fit. Otherwise, sacrifice the
+ * colon, and use four-digit hexadecimal.
+ */
+ if (G.crec.compression_method <= 999) {
+ sprintf( &methbuf[ 4], "%03u", G.crec.compression_method);
+ } else {
+ sprintf( &methbuf[ 3], "%04X", G.crec.compression_method);
+ }
+ }
+
+#if 0 /* GRR/Euro: add this? */
+#if defined(DOS_FLX_NLM_OS2_W32) || defined(THEOS) || defined(UNIX)
+ for (p = G.filename; *p; ++p)
+ if (!isprint(*p))
+ *p = '?'; /* change non-printable chars to '?' */
+#endif /* DOS_FLX_NLM_OS2_W32 || THEOS || UNIX */
+#endif /* 0 */
+
+#ifdef WINDLL
+ /* send data to application for formatting and printing */
+ if (G.lpUserFunctions->SendApplicationMessage != NULL)
+ (*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize,
+ csiz, (unsigned)cfactor, mo, dy, yr, hh, mm,
+ (char)(G.pInfo->lcflag ? '^' : ' '),
+ (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
+ (LPCSTR)methbuf, G.crec.crc32,
+ (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
+ else if (G.lpUserFunctions->SendApplicationMessage_i32 != NULL) {
+ unsigned long ucsize_lo, csiz_lo;
+ unsigned long ucsize_hi=0L, csiz_hi=0L;
+ ucsize_lo = (unsigned long)(G.crec.ucsize);
+ csiz_lo = (unsigned long)(csiz);
+#ifdef ZIP64_SUPPORT
+ ucsize_hi = (unsigned long)(G.crec.ucsize >> 32);
+ csiz_hi = (unsigned long)(csiz >> 32);
+#endif /* ZIP64_SUPPORT */
+ (*G.lpUserFunctions->SendApplicationMessage_i32)(ucsize_lo,
+ ucsize_hi, csiz_lo, csiz_hi, (unsigned)cfactor,
+ mo, dy, yr, hh, mm,
+ (char)(G.pInfo->lcflag ? '^' : ' '),
+ (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
+ (LPCSTR)methbuf, G.crec.crc32,
+ (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
+ }
+#else /* !WINDLL */
+ if (cfactor == 100)
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+ else
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+ if (longhdr)
+ Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
+ FmZofft(G.crec.ucsize, "8", "u"), methbuf,
+ FmZofft(csiz, "8", "u"), cfactorstr,
+ mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+ G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
+ else
+#ifdef OS2_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+ FmZofft(G.crec.ucsize, "9", "u"), ea_size, acl_size,
+ mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+ (G.pInfo->lcflag? '^':' ')));
+#else
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+ FmZofft(G.crec.ucsize, "9", "u"),
+ mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
+ (G.pInfo->lcflag? '^':' ')));
+#endif
+ fnprint(__G);
+#endif /* ?WINDLL */
+
+ if ((error = do_string(__G__ G.crec.file_comment_length,
+ QCOND? DISPL_8 : SKIP)) != 0)
+ {
+ error_in_archive = error; /* might be just warning */
+ if (error > PK_WARN) /* fatal */
+ return error;
+ }
+ tot_ucsize += G.crec.ucsize;
+ tot_csize += csiz;
+ ++members;
+#ifdef OS2_EAS
+ if (ea_size) {
+ tot_easize += ea_size;
+ ++tot_eafiles;
+ }
+ if (acl_size) {
+ tot_aclsize += acl_size;
+ ++tot_aclfiles;
+ }
+#endif
+#ifdef OS2DLL
+ } /* end of "if (G.processExternally) {...} else {..." */
+#endif
+ } else { /* not listing this file */
+ SKIP_(G.crec.file_comment_length)
+ }
+ } /* end for-loop (j: files in central directory) */
+
+/*---------------------------------------------------------------------------
+ Print footer line and totals (compressed size, uncompressed size, number
+ of members in zipfile).
+ ---------------------------------------------------------------------------*/
+
+ if (uO.qflag < 2
+#ifdef OS2DLL
+ && !G.processExternally
+#endif
+ ) {
+ if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
+#ifndef WINDLL
+ sgn = '-';
+#endif
+ cfactor = (-cfactor + 5) / 10;
+ } else {
+#ifndef WINDLL
+ sgn = ' ';
+#endif
+ cfactor = (cfactor + 5) / 10;
+ }
+#ifdef WINDLL
+ /* pass the totals back to the calling application */
+ G.lpUserFunctions->TotalSizeComp = tot_csize;
+ G.lpUserFunctions->TotalSize = tot_ucsize;
+ G.lpUserFunctions->CompFactor = (ulg)cfactor;
+ G.lpUserFunctions->NumMembers = members;
+
+#else /* !WINDLL */
+ if (cfactor == 100)
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+ else
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+ if (longhdr) {
+ Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
+ FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"),
+ cfactorstr, members, members==1? "":"s"));
+#ifdef OS2_EAS
+ if (tot_easize || tot_aclsize)
+ Info(slide, 0, ((char *)slide, "\n"));
+ if (tot_eafiles && tot_easize)
+ Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
+ tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
+ tot_easize));
+ if (tot_aclfiles && tot_aclsize)
+ Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
+ tot_aclfiles,
+ tot_aclfiles == 1 ? " has" : "s have a total of",
+ tot_aclsize));
+#endif /* OS2_EAS */
+ } else
+#ifdef OS2_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
+ FmZofft(tot_ucsize, "9", "u"), tot_easize, tot_aclsize,
+ members, members == 1 ? "" : "s"));
+#else
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
+ FmZofft(tot_ucsize, "9", "u"),
+ members, members == 1 ? "" : "s"));
+#endif /* OS2_EAS */
+#endif /* ?WINDLL */
+ }
+
+ /* Skip the following checks in case of a premature listing break. */
+ if (error_in_archive <= PK_WARN) {
+
+/*---------------------------------------------------------------------------
+ Double check that we're back at the end-of-central-directory record.
+ ---------------------------------------------------------------------------*/
+
+ if ( (memcmp(G.sig,
+ (G.ecrec.have_ecr64 ?
+ end_central64_sig : end_central_sig),
+ 4) != 0)
+ && (!G.ecrec.is_zip64_archive)
+ && (memcmp(G.sig, end_central_sig, 4) != 0)
+ ) { /* just to make sure again */
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+ error_in_archive = PK_WARN; /* didn't find sig */
+ }
+
+ /* Set specific return code when no files have been found. */
+ if (members == 0L && error_in_archive <= PK_WARN)
+ error_in_archive = PK_FIND;
+
+ }
+
+ return error_in_archive;
+
+} /* end function list_files() */
+
+
+
+
+
+#ifdef TIMESTAMP
+
+/************************/
+/* Function fn_is_dir() */
+/************************/
+
+static int fn_is_dir(__G) /* returns TRUE if G.filename is directory */
+ __GDEF
+{
+ extent fn_len = strlen(G.filename);
+ register char endc;
+
+ return fn_len > 0 &&
+ ((endc = lastchar(G.filename, fn_len)) == '/' ||
+ (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
+ endc == '\\'));
+}
+
+
+
+
+
+/*****************************/
+/* Function get_time_stamp() */
+/*****************************/
+
+int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
+ __GDEF
+ time_t *last_modtime;
+ ulg *nmember;
+{
+ int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+ ulg j;
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+#endif
+ min_info info;
+
+
+/*---------------------------------------------------------------------------
+ Unlike extract_or_test_files() but like list_files(), this function works
+ on information in the central directory alone. Thus we have a single,
+ large loop through the entire directory, searching for the latest time
+ stamp.
+ ---------------------------------------------------------------------------*/
+
+ *last_modtime = 0L; /* assuming no zipfile data older than 1970 */
+ *nmember = 0L;
+ G.pInfo = &info;
+
+ for (j = 1L;; j++) {
+
+ if (readbuf(__G__ G.sig, 4) == 0)
+ return PK_EOF;
+ if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a CentDir entry? */
+ if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
+ (unsigned)G.ecrec.total_entries_central_dir) {
+ /* "j modulus 64k" matches the reported 16-bit-unsigned
+ * number of directory entries -> probably, the regular
+ * end of the central directory has been reached
+ */
+ break;
+ } else {
+ Info(slide, 0x401,
+ ((char *)slide, LoadFarString(CentSigMsg), j));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
+ return PK_BADERR; /* sig not found */
+ }
+ }
+ /* process_cdir_file_hdr() sets pInfo->lcflag: */
+ if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
+ return error; /* only PK_EOF defined */
+ if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
+ { /* ^-- (uses pInfo->lcflag) */
+ error_in_archive = error;
+ if (error > PK_WARN) /* fatal: can't continue */
+ return error;
+ }
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+ if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
+ != 0)
+ {
+ error_in_archive = error;
+ if (error > PK_WARN) /* fatal */
+ return error;
+ }
+ if (!G.process_all_files) { /* check if specified on command line */
+ unsigned i;
+
+ if (G.filespecs == 0)
+ do_this_file = TRUE;
+ else { /* check if this entry matches an `include' argument */
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+ do_this_file = TRUE;
+ break; /* found match, so stop looping */
+ }
+ }
+ if (do_this_file) { /* check if this is an excluded file */
+ for (i = 0; i < G.xfilespecs; i++)
+ if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+ do_this_file = FALSE; /* ^-- ignore case in match */
+ break;
+ }
+ }
+ }
+
+ /* If current file was specified on command line, or if no names were
+ * specified, check the time for this file. Either way, get rid of the
+ * file comment and go back for the next file.
+ * Directory entries are always ignored, to stay compatible with both
+ * Zip and PKZIP.
+ */
+ if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
+#ifdef USE_EF_UT_TIME
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+ G.crec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME))
+ {
+ if (*last_modtime < z_utime.mtime)
+ *last_modtime = z_utime.mtime;
+ } else
+#endif /* USE_EF_UT_TIME */
+ {
+ time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
+
+ if (*last_modtime < modtime)
+ *last_modtime = modtime;
+ }
+ ++*nmember;
+ }
+ SKIP_(G.crec.file_comment_length)
+
+ } /* end for-loop (j: files in central directory) */
+
+/*---------------------------------------------------------------------------
+ Double check that we're back at the end-of-central-directory record.
+ ---------------------------------------------------------------------------*/
+
+ if (memcmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+ error_in_archive = PK_WARN;
+ }
+ if (*nmember == 0L && error_in_archive <= PK_WARN)
+ error_in_archive = PK_FIND;
+
+ return error_in_archive;
+
+} /* end function get_time_stamp() */
+
+#endif /* TIMESTAMP */
+
+
+
+
+
+/********************/
+/* Function ratio() */ /* also used by ZipInfo routines */
+/********************/
+
+int ratio(uc, c)
+ zusz_t uc, c;
+{
+ zusz_t denom;
+
+ if (uc == 0)
+ return 0;
+ if (uc > 2000000L) { /* risk signed overflow if multiply numerator */
+ denom = uc / 1000L;
+ return ((uc >= c) ?
+ (int) ((uc-c + (denom>>1)) / denom) :
+ -((int) ((c-uc + (denom>>1)) / denom)));
+ } else { /* ^^^^^^^^ rounding */
+ denom = uc;
+ return ((uc >= c) ?
+ (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
+ -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
+ } /* ^^^^^^^^ rounding */
+}
+
+
+
+
+
+/************************/
+/* Function fnprint() */ /* also used by ZipInfo routines */
+/************************/
+
+void fnprint(__G) /* print filename (after filtering) and newline */
+ __GDEF
+{
+ char *name = fnfilter(G.filename, slide, (extent)(WSIZE>>1));
+
+ (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+} /* end function fnprint() */
Index: unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1 (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/man/unzip.1 (revision 5)
@@ -0,0 +1,1040 @@
+.\" Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+.\"
+.\" See the accompanying file LICENSE, version 2009-Jan-02 or later
+.\" (the contents of which are also included in unzip.h) for terms of use.
+.\" If, for some reason, all these files are missing, the Info-ZIP license
+.\" also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+.\"
+.\" unzip.1 by Greg Roelofs, Fulvio Marino, Jim van Zandt and others.
+.\"
+.\" =========================================================================
+.\" define .EX/.EE (for multiline user-command examples; normal Courier font)
+.de EX
+.in +4n
+.nf
+.ft CW
+..
+.de EE
+.ft R
+.fi
+.in -4n
+..
+.\" =========================================================================
+.TH UNZIP 1L "20 April 2009 (v6.0)" "Info-ZIP"
+.SH NAME
+unzip \- list, test and extract compressed files in a ZIP archive
+.PD
+.SH SYNOPSIS
+\fBunzip\fP [\fB\-Z\fP] [\fB\-cflptTuvz\fP[\fBabjnoqsCDKLMUVWX$/:^\fP]]
+\fIfile\fP[\fI.zip\fP] [\fIfile(s)\fP\ .\|.\|.]
+[\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.] [\fB\-d\fP\ \fIexdir\fP]
+.PD
+.\" =========================================================================
+.SH DESCRIPTION
+\fIunzip\fP will list, test, or extract files from a ZIP archive, commonly
+found on MS-DOS systems. The default behavior (with no options) is to extract
+into the current directory (and subdirectories below it) all files from the
+specified ZIP archive. A companion program, \fIzip\fP(1L), creates ZIP
+archives; both programs are compatible with archives created by PKWARE's
+\fIPKZIP\fP and \fIPKUNZIP\fP for MS-DOS, but in many cases the program
+options or default behaviors differ.
+.PD
+.\" =========================================================================
+.SH ARGUMENTS
+.TP
+.IR file [ .zip ]
+Path of the ZIP archive(s). If the file specification is a wildcard,
+each matching file is processed in an order determined by the operating
+system (or file system). Only the filename can be a wildcard; the path
+itself cannot. Wildcard expressions are similar to those supported in
+commonly used Unix shells (\fIsh\fP, \fIksh\fP, \fIcsh\fP) and may contain:
+.RS
+.IP *
+matches a sequence of 0 or more characters
+.IP ?
+matches exactly 1 character
+.IP [.\|.\|.]
+matches any single character found inside the brackets; ranges are specified
+by a beginning character, a hyphen, and an ending character. If an exclamation
+point or a caret (`!' or `^') follows the left bracket, then the range of
+characters within the brackets is complemented (that is, anything \fIexcept\fP
+the characters inside the brackets is considered a match). To specify a
+verbatim left bracket, the three-character sequence ``[[]'' has to be used.
+.RE
+.IP
+(Be sure to quote any character that might otherwise be interpreted or
+modified by the operating system, particularly under Unix and VMS.) If no
+matches are found, the specification is assumed to be a literal filename;
+and if that also fails, the suffix \fC.zip\fR is appended. Note that
+self-extracting ZIP files are supported, as with any other ZIP archive;
+just specify the \fC.exe\fR suffix (if any) explicitly.
+.IP [\fIfile(s)\fP]
+An optional list of archive members to be processed, separated by spaces.
+(VMS versions compiled with VMSCLI defined must delimit files with commas
+instead. See \fB\-v\fP in \fBOPTIONS\fP below.)
+Regular expressions (wildcards) may be used to match multiple members; see
+above. Again, be sure to quote expressions that would otherwise be expanded
+or modified by the operating system.
+.IP [\fB\-x\fP\ \fIxfile(s)\fP]
+An optional list of archive members to be excluded from processing.
+Since wildcard characters normally match (`/') directory separators
+(for exceptions see the option \fB\-W\fP), this option may be used
+to exclude any files that are in subdirectories. For
+example, ``\fCunzip foo *.[ch] -x */*\fR'' would extract all C source files
+in the main directory, but none in any subdirectories. Without the \fB\-x\fP
+option, all C source files in all directories within the zipfile would be
+extracted.
+.IP [\fB\-d\fP\ \fIexdir\fP]
+An optional directory to which to extract files. By default, all files
+and subdirectories are recreated in the current directory; the \fB\-d\fP
+option allows extraction in an arbitrary directory (always assuming one
+has permission to write to the directory). This option need not appear
+at the end of the command line; it is also accepted before the zipfile
+specification (with the normal options), immediately after the zipfile
+specification, or between the \fIfile(s)\fP and the \fB\-x\fP option.
+The option and directory may be concatenated without any white space
+between them, but note that this may cause normal shell behavior to be
+suppressed. In particular, ``\fC\-d\ ~\fR'' (tilde) is expanded by Unix
+C shells into the name of the user's home directory, but ``\fC\-d~\fR''
+is treated as a literal subdirectory ``\fB~\fP'' of the current directory.
+.\" =========================================================================
+.SH OPTIONS
+Note that, in order to support obsolescent hardware, \fIunzip\fP's usage
+screen is limited to 22 or 23 lines and should therefore be considered
+only a reminder of the basic \fIunzip\fP syntax rather than an exhaustive
+list of all possible flags. The exhaustive list follows:
+.TP
+.B \-Z
+\fIzipinfo\fP(1L) mode. If the first option on the command line is \fB\-Z\fP,
+the remaining options are taken to be \fIzipinfo\fP(1L) options. See the
+appropriate manual page for a description of these options.
+.TP
+.B \-A
+[OS/2, Unix DLL] print extended help for the DLL's programming interface (API).
+.TP
+.B \-c
+extract files to stdout/screen (``CRT''). This option is similar to the
+\fB\-p\fP option except that the name of each file is printed as it is
+extracted, the \fB\-a\fP option is allowed, and ASCII-EBCDIC conversion
+is automatically performed if appropriate. This option is not listed in
+the \fIunzip\fP usage screen.
+.TP
+.B \-f
+freshen existing files, i.e., extract only those files that
+already exist on disk and that are newer than the disk copies. By
+default \fIunzip\fP queries before overwriting, but the \fB\-o\fP option
+may be used to suppress the queries. Note that under many operating systems,
+the TZ (timezone) environment variable must be set correctly in order for
+\fB\-f\fP and \fB\-u\fP to work properly (under Unix the variable is usually
+set automatically). The reasons for this are somewhat subtle but
+have to do with the differences between DOS-format file times (always local
+time) and Unix-format times (always in GMT/UTC) and the necessity to compare
+the two. A typical TZ value is ``PST8PDT'' (US Pacific time with automatic
+adjustment for Daylight Savings Time or ``summer time'').
+.TP
+.B \-l
+list archive files (short format). The names, uncompressed file sizes and
+modification dates and times of the specified files are printed, along
+with totals for all files specified. If UnZip was compiled with OS2_EAS
+defined, the \fB\-l\fP option also lists columns for the sizes of stored
+OS/2 extended attributes (EAs) and OS/2 access control lists (ACLs). In
+addition, the zipfile comment and individual file comments (if any) are
+displayed. If a file was archived from a single-case file system (for
+example, the old MS-DOS FAT file system) and the \fB\-L\fP option was given,
+the filename is converted to lowercase and is prefixed with a caret (^).
+.TP
+.B \-p
+extract files to pipe (stdout). Nothing but the file data is sent to
+stdout, and the files are always extracted in binary format, just as they
+are stored (no conversions).
+.TP
+.B \-t
+test archive files. This option extracts each specified file in memory
+and compares the CRC (cyclic redundancy check, an enhanced checksum) of
+the expanded file with the original file's stored CRC value.
+.TP
+.B \-T
+[most OSes] set the timestamp on the archive(s) to that of the newest file
+in each one. This corresponds to \fIzip\fP's \fB\-go\fP option except that
+it can be used on wildcard zipfiles (e.g., ``\fCunzip \-T \e*.zip\fR'') and
+is much faster.
+.TP
+.B \-u
+update existing files and create new ones if needed. This option performs
+the same function as the \fB\-f\fP option, extracting (with query) files
+that are newer than those with the same name on disk, and in addition it
+extracts those files that do not already exist on disk. See \fB\-f\fP
+above for information on setting the timezone properly.
+.TP
+.B \-v
+list archive files (verbose format) or show diagnostic version info.
+This option has evolved and now behaves as both an option and a modifier.
+As an option it has two purposes: when a zipfile is specified with no
+other options, \fB\-v\fP lists archive files verbosely, adding to the
+basic \fB\-l\fP info the compression method, compressed size,
+compression ratio and 32-bit CRC. In contrast to most of the competing
+utilities, \fIunzip\fP removes the 12 additional header bytes of
+encrypted entries from the compressed size numbers. Therefore,
+compressed size and compression ratio figures are independent of the entry's
+encryption status and show the correct compression performance. (The complete
+size of the encrypted compressed data stream for zipfile entries is reported
+by the more verbose \fIzipinfo\fP(1L) reports, see the separate manual.)
+When no zipfile is specified (that is, the complete command is simply
+``\fCunzip \-v\fR''), a diagnostic screen is printed. In addition to
+the normal header with release date and version, \fIunzip\fP lists the
+home Info-ZIP ftp site and where to find a list of other ftp and non-ftp
+sites; the target operating system for which it was compiled, as well
+as (possibly) the hardware on which it was compiled, the compiler and
+version used, and the compilation date; any special compilation options
+that might affect the program's operation (see also \fBDECRYPTION\fP below);
+and any options stored in environment variables that might do the same
+(see \fBENVIRONMENT OPTIONS\fP below). As a modifier it works in
+conjunction with other options (e.g., \fB\-t\fP) to produce more
+verbose or debugging output; this is not yet fully implemented
+but will be in future releases.
+.TP
+.B \-z
+display only the archive comment.
+.PD
+.\" =========================================================================
+.SH MODIFIERS
+.TP
+.B \-a
+convert text files. Ordinarily all files are extracted exactly as they
+are stored (as ``binary'' files). The \fB\-a\fP option causes files identified
+by \fIzip\fP as text files (those with the `t' label in \fIzipinfo\fP
+listings, rather than `b') to be automatically extracted as such, converting
+line endings, end-of-file characters and the character set itself as necessary.
+(For example, Unix files use line feeds (LFs) for end-of-line (EOL) and
+have no end-of-file (EOF) marker; Macintoshes use carriage returns (CRs)
+for EOLs; and most PC operating systems use CR+LF for EOLs and control-Z for
+EOF. In addition, IBM mainframes and the Michigan Terminal System use EBCDIC
+rather than the more common ASCII character set, and NT supports Unicode.)
+Note that \fIzip\fP's identification of text files is by no means perfect; some
+``text'' files may actually be binary and vice versa. \fIunzip\fP therefore
+prints ``\fC[text]\fR'' or ``\fC[binary]\fR'' as a visual check for each file
+it extracts when using the \fB\-a\fP option. The \fB\-aa\fP option forces
+all files to be extracted as text, regardless of the supposed file type.
+On VMS, see also \fB\-S\fP.
+.TP
+.B \-b
+[general] treat all files as binary (no text conversions). This is a shortcut
+for \fB\-\-\-a\fP.
+.TP
+.B \-b
+[Tandem] force the creation files with filecode type 180 ('C') when
+extracting Zip entries marked as "text". (On Tandem, \fB\-a\fP is enabled
+by default, see above).
+.TP
+.B \-b
+[VMS] auto-convert binary files (see \fB\-a\fP above) to fixed-length,
+512-byte record format. Doubling the option (\fB\-bb\fP) forces all files
+to be extracted in this format. When extracting to standard output
+(\fB\-c\fP or \fB\-p\fP option in effect), the default conversion of text
+record delimiters is disabled for binary (\fB\-b\fP) resp. all (\fB\-bb\fP)
+files.
+.TP
+.B \-B
+[when compiled with UNIXBACKUP defined] save a backup copy of each
+overwritten file. The backup file is gets the name of the target file with
+a tilde and optionally a unique sequence number (up to 5 digits) appended.
+The sequence number is applied whenever another file with the original name
+plus tilde already exists. When used together with the "overwrite all"
+option \fB\-o\fP, numbered backup files are never created. In this case,
+all backup files are named as the original file with an appended tilde,
+existing backup files are deleted without notice.
+This feature works similarly to the default behavior of \fIemacs\fP(1)
+in many locations.
+.IP
+Example: the old copy of ``\fCfoo\fR'' is renamed to ``\fCfoo~\fR''.
+.IP
+Warning: Users should be aware that the \fB-B\fP option does not prevent
+loss of existing data under all circumstances. For example, when
+\fIunzip\fP is run in overwrite-all mode, an existing ``\fCfoo~\fR'' file
+is deleted before \fIunzip\fP attempts to rename ``\fCfoo\fR'' to
+``\fCfoo~\fR''. When this rename attempt fails (because of a file locks,
+insufficient privileges, or ...), the extraction of ``\fCfoo~\fR'' gets
+cancelled, but the old backup file is already lost. A similar scenario
+takes place when the sequence number range for numbered backup files gets
+exhausted (99999, or 65535 for 16-bit systems). In this case, the backup
+file with the maximum sequence number is deleted and replaced by the new
+backup version without notice.
+.TP
+.B \-C
+use case-insensitive matching for the selection of archive entries
+from the command-line list of extract selection patterns.
+\fIunzip\fP's philosophy is ``you get what you ask for'' (this is
+also responsible for the \fB\-L\fP/\fB\-U\fP change; see the relevant
+options below). Because some file systems are fully case-sensitive
+(notably those under the Unix operating system) and because
+both ZIP archives and \fIunzip\fP itself are portable across platforms,
+\fIunzip\fP's default behavior is to match both wildcard and literal
+filenames case-sensitively. That is, specifying ``\fCmakefile\fR''
+on the command line will \fIonly\fP match ``makefile'' in the archive,
+not ``Makefile'' or ``MAKEFILE'' (and similarly for wildcard specifications).
+Since this does not correspond to the behavior of many other
+operating/file systems (for example, OS/2 HPFS, which preserves
+mixed case but is not sensitive to it), the \fB\-C\fP option may be
+used to force all filename matches to be case-insensitive. In the
+example above, all three files would then match ``\fCmakefile\fR''
+(or ``\fCmake*\fR'', or similar). The \fB\-C\fP option affects
+file specs in both the normal file list and the excluded-file list (xlist).
+.IP
+Please note that the \fB\-C\fP option does neither affect the search for
+the zipfile(s) nor the matching of archive entries to existing files on
+the extraction path. On a case-sensitive file system, \fIunzip\fP will
+never try to overwrite a file ``FOO'' when extracting an entry ``foo''!
+.TP
+.B \-D
+skip restoration of timestamps for extracted items. Normally, \fIunzip\fP
+tries to restore all meta-information for extracted items that are supplied
+in the Zip archive (and do not require privileges or impose a security risk).
+By specifying \fB\-D\fP, \fIunzip\fP is told to suppress restoration of
+timestamps for directories explicitly created from Zip archive entries.
+This option only applies to ports that support setting timestamps for
+directories (currently ATheOS, BeOS, MacOS, OS/2, Unix, VMS, Win32, for other
+\fIunzip\fP ports, \fB\-D\fP has no effect).
+The duplicated option \fB\-DD\fP forces suppression of timestamp restoration
+for all extracted entries (files and directories). This option results in
+setting the timestamps for all extracted entries to the current time.
+.IP
+On VMS, the default setting for this option is \fB\-D\fP for consistency
+with the behaviour of BACKUP: file timestamps are restored, timestamps of
+extracted directories are left at the current time. To enable restoration
+of directory timestamps, the negated option \fB\--D\fP should be specified.
+On VMS, the option \fB\-D\fP disables timestamp restoration for all extracted
+Zip archive items. (Here, a single \fB\-D\fP on the command line combines
+with the default \fB\-D\fP to do what an explicit \fB\-DD\fP does on other
+systems.)
+.TP
+.B \-E
+[MacOS only] display contents of MacOS extra field during restore operation.
+.TP
+.B \-F
+[Acorn only] suppress removal of NFS filetype extension from stored filenames.
+.TP
+.B \-F
+[non-Acorn systems supporting long filenames with embedded commas,
+and only if compiled with ACORN_FTYPE_NFS defined] translate
+filetype information from ACORN RISC OS extra field blocks into a
+NFS filetype extension and append it to the names of the extracted files.
+(When the stored filename appears to already have an appended NFS filetype
+extension, it is replaced by the info from the extra field.)
+.TP
+.B \-i
+[MacOS only] ignore filenames stored in MacOS extra fields. Instead, the
+most compatible filename stored in the generic part of the entry's header
+is used.
+.TP
+.B \-j
+junk paths. The archive's directory structure is not recreated; all files
+are deposited in the extraction directory (by default, the current one).
+.TP
+.B \-J
+[BeOS only] junk file attributes. The file's BeOS file attributes are not
+restored, just the file's data.
+.TP
+.B \-J
+[MacOS only] ignore MacOS extra fields. All Macintosh specific info
+is skipped. Data-fork and resource-fork are restored as separate files.
+.TP
+.B \-K
+[AtheOS, BeOS, Unix only] retain SUID/SGID/Tacky file attributes. Without
+this flag, these attribute bits are cleared for security reasons.
+.TP
+.B \-L
+convert to lowercase any filename originating on an uppercase-only operating
+system or file system. (This was \fIunzip\fP's default behavior in releases
+prior to 5.11; the new default behavior is identical to the old behavior with
+the \fB\-U\fP option, which is now obsolete and will be removed in a future
+release.) Depending on the archiver, files archived under single-case
+file systems (VMS, old MS-DOS FAT, etc.) may be stored as all-uppercase names;
+this can be ugly or inconvenient when extracting to a case-preserving
+file system such as OS/2 HPFS or a case-sensitive one such as under
+Unix. By default \fIunzip\fP lists and extracts such filenames exactly as
+they're stored (excepting truncation, conversion of unsupported characters,
+etc.); this option causes the names of all files from certain systems to be
+converted to lowercase. The \fB\-LL\fP option forces conversion of every
+filename to lowercase, regardless of the originating file system.
+.TP
+.B \-M
+pipe all output through an internal pager similar to the Unix \fImore\fP(1)
+command. At the end of a screenful of output, \fIunzip\fP pauses with a
+``\-\-More\-\-'' prompt; the next screenful may be viewed by pressing the
+Enter (Return) key or the space bar. \fIunzip\fP can be terminated by
+pressing the ``q'' key and, on some systems, the Enter/Return key. Unlike
+Unix \fImore\fP(1), there is no forward-searching or editing capability.
+Also, \fIunzip\fP doesn't notice if long lines wrap at the edge of the screen,
+effectively resulting in the printing of two or more lines and the likelihood
+that some text will scroll off the top of the screen before being viewed.
+On some systems the number of available lines on the screen is not detected,
+in which case \fIunzip\fP assumes the height is 24 lines.
+.TP
+.B \-n
+never overwrite existing files. If a file already exists, skip the extraction
+of that file without prompting. By default \fIunzip\fP queries before
+extracting any file that already exists; the user may choose to overwrite
+only the current file, overwrite all files, skip extraction of the current
+file, skip extraction of all existing files, or rename the current file.
+.TP
+.B \-N
+[Amiga] extract file comments as Amiga filenotes. File comments are created
+with the \-c option of \fIzip\fP(1L), or with the \-N option of the Amiga port
+of \fIzip\fP(1L), which stores filenotes as comments.
+.TP
+.B \-o
+overwrite existing files without prompting. This is a dangerous option, so
+use it with care. (It is often used with \fB\-f\fP, however, and is the only
+way to overwrite directory EAs under OS/2.)
+.IP \fB\-P\fP\ \fIpassword\fP
+use \fIpassword\fP to decrypt encrypted zipfile entries (if any). \fBTHIS IS
+INSECURE!\fP Many multi-user operating systems provide ways for any user to
+see the current command line of any other user; even on stand-alone systems
+there is always the threat of over-the-shoulder peeking. Storing the plaintext
+password as part of a command line in an automated script is even worse.
+Whenever possible, use the non-echoing, interactive prompt to enter passwords.
+(And where security is truly important, use strong encryption such as Pretty
+Good Privacy instead of the relatively weak encryption provided by standard
+zipfile utilities.)
+.TP
+.B \-q
+perform operations quietly (\fB\-qq\fP = even quieter). Ordinarily \fIunzip\fP
+prints the names of the files it's extracting or testing, the extraction
+methods, any file or zipfile comments that may be stored in the archive,
+and possibly a summary when finished with each archive. The \fB\-q\fP[\fBq\fP]
+options suppress the printing of some or all of these messages.
+.TP
+.B \-s
+[OS/2, NT, MS-DOS] convert spaces in filenames to underscores. Since all PC
+operating systems allow spaces in filenames, \fIunzip\fP by default extracts
+filenames with spaces intact (e.g., ``\fCEA\ DATA.\ SF\fR''). This can be
+awkward, however, since MS-DOS in particular does not gracefully support
+spaces in filenames. Conversion of spaces to underscores can eliminate the
+awkwardness in some cases.
+.TP
+.B \-S
+[VMS] convert text files (\fB\-a\fP, \fB\-aa\fP) into Stream_LF record format,
+instead of the text-file default, variable-length record format.
+(Stream_LF is the default record format of VMS \fIunzip\fP. It is applied
+unless conversion (\fB\-a\fP, \fB\-aa\fP and/or \fB\-b\fP, \fB\-bb\fP) is
+requested or a VMS-specific entry is processed.)
+.TP
+.B \-U
+[UNICODE_SUPPORT only] modify or disable UTF-8 handling.
+When UNICODE_SUPPORT is available, the option \fB\-U\fP forces \fIunzip\fP
+to escape all non-ASCII characters from UTF-8 coded filenames as ``#Uxxxx''
+(for UCS-2 characters, or ``#Lxxxxxx'' for unicode codepoints needing 3
+octets). This option is mainly provided for debugging purpose when the
+fairly new UTF-8 support is suspected to mangle up extracted filenames.
+.IP
+The option \fB\-UU\fP allows to entirely disable the recognition of UTF-8
+encoded filenames. The handling of filename codings within \fIunzip\fP falls
+back to the behaviour of previous versions.
+.IP
+[old, obsolete usage] leave filenames uppercase if
+created under MS-DOS, VMS, etc. See \fB\-L\fP above.
+.TP
+.B \-V
+retain (VMS) file version numbers. VMS files can be stored with a version
+number, in the format \fCfile.ext;##\fR. By default the ``\fC;##\fR'' version
+numbers are stripped, but this option allows them to be retained. (On
+file systems that limit filenames to particularly short lengths, the version
+numbers may be truncated or stripped regardless of this option.)
+.TP
+.B \-W
+[only when WILD_STOP_AT_DIR compile-time option enabled]
+modifies the pattern matching routine so that both `?' (single-char wildcard)
+and `*' (multi-char wildcard) do not match the directory separator character
+`/'. (The two-character sequence ``**'' acts as a multi-char wildcard that
+includes the directory separator in its matched characters.) Examples:
+.PP
+.EX
+ "*.c" matches "foo.c" but not "mydir/foo.c"
+ "**.c" matches both "foo.c" and "mydir/foo.c"
+ "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c"
+ "??*/*" matches "ab/foo" and "abc/foo"
+ but not "a/foo" or "a/b/foo"
+.EE
+.IP
+This modified behaviour is equivalent to the pattern matching style
+used by the shells of some of UnZip's supported target OSs (one
+example is Acorn RISC OS). This option may not be available on systems
+where the Zip archive's internal directory separator character `/' is
+allowed as regular character in native operating system filenames.
+(Currently, UnZip uses the same pattern matching rules for both wildcard
+zipfile specifications and zip entry selection patterns in most ports.
+For systems allowing `/' as regular filename character, the -W option
+would not work as expected on a wildcard zipfile specification.)
+.TP
+.B \-X
+[VMS, Unix, OS/2, NT, Tandem] restore owner/protection info (UICs and ACL
+entries) under VMS, or user and group info (UID/GID) under Unix, or access
+control lists (ACLs) under certain network-enabled versions of OS/2
+(Warp Server with IBM LAN Server/Requester 3.0 to 5.0; Warp Connect with
+IBM Peer 1.0), or security ACLs under Windows NT. In most cases this will
+require special system privileges, and doubling the option (\fB\-XX\fP)
+under NT instructs \fIunzip\fP to use privileges for extraction; but under
+Unix, for example, a user who belongs to several groups can restore files
+owned by any of those groups, as long as the user IDs match his or her own.
+Note that ordinary file attributes are always restored--this option applies
+only to optional, extra ownership info available on some operating systems.
+[NT's access control lists do not appear to be especially compatible with
+OS/2's, so no attempt is made at cross-platform portability of access
+privileges. It is not clear under what conditions this would ever be
+useful anyway.]
+.TP
+.B \-Y
+[VMS] treat archived file name endings of ``.nnn'' (where ``nnn'' is a
+decimal number) as if they were VMS version numbers (``;nnn'').
+(The default is to treat them as file types.) Example:
+.EX
+ "a.b.3" -> "a.b;3".
+.EE
+.TP
+.B \-$
+.\" Amiga support possible eventually, but not yet
+[MS-DOS, OS/2, NT] restore the volume label if the extraction medium is
+removable (e.g., a diskette). Doubling the option (\fB\-$$\fP) allows fixed
+media (hard disks) to be labeled as well. By default, volume labels are
+ignored.
+.IP \fB\-/\fP\ \fIextensions\fP
+[Acorn only] overrides the extension list supplied by Unzip$Ext environment
+variable. During extraction, filename extensions that match one of the items
+in this extension list are swapped in front of the base name of the extracted
+file.
+.TP
+.B \-:
+[all but Acorn, VM/CMS, MVS, Tandem] allows to extract archive members into
+locations outside of the current `` extraction root folder''. For security
+reasons, \fIunzip\fP normally removes ``parent dir'' path components
+(``../'') from the names of extracted file. This safety feature (new for
+version 5.50) prevents \fIunzip\fP from accidentally writing files to
+``sensitive'' areas outside the active extraction folder tree head. The
+\fB\-:\fP option lets \fIunzip\fP switch back to its previous, more liberal
+behaviour, to allow exact extraction of (older) archives that used ``../''
+components to create multiple directory trees at the level of the current
+extraction folder. This option does not enable writing explicitly to the
+root directory (``/''). To achieve this, it is necessary to set the
+extraction target folder to root (e.g. \fB\-d / \fP). However, when the
+\fB\-:\fP option is specified, it is still possible to implicitly write to
+the root directory by specifying enough ``../'' path components within the
+zip archive.
+Use this option with extreme caution.
+.TP
+.B \-^
+[Unix only] allow control characters in names of extracted ZIP archive
+entries. On Unix, a file name may contain any (8-bit) character code with
+the two exception '/' (directory delimiter) and NUL (0x00, the C string
+termination indicator), unless the specific file system has more
+restrictive conventions. Generally, this allows to embed ASCII control
+characters (or even sophisticated control sequences) in file names, at least
+on 'native' Unix file systems. However, it may be highly suspicious to
+make use of this Unix "feature". Embedded control characters in file names
+might have nasty side effects when displayed on screen by some listing code
+without sufficient filtering. And, for ordinary users, it may be difficult
+to handle such file names (e.g. when trying to specify it for open, copy,
+move, or delete operations). Therefore, \fIunzip\fP applies a filter by
+default that removes potentially dangerous control characters from the
+extracted file names. The \fB-^\fP option allows to override this filter
+in the rare case that embedded filename control characters are to be
+intentionally restored.
+.TP
+.B \-2
+[VMS] force unconditionally conversion of file names to ODS2-compatible
+names. The default is to exploit the destination file system, preserving
+case and extended file name characters on an ODS5 destination file system;
+and applying the ODS2-compatibility file name filtering on an ODS2 destination
+file system.
+.PD
+.\" =========================================================================
+.SH "ENVIRONMENT OPTIONS"
+\fIunzip\fP's default behavior may be modified via options placed in
+an environment variable. This can be done with any option, but it
+is probably most useful with the \fB\-a\fP, \fB\-L\fP, \fB\-C\fP, \fB\-q\fP,
+\fB\-o\fP, or \fB\-n\fP modifiers: make \fIunzip\fP auto-convert text
+files by default, make it convert filenames from uppercase systems to
+lowercase, make it match names case-insensitively, make it quieter,
+or make it always overwrite or never overwrite files as it extracts
+them. For example, to make \fIunzip\fP act as quietly as possible, only
+reporting errors, one would use one of the following commands:
+.TP
+ Unix Bourne shell:
+UNZIP=\-qq; export UNZIP
+.TP
+ Unix C shell:
+setenv UNZIP \-qq
+.TP
+ OS/2 or MS-DOS:
+set UNZIP=\-qq
+.TP
+ VMS (quotes for \fIlowercase\fP):
+define UNZIP_OPTS "\-qq"
+.PP
+Environment options are, in effect, considered to be just like any other
+command-line options, except that they are effectively the first options
+on the command line. To override an environment option, one may use the
+``minus operator'' to remove it. For instance, to override one of the
+quiet-flags in the example above, use the command
+.PP
+.EX
+unzip \-\-q[\fIother options\fP] zipfile
+.EE
+.PP
+The first hyphen is the normal
+switch character, and the second is a minus sign, acting on the q option.
+Thus the effect here is to cancel one quantum of quietness. To cancel
+both quiet flags, two (or more) minuses may be used:
+.PP
+.EX
+unzip \-t\-\-q zipfile
+unzip \-\-\-qt zipfile
+.EE
+.PP
+(the two are equivalent). This may seem awkward
+or confusing, but it is reasonably intuitive: just ignore the first
+hyphen and go from there. It is also consistent with the behavior of
+Unix \fInice\fP(1).
+.PP
+As suggested by the examples above, the default variable names are UNZIP_OPTS
+for VMS (where the symbol used to install \fIunzip\fP as a foreign command
+would otherwise be confused with the environment variable), and UNZIP
+for all other operating systems. For compatibility with \fIzip\fP(1L),
+UNZIPOPT is also accepted (don't ask). If both UNZIP and UNZIPOPT
+are defined, however, UNZIP takes precedence. \fIunzip\fP's diagnostic
+option (\fB\-v\fP with no zipfile name) can be used to check the values
+of all four possible \fIunzip\fP and \fIzipinfo\fP environment variables.
+.PP
+The timezone variable (TZ) should be set according to the local timezone
+in order for the \fB\-f\fP and \fB\-u\fP to operate correctly. See the
+description of \fB\-f\fP above for details. This variable may also be
+necessary to get timestamps of extracted files to be set correctly.
+The WIN32 (Win9x/ME/NT4/2K/XP/2K3) port of \fIunzip\fP gets the timezone
+configuration from the registry, assuming it is correctly set in the
+Control Panel. The TZ variable is ignored for this port.
+.PD
+.\" =========================================================================
+.SH DECRYPTION
+Encrypted archives are fully supported by Info-ZIP software, but due to
+United States export restrictions, de-/encryption support might be disabled
+in your compiled binary. However, since spring 2000, US export restrictions
+have been liberated, and our source archives do now include full crypt code.
+In case you need binary distributions with crypt support enabled, see the
+file ``WHERE'' in any Info-ZIP source or binary distribution for locations
+both inside and outside the US.
+.PP
+Some compiled versions of \fIunzip\fP may not support decryption.
+To check a version for crypt support, either attempt to test or extract
+an encrypted archive, or else check \fIunzip\fP's diagnostic
+screen (see the \fB\-v\fP option above) for ``\fC[decryption]\fR'' as one
+of the special compilation options.
+.PP
+As noted above, the \fB\-P\fP option may be used to supply a password on
+the command line, but at a cost in security. The preferred decryption
+method is simply to extract normally; if a zipfile member is encrypted,
+\fIunzip\fP will prompt for the password without echoing what is typed.
+\fIunzip\fP continues to use the same password as long as it appears to be
+valid, by testing a 12-byte header on each file. The correct password will
+always check out against the header, but there is a 1-in-256 chance that an
+incorrect password will as well. (This is a security feature of the PKWARE
+zipfile format; it helps prevent brute-force attacks that might otherwise
+gain a large speed advantage by testing only the header.) In the case that
+an incorrect password is given but it passes the header test anyway, either
+an incorrect CRC will be generated for the extracted data or else \fIunzip\fP
+will fail during the extraction because the ``decrypted'' bytes do not
+constitute a valid compressed data stream.
+.PP
+If the first password fails the header check on some file, \fIunzip\fP will
+prompt for another password, and so on until all files are extracted. If
+a password is not known, entering a null password (that is, just a carriage
+return or ``Enter'') is taken as a signal to skip all further prompting.
+Only unencrypted files in the archive(s) will thereafter be extracted. (In
+fact, that's not quite true; older versions of \fIzip\fP(1L) and
+\fIzipcloak\fP(1L) allowed null passwords, so \fIunzip\fP checks each encrypted
+file to see if the null password works. This may result in ``false positives''
+and extraction errors, as noted above.)
+.PP
+Archives encrypted with 8-bit passwords (for example, passwords with accented
+European characters) may not be portable across systems and/or other
+archivers. This problem stems from the use of multiple encoding methods for
+such characters, including Latin-1 (ISO 8859-1) and OEM code page 850.
+DOS \fIPKZIP\fP 2.04g uses the OEM code page; Windows \fIPKZIP\fP 2.50
+uses Latin-1 (and is therefore incompatible with DOS \fIPKZIP\fP); Info-ZIP
+uses the OEM code page on DOS, OS/2 and Win3.x ports but ISO coding
+(Latin-1 etc.) everywhere else; and Nico Mak's \fIWinZip\fP 6.x does not
+allow 8-bit passwords at all. \fIUnZip\fP 5.3 (or newer) attempts to use
+the default character set first (e.g., Latin-1), followed by the alternate
+one (e.g., OEM code page) to test passwords. On EBCDIC systems, if both
+of these fail, EBCDIC encoding will be tested as a last resort. (EBCDIC is
+not tested on non-EBCDIC systems, because there are no known archivers
+that encrypt using EBCDIC encoding.) ISO character encodings other than
+Latin-1 are not supported. The new addition of (partially) Unicode (resp.
+UTF-8) support in \fIUnZip\fP 6.0 has not yet been adapted to the encryption
+password handling in \fIunzip\fP. On systems that use UTF-8 as native
+character encoding, \fIunzip\fP simply tries decryption with the native
+UTF-8 encoded password; the built-in attempts to check the password in
+translated encoding have not yet been adapted for UTF-8 support and
+will consequently fail.
+.PD
+.\" =========================================================================
+.SH EXAMPLES
+To use \fIunzip\fP to extract all members of the archive \fIletters.zip\fP
+into the current directory and subdirectories below it, creating any
+subdirectories as necessary:
+.PP
+.EX
+unzip letters
+.EE
+.PP
+To extract all members of \fIletters.zip\fP into the current directory only:
+.PP
+.EX
+unzip -j letters
+.EE
+.PP
+To test \fIletters.zip\fP, printing only a summary message indicating
+whether the archive is OK or not:
+.PP
+.EX
+unzip -tq letters
+.EE
+.PP
+To test \fIall\fP zipfiles in the current directory, printing only the
+summaries:
+.PP
+.EX
+unzip -tq \e*.zip
+.EE
+.PP
+(The backslash before the asterisk is only required if the shell expands
+wildcards, as in Unix; double quotes could have been used instead, as in
+the source examples below.)\ \ To extract to standard output all members of
+\fIletters.zip\fP whose names end in \fI.tex\fP, auto-converting to the
+local end-of-line convention and piping the output into \fImore\fP(1):
+.PP
+.EX
+unzip \-ca letters \e*.tex | more
+.EE
+.PP
+To extract the binary file \fIpaper1.dvi\fP to standard output and pipe it
+to a printing program:
+.PP
+.EX
+unzip \-p articles paper1.dvi | dvips
+.EE
+.PP
+To extract all FORTRAN and C source files--*.f, *.c, *.h, and Makefile--into
+the /tmp directory:
+.PP
+.EX
+unzip source.zip "*.[fch]" Makefile -d /tmp
+.EE
+.PP
+(the double quotes are necessary only in Unix and only if globbing is turned
+on). To extract all FORTRAN and C source files, regardless of case (e.g.,
+both *.c and *.C, and any makefile, Makefile, MAKEFILE or similar):
+.PP
+.EX
+unzip \-C source.zip "*.[fch]" makefile -d /tmp
+.EE
+.PP
+To extract any such files but convert any uppercase MS-DOS or VMS names to
+lowercase and convert the line-endings of all of the files to the local
+standard (without respect to any files that might be marked ``binary''):
+.PP
+.EX
+unzip \-aaCL source.zip "*.[fch]" makefile -d /tmp
+.EE
+.PP
+To extract only newer versions of the files already in the current
+directory, without querying (NOTE: be careful of unzipping in one timezone a
+zipfile created in another--ZIP archives other than those created by Zip 2.1
+or later contain no timezone information, and a ``newer'' file from an eastern
+timezone may, in fact, be older):
+.PP
+.EX
+unzip \-fo sources
+.EE
+.PP
+To extract newer versions of the files already in the current directory and
+to create any files not already there (same caveat as previous example):
+.PP
+.EX
+unzip \-uo sources
+.EE
+.PP
+To display a diagnostic screen showing which \fIunzip\fP and \fIzipinfo\fP
+options are stored in environment variables, whether decryption support was
+compiled in, the compiler with which \fIunzip\fP was compiled, etc.:
+.PP
+.EX
+unzip \-v
+.EE
+.PP
+In the last five examples, assume that UNZIP or UNZIP_OPTS is set to -q.
+To do a singly quiet listing:
+.PP
+.EX
+unzip \-l file.zip
+.EE
+.PP
+To do a doubly quiet listing:
+.PP
+.EX
+unzip \-ql file.zip
+.EE
+.PP
+(Note that the ``\fC.zip\fR'' is generally not necessary.) To do a standard
+listing:
+.PP
+.EX
+unzip \-\-ql file.zip
+.EE
+or
+.EX
+unzip \-l\-q file.zip
+.EE
+or
+.EX
+unzip \-l\-\-q file.zip
+.EE
+\fR(Extra minuses in options don't hurt.)
+.PD
+.\" =========================================================================
+.SH TIPS
+The current maintainer, being a lazy sort, finds it very useful to define
+a pair of aliases: \fCtt\fR for ``\fCunzip \-tq\fR'' and \fCii\fR for
+``\fCunzip \-Z\fR'' (or ``\fCzipinfo\fR''). One may then simply type
+``\fCtt zipfile\fR'' to test an archive, something that is worth making a
+habit of doing. With luck \fIunzip\fP will report ``\fCNo errors detected
+in compressed data of zipfile.zip\fR,'' after which one may breathe a sigh
+of relief.
+.PP
+The maintainer also finds it useful to set the UNZIP environment variable
+to ``\fC\-aL\fR'' and is tempted to add ``\fC\-C\fR'' as well. His ZIPINFO
+variable is set to ``\fC\-z\fR''.
+.PD
+.\" =========================================================================
+.SH DIAGNOSTICS
+The exit status (or error level) approximates the exit codes defined by PKWARE
+and takes on the following values, except under VMS:
+.RS
+.IP 0
+normal; no errors or warnings detected.
+.IP 1
+one or more warning errors were encountered, but processing completed
+successfully anyway. This includes zipfiles where one or more files
+was skipped due to unsupported compression method or encryption with an
+unknown password.
+.IP 2
+a generic error in the zipfile format was detected. Processing may have
+completed successfully anyway; some broken zipfiles created by other
+archivers have simple work-arounds.
+.IP 3
+a severe error in the zipfile format was detected. Processing probably
+failed immediately.
+.IP 4
+\fIunzip\fP was unable to allocate memory for one or more buffers during
+program initialization.
+.IP 5
+\fIunzip\fP was unable to allocate memory or unable to obtain a tty to read
+the decryption password(s).
+.IP 6
+\fIunzip\fP was unable to allocate memory during decompression to disk.
+.IP 7
+\fIunzip\fP was unable to allocate memory during in-memory decompression.
+.IP 8
+[currently not used]
+.IP 9
+the specified zipfiles were not found.
+.IP 10
+invalid options were specified on the command line.
+.IP 11
+no matching files were found.
+.IP 50
+the disk is (or was) full during extraction.
+.IP 51
+the end of the ZIP archive was encountered prematurely.
+.IP 80
+the user aborted \fIunzip\fP prematurely with control-C (or similar)
+.IP 81
+testing or extraction of one or more files failed due to unsupported
+compression methods or unsupported decryption.
+.IP 82
+no files were found due to bad decryption password(s). (If even one file is
+successfully processed, however, the exit status is 1.)
+.RE
+.PP
+VMS interprets standard Unix (or PC) return values as other, scarier-looking
+things, so \fIunzip\fP instead maps them into VMS-style status codes. The
+current mapping is as follows: 1 (success) for normal exit, 0x7fff0001
+for warning errors, and (0x7fff000? + 16*normal_unzip_exit_status) for all
+other errors, where the `?' is 2 (error) for \fIunzip\fP values 2, 9-11 and
+80-82, and 4 (fatal error) for the remaining ones (3-8, 50, 51). In addition,
+there is a compilation option to expand upon this behavior: defining
+RETURN_CODES results in a human-readable explanation of what the error
+status means.
+.PD
+.\" =========================================================================
+.SH BUGS
+Multi-part archives are not yet supported, except in conjunction with
+\fIzip\fP. (All parts must be concatenated together in order, and then
+``\fCzip \-F\fR'' (for \fIzip 2.x\fP) or ``\fCzip \-FF\fR'' (for
+\fIzip 3.x\fP) must be performed on the concatenated archive in order to
+``fix'' it. Also, \fIzip 3.0\fP and later can combine multi-part (split)
+archives into a combined single-file archive using ``\fCzip \-s\- inarchive
+-O outarchive\fR''. See the \fIzip 3\fP manual page for more information.)
+This will definitely be corrected in the next major release.
+.PP
+Archives read from standard input are not yet supported, except with
+\fIfunzip\fP (and then only the first member of the archive can be extracted).
+.PP
+Archives encrypted with 8-bit passwords (e.g., passwords with accented
+European characters) may not be portable across systems and/or other
+archivers. See the discussion in \fBDECRYPTION\fP above.
+.PP
+\fIunzip\fP's \fB\-M\fP (``more'') option tries to take into account automatic
+wrapping of long lines. However, the code may fail to detect the correct
+wrapping locations. First, TAB characters (and similar control sequences) are
+not taken into account, they are handled as ordinary printable characters.
+Second, depending on the actual system / OS port, \fIunzip\fP may not detect
+the true screen geometry but rather rely on "commonly used" default dimensions.
+The correct handling of tabs would require the implementation of a query for
+the actual tabulator setup on the output console.
+.PP
+Dates, times and permissions of stored directories are not restored except
+under Unix. (On Windows NT and successors, timestamps are now restored.)
+.PP
+[MS-DOS] When extracting or testing files from an archive on a defective
+floppy diskette, if the ``Fail'' option is chosen from DOS's ``Abort, Retry,
+Fail?'' message, older versions of \fIunzip\fP may hang the system, requiring
+a reboot. This problem appears to be fixed, but control-C (or control-Break)
+can still be used to terminate \fIunzip\fP.
+.PP
+Under DEC Ultrix, \fIunzip\fP would sometimes fail on long zipfiles (bad CRC,
+not always reproducible). This was apparently due either to a hardware bug
+(cache memory) or an operating system bug (improper handling of page faults?).
+Since Ultrix has been abandoned in favor of Digital Unix (OSF/1), this may not
+be an issue anymore.
+.PP
+[Unix] Unix special files such as FIFO buffers (named pipes), block devices
+and character devices are not restored even if they are somehow represented
+in the zipfile, nor are hard-linked files relinked. Basically the only file
+types restored by \fIunzip\fP are regular files, directories and symbolic
+(soft) links.
+.PP
+[OS/2] Extended attributes for existing directories are only updated if the
+\fB\-o\fP (``overwrite all'') option is given. This is a limitation of the
+operating system; because directories only have a creation time associated
+with them, \fIunzip\fP has no way to determine whether the stored attributes
+are newer or older than those on disk. In practice this may mean a two-pass
+approach is required: first unpack the archive normally (with or without
+freshening/updating existing files), then overwrite just the directory entries
+(e.g., ``\fCunzip -o foo */\fR'').
+.PP
+[VMS] When extracting to another directory, only the \fI[.foo]\fP syntax is
+accepted for the \fB\-d\fP option; the simple Unix \fIfoo\fP syntax is
+silently ignored (as is the less common VMS \fIfoo.dir\fP syntax).
+.PP
+[VMS] When the file being extracted already exists, \fIunzip\fP's query only
+allows skipping, overwriting or renaming; there should additionally be a
+choice for creating a new version of the file. In fact, the ``overwrite''
+choice does create a new version; the old version is not overwritten or
+deleted.
+.PD
+.\" =========================================================================
+.SH "SEE ALSO"
+\fIfunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipgrep\fP(1L),
+\fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
+.PD
+.\" =========================================================================
+.SH URL
+The Info-ZIP home page is currently at
+.EX
+\fChttp://www.info-zip.org/pub/infozip/\fR
+.EE
+or
+.EX
+\fCftp://ftp.info-zip.org/pub/infozip/\fR .
+.EE
+.PD
+.\" =========================================================================
+.SH AUTHORS
+The primary Info-ZIP authors (current semi-active members of the Zip-Bugs
+workgroup) are: Ed Gordon (Zip, general maintenance, shared code, Zip64,
+Win32, Unix, Unicode); Christian Spieler (UnZip maintenance coordination,
+VMS, MS-DOS, Win32, shared code, general Zip and UnZip integration and
+optimization); Onno van der Linden (Zip); Mike White (Win32, Windows GUI,
+Windows DLLs); Kai Uwe Rommel (OS/2, Win32); Steven M. Schweda (VMS, Unix,
+support of new features); Paul Kienitz (Amiga, Win32, Unicode); Chris
+Herborth (BeOS, QNX, Atari); Jonathan Hudson (SMS/QDOS); Sergio Monesi
+(Acorn RISC OS); Harald Denker (Atari, MVS); John Bush (Solaris, Amiga);
+Hunter Goatley (VMS, Info-ZIP Site maintenance); Steve Salisbury (Win32);
+Steve Miller (Windows CE GUI), Johnny Lee (MS-DOS, Win32, Zip64); and Dave
+Smith (Tandem NSK).
+.PP
+The following people were former members of the Info-ZIP development group
+and provided major contributions to key parts of the current code:
+Greg ``Cave Newt'' Roelofs (UnZip, unshrink decompression);
+Jean-loup Gailly (deflate compression);
+Mark Adler (inflate decompression, fUnZip).
+.PP
+The author of the original unzip code upon which Info-ZIP's was based
+is Samuel H. Smith; Carl Mascott did the first Unix port; and David P.
+Kirschbaum organized and led Info-ZIP in its early days with Keith Petersen
+hosting the original mailing list at WSMR-SimTel20. The full list of
+contributors to UnZip has grown quite large; please refer to the CONTRIBS
+file in the UnZip source distribution for a relatively complete version.
+.PD
+.\" =========================================================================
+.SH VERSIONS
+.ta \w'vx.xxnn'u +\w'fall 1989'u+3n
+.PD 0
+.IP "v1.2\t15 Mar 89" \w'\t\t'u
+Samuel H. Smith
+.IP "v2.0\t\ 9 Sep 89"
+Samuel H. Smith
+.IP "v2.x\tfall 1989"
+many Usenet contributors
+.IP "v3.0\t\ 1 May 90"
+Info-ZIP (DPK, consolidator)
+.IP "v3.1\t15 Aug 90"
+Info-ZIP (DPK, consolidator)
+.IP "v4.0\t\ 1 Dec 90"
+Info-ZIP (GRR, maintainer)
+.IP "v4.1\t12 May 91"
+Info-ZIP
+.IP "v4.2\t20 Mar 92"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.0\t21 Aug 92"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.01\t15 Jan 93"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.1\t\ 7 Feb 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.11\t\ 2 Aug 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.12\t28 Aug 94"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.2\t30 Apr 96"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.3\t22 Apr 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.31\t31 May 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.32\t\ 3 Nov 97"
+Info-ZIP (Zip-Bugs subgroup, GRR)
+.IP "v5.4\t28 Nov 98"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.41\t16 Apr 00"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.42\t14 Jan 01"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.5\t17 Feb 02"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.51\t22 May 04"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v5.52\t28 Feb 05"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.IP "v6.0\t20 Apr 09"
+Info-ZIP (Zip-Bugs subgroup, SPC)
+.PD
Index: unzip/create-6.0-slackware-patch/unzip60-new/man
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/man (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/man (revision 5)
Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/man
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch/unzip60-new/match.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/match.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/match.c (revision 5)
@@ -0,0 +1,512 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ match.c
+
+ The match() routine recursively compares a string to a "pattern" (regular
+ expression), returning TRUE if a match is found or FALSE if not. This
+ version is specifically for use with unzip.c: as did the previous match()
+ routines from SEA and J. Kercheval, it leaves the case (upper, lower, or
+ mixed) of the string alone, but converts any uppercase characters in the
+ pattern to lowercase if indicated by the global var pInfo->lcflag (which
+ is to say, string is assumed to have been converted to lowercase already,
+ if such was necessary).
+
+ GRR: reversed order of text, pattern in matche() (now same as match());
+ added ignore_case/ic flags, Case() macro.
+
+ PaulK: replaced matche() with recmatch() from Zip, modified to have an
+ ignore_case argument; replaced test frame with simpler one.
+
+ ---------------------------------------------------------------------------
+
+ Copyright on recmatch() from Zip's util.c
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+
+
+ ---------------------------------------------------------------------------
+
+ Match the pattern (wildcard) against the string (fixed):
+
+ match(string, pattern, ignore_case, sepc);
+
+ returns TRUE if string matches pattern, FALSE otherwise. In the pattern:
+
+ `*' matches any sequence of characters (zero or more)
+ `?' matches any single character
+ [SET] matches any character in the specified set,
+ [!SET] or [^SET] matches any character not in the specified set.
+
+ A set is composed of characters or ranges; a range looks like ``character
+ hyphen character'' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
+ characters ALlowed in the [..] pattern construct. Other characters are
+ allowed (i.e., 8-bit characters) if your system will support them.
+
+ To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
+ side or outside a [..] construct, and match the character exactly, precede
+ it with a ``\'' (backslash).
+
+ Note that "*.*" and "*." are treated specially under MS-DOS if DOSWILD is
+ defined. See the DOSWILD section below for an explanation. Note also
+ that with VMSWILD defined, '%' is used instead of '?', and sets (ranges)
+ are delimited by () instead of [].
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __MATCH_C /* identifies this source module */
+
+/* define ToLower() in here (for Unix, define ToLower to be macro (using
+ * isupper()); otherwise just use tolower() */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#ifndef THEOS /* the Theos port defines its own variant of match() */
+
+#if 0 /* this is not useful until it matches Amiga names insensitively */
+#ifdef AMIGA /* some other platforms might also want to use this */
+# define ANSI_CHARSET /* MOVE INTO UNZIP.H EVENTUALLY */
+#endif
+#endif /* 0 */
+
+#ifdef ANSI_CHARSET
+# ifdef ToLower
+# undef ToLower
+# endif
+ /* uppercase letters are values 41 thru 5A, C0 thru D6, and D8 thru DE */
+# define IsUpper(c) (c>=0xC0 ? c<=0xDE && c!=0xD7 : c>=0x41 && c<=0x5A)
+# define ToLower(c) (IsUpper((uch) c) ? (unsigned) c | 0x20 : (unsigned) c)
+#endif
+#define Case(x) (ic? ToLower(x) : (x))
+
+#ifdef VMSWILD
+# define WILDCHAR '%'
+# define BEG_RANGE '('
+# define END_RANGE ')'
+#else
+# define WILDCHAR '?'
+# define BEG_RANGE '['
+# define END_RANGE ']'
+# define WILDCHR_SINGLE '?'
+# define DIRSEP_CHR '/'
+# define WILDCHR_MULTI '*'
+#endif
+
+#ifdef WILD_STOP_AT_DIR
+ int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
+#else
+ int wild_stop_at_dir = 0; /* default wildcards do include / in matches */
+#endif
+
+
+
+/*
+ * case mapping functions. case_map is used to ignore case in comparisons,
+ * to_up is used to force upper case even on Unix (for dosify option).
+ */
+#ifdef USE_CASE_MAP
+# define case_map(c) upper[(c) & 0xff]
+# define to_up(c) upper[(c) & 0xff]
+#else
+# define case_map(c) (c)
+# define to_up(c) ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
+#endif /* USE_CASE_MAP */
+
+
+#if 0 /* GRR: add this to unzip.h someday... */
+#if !(defined(MSDOS) && defined(DOSWILD))
+#ifdef WILD_STOP_AT_DIR
+#define match(s,p,ic,sc) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic,sc) == 1)
+#else
+#define match(s,p,ic) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic) == 1)
+#endif
+int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
+ int ignore_case __WDLPRO));
+#endif
+#endif /* 0 */
+static int recmatch OF((ZCONST char *, ZCONST char *,
+ int));
+static char *isshexp OF((ZCONST char *p));
+static int namecmp OF((ZCONST char *s1, ZCONST char *s2));
+
+
+/* match() is a shell to recmatch() to return only Boolean values. */
+
+int match(string, pattern, ignore_case __WDL)
+ ZCONST char *string, *pattern;
+ int ignore_case;
+ __WDLDEF
+{
+#if (defined(MSDOS) && defined(DOSWILD))
+ char *dospattern;
+ int j = strlen(pattern);
+
+/*---------------------------------------------------------------------------
+ Optional MS-DOS preprocessing section: compare last three chars of the
+ wildcard to "*.*" and translate to "*" if found; else compare the last
+ two characters to "*." and, if found, scan the non-wild string for dots.
+ If in the latter case a dot is found, return failure; else translate the
+ "*." to "*". In either case, continue with the normal (Unix-like) match
+ procedure after translation. (If not enough memory, default to normal
+ match.) This causes "a*.*" and "a*." to behave as MS-DOS users expect.
+ ---------------------------------------------------------------------------*/
+
+ if ((dospattern = (char *)malloc(j+1)) != NULL) {
+ strcpy(dospattern, pattern);
+ if (!strcmp(dospattern+j-3, "*.*")) {
+ dospattern[j-2] = '\0'; /* nuke the ".*" */
+ } else if (!strcmp(dospattern+j-2, "*.")) {
+ char *p = MBSCHR(string, '.');
+
+ if (p) { /* found a dot: match fails */
+ free(dospattern);
+ return 0;
+ }
+ dospattern[j-1] = '\0'; /* nuke the end "." */
+ }
+ j = recmatch(dospattern, string, ignore_case);
+ free(dospattern);
+ return j == 1;
+ } else
+#endif /* MSDOS && DOSWILD */
+ return recmatch(pattern, string, ignore_case) == 1;
+}
+
+#ifdef _MBCS
+
+char *___tmp_ptr;
+
+#endif
+
+static int recmatch(p, s, ci)
+ZCONST char *p; /* sh pattern to match */
+ZCONST char *s; /* string to match it to */
+int ci; /* flag: force case-insensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+ they match, and 0 or 2 if they don't or if there is a syntax error in the
+ pattern. This routine recurses on itself no deeper than the number of
+ characters in the pattern. */
+{
+ int c; /* pattern char or start of range in [-] loop */
+ /* Get first character, the pattern for new recmatch calls follows */
+ /* borrowed from Zip's global.c */
+ int no_wild = 0;
+ int allow_regex=1;
+ /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+ See 21 July 2006 mail.
+ It only applies when p is pointing to a doublebyte character and
+ things like / and wildcards are not doublebyte. This probably
+ should not be needed. */
+
+#ifdef _MBCS
+ if (CLEN(p) == 2) {
+ if (CLEN(s) == 2) {
+ return (*p == *s && *(p+1) == *(s+1)) ?
+ recmatch(p + 2, s + 2, ci) : 0;
+ } else {
+ return 0;
+ }
+ }
+#endif /* ?_MBCS */
+
+ c = *POSTINCSTR(p);
+
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *s == 0;
+
+ /* '?' (or '%' or '#') matches any character (but not an empty string) */
+ if (c == WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), ci) : 0;
+ else
+ return *s ? recmatch(p, s + CLEN(s), ci) : 0;
+ }
+
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+#ifdef AMIGA
+ if (!no_wild && c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+#endif /* AMIGA */
+ if (!no_wild && c == WILDCHR_MULTI)
+ {
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+ if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+ if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+ if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+ if ((c = recmatch(p, s, ci)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*p == 0)
+ return (*s == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+ ? recmatch(p, s, ci) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ p++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
+ if (*p == 0)
+ return 1;
+ if (!isshexp((char *)p))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST char *srest;
+
+ srest = s + (strlen(s) - strlen(p));
+ if (srest - s < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
+#ifdef _MBCS
+ {
+ ZCONST char *q = s;
+
+ /* MBCS-aware code must not scan backwards into a string from
+ * the end.
+ * So, we have to move forward by character from our well-known
+ * character position s in the test string until we have advanced
+ * to the srest position.
+ */
+ while (q < srest)
+ INCSTR(q);
+ /* In case the byte *srest is a trailing byte of a multibyte
+ * character, we have actually advanced past the position (srest).
+ * For this case, the match has failed!
+ */
+ if (q != srest)
+ return 0;
+ return ((!ci ? strcmp(p, q) : namecmp(p, q)) == 0);
+ }
+#else /* !_MBCS */
+ return ((!ci ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+#endif /* ?_MBCS */
+ }
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *s; INCSTR(s))
+ if ((c = recmatch(p, s, ci)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
+ }
+ }
+
+#ifndef VMS /* No bracket matching in VMS */
+ /* Parse and process the list of characters and ranges in brackets */
+ if (!no_wild && allow_regex && c == '[')
+ {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST char *q; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*s == 0) /* need a character to match */
+ return 0;
+ p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+ for (q = p, e = 0; *q; q++) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*q == '\\')
+ e = 1;
+ else if (*q == ']')
+ break;
+ if (*q != ']') /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = *p == '-'; p < q; p++) /* go through the list */
+ {
+ if (e == 0 && *p == '\\') /* set escape flag if \ */
+ e = 1;
+ else if (e == 0 && *p == '-') /* set start of range if - */
+ c = *(p-1);
+ else
+ {
+ uch cc = (!ci ? (uch)*s : to_up((uch)*s));
+ uch uc = (uch) c;
+ if (*(p+1) != '-')
+ for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+ /* compare range */
+ if ((!ci ? uc : to_up(uc)) == cc)
+ return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), ci);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatch(q + CLEN(q), s + CLEN(s), ci) : 0;
+ /* bracket match failed */
+ }
+#endif /* !VMS */
+
+ /* If escape ('\'), just compare next character */
+ if (!no_wild && c == '\\')
+ if ((c = *p++) == '\0') /* if \ at end, then syntax error */
+ return 0;
+
+#ifdef VMS
+ /* 2005-11-06 SMS.
+ Handle "..." wildcard in p with "." or "]" in s.
+ */
+ if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+ ((*s == '.') || (*s == ']')))
+ {
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+
+ /* Else, look for a reduced match in s, until "]" in or end of s. */
+ for (; *s && (*s != ']'); INCSTR(s))
+ if (*s == '.')
+ /* If reduced match, then continue after "..." in p, "." in s. */
+ if ((c = recmatch( (p+ CLEN( p)), s, ci)) != 0)
+ return (int)c;
+
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+
+ /* No reduced match. Quit. */
+ return 2;
+ }
+
+#endif /* def VMS */
+
+ /* Just a character--compare it */
+ return (!ci ? c == *s : to_up((uch)c) == to_up((uch)*s)) ?
+ recmatch(p, s + CLEN(s), ci) : 0;
+}
+
+
+
+
+/*************************************************************************************************/
+static char *isshexp(p)
+ZCONST char *p;
+/* If p is a sh expression, a pointer to the first special character is
+ returned. Otherwise, NULL is returned. */
+{
+ for (; *p; INCSTR(p))
+ if (*p == '\\' && *(p+1))
+ p++;
+ else if (*p == WILDCHAR || *p == '*' || *p == BEG_RANGE)
+ return (char *)p;
+ return NULL;
+} /* end function isshexp() */
+
+
+
+static int namecmp(s1, s2)
+ ZCONST char *s1, *s2;
+{
+ int d;
+
+ for (;;) {
+ d = (int)ToLower((uch)*s1)
+ - (int)ToLower((uch)*s2);
+
+ if (d || *s1 == 0 || *s2 == 0)
+ return d;
+
+ s1++;
+ s2++;
+ }
+} /* end function namecmp() */
+
+#endif /* !THEOS */
+
+
+
+
+int iswild(p) /* originally only used for stat()-bug workaround in */
+ ZCONST char *p; /* VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
+{ /* now used in process_zipfiles() as well */
+ for (; *p; INCSTR(p))
+ if (*p == '\\' && *(p+1))
+ ++p;
+#ifdef THEOS
+ else if (*p == '?' || *p == '*' || *p=='#'|| *p == '@')
+#else /* !THEOS */
+#ifdef VMS
+ else if (*p == '%' || *p == '*')
+#else /* !VMS */
+#ifdef AMIGA
+ else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
+#else /* !AMIGA */
+ else if (*p == '?' || *p == '*' || *p == '[')
+#endif /* ?AMIGA */
+#endif /* ?VMS */
+#endif /* ?THEOS */
+#ifdef QDOS
+ return (int)p;
+#else
+ return TRUE;
+#endif
+
+ return FALSE;
+
+} /* end function iswild() */
+
+
+
+
+
+#ifdef TEST_MATCH
+
+#define put(s) {fputs(s,stdout); fflush(stdout);}
+#ifdef main
+# undef main
+#endif
+
+int main(int argc, char **argv)
+{
+ char pat[256], str[256];
+
+ for (;;) {
+ put("Pattern (return to exit): ");
+ gets(pat);
+ if (!pat[0])
+ break;
+ for (;;) {
+ put("String (return for new pattern): ");
+ gets(str);
+ if (!str[0])
+ break;
+ printf("Case sensitive: %s insensitive: %s\n",
+ match(str, pat, 0) ? "YES" : "NO",
+ match(str, pat, 1) ? "YES" : "NO");
+ }
+ }
+ EXIT(0);
+}
+
+#endif /* TEST_MATCH */
Index: unzip/create-6.0-slackware-patch/unzip60-new/process.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/process.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/process.c (revision 5)
@@ -0,0 +1,3170 @@
+/*
+ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ process.c
+
+ This file contains the top-level routines for processing multiple zipfiles.
+
+ Contains: process_zipfiles()
+ free_G_buffers()
+ do_seekable()
+ file_size()
+ rec_find()
+ find_ecrec64()
+ find_ecrec()
+ process_zip_cmmnt()
+ process_cdir_file_hdr()
+ get_cdir_ent()
+ process_local_file_hdr()
+ getZip64Data()
+ ef_scan_for_izux()
+ getRISCOSexfield()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+#endif
+#if defined(DYNALLOC_CRCTAB) || defined(UNICODE_SUPPORT)
+# include "crc32.h"
+#endif
+
+static int do_seekable OF((__GPRO__ int lastchance));
+#ifdef DO_SAFECHECK_2GB
+# ifdef USE_STRM_INPUT
+static zoff_t file_size OF((FILE *file));
+# else
+static zoff_t file_size OF((int fh));
+# endif
+#endif /* DO_SAFECHECK_2GB */
+static int rec_find OF((__GPRO__ zoff_t, char *, int));
+static int find_ecrec64 OF((__GPRO__ zoff_t searchlen));
+static int find_ecrec OF((__GPRO__ zoff_t searchlen));
+static int process_zip_cmmnt OF((__GPRO));
+static int get_cdir_ent OF((__GPRO));
+#ifdef IZ_HAVE_UXUIDGID
+static int read_ux3_value OF((ZCONST uch *dbuf, unsigned uidgid_sz,
+ ulg *p_uidgid));
+#endif /* IZ_HAVE_UXUIDGID */
+
+
+static ZCONST char Far CannotAllocateBuffers[] =
+ "error: cannot allocate unzip buffers\n";
+
+#ifdef SFX
+ static ZCONST char Far CannotFindMyself[] =
+ "unzipsfx: cannot find myself! [%s]\n";
+# ifdef CHEAP_SFX_AUTORUN
+ static ZCONST char Far AutorunPrompt[] =
+ "\nAuto-run command: %s\nExecute this command? [y/n] ";
+ static ZCONST char Far NotAutoRunning[] =
+ "Not executing auto-run command.";
+# endif
+
+#else /* !SFX */
+ /* process_zipfiles() strings */
+# if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+ static ZCONST char Far WarnInvalidTZ[] =
+ "Warning: TZ environment variable not found, cannot use UTC times!!\n";
+# endif
+# if !(defined(UNIX) || defined(AMIGA))
+ static ZCONST char Far CannotFindWildcardMatch[] =
+ "%s: cannot find any matches for wildcard specification \"%s\".\n";
+# endif /* !(UNIX || AMIGA) */
+ static ZCONST char Far FilesProcessOK[] =
+ "%d archive%s successfully processed.\n";
+ static ZCONST char Far ArchiveWarning[] =
+ "%d archive%s had warnings but no fatal errors.\n";
+ static ZCONST char Far ArchiveFatalError[] =
+ "%d archive%s had fatal errors.\n";
+ static ZCONST char Far FileHadNoZipfileDir[] =
+ "%d file%s had no zipfile directory.\n";
+ static ZCONST char Far ZipfileWasDir[] = "1 \"zipfile\" was a directory.\n";
+ static ZCONST char Far ManyZipfilesWereDir[] =
+ "%d \"zipfiles\" were directories.\n";
+ static ZCONST char Far NoZipfileFound[] = "No zipfiles found.\n";
+
+ /* do_seekable() strings */
+# ifdef UNIX
+ static ZCONST char Far CannotFindZipfileDirMsg[] =
+ "%s: cannot find zipfile directory in one of %s or\n\
+ %s%s.zip, and cannot find %s, period.\n";
+ static ZCONST char Far CannotFindEitherZipfile[] =
+ "%s: cannot find or open %s, %s.zip or %s.\n";
+# else /* !UNIX */
+ static ZCONST char Far CannotFindZipfileDirMsg[] =
+ "%s: cannot find zipfile directory in %s,\n\
+ %sand cannot find %s, period.\n";
+# ifdef VMS
+ static ZCONST char Far CannotFindEitherZipfile[] =
+ "%s: cannot find %s (%s).\n";
+# else /* !VMS */
+ static ZCONST char Far CannotFindEitherZipfile[] =
+ "%s: cannot find either %s or %s.\n";
+# endif /* ?VMS */
+# endif /* ?UNIX */
+ extern ZCONST char Far Zipnfo[]; /* in unzip.c */
+#ifndef WINDLL
+ static ZCONST char Far Unzip[] = "unzip";
+#else
+ static ZCONST char Far Unzip[] = "UnZip DLL";
+#endif
+#ifdef DO_SAFECHECK_2GB
+ static ZCONST char Far ZipfileTooBig[] =
+ "Trying to read large file (> 2 GiB) without large file support\n";
+#endif /* DO_SAFECHECK_2GB */
+ static ZCONST char Far MaybeExe[] =
+ "note: %s may be a plain executable, not an archive\n";
+ static ZCONST char Far CentDirNotInZipMsg[] = "\n\
+ [%s]:\n\
+ Zipfile is disk %lu of a multi-disk archive, and this is not the disk on\n\
+ which the central zipfile directory begins (disk %lu).\n";
+ static ZCONST char Far EndCentDirBogus[] =
+ "\nwarning [%s]: end-of-central-directory record claims this\n\
+ is disk %lu but that the central directory starts on disk %lu; this is a\n\
+ contradiction. Attempting to process anyway.\n";
+# ifdef NO_MULTIPART
+ static ZCONST char Far NoMultiDiskArcSupport[] =
+ "\nerror [%s]: zipfile is part of multi-disk archive\n\
+ (sorry, not yet supported).\n";
+ static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+ zipfile claims to be 2nd disk of a 2-part archive;\n\
+ attempting to process anyway. If no further errors occur, this archive\n\
+ was probably created by PAK v2.51 or earlier. This bug was reported to\n\
+ NoGate in March 1991 and was supposed to have been fixed by mid-1991; as\n\
+ of mid-1992 it still hadn't been. (If further errors do occur, archive\n\
+ was probably created by PKZIP 2.04c or later; UnZip does not yet support\n\
+ multi-part archives.)\n";
+# else
+ static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+ zipfile claims to be last disk of a multi-part archive;\n\
+ attempting to process anyway, assuming all parts have been concatenated\n\
+ together in order. Expect \"errors\" and warnings...true multi-part support\
+\n doesn't exist yet (coming soon).\n";
+# endif
+ static ZCONST char Far ExtraBytesAtStart[] =
+ "warning [%s]: %s extra byte%s at beginning or within zipfile\n\
+ (attempting to process anyway)\n";
+#endif /* ?SFX */
+
+#if ((!defined(WINDLL) && !defined(SFX)) || !defined(NO_ZIPINFO))
+ static ZCONST char Far LogInitline[] = "Archive: %s\n";
+#endif
+
+static ZCONST char Far MissingBytes[] =
+ "error [%s]: missing %s bytes in zipfile\n\
+ (attempting to process anyway)\n";
+static ZCONST char Far NullCentDirOffset[] =
+ "error [%s]: NULL central directory offset\n\
+ (attempting to process anyway)\n";
+static ZCONST char Far ZipfileEmpty[] = "warning [%s]: zipfile is empty\n";
+static ZCONST char Far CentDirStartNotFound[] =
+ "error [%s]: start of central directory not found;\n\
+ zipfile corrupt.\n%s";
+static ZCONST char Far Cent64EndSigSearchErr[] =
+ "fatal error: read failure while seeking for End-of-centdir-64 signature.\n\
+ This zipfile is corrupt.\n";
+static ZCONST char Far Cent64EndSigSearchOff[] =
+ "error: End-of-centdir-64 signature not where expected (prepended bytes?)\n\
+ (attempting to process anyway)\n";
+#ifndef SFX
+ static ZCONST char Far CentDirTooLong[] =
+ "error [%s]: reported length of central directory is\n\
+ %s bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1\n\
+ zipfile?). Compensating...\n";
+ static ZCONST char Far CentDirEndSigNotFound[] = "\
+ End-of-central-directory signature not found. Either this file is not\n\
+ a zipfile, or it constitutes one disk of a multi-part archive. In the\n\
+ latter case the central directory and zipfile comment will be found on\n\
+ the last disk(s) of this archive.\n";
+#else /* SFX */
+ static ZCONST char Far CentDirEndSigNotFound[] =
+ " End-of-central-directory signature not found.\n";
+#endif /* ?SFX */
+#ifdef TIMESTAMP
+ static ZCONST char Far ZipTimeStampFailed[] =
+ "warning: cannot set time for %s\n";
+ static ZCONST char Far ZipTimeStampSuccess[] =
+ "Updated time stamp for %s.\n";
+#endif
+static ZCONST char Far ZipfileCommTrunc1[] =
+ "\ncaution: zipfile comment truncated\n";
+#ifndef NO_ZIPINFO
+ static ZCONST char Far NoZipfileComment[] =
+ "There is no zipfile comment.\n";
+ static ZCONST char Far ZipfileCommentDesc[] =
+ "The zipfile comment is %u bytes long and contains the following text:\n";
+ static ZCONST char Far ZipfileCommBegin[] =
+ "======================== zipfile comment begins\
+ ==========================\n";
+ static ZCONST char Far ZipfileCommEnd[] =
+ "========================= zipfile comment ends\
+ ===========================\n";
+ static ZCONST char Far ZipfileCommTrunc2[] =
+ "\n The zipfile comment is truncated.\n";
+#endif /* !NO_ZIPINFO */
+#ifdef UNICODE_SUPPORT
+ static ZCONST char Far UnicodeVersionError[] =
+ "\nwarning: Unicode Path version > 1\n";
+ static ZCONST char Far UnicodeMismatchError[] =
+ "\nwarning: Unicode Path checksum invalid\n";
+ static ZCONST char Far UFilenameTooLongTrunc[] =
+ "warning: filename too long (P1) -- truncating.\n";
+#endif
+
+
+
+
+/*******************************/
+/* Function process_zipfiles() */
+/*******************************/
+
+int process_zipfiles(__G) /* return PK-type error code */
+ __GDEF
+{
+#ifndef SFX
+ char *lastzipfn = (char *)NULL;
+ int NumWinFiles, NumLoseFiles, NumWarnFiles;
+ int NumMissDirs, NumMissFiles;
+#endif
+ int error=0, error_in_archive=0;
+
+
+/*---------------------------------------------------------------------------
+ Start by allocating buffers and (re)constructing the various PK signature
+ strings.
+ ---------------------------------------------------------------------------*/
+
+ G.inbuf = (uch *)malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */
+ G.outbuf = (uch *)malloc(OUTBUFSIZ + 1); /* 1 extra for string term. */
+
+ if ((G.inbuf == (uch *)NULL) || (G.outbuf == (uch *)NULL)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotAllocateBuffers)));
+ return(PK_MEM);
+ }
+ G.hold = G.inbuf + INBUFSIZ; /* to check for boundary-spanning sigs */
+#ifndef VMS /* VMS uses its own buffer scheme for textmode flush(). */
+#ifdef SMALL_MEM
+ G.outbuf2 = G.outbuf+RAWBUFSIZ; /* never changes */
+#endif
+#endif /* !VMS */
+
+#if 0 /* CRC_32_TAB has been NULLified by CONSTRUCTGLOBALS !!!! */
+ /* allocate the CRC table later when we know we can read zipfile data */
+ CRC_32_TAB = NULL;
+#endif /* 0 */
+
+ /* finish up initialization of magic signature strings */
+ local_hdr_sig[0] /* = extd_local_sig[0] */ = /* ASCII 'P', */
+ central_hdr_sig[0] = end_central_sig[0] = /* not EBCDIC */
+ end_centloc64_sig[0] = end_central64_sig[0] = 0x50;
+
+ local_hdr_sig[1] /* = extd_local_sig[1] */ = /* ASCII 'K', */
+ central_hdr_sig[1] = end_central_sig[1] = /* not EBCDIC */
+ end_centloc64_sig[1] = end_central64_sig[1] = 0x4B;
+
+/*---------------------------------------------------------------------------
+ Make sure timezone info is set correctly; localtime() returns GMT on some
+ OSes (e.g., Solaris 2.x) if this isn't done first. The ifdefs around
+ tzset() were initially copied from dos_to_unix_time() in fileio.c. They
+ may still be too strict; any listed OS that supplies tzset(), regardless
+ of whether the function does anything, should be removed from the ifdefs.
+ ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && defined(USE_EF_UT_TIME))
+ /* For the Win32 environment, we may have to "prepare" the environment
+ prior to the tzset() call, to work around tzset() implementation bugs.
+ */
+ iz_w32_prepareTZenv();
+#endif
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+# ifndef VALID_TIMEZONE
+# define VALID_TIMEZONE(tmp) \
+ (((tmp = getenv("TZ")) != NULL) && (*tmp != '\0'))
+# endif
+ {
+ char *p;
+ G.tz_is_valid = VALID_TIMEZONE(p);
+# ifndef SFX
+ if (!G.tz_is_valid) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(WarnInvalidTZ)));
+ error_in_archive = error = PK_WARN;
+ }
+# endif /* !SFX */
+ }
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+/* For systems that do not have tzset() but supply this function using another
+ name (_tzset() or something similar), an appropiate "#define tzset ..."
+ should be added to the system specifc configuration section. */
+#if (!defined(T20_VMS) && !defined(MACOS) && !defined(RISCOS) && !defined(QDOS))
+#if (!defined(BSD) && !defined(MTS) && !defined(CMS_MVS) && !defined(TANDEM))
+ tzset();
+#endif
+#endif
+
+/* Initialize UnZip's built-in pseudo hard-coded "ISO <--> OEM" translation,
+ depending on the detected codepage setup. */
+#ifdef NEED_ISO_OEM_INIT
+ prepare_ISO_OEM_translat(__G);
+#endif
+
+/*---------------------------------------------------------------------------
+ Initialize the internal flag holding the mode of processing "overwrite
+ existing file" cases. We do not use the calling interface flags directly
+ because the overwrite mode may be changed by user interaction while
+ processing archive files. Such a change should not affect the option
+ settings as passed through the DLL calling interface.
+ In case of conflicting options, the 'safer' flag uO.overwrite_none takes
+ precedence.
+ ---------------------------------------------------------------------------*/
+ G.overwrite_mode = (uO.overwrite_none ? OVERWRT_NEVER :
+ (uO.overwrite_all ? OVERWRT_ALWAYS : OVERWRT_QUERY));
+
+/*---------------------------------------------------------------------------
+ Match (possible) wildcard zipfile specification with existing files and
+ attempt to process each. If no hits, try again after appending ".zip"
+ suffix. If still no luck, give up.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+ if ((error = do_seekable(__G__ 0)) == PK_NOZIP) {
+#ifdef EXE_EXTENSION
+ int len=strlen(G.argv0);
+
+ /* append .exe if appropriate; also .sfx? */
+ if ( (G.zipfn = (char *)malloc(len+sizeof(EXE_EXTENSION))) !=
+ (char *)NULL ) {
+ strcpy(G.zipfn, G.argv0);
+ strcpy(G.zipfn+len, EXE_EXTENSION);
+ error = do_seekable(__G__ 0);
+ free(G.zipfn);
+ G.zipfn = G.argv0; /* for "cannot find myself" message only */
+ }
+#endif /* EXE_EXTENSION */
+#ifdef WIN32
+ G.zipfn = G.argv0; /* for "cannot find myself" message only */
+#endif
+ }
+ if (error) {
+ if (error == IZ_DIR)
+ error_in_archive = PK_NOZIP;
+ else
+ error_in_archive = error;
+ if (error == PK_NOZIP)
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotFindMyself),
+ G.zipfn));
+ }
+#ifdef CHEAP_SFX_AUTORUN
+ if (G.autorun_command[0] && !uO.qflag) { /* NO autorun without prompt! */
+ Info(slide, 0x81, ((char *)slide, LoadFarString(AutorunPrompt),
+ FnFilter1(G.autorun_command)));
+ if (fgets(G.answerbuf, 9, stdin) != (char *)NULL
+ && toupper(*G.answerbuf) == 'Y')
+ system(G.autorun_command);
+ else
+ Info(slide, 1, ((char *)slide, LoadFarString(NotAutoRunning)));
+ }
+#endif /* CHEAP_SFX_AUTORUN */
+
+#else /* !SFX */
+ NumWinFiles = NumLoseFiles = NumWarnFiles = 0;
+ NumMissDirs = NumMissFiles = 0;
+
+ while ((G.zipfn = do_wild(__G__ G.wildzipfn)) != (char *)NULL) {
+ Trace((stderr, "do_wild( %s ) returns %s\n", G.wildzipfn, G.zipfn));
+
+ lastzipfn = G.zipfn;
+
+ /* print a blank line between the output of different zipfiles */
+ if (!uO.qflag && error != PK_NOZIP && error != IZ_DIR
+#ifdef TIMESTAMP
+ && (!uO.T_flag || uO.zipinfo_mode)
+#endif
+ && (NumWinFiles+NumLoseFiles+NumWarnFiles+NumMissFiles) > 0)
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+ if ((error = do_seekable(__G__ 0)) == PK_WARN)
+ ++NumWarnFiles;
+ else if (error == IZ_DIR)
+ ++NumMissDirs;
+ else if (error == PK_NOZIP)
+ ++NumMissFiles;
+ else if (error != PK_OK)
+ ++NumLoseFiles;
+ else
+ ++NumWinFiles;
+
+ Trace((stderr, "do_seekable(0) returns %d\n", error));
+ if (error != IZ_DIR && error > error_in_archive)
+ error_in_archive = error;
+#ifdef WINDLL
+ if (error == IZ_CTRLC) {
+ free_G_buffers(__G);
+ return error;
+ }
+#endif
+
+ } /* end while-loop (wildcard zipfiles) */
+
+ if ((NumWinFiles + NumWarnFiles + NumLoseFiles) == 0 &&
+ (NumMissDirs + NumMissFiles) == 1 && lastzipfn != (char *)NULL)
+ {
+#if (!defined(UNIX) && !defined(AMIGA)) /* filenames with wildcard characters */
+ if (iswild(G.wildzipfn)) {
+ if (iswild(lastzipfn)) {
+ NumMissDirs = NumMissFiles = 0;
+ error_in_archive = PK_COOL;
+ if (uO.qflag < 3)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindWildcardMatch),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn));
+ }
+ } else
+#endif
+ {
+#ifndef VMS
+ /* 2004-11-24 SMS.
+ * VMS has already tried a default file type of ".zip" in
+ * do_wild(), so adding ZSUFX here only causes confusion by
+ * corrupting some valid (though nonexistent) file names.
+ * Complaining below about "fred;4.zip" is unlikely to be
+ * helpful to the victim.
+ */
+ /* 2005-08-14 Chr. Spieler
+ * Although we already "know" the failure result, we call
+ * do_seekable() again with the same zipfile name (and the
+ * lastchance flag set), just to trigger the error report...
+ */
+#if defined(UNIX) || defined(QDOS)
+ char *p =
+#endif
+ strcpy(lastzipfn + strlen(lastzipfn), ZSUFX);
+#endif /* !VMS */
+
+ G.zipfn = lastzipfn;
+
+ NumMissDirs = NumMissFiles = 0;
+ error_in_archive = PK_COOL;
+
+#if defined(UNIX) || defined(QDOS)
+ /* only Unix has case-sensitive filesystems */
+ /* Well FlexOS (sometimes) also has them, but support is per media */
+ /* and a pig to code for, so treat as case insensitive for now */
+ /* we do this under QDOS to check for .zip as well as _zip */
+ if ((error = do_seekable(__G__ 0)) == PK_NOZIP || error == IZ_DIR) {
+ if (error == IZ_DIR)
+ ++NumMissDirs;
+ strcpy(p, ALT_ZSUFX);
+ error = do_seekable(__G__ 1);
+ }
+#else
+ error = do_seekable(__G__ 1);
+#endif
+ Trace((stderr, "do_seekable(1) returns %d\n", error));
+ switch (error) {
+ case PK_WARN:
+ ++NumWarnFiles;
+ break;
+ case IZ_DIR:
+ ++NumMissDirs;
+ error = PK_NOZIP;
+ break;
+ case PK_NOZIP:
+ /* increment again => bug:
+ "1 file had no zipfile directory." */
+ /* ++NumMissFiles */ ;
+ break;
+ default:
+ if (error)
+ ++NumLoseFiles;
+ else
+ ++NumWinFiles;
+ break;
+ }
+
+ if (error > error_in_archive)
+ error_in_archive = error;
+#ifdef WINDLL
+ if (error == IZ_CTRLC) {
+ free_G_buffers(__G);
+ return error;
+ }
+#endif
+ }
+ }
+#endif /* ?SFX */
+
+/*---------------------------------------------------------------------------
+ Print summary of all zipfiles, assuming zipfile spec was a wildcard (no
+ need for a summary if just one zipfile).
+ ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+ if (iswild(G.wildzipfn) && uO.qflag < 3
+#ifdef TIMESTAMP
+ && !(uO.T_flag && !uO.zipinfo_mode && uO.qflag > 1)
+#endif
+ )
+ {
+ if ((NumMissFiles + NumLoseFiles + NumWarnFiles > 0 || NumWinFiles != 1)
+#ifdef TIMESTAMP
+ && !(uO.T_flag && !uO.zipinfo_mode && uO.qflag)
+#endif
+ && !(uO.tflag && uO.qflag > 1))
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0x401);
+ if ((NumWinFiles > 1) ||
+ (NumWinFiles == 1 &&
+ NumMissDirs + NumMissFiles + NumLoseFiles + NumWarnFiles > 0))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(FilesProcessOK),
+ NumWinFiles, (NumWinFiles == 1)? " was" : "s were"));
+ if (NumWarnFiles > 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveWarning),
+ NumWarnFiles, (NumWarnFiles == 1)? "" : "s"));
+ if (NumLoseFiles > 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveFatalError),
+ NumLoseFiles, (NumLoseFiles == 1)? "" : "s"));
+ if (NumMissFiles > 0)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FileHadNoZipfileDir), NumMissFiles,
+ (NumMissFiles == 1)? "" : "s"));
+ if (NumMissDirs == 1)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileWasDir)));
+ else if (NumMissDirs > 0)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ManyZipfilesWereDir), NumMissDirs));
+ if (NumWinFiles + NumLoseFiles + NumWarnFiles == 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoZipfileFound)));
+ }
+#endif /* !SFX */
+
+ /* free allocated memory */
+ free_G_buffers(__G);
+
+ return error_in_archive;
+
+} /* end function process_zipfiles() */
+
+
+
+
+
+/*****************************/
+/* Function free_G_buffers() */
+/*****************************/
+
+void free_G_buffers(__G) /* releases all memory allocated in global vars */
+ __GDEF
+{
+#ifndef SFX
+ unsigned i;
+#endif
+
+#ifdef SYSTEM_SPECIFIC_DTOR
+ SYSTEM_SPECIFIC_DTOR(__G);
+#endif
+
+ inflate_free(__G);
+ checkdir(__G__ (char *)NULL, END);
+
+#ifdef DYNALLOC_CRCTAB
+ if (CRC_32_TAB) {
+ free_crc_table();
+ CRC_32_TAB = NULL;
+ }
+#endif
+
+ if (G.key != (char *)NULL) {
+ free(G.key);
+ G.key = (char *)NULL;
+ }
+
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+
+#if (!defined(VMS) && !defined(SMALL_MEM))
+ /* VMS uses its own buffer scheme for textmode flush() */
+ if (G.outbuf2) {
+ free(G.outbuf2); /* malloc'd ONLY if unshrink and -a */
+ G.outbuf2 = (uch *)NULL;
+ }
+#endif
+
+ if (G.outbuf)
+ free(G.outbuf);
+ if (G.inbuf)
+ free(G.inbuf);
+ G.inbuf = G.outbuf = (uch *)NULL;
+
+#ifdef UNICODE_SUPPORT
+ if (G.filename_full) {
+ free(G.filename_full);
+ G.filename_full = (char *)NULL;
+ G.fnfull_bufsize = 0;
+ }
+#endif /* UNICODE_SUPPORT */
+
+#ifndef SFX
+ for (i = 0; i < DIR_BLKSIZ; i++) {
+ if (G.info[i].cfilname != (char Far *)NULL) {
+ zffree(G.info[i].cfilname);
+ G.info[i].cfilname = (char Far *)NULL;
+ }
+ }
+#endif
+
+#ifdef MALLOC_WORK
+ if (G.area.Slide) {
+ free(G.area.Slide);
+ G.area.Slide = (uch *)NULL;
+ }
+#endif
+
+} /* end function free_G_buffers() */
+
+
+
+
+
+/**************************/
+/* Function do_seekable() */
+/**************************/
+
+static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ __GDEF
+ int lastchance;
+{
+#ifndef SFX
+ /* static int no_ecrec = FALSE; SKM: moved to globals.h */
+ int maybe_exe=FALSE;
+ int too_weird_to_continue=FALSE;
+#ifdef TIMESTAMP
+ time_t uxstamp;
+ ulg nmember = 0L;
+#endif
+#endif
+ int error=0, error_in_archive;
+
+
+/*---------------------------------------------------------------------------
+ Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
+ which would corrupt the bit streams.
+ ---------------------------------------------------------------------------*/
+
+ if (SSTAT(G.zipfn, &G.statbuf) ||
+#ifdef THEOS
+ (error = S_ISLIB(G.statbuf.st_mode)) != 0 ||
+#endif
+ (error = S_ISDIR(G.statbuf.st_mode)) != 0)
+ {
+#ifndef SFX
+ if (lastchance && (uO.qflag < 3)) {
+#if defined(UNIX) || defined(QDOS)
+ if (G.no_ecrec)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(CannotFindZipfileDirMsg),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn, uO.zipinfo_mode? " " : "", G.wildzipfn,
+ G.zipfn));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(CannotFindEitherZipfile),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn, G.wildzipfn, G.zipfn));
+#else /* !(UNIX || QDOS) */
+ if (G.no_ecrec)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindZipfileDirMsg),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn, uO.zipinfo_mode? " " : "", G.zipfn));
+ else
+#ifdef VMS
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindEitherZipfile),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn,
+ (*G.zipfn ? G.zipfn : vms_msg_text())));
+#else /* !VMS */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindEitherZipfile),
+ LoadFarStringSmall((uO.zipinfo_mode ? Zipnfo : Unzip)),
+ G.wildzipfn, G.zipfn));
+#endif /* ?VMS */
+#endif /* ?(UNIX || QDOS) */
+ }
+#endif /* !SFX */
+ return error? IZ_DIR : PK_NOZIP;
+ }
+ G.ziplen = G.statbuf.st_size;
+
+#ifndef SFX
+#if defined(UNIX) || defined(DOS_OS2_W32) || defined(THEOS)
+ if (G.statbuf.st_mode & S_IEXEC) /* no extension on Unix exes: might */
+ maybe_exe = TRUE; /* find unzip, not unzip.zip; etc. */
+#endif
+#endif /* !SFX */
+
+#ifdef VMS
+ if (check_format(__G)) /* check for variable-length format */
+ return PK_ERR;
+#endif
+
+ if (open_input_file(__G)) /* this should never happen, given */
+ return PK_NOZIP; /* the stat() test above, but... */
+
+#ifdef DO_SAFECHECK_2GB
+ /* Need more care: Do not trust the size returned by stat() but
+ determine it by reading beyond the end of the file. */
+ G.ziplen = file_size(G.zipfd);
+
+ if (G.ziplen == EOF) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileTooBig)));
+ /*
+ printf(
+" We need a better error message for: 64-bit file, 32-bit program.\n");
+ */
+ CLOSE_INFILE();
+ return IZ_ERRBF;
+ }
+#endif /* DO_SAFECHECK_2GB */
+
+/*---------------------------------------------------------------------------
+ Find and process the end-of-central-directory header. UnZip need only
+ check last 65557 bytes of zipfile: comment may be up to 65535, end-of-
+ central-directory record is 18 bytes, and signature itself is 4 bytes;
+ add some to allow for appended garbage. Since ZipInfo is often used as
+ a debugging tool, search the whole zipfile if zipinfo_mode is true.
+ ---------------------------------------------------------------------------*/
+
+ G.cur_zipfile_bufstart = 0;
+ G.inptr = G.inbuf;
+
+#if ((!defined(WINDLL) && !defined(SFX)) || !defined(NO_ZIPINFO))
+# if (!defined(WINDLL) && !defined(SFX))
+ if ( (!uO.zipinfo_mode && !uO.qflag
+# ifdef TIMESTAMP
+ && !uO.T_flag
+# endif
+ )
+# ifndef NO_ZIPINFO
+ || (uO.zipinfo_mode && uO.hflag)
+# endif
+ )
+# else /* not (!WINDLL && !SFX) ==> !NO_ZIPINFO !! */
+ if (uO.zipinfo_mode && uO.hflag)
+# endif /* if..else..: (!WINDLL && !SFX) */
+# ifdef WIN32 /* Win32 console may require codepage conversion for G.zipfn */
+ Info(slide, 0, ((char *)slide, LoadFarString(LogInitline),
+ FnFilter1(G.zipfn)));
+# else
+ Info(slide, 0, ((char *)slide, LoadFarString(LogInitline), G.zipfn));
+# endif
+#endif /* (!WINDLL && !SFX) || !NO_ZIPINFO */
+
+ if ( (error_in_archive = find_ecrec(__G__
+#ifndef NO_ZIPINFO
+ uO.zipinfo_mode ? G.ziplen :
+#endif
+ MIN(G.ziplen, 66000L)))
+ > PK_WARN )
+ {
+ CLOSE_INFILE();
+
+#ifdef SFX
+ ++lastchance; /* avoid picky compiler warnings */
+ return error_in_archive;
+#else
+ if (maybe_exe)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeExe),
+ G.zipfn));
+ if (lastchance)
+ return error_in_archive;
+ else {
+ G.no_ecrec = TRUE; /* assume we found wrong file: e.g., */
+ return PK_NOZIP; /* unzip instead of unzip.zip */
+ }
+#endif /* ?SFX */
+ }
+
+ if ((uO.zflag > 0) && !uO.zipinfo_mode) { /* unzip: zflag = comment ONLY */
+ CLOSE_INFILE();
+ return error_in_archive;
+ }
+
+/*---------------------------------------------------------------------------
+ Test the end-of-central-directory info for incompatibilities (multi-disk
+ archives) or inconsistencies (missing or extra bytes in zipfile).
+ ---------------------------------------------------------------------------*/
+
+#ifdef NO_MULTIPART
+ error = !uO.zipinfo_mode && (G.ecrec.number_this_disk == 1) &&
+ (G.ecrec.num_disk_start_cdir == 1);
+#else
+ error = !uO.zipinfo_mode && (G.ecrec.number_this_disk != 0);
+#endif
+
+#ifndef SFX
+ if (uO.zipinfo_mode &&
+ G.ecrec.number_this_disk != G.ecrec.num_disk_start_cdir)
+ {
+ if (G.ecrec.number_this_disk > G.ecrec.num_disk_start_cdir) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirNotInZipMsg), G.zipfn,
+ (ulg)G.ecrec.number_this_disk,
+ (ulg)G.ecrec.num_disk_start_cdir));
+ error_in_archive = PK_FIND;
+ too_weird_to_continue = TRUE;
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(EndCentDirBogus), G.zipfn,
+ (ulg)G.ecrec.number_this_disk,
+ (ulg)G.ecrec.num_disk_start_cdir));
+ error_in_archive = PK_WARN;
+ }
+#ifdef NO_MULTIPART /* concatenation of multiple parts works in some cases */
+ } else if (!uO.zipinfo_mode && !error && G.ecrec.number_this_disk != 0) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMultiDiskArcSupport),
+ G.zipfn));
+ error_in_archive = PK_FIND;
+ too_weird_to_continue = TRUE;
+#endif
+ }
+
+ if (!too_weird_to_continue) { /* (relatively) normal zipfile: go for it */
+ if (error) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybePakBug),
+ G.zipfn));
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ if ((G.extra_bytes = G.real_ecrec_offset-G.expect_ecrec_offset) <
+ (zoff_t)0)
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MissingBytes),
+ G.zipfn, FmZofft((-G.extra_bytes), NULL, NULL)));
+ error_in_archive = PK_ERR;
+ } else if (G.extra_bytes > 0) {
+ if ((G.ecrec.offset_start_central_directory == 0) &&
+ (G.ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NullCentDirOffset), G.zipfn));
+ G.ecrec.offset_start_central_directory = G.extra_bytes;
+ G.extra_bytes = 0;
+ error_in_archive = PK_ERR;
+ }
+#ifndef SFX
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtraBytesAtStart), G.zipfn,
+ FmZofft(G.extra_bytes, NULL, NULL),
+ (G.extra_bytes == 1)? "":"s"));
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ }
+
+ /*-----------------------------------------------------------------------
+ Check for empty zipfile and exit now if so.
+ -----------------------------------------------------------------------*/
+
+ if (G.expect_ecrec_offset==0L && G.ecrec.size_central_directory==0) {
+ if (uO.zipinfo_mode)
+ Info(slide, 0, ((char *)slide, "%sEmpty zipfile.\n",
+ uO.lflag>9? "\n " : ""));
+ else
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileEmpty),
+ G.zipfn));
+ CLOSE_INFILE();
+ return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
+ }
+
+ /*-----------------------------------------------------------------------
+ Compensate for missing or extra bytes, and seek to where the start
+ of central directory should be. If header not found, uncompensate
+ and try again (necessary for at least some Atari archives created
+ with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
+ -----------------------------------------------------------------------*/
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error == PK_BADERR) {
+ CLOSE_INFILE();
+ return PK_BADERR;
+ }
+#ifdef OLD_SEEK_TEST
+ if (error != PK_OK || readbuf(__G__ G.sig, 4) == 0) {
+ CLOSE_INFILE();
+ return PK_ERR; /* file may be locked, or possibly disk error(?) */
+ }
+ if (memcmp(G.sig, central_hdr_sig, 4))
+#else
+ if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+ memcmp(G.sig, central_hdr_sig, 4))
+#endif
+ {
+#ifndef SFX
+ zoff_t tmp = G.extra_bytes;
+#endif
+
+ G.extra_bytes = 0;
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+ memcmp(G.sig, central_hdr_sig, 4))
+ {
+ if (error != PK_BADERR)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirStartNotFound), G.zipfn,
+ LoadFarStringSmall(ReportMsg)));
+ CLOSE_INFILE();
+ return (error != PK_OK ? error : PK_BADERR);
+ }
+#ifndef SFX
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirTooLong),
+ G.zipfn, FmZofft((-tmp), NULL, NULL)));
+#endif
+ error_in_archive = PK_ERR;
+ }
+
+ /*-----------------------------------------------------------------------
+ Seek to the start of the central directory one last time, since we
+ have just read the first entry's signature bytes; then list, extract
+ or test member files as instructed, and close the zipfile.
+ -----------------------------------------------------------------------*/
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error != PK_OK) {
+ CLOSE_INFILE();
+ return error;
+ }
+
+ Trace((stderr, "about to extract/list files (error = %d)\n",
+ error_in_archive));
+
+#ifdef DLL
+ /* G.fValidate is used only to look at an archive to see if
+ it appears to be a valid archive. There is no interest
+ in what the archive contains, nor in validating that the
+ entries in the archive are in good condition. This is
+ currently used only in the Windows DLLs for purposes of
+ checking archives within an archive to determine whether
+ or not to display the inner archives.
+ */
+ if (!G.fValidate)
+#endif
+ {
+#ifndef NO_ZIPINFO
+ if (uO.zipinfo_mode)
+ error = zipinfo(__G); /* ZIPINFO 'EM */
+ else
+#endif
+#ifndef SFX
+#ifdef TIMESTAMP
+ if (uO.T_flag)
+ error = get_time_stamp(__G__ &uxstamp, &nmember);
+ else
+#endif
+ if (uO.vflag && !uO.tflag && !uO.cflag)
+ error = list_files(__G); /* LIST 'EM */
+ else
+#endif /* !SFX */
+ error = extract_or_test_files(__G); /* EXTRACT OR TEST 'EM */
+
+ Trace((stderr, "done with extract/list files (error = %d)\n",
+ error));
+ }
+
+ if (error > error_in_archive) /* don't overwrite stronger error */
+ error_in_archive = error; /* with (for example) a warning */
+#ifndef SFX
+ } /* end if (!too_weird_to_continue) */
+#endif
+
+ CLOSE_INFILE();
+
+#ifdef TIMESTAMP
+ if (uO.T_flag && !uO.zipinfo_mode && (nmember > 0L)) {
+# ifdef WIN32
+ if (stamp_file(__G__ G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */
+# else
+ if (stamp_file(G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */
+# endif
+ if (uO.qflag < 3)
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(ZipTimeStampFailed), G.zipfn));
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ } else {
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ZipTimeStampSuccess), G.zipfn));
+ }
+ }
+#endif
+ return error_in_archive;
+
+} /* end function do_seekable() */
+
+
+
+
+#ifdef DO_SAFECHECK_2GB
+/************************/
+/* Function file_size() */
+/************************/
+/* File size determination which does not mislead for large files in a
+ small-file program. Probably should be somewhere else.
+ The file has to be opened previously
+*/
+#ifdef USE_STRM_INPUT
+static zoff_t file_size(file)
+ FILE *file;
+{
+ int sts;
+ size_t siz;
+#else /* !USE_STRM_INPUT */
+static zoff_t file_size(fh)
+ int fh;
+{
+ int siz;
+#endif /* ?USE_STRM_INPUT */
+ zoff_t ofs;
+ char waste[4];
+
+#ifdef USE_STRM_INPUT
+ /* Seek to actual EOF. */
+ sts = zfseeko(file, 0, SEEK_END);
+ if (sts != 0) {
+ /* fseeko() failed. (Unlikely.) */
+ ofs = EOF;
+ } else {
+ /* Get apparent offset at EOF. */
+ ofs = zftello(file);
+ if (ofs < 0) {
+ /* Offset negative (overflow). File too big. */
+ ofs = EOF;
+ } else {
+ /* Seek to apparent EOF offset.
+ Won't be at actual EOF if offset was truncated.
+ */
+ sts = zfseeko(file, ofs, SEEK_SET);
+ if (sts != 0) {
+ /* fseeko() failed. (Unlikely.) */
+ ofs = EOF;
+ } else {
+ /* Read a byte at apparent EOF. Should set EOF flag. */
+ siz = fread(waste, 1, 1, file);
+ if (feof(file) == 0) {
+ /* Not at EOF, but should be. File too big. */
+ ofs = EOF;
+ }
+ }
+ }
+ }
+#else /* !USE_STRM_INPUT */
+ /* Seek to actual EOF. */
+ ofs = zlseek(fh, 0, SEEK_END);
+ if (ofs == (zoff_t) -1) {
+ /* zlseek() failed. (Unlikely.) */
+ ofs = EOF;
+ } else if (ofs < 0) {
+ /* Offset negative (overflow). File too big. */
+ ofs = EOF;
+ } else {
+ /* Seek to apparent EOF offset.
+ Won't be at actual EOF if offset was truncated.
+ */
+ ofs = zlseek(fh, ofs, SEEK_SET);
+ if (ofs == (zoff_t) -1) {
+ /* zlseek() failed. (Unlikely.) */
+ ofs = EOF;
+ } else {
+ /* Read a byte at apparent EOF. Should set EOF flag. */
+ siz = read(fh, waste, 1);
+ if (siz != 0) {
+ /* Not at EOF, but should be. File too big. */
+ ofs = EOF;
+ }
+ }
+ }
+#endif /* ?USE_STRM_INPUT */
+ return ofs;
+} /* end function file_size() */
+#endif /* DO_SAFECHECK_2GB */
+
+
+
+
+/***********************/
+/* Function rec_find() */
+/***********************/
+
+static int rec_find(__G__ searchlen, signature, rec_size)
+ /* return 0 when rec found, 1 when not found, 2 in case of read error */
+ __GDEF
+ zoff_t searchlen;
+ char* signature;
+ int rec_size;
+{
+ int i, numblks, found=FALSE;
+ zoff_t tail_len;
+
+/*---------------------------------------------------------------------------
+ Zipfile is longer than INBUFSIZ: may need to loop. Start with short
+ block at end of zipfile (if not TOO short).
+ ---------------------------------------------------------------------------*/
+
+ if ((tail_len = G.ziplen % INBUFSIZ) > rec_size) {
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, G.ziplen-tail_len, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = zlseek(G.zipfd, G.ziplen-tail_len, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf,
+ (unsigned int)tail_len)) != (int)tail_len)
+ return 2; /* it's expedient... */
+
+ /* 'P' must be at least (rec_size+4) bytes from end of zipfile */
+ for (G.inptr = G.inbuf+(int)tail_len-(rec_size+4);
+ G.inptr >= G.inbuf;
+ --G.inptr) {
+ if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */
+ !memcmp((char *)G.inptr, signature, 4) ) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ }
+ /* sig may span block boundary: */
+ memcpy((char *)G.hold, (char *)G.inbuf, 3);
+ } else
+ G.cur_zipfile_bufstart = G.ziplen - tail_len;
+
+/*-----------------------------------------------------------------------
+ Loop through blocks of zipfile data, starting at the end and going
+ toward the beginning. In general, need not check whole zipfile for
+ signature, but may want to do so if testing.
+ -----------------------------------------------------------------------*/
+
+ numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
+ /* ==amount= ==done== ==rounding== =blksiz= */
+
+ for (i = 1; !found && (i <= numblks); ++i) {
+ G.cur_zipfile_bufstart -= INBUFSIZ;
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET);
+#else /* !USE_STRM_INPUT */
+ zlseek(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ))
+ != INBUFSIZ)
+ return 2; /* read error is fatal failure */
+
+ for (G.inptr = G.inbuf+INBUFSIZ-1; G.inptr >= G.inbuf; --G.inptr)
+ if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */
+ !memcmp((char *)G.inptr, signature, 4) ) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ /* sig may span block boundary: */
+ memcpy((char *)G.hold, (char *)G.inbuf, 3);
+ }
+ return (found ? 0 : 1);
+} /* end function rec_find() */
+
+
+
+
+#if 0
+/********************************/
+/* Function check_ecrec_zip64() */
+/********************************/
+
+static int check_ecrec_zip64(__G)
+ __GDEF
+{
+ return G.ecrec.offset_start_central_directory == 0xFFFFFFFFL
+ || G.ecrec.size_central_directory == 0xFFFFFFFFL
+ || G.ecrec.total_entries_central_dir == 0xFFFF
+ || G.ecrec.num_entries_centrl_dir_ths_disk == 0xFFFF
+ || G.ecrec.num_disk_start_cdir == 0xFFFF
+ || G.ecrec.number_this_disk == 0xFFFF;
+} /* end function check_ecrec_zip64() */
+#endif /* never */
+
+
+
+/***************************/
+/* Function find_ecrec64() */
+/***************************/
+
+static int find_ecrec64(__G__ searchlen) /* return PK-class error */
+ __GDEF
+ zoff_t searchlen;
+{
+ ec_byte_rec64 byterec; /* buf for ecrec64 */
+ ec_byte_loc64 byterecL; /* buf for ecrec64 locator */
+ zoff_t ecloc64_start_offset; /* start offset of ecrec64 locator */
+ zusz_t ecrec64_start_offset; /* start offset of ecrec64 */
+ zuvl_t ecrec64_start_disk; /* start disk of ecrec64 */
+ zuvl_t ecloc64_total_disks; /* total disks */
+ zuvl_t ecrec64_disk_cdstart; /* disk number of central dir start */
+ zucn_t ecrec64_this_entries; /* entries on disk with ecrec64 */
+ zucn_t ecrec64_tot_entries; /* total number of entries */
+ zusz_t ecrec64_cdirsize; /* length of central dir */
+ zusz_t ecrec64_offs_cdstart; /* offset of central dir start */
+
+ /* First, find the ecrec64 locator. By definition, this must be before
+ ecrec with nothing in between. We back up the size of the ecrec64
+ locator and check. */
+
+ ecloc64_start_offset = G.real_ecrec_offset - (ECLOC64_SIZE+4);
+ if (ecloc64_start_offset < 0)
+ /* Seeking would go past beginning, so probably empty archive */
+ return PK_COOL;
+
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, ecloc64_start_offset, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = zlseek(G.zipfd, ecloc64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+ if ((G.incnt = read(G.zipfd, (char *)byterecL, ECLOC64_SIZE+4))
+ != (ECLOC64_SIZE+4)) {
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchErr)));
+ return PK_ERR;
+ }
+
+ if (memcmp((char *)byterecL, end_centloc64_sig, 4) ) {
+ /* not found */
+ return PK_COOL;
+ }
+
+ /* Read the locator. */
+ ecrec64_start_disk = (zuvl_t)makelong(&byterecL[NUM_DISK_START_EOCDR64]);
+ ecrec64_start_offset = (zusz_t)makeint64(&byterecL[OFFSET_START_EOCDR64]);
+ ecloc64_total_disks = (zuvl_t)makelong(&byterecL[NUM_THIS_DISK_LOC64]);
+
+ /* Check for consistency */
+#ifdef TEST
+ fprintf(stdout,"\nnumber of disks (ECR) %u, (ECLOC64) %lu\n",
+ G.ecrec.number_this_disk, ecloc64_total_disks); fflush(stdout);
+#endif
+ if ((G.ecrec.number_this_disk != 0xFFFF) &&
+ (G.ecrec.number_this_disk != ecloc64_total_disks - 1)) {
+ /* Note: For some unknown reason, the developers at PKWARE decided to
+ store the "zip64 total disks" value as a counter starting from 1,
+ whereas all other "split/span volume" related fields use 0-based
+ volume numbers. Sigh... */
+ /* When the total number of disks as found in the traditional ecrec
+ is not 0xFFFF, the disk numbers in ecrec and ecloc64 must match.
+ When this is not the case, the found ecrec64 locator cannot be valid.
+ -> This is not a Zip64 archive.
+ */
+ Trace((stderr,
+ "\ninvalid ECLOC64, differing disk# (ECR %u, ECL64 %lu)\n",
+ G.ecrec.number_this_disk, ecloc64_total_disks - 1));
+ return PK_COOL;
+ }
+
+ /* If found locator, look for ecrec64 where the locator says it is. */
+
+ /* For now assume that ecrec64 is on the same disk as ecloc64 and ecrec,
+ which is usually the case and is how Zip writes it. To do this right,
+ however, we should allow the ecrec64 to be on another disk since
+ the AppNote allows it and the ecrec64 can be large, especially if
+ Version 2 is used (AppNote uses 8 bytes for the size of this record). */
+
+ /* FIX BELOW IF ADD SUPPORT FOR MULTIPLE DISKS */
+
+ if (ecrec64_start_offset > (zusz_t)ecloc64_start_offset) {
+ /* ecrec64 has to be before ecrec64 locator */
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchErr)));
+ return PK_ERR;
+ }
+
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, ecrec64_start_offset, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = zlseek(G.zipfd, ecrec64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+ if ((G.incnt = read(G.zipfd, (char *)byterec, ECREC64_SIZE+4))
+ != (ECREC64_SIZE+4)) {
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchErr)));
+ return PK_ERR;
+ }
+
+ if (memcmp((char *)byterec, end_central64_sig, 4) ) {
+ /* Zip64 EOCD Record not found */
+ /* Since we already have seen the Zip64 EOCD Locator, it's
+ possible we got here because there are bytes prepended
+ to the archive, like the sfx prefix. */
+
+ /* Make a guess as to where the Zip64 EOCD Record might be */
+ ecrec64_start_offset = ecloc64_start_offset - ECREC64_SIZE - 4;
+
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, ecrec64_start_offset, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = zlseek(G.zipfd, ecrec64_start_offset, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+
+ if ((G.incnt = read(G.zipfd, (char *)byterec, ECREC64_SIZE+4))
+ != (ECREC64_SIZE+4)) {
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchErr)));
+ return PK_ERR;
+ }
+
+ if (memcmp((char *)byterec, end_central64_sig, 4) ) {
+ /* Zip64 EOCD Record not found */
+ /* Probably something not so easy to handle so exit */
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchErr)));
+ return PK_ERR;
+ }
+
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(Cent64EndSigSearchOff)));
+ }
+
+ /* Check consistency of found ecrec64 with ecloc64 (and ecrec): */
+ if ( (zuvl_t)makelong(&byterec[NUMBER_THIS_DSK_REC64])
+ != ecrec64_start_disk )
+ /* found ecrec64 does not match ecloc64 info -> no Zip64 archive */
+ return PK_COOL;
+ /* Read all relevant ecrec64 fields and compare them to the corresponding
+ ecrec fields unless those are set to "all-ones".
+ */
+ ecrec64_disk_cdstart =
+ (zuvl_t)makelong(&byterec[NUM_DISK_START_CEN_DIR64]);
+ if ( (G.ecrec.num_disk_start_cdir != 0xFFFF) &&
+ (G.ecrec.num_disk_start_cdir != ecrec64_disk_cdstart) )
+ return PK_COOL;
+ ecrec64_this_entries
+ = makeint64(&byterec[NUM_ENTRIES_CEN_DIR_THS_DISK64]);
+ if ( (G.ecrec.num_entries_centrl_dir_ths_disk != 0xFFFF) &&
+ (G.ecrec.num_entries_centrl_dir_ths_disk != ecrec64_this_entries) )
+ return PK_COOL;
+ ecrec64_tot_entries
+ = makeint64(&byterec[TOTAL_ENTRIES_CENTRAL_DIR64]);
+ if ( (G.ecrec.total_entries_central_dir != 0xFFFF) &&
+ (G.ecrec.total_entries_central_dir != ecrec64_tot_entries) )
+ return PK_COOL;
+ ecrec64_cdirsize
+ = makeint64(&byterec[SIZE_CENTRAL_DIRECTORY64]);
+ if ( (G.ecrec.size_central_directory != 0xFFFFFFFFL) &&
+ (G.ecrec.size_central_directory != ecrec64_cdirsize) )
+ return PK_COOL;
+ ecrec64_offs_cdstart
+ = makeint64(&byterec[OFFSET_START_CENTRAL_DIRECT64]);
+ if ( (G.ecrec.offset_start_central_directory != 0xFFFFFFFFL) &&
+ (G.ecrec.offset_start_central_directory != ecrec64_offs_cdstart) )
+ return PK_COOL;
+
+ /* Now, we are (almost) sure that we have a Zip64 archive. */
+ G.ecrec.have_ecr64 = 1;
+
+ /* Update the "end-of-central-dir offset" for later checks. */
+ G.real_ecrec_offset = ecrec64_start_offset;
+
+ /* Update all ecdir_rec data that are flagged to be invalid
+ in Zip64 mode. Set the ecrec64-mandatory flag when such a
+ case is found. */
+ if (G.ecrec.number_this_disk == 0xFFFF) {
+ G.ecrec.number_this_disk = ecrec64_start_disk;
+ if (ecrec64_start_disk != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+ if (G.ecrec.num_disk_start_cdir == 0xFFFF) {
+ G.ecrec.num_disk_start_cdir = ecrec64_disk_cdstart;
+ if (ecrec64_disk_cdstart != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+ if (G.ecrec.num_entries_centrl_dir_ths_disk == 0xFFFF) {
+ G.ecrec.num_entries_centrl_dir_ths_disk = ecrec64_this_entries;
+ if (ecrec64_this_entries != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+ if (G.ecrec.total_entries_central_dir == 0xFFFF) {
+ G.ecrec.total_entries_central_dir = ecrec64_tot_entries;
+ if (ecrec64_tot_entries != 0xFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+ if (G.ecrec.size_central_directory == 0xFFFFFFFFL) {
+ G.ecrec.size_central_directory = ecrec64_cdirsize;
+ if (ecrec64_cdirsize != 0xFFFFFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+ if (G.ecrec.offset_start_central_directory == 0xFFFFFFFFL) {
+ G.ecrec.offset_start_central_directory = ecrec64_offs_cdstart;
+ if (ecrec64_offs_cdstart != 0xFFFFFFFF) G.ecrec.is_zip64_archive = TRUE;
+ }
+
+ return PK_COOL;
+} /* end function find_ecrec64() */
+
+
+
+/*************************/
+/* Function find_ecrec() */
+/*************************/
+
+static int find_ecrec(__G__ searchlen) /* return PK-class error */
+ __GDEF
+ zoff_t searchlen;
+{
+ int found = FALSE;
+ int error_in_archive;
+ int result;
+ ec_byte_rec byterec;
+
+/*---------------------------------------------------------------------------
+ Treat case of short zipfile separately.
+ ---------------------------------------------------------------------------*/
+
+ if (G.ziplen <= INBUFSIZ) {
+#ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, 0L, SEEK_SET);
+#else /* !USE_STRM_INPUT */
+ zlseek(G.zipfd, 0L, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd,(char *)G.inbuf,(unsigned int)G.ziplen))
+ == (int)G.ziplen)
+
+ /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */
+ for (G.inptr = G.inbuf+(int)G.ziplen-(ECREC_SIZE+4);
+ G.inptr >= G.inbuf;
+ --G.inptr) {
+ if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */
+ !memcmp((char *)G.inptr, end_central_sig, 4)) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ }
+
+/*---------------------------------------------------------------------------
+ Zipfile is longer than INBUFSIZ:
+
+ MB - this next block of code moved to rec_find so that same code can be
+ used to look for zip64 ec record. No need to include code above since
+ a zip64 ec record will only be looked for if it is a BIG file.
+ ---------------------------------------------------------------------------*/
+
+ } else {
+ found =
+ (rec_find(__G__ searchlen, end_central_sig, ECREC_SIZE) == 0
+ ? TRUE : FALSE);
+ } /* end if (ziplen > INBUFSIZ) */
+
+/*---------------------------------------------------------------------------
+ Searched through whole region where signature should be without finding
+ it. Print informational message and die a horrible death.
+ ---------------------------------------------------------------------------*/
+
+ if (!found) {
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirEndSigNotFound)));
+ return PK_ERR; /* failed */
+ }
+
+/*---------------------------------------------------------------------------
+ Found the signature, so get the end-central data before returning. Do
+ any necessary machine-type conversions (byte ordering, structure padding
+ compensation) by reading data into character array and copying to struct.
+ ---------------------------------------------------------------------------*/
+
+ G.real_ecrec_offset = G.cur_zipfile_bufstart + (G.inptr-G.inbuf);
+#ifdef TEST
+ printf("\n found end-of-central-dir signature at offset %s (%sh)\n",
+ FmZofft(G.real_ecrec_offset, NULL, NULL),
+ FmZofft(G.real_ecrec_offset, FZOFFT_HEX_DOT_WID, "X"));
+ printf(" from beginning of file; offset %d (%.4Xh) within block\n",
+ G.inptr-G.inbuf, G.inptr-G.inbuf);
+#endif
+
+ if (readbuf(__G__ (char *)byterec, ECREC_SIZE+4) == 0)
+ return PK_EOF;
+
+ G.ecrec.number_this_disk =
+ makeword(&byterec[NUMBER_THIS_DISK]);
+ G.ecrec.num_disk_start_cdir =
+ makeword(&byterec[NUM_DISK_WITH_START_CEN_DIR]);
+ G.ecrec.num_entries_centrl_dir_ths_disk =
+ makeword(&byterec[NUM_ENTRIES_CEN_DIR_THS_DISK]);
+ G.ecrec.total_entries_central_dir =
+ makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
+ G.ecrec.size_central_directory =
+ makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
+ G.ecrec.offset_start_central_directory =
+ makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
+ G.ecrec.zipfile_comment_length =
+ makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
+
+ /* Now, we have to read the archive comment, BEFORE the file pointer
+ is moved away backwards to seek for a Zip64 ECLOC64 structure.
+ */
+ if ( (error_in_archive = process_zip_cmmnt(__G)) > PK_WARN )
+ return error_in_archive;
+
+ /* Next: Check for existence of Zip64 end-of-cent-dir locator
+ ECLOC64. This structure must reside on the same volume as the
+ classic ECREC, at exactly (ECLOC64_SIZE+4) bytes in front
+ of the ECREC.
+ The ECLOC64 structure directs to the longer ECREC64 structure
+ A ECREC64 will ALWAYS exist for a proper Zip64 archive, as
+ the "Version Needed To Extract" field is required to be set
+ to 4.5 or higher whenever any Zip64 features are used anywhere
+ in the archive, so just check for that to see if this is a
+ Zip64 archive.
+ */
+ result = find_ecrec64(__G__ searchlen+76);
+ /* 76 bytes for zip64ec & zip64 locator */
+ if (result != PK_COOL) {
+ if (error_in_archive < result)
+ error_in_archive = result;
+ return error_in_archive;
+ }
+
+ G.expect_ecrec_offset = G.ecrec.offset_start_central_directory +
+ G.ecrec.size_central_directory;
+
+#ifndef NO_ZIPINFO
+ if (uO.zipinfo_mode) {
+ /* In ZipInfo mode, additional info about the data found in the
+ end-of-central-directory areas is printed out.
+ */
+ zi_end_central(__G);
+ }
+#endif
+
+ return error_in_archive;
+
+} /* end function find_ecrec() */
+
+
+
+
+
+/********************************/
+/* Function process_zip_cmmnt() */
+/********************************/
+
+static int process_zip_cmmnt(__G) /* return PK-type error code */
+ __GDEF
+{
+ int error = PK_COOL;
+
+
+/*---------------------------------------------------------------------------
+ Get the zipfile comment (up to 64KB long), if any, and print it out.
+ ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+ /* for comment button: */
+ if ((!G.fValidate) && (G.lpUserFunctions != NULL))
+ G.lpUserFunctions->cchComment = G.ecrec.zipfile_comment_length;
+#endif /* WINDLL */
+
+#ifndef NO_ZIPINFO
+ /* ZipInfo, verbose format */
+ if (uO.zipinfo_mode && uO.lflag > 9) {
+ /*-------------------------------------------------------------------
+ Get the zipfile comment, if any, and print it out.
+ (Comment may be up to 64KB long. May the fleas of a thousand
+ camels infest the arm-pits of anyone who actually takes advantage
+ of this fact.)
+ -------------------------------------------------------------------*/
+
+ if (!G.ecrec.zipfile_comment_length)
+ Info(slide, 0, ((char *)slide, LoadFarString(NoZipfileComment)));
+ else {
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommentDesc),
+ G.ecrec.zipfile_comment_length));
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommBegin)));
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY))
+ error = PK_WARN;
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommEnd)));
+ if (error)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc2)));
+ } /* endif (comment exists) */
+
+ /* ZipInfo, non-verbose mode: print zipfile comment only if requested */
+ } else if (G.ecrec.zipfile_comment_length &&
+ (uO.zflag > 0) && uO.zipinfo_mode) {
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc1)));
+ error = PK_WARN;
+ }
+ } else
+#endif /* !NO_ZIPINFO */
+ if ( G.ecrec.zipfile_comment_length &&
+ (uO.zflag > 0
+#ifndef WINDLL
+ || (uO.zflag == 0
+# ifndef NO_ZIPINFO
+ && !uO.zipinfo_mode
+# endif
+# ifdef TIMESTAMP
+ && !uO.T_flag
+# endif
+ && !uO.qflag)
+#endif /* !WINDLL */
+ ) )
+ {
+ if (do_string(__G__ G.ecrec.zipfile_comment_length,
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+# ifndef NO_ZIPINFO
+ (oU.zipinfo_mode ? DISPLAY : CHECK_AUTORUN)
+# else
+ CHECK_AUTORUN
+# endif
+#else
+ DISPLAY
+#endif
+ ))
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc1)));
+ error = PK_WARN;
+ }
+ }
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ else if (G.ecrec.zipfile_comment_length) {
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, CHECK_AUTORUN_Q))
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc1)));
+ error = PK_WARN;
+ }
+ }
+#endif
+ return error;
+
+} /* end function process_zip_cmmnt() */
+
+
+
+
+
+/************************************/
+/* Function process_cdir_file_hdr() */
+/************************************/
+
+int process_cdir_file_hdr(__G) /* return PK-type error code */
+ __GDEF
+{
+ int error;
+
+
+/*---------------------------------------------------------------------------
+ Get central directory info, save host and method numbers, and set flag
+ for lowercase conversion of filename, depending on the OS from which the
+ file is coming.
+ ---------------------------------------------------------------------------*/
+
+ if ((error = get_cdir_ent(__G)) != 0)
+ return error;
+
+ G.pInfo->hostver = G.crec.version_made_by[0];
+ G.pInfo->hostnum = MIN(G.crec.version_made_by[1], NUM_HOSTS);
+/* extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
+
+ G.pInfo->lcflag = 0;
+ if (uO.L_flag == 1) /* name conversion for monocase systems */
+ switch (G.pInfo->hostnum) {
+ case FS_FAT_: /* PKZIP and zip -k store in uppercase */
+ case CPM_: /* like MS-DOS, right? */
+ case VM_CMS_: /* all caps? */
+ case MVS_: /* all caps? */
+ case TANDEM_:
+ case TOPS20_:
+ case VMS_: /* our Zip uses lowercase, but ASi's doesn't */
+ /* case Z_SYSTEM_: ? */
+ /* case QDOS_: ? */
+ G.pInfo->lcflag = 1; /* convert filename to lowercase */
+ break;
+
+ default: /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, ATARI_, */
+ break; /* FS_VFAT_, ATHEOS_, BEOS_ (Z_SYSTEM_), THEOS_: */
+ /* no conversion */
+ }
+ else if (uO.L_flag > 1) /* let -LL force lower case for all names */
+ G.pInfo->lcflag = 1;
+
+ /* do Amigas (AMIGA_) also have volume labels? */
+ if (IS_VOLID(G.crec.external_file_attributes) &&
+ (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
+ G.pInfo->hostnum == FS_NTFS_ || G.pInfo->hostnum == ATARI_))
+ {
+ G.pInfo->vollabel = TRUE;
+ G.pInfo->lcflag = 0; /* preserve case of volume labels */
+ } else
+ G.pInfo->vollabel = FALSE;
+
+ /* this flag is needed to detect archives made by "PKZIP for Unix" when
+ deciding which kind of codepage conversion has to be applied to
+ strings (see do_string() function in fileio.c) */
+ G.pInfo->HasUxAtt = (G.crec.external_file_attributes & 0xffff0000L) != 0L;
+
+#ifdef UNICODE_SUPPORT
+ /* remember the state of GPB11 (General Purpuse Bit 11) which indicates
+ that the standard path and comment are UTF-8. */
+ G.pInfo->GPFIsUTF8
+ = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
+#endif
+
+#ifdef SYMLINKS
+ /* Initialize the symlink flag, may be set by the platform-specific
+ mapattr function. */
+ G.pInfo->symlink = 0;
+#endif
+
+ return PK_COOL;
+
+} /* end function process_cdir_file_hdr() */
+
+
+
+
+
+/***************************/
+/* Function get_cdir_ent() */
+/***************************/
+
+static int get_cdir_ent(__G) /* return PK-type error code */
+ __GDEF
+{
+ cdir_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+ Read the next central directory entry and do any necessary machine-type
+ conversions (byte ordering, structure padding compensation--do so by
+ copying the data from the array into which it was read (byterec) to the
+ usable struct (crec)).
+ ---------------------------------------------------------------------------*/
+
+ if (readbuf(__G__ (char *)byterec, CREC_SIZE) == 0)
+ return PK_EOF;
+
+ G.crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
+ G.crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
+ G.crec.version_needed_to_extract[0] =
+ byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
+ G.crec.version_needed_to_extract[1] =
+ byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
+
+ G.crec.general_purpose_bit_flag =
+ makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
+ G.crec.compression_method =
+ makeword(&byterec[C_COMPRESSION_METHOD]);
+ G.crec.last_mod_dos_datetime =
+ makelong(&byterec[C_LAST_MOD_DOS_DATETIME]);
+ G.crec.crc32 =
+ makelong(&byterec[C_CRC32]);
+ G.crec.csize =
+ makelong(&byterec[C_COMPRESSED_SIZE]);
+ G.crec.ucsize =
+ makelong(&byterec[C_UNCOMPRESSED_SIZE]);
+ G.crec.filename_length =
+ makeword(&byterec[C_FILENAME_LENGTH]);
+ G.crec.extra_field_length =
+ makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
+ G.crec.file_comment_length =
+ makeword(&byterec[C_FILE_COMMENT_LENGTH]);
+ G.crec.disk_number_start =
+ makeword(&byterec[C_DISK_NUMBER_START]);
+ G.crec.internal_file_attributes =
+ makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
+ G.crec.external_file_attributes =
+ makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
+ G.crec.relative_offset_local_header =
+ makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
+
+ return PK_COOL;
+
+} /* end function get_cdir_ent() */
+
+
+
+
+
+/*************************************/
+/* Function process_local_file_hdr() */
+/*************************************/
+
+int process_local_file_hdr(__G) /* return PK-type error code */
+ __GDEF
+{
+ local_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+ Read the next local file header and do any necessary machine-type con-
+ versions (byte ordering, structure padding compensation--do so by copy-
+ ing the data from the array into which it was read (byterec) to the
+ usable struct (lrec)).
+ ---------------------------------------------------------------------------*/
+
+ if (readbuf(__G__ (char *)byterec, LREC_SIZE) == 0)
+ return PK_EOF;
+
+ G.lrec.version_needed_to_extract[0] =
+ byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
+ G.lrec.version_needed_to_extract[1] =
+ byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
+
+ G.lrec.general_purpose_bit_flag =
+ makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
+ G.lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
+ G.lrec.last_mod_dos_datetime = makelong(&byterec[L_LAST_MOD_DOS_DATETIME]);
+ G.lrec.crc32 = makelong(&byterec[L_CRC32]);
+ G.lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]);
+ G.lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
+ G.lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
+ G.lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
+
+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
+ /* can't trust local header, use central directory: */
+ G.lrec.crc32 = G.pInfo->crc;
+ G.lrec.csize = G.pInfo->compr_size;
+ G.lrec.ucsize = G.pInfo->uncompr_size;
+ }
+
+ G.csize = G.lrec.csize;
+
+ return PK_COOL;
+
+} /* end function process_local_file_hdr() */
+
+
+/*******************************/
+/* Function getZip64Data() */
+/*******************************/
+
+int getZip64Data(__G__ ef_buf, ef_len)
+ __GDEF
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for zip64 information, ie 8-byte
+ versions of compressed file size, uncompressed file size, relative offset
+ and a 4-byte version of disk start number.
+ Sets both local header and central header fields. Not terribly clever,
+ but it means that this procedure is only called in one place.
+
+ 2014-12-05 SMS. (oCERT.org report.) CVE-2014-8141.
+ Added checks to ensure that enough data are available before calling
+ makeint64() or makelong(). Replaced various sizeof() values with
+ simple ("4" or "8") constants. (The Zip64 structures do not depend
+ on our variable sizes.) Error handling is crude, but we should now
+ stay within the buffer.
+ ---------------------------------------------------------------------------*/
+
+#define Z64FLGS 0xffff
+#define Z64FLGL 0xffffffff
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return PK_COOL;
+
+ Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE)
+ {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE))
+ {
+ /* Extra block length exceeds remaining extra field length. */
+ Trace((stderr,
+ "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ if (eb_id == EF_PKSZ64)
+ {
+ unsigned offset = EB_HEADSIZE;
+
+ if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
+ G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
+ offset += 8;
+ }
+
+ if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
+ G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
+ offset += 8;
+ }
+
+ if (G.crec.relative_offset_local_header == Z64FLGL)
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
+ G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
+ offset += 8;
+ }
+
+ if (G.crec.disk_number_start == Z64FLGS)
+ {
+ if (offset+ 4 > ef_len)
+ return PK_ERR;
+
+ G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
+ offset += 4;
+ }
+#if 0
+ break; /* Expect only one EF_PKSZ64 block. */
+#endif /* 0 */
+ }
+
+ /* Skip this extra field block. */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return PK_COOL;
+} /* end function getZip64Data() */
+
+
+#ifdef UNICODE_SUPPORT
+
+/*******************************/
+/* Function getUnicodeData() */
+/*******************************/
+
+int getUnicodeData(__G__ ef_buf, ef_len)
+ __GDEF
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for Unicode information, ie UTF-8
+ path extra fields.
+
+ On return, G.unipath_filename =
+ NULL, if no Unicode path extra field or error
+ "", if the standard path is UTF-8 (free when done)
+ null-terminated UTF-8 path (free when done)
+ Return PK_COOL if no error.
+ ---------------------------------------------------------------------------*/
+
+ G.unipath_filename = NULL;
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return PK_COOL;
+
+ Trace((stderr,"\ngetUnicodeData: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "getUnicodeData: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+ if (eb_id == EF_UNIPATH) {
+
+ unsigned offset = EB_HEADSIZE;
+ ush ULen = eb_len - 5;
+ ulg chksum = CRCVAL_INITIAL;
+
+ /* version */
+ G.unipath_version = (uch) *(offset + ef_buf);
+ offset += 1;
+ if (G.unipath_version > 1) {
+ /* can do only version 1 */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UnicodeVersionError)));
+ return PK_ERR;
+ }
+
+ /* filename CRC */
+ G.unipath_checksum = makelong(offset + ef_buf);
+ offset += 4;
+
+ if (!G.filename_full) {
+ /* Check if we have a unicode extra section but no filename set */
+ return PK_ERR;
+ }
+
+ /*
+ * Compute 32-bit crc
+ */
+
+ chksum = crc32(chksum, (uch *)(G.filename_full),
+ strlen(G.filename_full));
+
+ /* If the checksums's don't match then likely filename has been
+ * modified and the Unicode Path is no longer valid.
+ */
+ if (chksum != G.unipath_checksum) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UnicodeMismatchError)));
+ if (G.unicode_mismatch == 1) {
+ /* warn and continue */
+ } else if (G.unicode_mismatch == 2) {
+ /* ignore and continue */
+ } else if (G.unicode_mismatch == 0) {
+ }
+ return PK_ERR;
+ }
+
+ /* UTF-8 Path */
+ if ((G.unipath_filename = malloc(ULen + 1)) == NULL) {
+ return PK_ERR;
+ }
+ if (ULen == 0) {
+ /* standard path is UTF-8 so use that */
+ G.unipath_filename[0] = '\0';
+ } else {
+ /* UTF-8 path */
+ strncpy(G.unipath_filename,
+ (ZCONST char *)(offset + ef_buf), ULen);
+ G.unipath_filename[ULen] = '\0';
+ }
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return PK_COOL;
+} /* end function getUnicodeData() */
+
+
+
+
+#ifdef UNICODE_WCHAR
+ /*---------------------------------------------
+ * Unicode conversion functions
+ *
+ * Based on functions provided by Paul Kienitz
+ *
+ *---------------------------------------------
+ */
+
+/*
+ NOTES APPLICABLE TO ALL STRING FUNCTIONS:
+
+ All of the x_to_y functions take parameters for an output buffer and
+ its available length, and return an int. The value returned is the
+ length of the string that the input produces, which may be larger than
+ the provided buffer length. If the returned value is less than the
+ buffer length, then the contents of the buffer will be null-terminated;
+ otherwise, it will not be terminated and may be invalid, possibly
+ stopping in the middle of a multibyte sequence.
+
+ In all cases you may pass NULL as the buffer and/or 0 as the length, if
+ you just want to learn how much space the string is going to require.
+
+ The functions will return -1 if the input is invalid UTF-8 or cannot be
+ encoded as UTF-8.
+*/
+
+static int utf8_char_bytes OF((ZCONST char *utf8));
+static ulg ucs4_char_from_utf8 OF((ZCONST char **utf8));
+static int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *ucs4buf,
+ int buflen));
+
+/* utility functions for managing UTF-8 and UCS-4 strings */
+
+
+/* utf8_char_bytes
+ *
+ * Returns the number of bytes used by the first character in a UTF-8
+ * string, or -1 if the UTF-8 is invalid or null.
+ */
+static int utf8_char_bytes(utf8)
+ ZCONST char *utf8;
+{
+ int t, r;
+ unsigned lead;
+
+ if (!utf8)
+ return -1; /* no input */
+ lead = (unsigned char) *utf8;
+ if (lead < 0x80)
+ r = 1; /* an ascii-7 character */
+ else if (lead < 0xC0)
+ return -1; /* error: trailing byte without lead byte */
+ else if (lead < 0xE0)
+ r = 2; /* an 11 bit character */
+ else if (lead < 0xF0)
+ r = 3; /* a 16 bit character */
+ else if (lead < 0xF8)
+ r = 4; /* a 21 bit character (the most currently used) */
+ else if (lead < 0xFC)
+ r = 5; /* a 26 bit character (shouldn't happen) */
+ else if (lead < 0xFE)
+ r = 6; /* a 31 bit character (shouldn't happen) */
+ else
+ return -1; /* error: invalid lead byte */
+ for (t = 1; t < r; t++)
+ if ((unsigned char) utf8[t] < 0x80 || (unsigned char) utf8[t] >= 0xC0)
+ return -1; /* error: not enough valid trailing bytes */
+ return r;
+}
+
+
+/* ucs4_char_from_utf8
+ *
+ * Given a reference to a pointer into a UTF-8 string, returns the next
+ * UCS-4 character and advances the pointer to the next character sequence.
+ * Returns ~0 (= -1 in twos-complement notation) and does not advance the
+ * pointer when input is ill-formed.
+ */
+static ulg ucs4_char_from_utf8(utf8)
+ ZCONST char **utf8;
+{
+ ulg ret;
+ int t, bytes;
+
+ if (!utf8)
+ return ~0L; /* no input */
+ bytes = utf8_char_bytes(*utf8);
+ if (bytes <= 0)
+ return ~0L; /* invalid input */
+ if (bytes == 1)
+ ret = **utf8; /* ascii-7 */
+ else
+ ret = **utf8 & (0x7F >> bytes); /* lead byte of a multibyte sequence */
+ (*utf8)++;
+ for (t = 1; t < bytes; t++) /* consume trailing bytes */
+ ret = (ret << 6) | (*((*utf8)++) & 0x3F);
+ return (zwchar) ret;
+}
+
+
+#if 0 /* currently unused */
+/* utf8_from_ucs4_char - Convert UCS char to UTF-8
+ *
+ * Returns the number of bytes put into utf8buf to represent ch, from 1 to 6,
+ * or -1 if ch is too large to represent. utf8buf must have room for 6 bytes.
+ */
+static int utf8_from_ucs4_char(utf8buf, ch)
+ char *utf8buf;
+ ulg ch;
+{
+ int trailing = 0;
+ int leadmask = 0x80;
+ int leadbits = 0x3F;
+ int tch = ch;
+ int ret;
+
+ if (ch > 0x7FFFFFFFL)
+ return -1; /* UTF-8 can represent 31 bits */
+ if (ch < 0x7F)
+ {
+ *utf8buf++ = (char) ch; /* ascii-7 */
+ return 1;
+ }
+ do {
+ trailing++;
+ leadmask = (leadmask >> 1) | 0x80;
+ leadbits >>= 1;
+ tch >>= 6;
+ } while (tch & ~leadbits);
+ ret = trailing + 1;
+ /* produce lead byte */
+ *utf8buf++ = (char) (leadmask | (ch >> (6 * trailing)));
+ while (--trailing >= 0)
+ /* produce trailing bytes */
+ *utf8buf++ = (char) (0x80 | ((ch >> (6 * trailing)) & 0x3F));
+ return ret;
+}
+#endif /* unused */
+
+
+/*===================================================================*/
+
+/* utf8_to_ucs4_string - convert UTF-8 string to UCS string
+ *
+ * Return UCS count. Now returns int so can return -1.
+ */
+static int utf8_to_ucs4_string(utf8, ucs4buf, buflen)
+ ZCONST char *utf8;
+ ulg *ucs4buf;
+ int buflen;
+{
+ int count = 0;
+
+ for (;;)
+ {
+ ulg ch = ucs4_char_from_utf8(&utf8);
+ if (ch == ~0L)
+ return -1;
+ else
+ {
+ if (ucs4buf && count < buflen)
+ ucs4buf[count] = ch;
+ if (ch == 0)
+ return count;
+ count++;
+ }
+ }
+}
+
+
+#if 0 /* currently unused */
+/* ucs4_string_to_utf8
+ *
+ *
+ */
+static int ucs4_string_to_utf8(ucs4, utf8buf, buflen)
+ ZCONST ulg *ucs4;
+ char *utf8buf;
+ int buflen;
+{
+ char mb[6];
+ int count = 0;
+
+ if (!ucs4)
+ return -1;
+ for (;;)
+ {
+ int mbl = utf8_from_ucs4_char(mb, *ucs4++);
+ int c;
+ if (mbl <= 0)
+ return -1;
+ /* We could optimize this a bit by passing utf8buf + count */
+ /* directly to utf8_from_ucs4_char when buflen >= count + 6... */
+ c = buflen - count;
+ if (mbl < c)
+ c = mbl;
+ if (utf8buf && count < buflen)
+ strncpy(utf8buf + count, mb, c);
+ if (mbl == 1 && !mb[0])
+ return count; /* terminating nul */
+ count += mbl;
+ }
+}
+
+
+/* utf8_chars
+ *
+ * Wrapper: counts the actual unicode characters in a UTF-8 string.
+ */
+static int utf8_chars(utf8)
+ ZCONST char *utf8;
+{
+ return utf8_to_ucs4_string(utf8, NULL, 0);
+}
+#endif /* unused */
+
+/* --------------------------------------------------- */
+/* Unicode Support
+ *
+ * These functions common for all Unicode ports.
+ *
+ * These functions should allocate and return strings that can be
+ * freed with free().
+ *
+ * 8/27/05 EG
+ *
+ * Use zwchar for wide char which is unsigned long
+ * in zip.h and 32 bits. This avoids problems with
+ * different sizes of wchar_t.
+ */
+
+#if 0 /* currently unused */
+/* is_ascii_string
+ * Checks if a string is all ascii
+ */
+int is_ascii_string(mbstring)
+ ZCONST char *mbstring;
+{
+ char *p;
+ uch c;
+
+ for (p = mbstring; c = (uch)*p; p++) {
+ if (c > 0x7F) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* local to UTF-8 */
+char *local_to_utf8_string(local_string)
+ ZCONST char *local_string;
+{
+ return wide_to_utf8_string(local_to_wide_string(local_string));
+}
+# endif /* unused */
+
+/* wide_to_escape_string
+ provides a string that represents a wide char not in local char set
+
+ An initial try at an algorithm. Suggestions welcome.
+
+ According to the standard, Unicode character points are restricted to
+ the number range from 0 to 0x10FFFF, respective 21 bits.
+ For a hexadecimal notation, 2 octets are sufficient for the mostly
+ used characters from the "Basic Multilingual Plane", all other
+ Unicode characters can be represented by 3 octets (= 6 hex digits).
+ The Unicode standard suggests to write Unicode character points
+ as 4 resp. 6 hex digits, preprended by "U+".
+ (e.g.: U+10FFFF for the highest character point, or U+0030 for the ASCII
+ digit "0")
+
+ However, for the purpose of escaping non-ASCII chars in an ASCII character
+ stream, the "U" is not a very good escape initializer. Therefore, we
+ use the following convention within our Info-ZIP code:
+
+ If not an ASCII char probably need 2 bytes at least. So if
+ a 2-byte wide encode it as 4 hex digits with a leading #U. If
+ needs 3 bytes then prefix the string with #L. So
+ #U1234
+ is a 2-byte wide character with bytes 0x12 and 0x34 while
+ #L123456
+ is a 3-byte wide character with bytes 0x12, 0x34, 0x56.
+ On Windows, wide that need two wide characters need to be converted
+ to a single number.
+ */
+
+ /* set this to the max bytes an escape can be */
+#define MAX_ESCAPE_BYTES 8
+
+char *wide_to_escape_string(wide_char)
+ zwchar wide_char;
+{
+ int i;
+ zwchar w = wide_char;
+ uch b[sizeof(zwchar)];
+ char d[3];
+ char e[11];
+ int len;
+ char *r;
+
+ /* fill byte array with zeros */
+ memzero(b, sizeof(zwchar));
+ /* get bytes in right to left order */
+ for (len = 0; w; len++) {
+ b[len] = (char)(w % 0x100);
+ w /= 0x100;
+ }
+ strcpy(e, "#");
+ /* either 2 bytes or 3 bytes */
+ if (len <= 2) {
+ len = 2;
+ strcat(e, "U");
+ } else {
+ strcat(e, "L");
+ }
+ for (i = len - 1; i >= 0; i--) {
+ sprintf(d, "%02x", b[i]);
+ strcat(e, d);
+ }
+ if ((r = malloc(strlen(e) + 1)) == NULL) {
+ return NULL;
+ }
+ strcpy(r, e);
+ return r;
+}
+
+#if 0 /* currently unused */
+/* returns the wide character represented by the escape string */
+zwchar escape_string_to_wide(escape_string)
+ ZCONST char *escape_string;
+{
+ int i;
+ zwchar w;
+ char c;
+ int len;
+ ZCONST char *e = escape_string;
+
+ if (e == NULL) {
+ return 0;
+ }
+ if (e[0] != '#') {
+ /* no leading # */
+ return 0;
+ }
+ len = strlen(e);
+ /* either #U1234 or #L123456 format */
+ if (len != 6 && len != 8) {
+ return 0;
+ }
+ w = 0;
+ if (e[1] == 'L') {
+ if (len != 8) {
+ return 0;
+ }
+ /* 3 bytes */
+ for (i = 2; i < 8; i++) {
+ c = e[i];
+ if (c < '0' || c > '9') {
+ return 0;
+ }
+ w = w * 0x10 + (zwchar)(c - '0');
+ }
+ } else if (e[1] == 'U') {
+ /* 2 bytes */
+ for (i = 2; i < 6; i++) {
+ c = e[i];
+ if (c < '0' || c > '9') {
+ return 0;
+ }
+ w = w * 0x10 + (zwchar)(c - '0');
+ }
+ }
+ return w;
+}
+#endif /* unused */
+
+#ifndef WIN32 /* WIN32 supplies a special variant of this function */
+/* convert wide character string to multi-byte character string */
+char *wide_to_local_string(wide_string, escape_all)
+ ZCONST zwchar *wide_string;
+ int escape_all;
+{
+ int i;
+ wchar_t wc;
+ int b;
+ int state_dependent;
+ int wsize = 0;
+ int max_bytes = MB_CUR_MAX;
+ char buf[ MB_CUR_MAX + 1]; /* ("+1" not really needed?) */
+ char *buffer = NULL;
+ char *local_string = NULL;
+ size_t buffer_size; /* CVE-2022-0529 */
+
+ for (wsize = 0; wide_string[wsize]; wsize++) ;
+
+ if (max_bytes < MAX_ESCAPE_BYTES)
+ max_bytes = MAX_ESCAPE_BYTES;
+
+ buffer_size = wsize * max_bytes + 1; /* Reused below. */
+ if ((buffer = (char *)malloc(buffer_size)) == NULL) {
+ return NULL;
+ }
+
+ /* convert it */
+ buffer[0] = '\0';
+ /* set initial state if state-dependent encoding */
+ wc = (wchar_t)'a';
+ b = wctomb(NULL, wc);
+ if (b == 0)
+ state_dependent = 0;
+ else
+ state_dependent = 1;
+ for (i = 0; i < wsize; i++) {
+ if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
+ /* wchar_t probably 2 bytes */
+ /* could do surrogates if state_dependent and wctomb can do */
+ wc = zwchar_to_wchar_t_default_char;
+ } else {
+ wc = (wchar_t)wide_string[i];
+ }
+ b = wctomb(buf, wc);
+ if (escape_all) {
+ if (b == 1 && (uch)buf[0] <= 0x7f) {
+ /* ASCII */
+ strncat(buffer, buf, b);
+ } else {
+ /* use escape for wide character */
+ char *escape_string = wide_to_escape_string(wide_string[i]);
+ strcat(buffer, escape_string);
+ free(escape_string);
+ }
+ } else if (b > 0) {
+ /* multi-byte char */
+ strncat(buffer, buf, b);
+ } else {
+ /* no MB for this wide */
+ /* use escape for wide character */
+ size_t buffer_len;
+ size_t escape_string_len;
+ char *escape_string;
+ int err_msg = 0;
+
+ escape_string = wide_to_escape_string(wide_string[i]);
+ buffer_len = strlen( buffer);
+ escape_string_len = strlen( escape_string);
+
+ /* Append escape string, as space allows. */
+ /* 2022-07-18 SMS, et al. CVE-2022-0529 */
+ if (escape_string_len > buffer_size- buffer_len- 1)
+ {
+ escape_string_len = buffer_size- buffer_len- 1;
+ if (err_msg == 0)
+ {
+ err_msg = 1;
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString( UFilenameTooLongTrunc)));
+ }
+ }
+ strncat( buffer, escape_string, escape_string_len);
+ free(escape_string);
+ }
+ }
+ if ((local_string = (char *)malloc(strlen(buffer) + 1)) != NULL) {
+ strcpy(local_string, buffer);
+ }
+ free(buffer);
+
+ return local_string;
+}
+#endif /* !WIN32 */
+
+#if 0 /* currently unused */
+/* convert local string to display character set string */
+char *local_to_display_string(local_string)
+ ZCONST char *local_string;
+{
+ char *display_string;
+
+ /* For Windows, OEM string should never be bigger than ANSI string, says
+ CharToOem description.
+ For all other ports, just make a copy of local_string.
+ */
+ if ((display_string = (char *)malloc(strlen(local_string) + 1)) == NULL) {
+ return NULL;
+ }
+
+ strcpy(display_string, local_string);
+
+#ifdef EBCDIC
+ {
+ char *ebc;
+
+ if ((ebc = malloc(strlen(display_string) + 1)) == NULL) {
+ return NULL;
+ }
+ strtoebc(ebc, display_string);
+ free(display_string);
+ display_string = ebc;
+ }
+#endif
+
+ return display_string;
+}
+#endif /* unused */
+
+/* UTF-8 to local */
+char *utf8_to_local_string(utf8_string, escape_all)
+ ZCONST char *utf8_string;
+ int escape_all;
+{
+ zwchar *wide;
+ char *loc = NULL;
+
+ wide = utf8_to_wide_string( utf8_string);
+
+ /* 2022-07-25 SMS, et al. CVE-2022-0530 */
+ if (wide != NULL)
+ {
+ loc = wide_to_local_string( wide, escape_all);
+ free( wide);
+ }
+
+ return loc;
+}
+
+#if 0 /* currently unused */
+/* convert multi-byte character string to wide character string */
+zwchar *local_to_wide_string(local_string)
+ ZCONST char *local_string;
+{
+ int wsize;
+ wchar_t *wc_string;
+ zwchar *wide_string;
+
+ /* for now try to convert as string - fails if a bad char in string */
+ wsize = mbstowcs(NULL, local_string, strlen(local_string) + 1);
+ if (wsize == (size_t)-1) {
+ /* could not convert */
+ return NULL;
+ }
+
+ /* convert it */
+ if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) {
+ return NULL;
+ }
+ wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1);
+ wc_string[wsize] = (wchar_t) 0;
+
+ /* in case wchar_t is not zwchar */
+ if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) {
+ return NULL;
+ }
+ for (wsize = 0; wide_string[wsize] = (zwchar)wc_string[wsize]; wsize++) ;
+ wide_string[wsize] = (zwchar) 0;
+ free(wc_string);
+
+ return wide_string;
+}
+
+
+/* convert wide string to UTF-8 */
+char *wide_to_utf8_string(wide_string)
+ ZCONST zwchar *wide_string;
+{
+ int mbcount;
+ char *utf8_string;
+
+ /* get size of utf8 string */
+ mbcount = ucs4_string_to_utf8(wide_string, NULL, 0);
+ if (mbcount == -1)
+ return NULL;
+ if ((utf8_string = (char *) malloc(mbcount + 1)) == NULL) {
+ return NULL;
+ }
+ mbcount = ucs4_string_to_utf8(wide_string, utf8_string, mbcount + 1);
+ if (mbcount == -1)
+ return NULL;
+
+ return utf8_string;
+}
+#endif /* unused */
+
+/* convert UTF-8 string to wide string */
+zwchar *utf8_to_wide_string(utf8_string)
+ ZCONST char *utf8_string;
+{
+ int wcount;
+ zwchar *wide_string;
+
+ wcount = utf8_to_ucs4_string(utf8_string, NULL, 0);
+ if (wcount == -1)
+ return NULL;
+ if ((wide_string = (zwchar *) malloc((wcount + 1) * sizeof(zwchar)))
+ == NULL) {
+ return NULL;
+ }
+ wcount = utf8_to_ucs4_string(utf8_string, wide_string, wcount + 1);
+
+ return wide_string;
+}
+
+#endif /* UNICODE_WCHAR */
+#endif /* UNICODE_SUPPORT */
+
+
+
+
+
+#ifdef USE_EF_UT_TIME
+
+#ifdef IZ_HAVE_UXUIDGID
+static int read_ux3_value(dbuf, uidgid_sz, p_uidgid)
+ ZCONST uch *dbuf; /* buffer a uid or gid value */
+ unsigned uidgid_sz; /* size of uid/gid value */
+ ulg *p_uidgid; /* return storage: uid or gid value */
+{
+ zusz_t uidgid64;
+
+ switch (uidgid_sz) {
+ case 2:
+ *p_uidgid = (ulg)makeword(dbuf);
+ break;
+ case 4:
+ *p_uidgid = (ulg)makelong(dbuf);
+ break;
+ case 8:
+ uidgid64 = makeint64(dbuf);
+#ifndef LARGE_FILE_SUPPORT
+ if (uidgid64 == (zusz_t)0xffffffffL)
+ return FALSE;
+#endif
+ *p_uidgid = (ulg)uidgid64;
+ if ((zusz_t)(*p_uidgid) != uidgid64)
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+#endif /* IZ_HAVE_UXUIDGID */
+
+
+/*******************************/
+/* Function ef_scan_for_izux() */
+/*******************************/
+
+unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
+ z_utim, z_uidgid)
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+ int ef_is_c; /* flag indicating "is central extra field" */
+ ulg dos_mdatetime; /* last_mod_file_date_time in DOS format */
+ iztimes *z_utim; /* return storage: atime, mtime, ctime */
+ ulg *z_uidgid; /* return storage: uid and gid */
+{
+ unsigned flags = 0;
+ unsigned eb_id;
+ unsigned eb_len;
+ int have_new_type_eb = 0;
+ long i_time; /* buffer for Unix style 32-bit integer time value */
+#ifdef TIME_T_TYPE_DOUBLE
+ int ut_in_archive_sgn = 0;
+#else
+ int ut_zip_unzip_compatible = FALSE;
+#endif
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for EF_TIME, EF_IZUNIX2, EF_IZUNIX, or
+ EF_PKUNIX blocks containing Unix-style time_t (GMT) values for the entry's
+ access, creation, and modification time.
+ If a valid block is found, the time stamps are copied to the iztimes
+ structure (provided the z_utim pointer is not NULL).
+ If a IZUNIX2 block is found or the IZUNIX block contains UID/GID fields,
+ and the z_uidgid array pointer is valid (!= NULL), the owner info is
+ transfered as well.
+ The presence of an EF_TIME or EF_IZUNIX2 block results in ignoring all
+ data from probably present obsolete EF_IZUNIX blocks.
+ If multiple blocks of the same type are found, only the information from
+ the last block is used.
+ The return value is a combination of the EF_TIME Flags field with an
+ additional flag bit indicating the presence of valid UID/GID info,
+ or 0 in case of failure.
+ ---------------------------------------------------------------------------*/
+
+ if (ef_len == 0 || ef_buf == NULL || (z_utim == 0 && z_uidgid == NULL))
+ return 0;
+
+ TTrace((stderr,"\nef_scan_for_izux: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ TTrace((stderr,
+ "ef_scan_for_izux: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id) {
+ case EF_TIME:
+ flags &= ~0x0ff; /* ignore previous IZUNIX or EF_TIME fields */
+ have_new_type_eb = 1;
+ if ( eb_len >= EB_UT_MINLEN && z_utim != NULL) {
+ unsigned eb_idx = EB_UT_TIME1;
+ TTrace((stderr,"ef_scan_for_izux: found TIME extra field\n"));
+ flags |= (ef_buf[EB_HEADSIZE+EB_UT_FLAGS] & 0x0ff);
+ if ((flags & EB_UT_FL_MTIME)) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ eb_idx += 4;
+ TTrace((stderr," UT e.f. modification time = %ld\n",
+ i_time));
+
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (dos_mdatetime == DOSTIME_MINIMUM) {
+ ut_in_archive_sgn = -1;
+ z_utim->mtime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+ ut_in_archive_sgn = 1;
+ z_utim->mtime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ ut_in_archive_sgn = 0;
+ /* cannot determine sign of mtime;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UT modtime range error; ignore e.f.!\n"));
+ break; /* stop scanning this field */
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_in_archive_sgn = 0;
+ z_utim->mtime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ ut_zip_unzip_compatible =
+ ((time_t)0x80000000L < (time_t)0L)
+ ? (dos_mdatetime == DOSTIME_MINIMUM)
+ : (dos_mdatetime >= DOSTIME_2038_01_18);
+ if (!ut_zip_unzip_compatible) {
+ /* UnZip interprets mtime differently than Zip;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UT modtime range error; ignore e.f.!\n"));
+ break; /* stop scanning this field */
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_zip_unzip_compatible = FALSE;
+ }
+ z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_MTIME;
+ TTrace((stderr," UT e.f. truncated; no modtime\n"));
+ }
+ }
+ if (ef_is_c) {
+ break; /* central version of TIME field ends here */
+ }
+
+ if (flags & EB_UT_FL_ATIME) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ eb_idx += 4;
+ TTrace((stderr," UT e.f. access time = %ld\n",
+ i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->atime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->atime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UT access time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible) {
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UT access time range error: skip time!\n"));
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_ATIME;
+ }
+ }
+ if (flags & EB_UT_FL_CTIME) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ TTrace((stderr," UT e.f. creation time = %ld\n",
+ i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->ctime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->ctime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_CTIME;
+ TTrace((stderr,
+ " UT creation time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->ctime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible) {
+ flags &= ~EB_UT_FL_CTIME;
+ TTrace((stderr,
+ " UT creation time range error: skip time!\n"));
+ } else {
+ z_utim->ctime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_CTIME;
+ }
+ }
+ }
+ break;
+
+ case EF_IZUNIX2:
+ if (have_new_type_eb == 0) { /* (< 1) */
+ have_new_type_eb = 1;
+ }
+ if (have_new_type_eb <= 1) {
+ /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
+ flags &= 0x0ff;
+ }
+#ifdef IZ_HAVE_UXUIDGID
+ if (have_new_type_eb > 1)
+ break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
+ if (eb_len == EB_UX2_MINLEN && z_uidgid != NULL) {
+ z_uidgid[0] = (ulg)makeword((EB_HEADSIZE+EB_UX2_UID) + ef_buf);
+ z_uidgid[1] = (ulg)makeword((EB_HEADSIZE+EB_UX2_GID) + ef_buf);
+ flags |= EB_UX2_VALID; /* signal success */
+ }
+#endif
+ break;
+
+ case EF_IZUNIX3:
+ /* new 3rd generation Unix ef */
+ have_new_type_eb = 2;
+
+ /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
+ flags &= 0x0ff;
+ /*
+ Version 1 byte version of this extra field, currently 1
+ UIDSize 1 byte Size of UID field
+ UID Variable UID for this entry
+ GIDSize 1 byte Size of GID field
+ GID Variable GID for this entry
+ */
+
+#ifdef IZ_HAVE_UXUIDGID
+ if ((eb_len >= EB_UX3_MINLEN)
+ && (z_uidgid != NULL)
+ && ((*((EB_HEADSIZE + 0) + ef_buf) == 1)))
+ /* only know about version 1 */
+ {
+ uch uid_size;
+ uch gid_size;
+
+ uid_size = *((EB_HEADSIZE + 1) + ef_buf);
+ gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
+
+ if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+ uid_size, &z_uidgid[0])
+ &&
+ read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
+ gid_size, &z_uidgid[1]) )
+ {
+ flags |= EB_UX2_VALID; /* signal success */
+ }
+ }
+#endif /* IZ_HAVE_UXUIDGID */
+ break;
+
+ case EF_IZUNIX:
+ case EF_PKUNIX: /* PKUNIX e.f. layout is identical to IZUNIX */
+ if (eb_len >= EB_UX_MINLEN) {
+ TTrace((stderr,"ef_scan_for_izux: found %s extra field\n",
+ (eb_id == EF_IZUNIX ? "IZUNIX" : "PKUNIX")));
+ if (have_new_type_eb > 0) {
+ break; /* Ignore IZUNIX extra field block ! */
+ }
+ if (z_utim != NULL) {
+ flags |= (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
+ i_time = (long)makelong((EB_HEADSIZE+EB_UX_MTIME)+ef_buf);
+ TTrace((stderr," Unix EF modtime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (dos_mdatetime == DOSTIME_MINIMUM) {
+ ut_in_archive_sgn = -1;
+ z_utim->mtime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+ ut_in_archive_sgn = 1;
+ z_utim->mtime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ ut_in_archive_sgn = 0;
+ /* cannot determine sign of mtime;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UX modtime range error: ignore e.f.!\n"));
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_in_archive_sgn = 0;
+ z_utim->mtime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ ut_zip_unzip_compatible =
+ ((time_t)0x80000000L < (time_t)0L)
+ ? (dos_mdatetime == DOSTIME_MINIMUM)
+ : (dos_mdatetime >= DOSTIME_2038_01_18);
+ if (!ut_zip_unzip_compatible) {
+ /* UnZip interpretes mtime differently than Zip;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UX modtime range error: ignore e.f.!\n"));
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_zip_unzip_compatible = FALSE;
+ }
+ z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ i_time = (long)makelong((EB_HEADSIZE+EB_UX_ATIME)+ef_buf);
+ TTrace((stderr," Unix EF actime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->atime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->atime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else if (flags & 0x0ff) {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UX access time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible && (flags & 0x0ff)) {
+ /* atime not in range of UnZip's time_t */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UX access time range error: skip time!\n"));
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ }
+#ifdef IZ_HAVE_UXUIDGID
+ if (eb_len >= EB_UX_FULLSIZE && z_uidgid != NULL) {
+ z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX_UID) + ef_buf);
+ z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX_GID) + ef_buf);
+ flags |= EB_UX2_VALID;
+ }
+#endif /* IZ_HAVE_UXUIDGID */
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return flags;
+}
+
+#endif /* USE_EF_UT_TIME */
+
+
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+
+#define SPARKID_2 0x30435241 /* = "ARC0" */
+
+/*******************************/
+/* Function getRISCOSexfield() */
+/*******************************/
+
+zvoid *getRISCOSexfield(ef_buf, ef_len)
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for a Acorn SPARK filetype ef-block.
+ If a valid block is found, the function returns a pointer to the start
+ of the SPARK_EF block in the extra field buffer. Otherwise, a NULL
+ pointer is returned.
+ ---------------------------------------------------------------------------*/
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return NULL;
+
+ Trace((stderr,"\ngetRISCOSexfield: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "getRISCOSexfield: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ if (eb_id == EF_SPARK && (eb_len == 24 || eb_len == 20)) {
+ if (makelong(EB_HEADSIZE + ef_buf) == SPARKID_2) {
+ /* Return a pointer to the valid SPARK filetype ef block */
+ return (zvoid *)ef_buf;
+ }
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return NULL;
+}
+
+#endif /* (RISCOS || ACORN_FTYPE_NFS) */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/configure
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/configure (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/configure (revision 5)
@@ -0,0 +1,669 @@
+:
+#!/bin/sh -x
+# The above : is necessary on some buggy systems.
+
+# configure: Guess values for system-dependent variables
+# Output the flag definitions to the file "flags".
+# Parameters: $1 = $(CC), $2 = $(CFLAGS), $3 = $(IZ_BZIP2)
+# To construct unzip automatically using this file, type
+# "make -f unix/Makefile generic".
+# If this fails, then type "make list" to get a list of special targets.
+
+trap "rm -f conftest* core a.out; exit 1" 1 2 3 15
+
+CC=${1-cc}
+CFLAGS=${2}
+CFLAGSR=${CFLAGS}
+IZ_BZIP2=${3}
+CFLAGS="${CFLAGS} -I. -DUNIX"
+LFLAGS1=""
+LFLAGS2="-s"
+LN="ln -s"
+
+CFLAGS_OPT=''
+CFLAGS_BZ=''
+BZLF=''
+
+echo "Check C compiler operation"
+cat > conftest.c << _EOF_
+int main()
+{
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c
+status=$?
+if test $status -ne 0; then
+ echo ''
+ echo "C compiler \"${CC}\" does not work as expected."
+ echo "Failing command was: $CC $CFLAGS -c conftest.c"
+ exit $status
+else
+ echo ' Ok'
+fi
+
+echo 'Check C compiler type (optimization options)'
+# Sun C?
+cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __SUNPRO_C
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+if test $? -eq 0; then
+ CFLAGS_OPT='-xO3'
+ echo " Sun C ($CFLAGS_OPT)"
+else
+ # Tru64 DEC/Compaq/HP C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __DECC
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ CFLAGS_OPT='-O3'
+ echo " DEC C ($CFLAGS_OPT)"
+ else
+ # HP-UX HP C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifdef __GNUC__
+ bad code
+#endif
+#ifndef __hpux
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ # HP-UX, not GCC. Lame bundled or real ANSI compiler?
+ CFLAGS_OPT_TRY="+O3 +Onolimit"
+ $CC $CFLAGS $CFLAGS_OPT_TRY -c conftest.c 2>&1 | \
+ grep '(Bundled)' > /dev/null
+ if test $? -ne 0; then
+ CFLAGS_OPT="$CFLAGS_OPT_TRY"
+ echo " HP-UX ANSI C ($CFLAGS_OPT)"
+ else
+ echo ' HP-UX Bundled C (no opt)'
+ fi
+ else
+ # GNU C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __GNUC__
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ CFLAGS_OPT='-O3'
+ echo " GNU C ($CFLAGS_OPT)"
+ # Special Mac OS X shared library "ld" option?
+ if test ` uname -s 2> /dev/null ` = 'Darwin'; then
+ lf='-Wl,-search_paths_first'
+ $CC $CFLAGS $lf conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ BZLF=${lf}
+ fi
+ rm -f conftest
+ fi
+ else
+ CFLAGS_OPT='-O'
+ echo " Other-unknown C ($CFLAGS_OPT)"
+ fi
+ fi
+ fi
+fi
+
+# optimization flags
+if test -n "${CFLAGS_OPT}"; then
+ CFLAGSR="${CFLAGSR} ${CFLAGS_OPT}"
+ CFLAGS_BZ="${CFLAGS_BZ} ${CFLAGS_OPT}"
+fi
+
+echo Check for the C preprocessor
+# on SVR4, cc -E does not produce correct assembler files. Need /lib/cpp.
+CPP="${CC} -E"
+# solaris as(1) needs -P, maybe others as well ?
+[ -f /usr/ccs/lib/cpp ] && CPP="/usr/ccs/lib/cpp -P"
+[ -f /usr/lib/cpp ] && CPP=/usr/lib/cpp
+[ -f /lib/cpp ] && CPP=/lib/cpp
+[ -f /usr/bin/cpp ] && CPP=/usr/bin/cpp
+[ -f /xenix ] && CPP="${CC} -E"
+[ -f /lynx.os ] && CPP="${CC} -E"
+
+echo "#include <stdio.h>" > conftest.c
+$CPP conftest.c >/dev/null 2>/dev/null || CPP="${CC} -E"
+
+echo Check if we can use asm code
+CRC32OA=""
+if eval "$CPP crc_i386.S > _crc_i386.s 2>/dev/null"; then
+ if test ! -s _crc_i386.s || grep error < _crc_i386.s > /dev/null; then
+ :
+ elif eval "$CC -c _crc_i386.s >/dev/null 2>/dev/null" && [ -f _crc_i386.o ]; then
+ CFLAGSR="${CFLAGSR} -DASM_CRC"
+ CRC32OA="crc_gcc.o"
+ echo "int foo() { return 0;}" > conftest.c
+ $CC -c conftest.c >/dev/null 2>/dev/null
+ echo Check if compiler generates underlines
+ nm conftest.o | grep "(^|[^_])foo" >/dev/null 2>/dev/null
+ [ $? -eq 0 ] && CPP="${CPP} -DNO_UNDERLINE"
+ fi
+fi
+rm -f _crc_i386.s _crc_i386.o
+
+# ANSI options for compilers that don't have __STDC__ defined by default
+# Currently HPUX, pyramid, Dynix, AIX, OSF/1 and ultrix
+
+echo Check for ANSI options
+cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __STDC__
+ forget it
+#endif
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ for OPT in "-Aa -D_HPUX_SOURCE" -Xa -qlanglvl=ansi -std1 -std
+ do
+ $CC $CFLAGS $OPT -c conftest.c > /dev/null 2>/dev/null
+ [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} ${OPT}" && break
+ done
+fi
+
+echo Check for prototypes
+echo "int main(int argc, char *argv[]) { return 0; }" > conftest.c
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_PROTO"
+
+# const check currently handles mips cc and non ANSI compilers.
+# does it need more ?
+echo Check the handling of const
+cat > conftest.c << _EOF_
+typedef int charset[2];
+int main()
+{
+ const charset x;
+ const char *foo;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_CONST"
+
+echo Check for time_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+#include <time.h>
+int main()
+{
+ time_t t;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_TIME_T"
+
+echo Check for size_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+int main()
+{
+ size_t s;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_SIZE_T"
+
+echo Check for off_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+int main()
+{
+ off_t s;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_OFF_T"
+
+# Added 11/4/2003 EG
+# Revised 8/12/04 EG
+# Now we set the 64-bit file environment and check the size of off_t
+echo Check for Large File Support
+cat > conftest.c << _EOF_
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+int main()
+{
+ off_t offset;
+ struct stat s;
+ /* see if have 64-bit off_t */
+ if (sizeof(offset) < 8)
+ return 1;
+ printf(" off_t is %d bytes\n", sizeof(off_t));
+ /* see if have 64-bit stat */
+ if (sizeof(s.st_size) < 8) {
+ printf(" s.st_size is %d bytes\n", sizeof(s.st_size));
+ return 2;
+ }
+ return 3;
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo -- no Large File Support
+else
+# run it
+ ./conftest
+ r=$?
+ if [ $r -eq 1 ]; then
+ echo -- no Large File Support - no 64-bit off_t
+ elif [ $r -eq 2 ]; then
+ echo -- no Large File Support - no 64-bit stat
+ elif [ $r -eq 3 ]; then
+ echo -- yes we have Large File Support!
+ CFLAGSR="${CFLAGSR} -DLARGE_FILE_SUPPORT"
+ else
+ echo -- no Large File Support - conftest returned $r
+ fi
+fi
+
+# Added 11/24/2005 EG
+# Check for wide char for Unicode support
+echo Check for wide char support
+cat > conftest.c << _EOF_
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+int main()
+{
+ size_t wsize;
+ wchar_t *wide_string;
+
+ if ((wide_string = (wchar_t *)malloc(4 * sizeof(wchar_t))) == NULL) {
+ return 0;
+ }
+ /* get wide string */
+ wsize = mbstowcs(wide_string, "foo", 3);
+ wide_string[wsize] = (wchar_t) NULL;
+#ifndef __STDC_ISO_10646__
+ return 1;
+#else
+ printf(" __STDC_ISO_10646__ = %d\n", __STDC_ISO_10646__);
+ return 2;
+#endif
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "-- no Unicode (wchar_t) support"
+else
+# have wide char support
+# run it
+ ./conftest
+ r=$?
+ if [ $r -eq 0 ]; then
+ echo -- no Unicode wchar_t support - wchar_t allocation error
+ elif [ $r -eq 1 ]; then
+ echo -- no Unicode support - wchar_t encoding unspecified
+ elif [ $r -eq 2 ]; then
+ echo -- have wchar_t with known UCS encoding - enabling Unicode support!
+ CFLAGSR="${CFLAGSR} -DUNICODE_SUPPORT -DUNICODE_WCHAR"
+ else
+ echo "-- no Unicode (wchar_t) support - conftest returned $r"
+ fi
+fi
+
+echo "Check for setlocale support (needed for UNICODE Native check)"
+cat > conftest.c << _EOF_
+#include <locale.h>
+int main()
+{
+ char *loc = setlocale(LC_CTYPE, "");
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "-- have setlocale, can check for charset type"
+ echo "-- - enabling UTF8-native support!"
+ CFLAGSR="${CFLAGSR} -DUNICODE_SUPPORT -DUTF8_MAYBE_NATIVE"
+else
+ echo "-- no Unicode (UTF-8 native) support!"
+ CFLAGSR="${CFLAGSR} -DNO_SETLOCALE"
+fi
+
+# from configure 2.4i (Onno) 12/5/04
+echo Check for gcc no-builtin flag
+# -fno-builtin since version 2
+cat > conftest.c << _EOF_
+int main()
+{
+#if __GNUC__ >= 2
+ return 0;
+#else
+ forget it
+#endif
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -eq 0 ] && BFLAG="-fno-builtin"
+
+# Check for missing functions
+# add NO_'function_name' to flags if missing
+for func in fchmod fchown lchown nl_langinfo
+do
+ echo Check for $func
+ echo "int main(){ $func(); return 0; }" > conftest.c
+ $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null
+ [ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_`echo $func | tr '[a-z]' '[A-Z]'`"
+done
+
+# Check (seriously) for a working lchmod.
+echo 'Check for lchmod'
+temp_file="/tmp/unzip_test_$$"
+temp_link="link_$$"
+( echo '#include <unistd.h>' ; \
+ echo "int main() { lchmod(\"${temp_file}\", 0666); }" \
+) > conftest.c
+ln -s "${temp_link}" "${temp_file}" && \
+ $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null && \
+ ./conftest
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_LCHMOD"
+rm -f "${temp_file}"
+
+echo Check for memset
+echo "int main(){ char k; memset(&k,0,0); return 0; }" > conftest.c
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DZMEM"
+
+echo Check for errno declaration
+cat > conftest.c << _EOF_
+#include <errno.h>
+main()
+{
+ errno = 0;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_ERRNO"
+
+echo Check for directory libraries
+cat > conftest.c << _EOF_
+int main() { return closedir(opendir(".")); }
+_EOF_
+
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ OPT=""
+ for lib in ndir dir ucb bsd BSD PW x dirent
+ do
+ $CC -o conftest conftest.c -l$lib >/dev/null 2>/dev/null
+ [ $? -eq 0 ] && OPT=-l$lib && break
+ done
+ if [ ${OPT} ]; then
+ LFLAGS2="${LFLAGS2} ${OPT}"
+ else
+ CFLAGSR="${CFLAGSR} -DNO_DIR"
+ fi
+fi
+
+# Dynix/ptx 1.3 needed this
+echo Check for readlink
+echo "int main(){ return readlink(); }" > conftest.c
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ $CC -o conftest conftest.c -lseq >/dev/null 2>/dev/null
+ [ $? -eq 0 ] && LFLAGS2="${LFLAGS2} -lseq"
+fi
+
+echo Check for directory include file
+OPT=""
+for inc in dirent.h sys/ndir.h ndir.h sys/dir.h
+do
+ echo "#include <$inc>" > conftest.c
+ $CPP conftest.c > /dev/null 2>/dev/null
+ [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+echo Check for non existent include files
+for inc in stdlib.h stddef.h unistd.h fcntl.h string.h langinfo.h
+do
+ echo "#include <$inc>" > conftest.c
+ $CPP conftest.c >/dev/null 2>/dev/null
+ [ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_`echo $inc | tr '[a-z]./' '[A-Z]__'`"
+done
+
+echo Check for term I/O include file
+OPT=""
+for inc in termios.h termio.h sgtty.h
+do
+ echo "#include <$inc>" > conftest.c
+ $CPP conftest.c > /dev/null 2>/dev/null
+ [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+echo Check for MBCS include files
+OPT=""
+for inc in mbstring.h mbctype.h
+do
+ echo "#include <$inc>" > conftest.c
+ $CPP conftest.c > /dev/null 2>/dev/null
+ [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
+done
+CFLAGSR="${CFLAGSR} ${OPT}"
+
+# Check for MBCS support
+echo Check for MBCS support
+cat > conftest.c << _EOF_
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#ifdef HAVE_MBSTRING_H
+# include <mbstring.h>
+#endif
+int main()
+{
+ char *tst;
+ tst = "Hallo";
+ return mblen(tst, MB_CUR_MAX);
+}
+_EOF_
+# compile it
+$CC ${CFLAGS} ${CFLAGSR} -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "-- no MBCS support"
+ CFLAGSR="${CFLAGSR} -DNO_MBCS"
+else
+#
+ echo "-- have MBCS support"
+ CFLAGSR="${CFLAGSR} -D_MBCS"
+# check for library-supplied functions
+# add FUNCTION_NAME='function_name' to flags if found
+ for func in mbschr mbsrchr
+ do
+ echo Check for MBCS $func
+ echo "int main() { $func(); return 0; }" > conftest.c
+ $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null
+ [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} -D`echo $func | tr '[a-z]' '[A-Z]'`=$func"
+ done
+fi
+
+# needed for AIX (and others ?) when mmap is used
+echo Check for valloc
+cat > conftest.c << _EOF_
+main()
+{
+#ifdef MMAP
+ valloc();
+#endif
+}
+_EOF_
+$CC ${CFLAGS} -c conftest.c > /dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGSR="${CFLAGSR} -DNO_VALLOC"
+
+echo Check for /usr/local/bin and /usr/local/man
+BINDIR=$HOME/bin
+[ -d /usr/local/bin ] && BINDIR=/usr/local/bin
+
+MANDIR=manl
+[ -d /usr/man/manl ] && MANDIR=/usr/man/manl
+[ -d /usr/local/man/manl ] && MANDIR=/usr/local/man/manl
+[ -d /usr/local/man/man1 ] && MANDIR=/usr/local/man/man1
+
+echo Checking for OS specialties
+if [ -f /usr/bin/hostinfo ]; then
+ if /usr/bin/hostinfo | grep NeXT > /dev/null; then
+ CFLAGSR="${CFLAGSR} -posix"
+ LFLAGS1="${LFLAGS1} -posix -object"
+ fi
+# XXX ATT6300, Cray
+elif [ -f /xenix ]; then
+ if uname -p | grep 286 > /dev/null; then
+ CFLAGSR="${CFLAGSR} -LARGE -Mel2 -DMEDIUM_MEM -DWSIZE=16384 -DNO_VOID"
+ LFLAGS1="${LFLAGS1} -LARGE -Mel2"
+ fi
+elif uname -X >/dev/null 2>/dev/null; then
+# SCO shared library check
+ echo "int main() { return 0;}" > conftest.c
+ $CC -o conftest conftest.c -lc_s -nointl >/dev/null 2> /dev/null
+ [ $? -eq 0 ] && LFLAGS2="-lc_s -nointl"
+else
+ SYSTEM=`uname -s 2>/dev/null` || SYSTEM="unknown"
+ echo "int main() { return 0;}" > conftest.c
+ case $SYSTEM in
+ OSF1|ULTRIX)
+ echo Check for -Olimit option
+ $CC ${CFLAGS} -Olimit 1000 -o conftest conftest.c >/dev/null 2>/dev/null
+ [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} -Olimit 1000"
+ ;;
+### HP-UX)
+### echo Check for +Onolimit option
+### $CC ${CFLAGS} +Onolimit -o conftest conftest.c >/dev/null 2>/dev/null
+### [ $? -eq 0 ] && CFLAGSR="${CFLAGSR} +Onolimit"
+### ;;
+### SunOS)
+### CFLAGSR="${CFLAGSR} -D_FILE_OFFSET_BITS=64"
+### ;;
+ esac
+fi
+
+echo Check for symbolic links
+ln -s /dev/null null > /dev/null 2>/dev/null || LN=ln
+
+rm -f a.out conftest.c conftest.o conftest null
+
+
+# bzip2
+
+echo "Check bzip2 support"
+D_USE_BZ2=""
+LIBBZ2=""
+L_BZ2=""
+CC_BZ="${CC}"
+
+if test -n "${IZ_BZIP2}" -a "${IZ_BZIP2}" != "bzip2" ; then
+ echo " Check for bzip2 compiled library in IZ_BZIP2 (${IZ_BZIP2})"
+ if test -f "${IZ_BZIP2}/libbz2.a"; then
+#
+# A bzip2 library built with BZ_NO_STDIO should have an
+# unresolved external, "bz_internal_error". The default,
+# full-function library will not mention it.
+#
+ nm ${IZ_BZIP2}/libbz2.a | grep bz_internal_error > /dev/null
+ if test $? -eq 0; then
+ echo " Found bzip2 BZ_NO_STDIO library, ${IZ_BZIP2}/libbz2.a"
+ if test -f "${IZ_BZIP2}/bzlib.h"; then
+ LIBBZ2="${IZ_BZIP2}/libbz2.a"
+ D_USE_BZ2="-DUSE_BZIP2"
+ L_BZ2="${BZLF} -lbz2"
+ echo "-- Found bzip2 library - linking in bzip2"
+ else
+ echo " ${IZ_BZIP2}/bzlib.h not found"
+ echo "-- Since IZ_BZIP2 defined (!= \"bzip2\"),"
+ echo "-- => skipping OS and bzip2 dir checks."
+ echo "-- NO bzip2 support !"
+ fi
+ else
+ echo " Found bzip2 library, ${IZ_BZIP2}/libbz2.a,"
+ echo " but library not compiled with BZ_NO_STDIO."
+ echo " ERROR: This (default) variant of bzip2 library is NOT"
+ echo " supported with UnZip because of its incompatible"
+ echo " error handling!"
+ echo " Please see the UnZip installation instructions in"
+ echo " the INSTALL text file."
+ echo " Skipping bzip2 support..."
+ fi
+ else
+ echo " ${IZ_BZIP2}/libbz2.a not found"
+ echo "-- Since IZ_BZIP2 defined (!= \"bzip2\"),"
+ echo "-- => skipping OS and bzip2 dir checks."
+ echo "-- NO bzip2 support !"
+ fi
+else
+ echo " Check for bzip2 sources in unzip's bzip2 subdirectory"
+ if test -f "${IZ_BZIP2}/bzlib.c" -a -f "${IZ_BZIP2}/bzlib.h"; then
+ echo "-- Found bzip2 source in ${IZ_BZIP2}/ directory"
+ echo "-- Will try to build bzip2 library from source and link in"
+ LIBBZ2="${IZ_BZIP2}/libbz2.a"
+ D_USE_BZ2="-DUSE_BZIP2"
+ L_BZ2="${BZLF} -lbz2"
+ else
+ echo " Check if OS already has bzip2 library installed"
+ cat > conftest.c << _EOF_
+#include "bzlib.h"
+int main()
+{
+ bz_stream strm;
+ BZ2_bzCompressEnd(&strm);
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -o conftest conftest.c -lbz2 > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ echo "-- OS supports bzip2 - linking in bzip2"
+ D_USE_BZ2="-DUSE_BZIP2"
+ L_BZ2="${BZLF} -lbz2"
+ else
+ echo "-- Either bzlib.h or libbz2.a not found - no bzip2"
+ fi
+ fi
+fi
+
+
+echo CC=\"${CC}\" CF=\"${CFLAGSR} ${D_USE_BZ2}\" CRCA_O=\"${CRC32OA}\" \
+ AS=\"${CC} -c\" LFLAGS1=\"${LFLAGS1}\" LF2=\"${LFLAGS2}\" \
+ CC_BZ=\"${CC_BZ}\" CFLAGS_BZ=\"${CFLAGS_BZ}\" \
+ IZ_BZIP2=\"${IZ_BZIP2}\" D_USE_BZ2=\"${D_USE_BZ2}\" \
+ L_BZ2=\"${L_BZ2}\" LIBBZ2=\"${LIBBZ2}\" > flags
Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/unix/configure
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/unix.c (revision 5)
@@ -0,0 +1,2013 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unix.c
+
+ Unix-specific routines for use with Info-ZIP's UnZip 5.41 and later.
+
+ Contains: readdir()
+ do_wild() <-- generic enough to put in fileio.c?
+ mapattr()
+ mapname()
+ checkdir()
+ mkdir()
+ close_outfile()
+ defer_dir_attribs()
+ set_direc_attribs()
+ stamp_file()
+ version()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#include <iconv.h>
+#include <langinfo.h>
+
+#ifdef SCO_XENIX
+# define SYSNDIR
+#else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
+# if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
+# define DIRENT
+# endif
+#endif
+#if defined(_AIX) || defined(__mpexl)
+# define DIRENT
+#endif
+#ifdef COHERENT
+# if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
+# define DIRENT
+# endif
+#endif
+
+#ifdef _POSIX_VERSION
+# ifndef DIRENT
+# define DIRENT
+# endif
+#endif
+
+#ifdef DIRENT
+# include <dirent.h>
+#else
+# ifdef SYSV
+# ifdef SYSNDIR
+# include <sys/ndir.h>
+# else
+# include <ndir.h>
+# endif
+# else /* !SYSV */
+# ifndef NO_SYSDIR
+# include <sys/dir.h>
+# endif
+# endif /* ?SYSV */
+# ifndef dirent
+# define dirent direct
+# endif
+#endif /* ?DIRENT */
+
+#ifdef SET_DIR_ATTRIB
+typedef struct uxdirattr { /* struct for holding unix style directory */
+ struct uxdirattr *next; /* info until can be sorted and set at end */
+ char *fn; /* filename of directory */
+ union {
+ iztimes t3; /* mtime, atime, ctime */
+ ztimbuf t2; /* modtime, actime */
+ } u;
+ unsigned perms; /* same as min_info.file_attr */
+ int have_uidgid; /* flag */
+ ulg uidgid[2];
+ char fnbuf[1]; /* buffer stub for directory name */
+} uxdirattr;
+#define UxAtt(d) ((uxdirattr *)d) /* typecast shortcut */
+#endif /* SET_DIR_ATTRIB */
+
+#ifdef ACORN_FTYPE_NFS
+/* Acorn bits for NFS filetyping */
+typedef struct {
+ uch ID[2];
+ uch size[2];
+ uch ID_2[4];
+ uch loadaddr[4];
+ uch execaddr[4];
+ uch attr[4];
+} RO_extra_block;
+
+#endif /* ACORN_FTYPE_NFS */
+
+/* static int created_dir; */ /* used in mapname(), checkdir() */
+/* static int renamed_fullpath; */ /* ditto */
+
+static unsigned filtattr OF((__GPRO__ unsigned perms));
+
+
+/*****************************/
+/* Strings used multiple */
+/* times in unix.c */
+/*****************************/
+
+#ifndef MTS
+/* messages of code for setting file/directory attributes */
+static ZCONST char CannotSetItemUidGid[] =
+ "warning: cannot set UID %lu and/or GID %lu for %s\n %s\n";
+static ZCONST char CannotSetUidGid[] =
+ " (warning) cannot set UID %lu and/or GID %lu\n %s";
+static ZCONST char CannotSetItemTimestamps[] =
+ "warning: cannot set modif./access times for %s\n %s\n";
+static ZCONST char CannotSetTimestamps[] =
+ " (warning) cannot set modif./access times\n %s";
+#endif /* !MTS */
+
+
+#ifndef SFX
+#ifdef NO_DIR /* for AT&T 3B1 */
+
+#define opendir(path) fopen(path,"r")
+#define closedir(dir) fclose(dir)
+typedef FILE DIR;
+typedef struct zdir {
+ FILE *dirhandle;
+ struct dirent *entry;
+} DIR
+DIR *opendir OF((ZCONST char *dirspec));
+void closedir OF((DIR *dirp));
+struct dirent *readdir OF((DIR *dirp));
+
+DIR *opendir(dirspec)
+ ZCONST char *dirspec;
+{
+ DIR *dirp;
+
+ if ((dirp = malloc(sizeof(DIR)) != NULL) {
+ if ((dirp->dirhandle = fopen(dirspec, "r")) == NULL) {
+ free(dirp);
+ dirp = NULL;
+ }
+ }
+ return dirp;
+}
+
+void closedir(dirp)
+ DIR *dirp;
+{
+ fclose(dirp->dirhandle);
+ free(dirp);
+}
+
+/*
+ * Apparently originally by Rich Salz.
+ * Cleaned up and modified by James W. Birdsall.
+ */
+struct dirent *readdir(dirp)
+ DIR *dirp;
+{
+
+ if (dirp == NULL)
+ return NULL;
+
+ for (;;)
+ if (fread(&(dirp->entry), sizeof (struct dirent), 1,
+ dirp->dirhandle) == 0)
+ return (struct dirent *)NULL;
+ else if ((dirp->entry).d_ino)
+ return &(dirp->entry);
+
+} /* end function readdir() */
+
+#endif /* NO_DIR */
+
+
+/**********************/
+/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
+/**********************/
+
+char *do_wild(__G__ wildspec)
+ __GDEF
+ ZCONST char *wildspec; /* only used first time on a given dir */
+{
+/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in unxcfg.h:
+ static DIR *wild_dir = (DIR *)NULL;
+ static ZCONST char *wildname;
+ static char *dirname, matchname[FILNAMSIZ];
+ static int notfirstcall=FALSE, have_dirname, dirnamelen;
+*/
+ struct dirent *file;
+
+ /* Even when we're just returning wildspec, we *always* do so in
+ * matchname[]--calling routine is allowed to append four characters
+ * to the returned string, and wildspec may be a pointer to argv[].
+ */
+ if (!G.notfirstcall) { /* first call: must initialize everything */
+ G.notfirstcall = TRUE;
+
+ if (!iswild(wildspec)) {
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ G.have_dirname = FALSE;
+ G.wild_dir = NULL;
+ return G.matchname;
+ }
+
+ /* break the wildspec into a directory part and a wildcard filename */
+ if ((G.wildname = (ZCONST char *)strrchr(wildspec, '/')) == NULL) {
+ G.dirname = ".";
+ G.dirnamelen = 1;
+ G.have_dirname = FALSE;
+ G.wildname = wildspec;
+ } else {
+ ++G.wildname; /* point at character after '/' */
+ G.dirnamelen = G.wildname - wildspec;
+ if ((G.dirname = (char *)malloc(G.dirnamelen+1)) == (char *)NULL) {
+ Info(slide, 0x201, ((char *)slide,
+ "warning: cannot allocate wildcard buffers\n"));
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ return G.matchname; /* but maybe filespec was not a wildcard */
+ }
+ strncpy(G.dirname, wildspec, G.dirnamelen);
+ G.dirname[G.dirnamelen] = '\0'; /* terminate for strcpy below */
+ G.have_dirname = TRUE;
+ }
+
+ if ((G.wild_dir = (zvoid *)opendir(G.dirname)) != (zvoid *)NULL) {
+ while ((file = readdir((DIR *)G.wild_dir)) !=
+ (struct dirent *)NULL) {
+ Trace((stderr, "do_wild: readdir returns %s\n",
+ FnFilter1(file->d_name)));
+ if (file->d_name[0] == '.' && G.wildname[0] != '.')
+ continue; /* Unix: '*' and '?' do not match leading dot */
+ if (match(file->d_name, G.wildname, 0 WISEP) &&/*0=case sens.*/
+ /* skip "." and ".." directory entries */
+ strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
+ Trace((stderr, "do_wild: match() succeeds\n"));
+ if (G.have_dirname) {
+ strcpy(G.matchname, G.dirname);
+ strcpy(G.matchname+G.dirnamelen, file->d_name);
+ } else
+ strcpy(G.matchname, file->d_name);
+ return G.matchname;
+ }
+ }
+ /* if we get to here directory is exhausted, so close it */
+ closedir((DIR *)G.wild_dir);
+ G.wild_dir = (zvoid *)NULL;
+ }
+ Trace((stderr, "do_wild: opendir(%s) returns NULL\n",
+ FnFilter1(G.dirname)));
+
+ /* return the raw wildspec in case that works (e.g., directory not
+ * searchable, but filespec was not wild and file is readable) */
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ return G.matchname;
+ }
+
+ /* last time through, might have failed opendir but returned raw wildspec */
+ if ((DIR *)G.wild_dir == (DIR *)NULL) {
+ G.notfirstcall = FALSE; /* nothing left--reset for new wildspec */
+ if (G.have_dirname)
+ free(G.dirname);
+ return (char *)NULL;
+ }
+
+ /* If we've gotten this far, we've read and matched at least one entry
+ * successfully (in a previous call), so dirname has been copied into
+ * matchname already.
+ */
+ while ((file = readdir((DIR *)G.wild_dir)) != (struct dirent *)NULL) {
+ Trace((stderr, "do_wild: readdir returns %s\n",
+ FnFilter1(file->d_name)));
+ if (file->d_name[0] == '.' && G.wildname[0] != '.')
+ continue; /* Unix: '*' and '?' do not match leading dot */
+ if (match(file->d_name, G.wildname, 0 WISEP)) { /* 0 == case sens. */
+ Trace((stderr, "do_wild: match() succeeds\n"));
+ if (G.have_dirname) {
+ /* strcpy(G.matchname, G.dirname); */
+ strcpy(G.matchname+G.dirnamelen, file->d_name);
+ } else
+ strcpy(G.matchname, file->d_name);
+ return G.matchname;
+ }
+ }
+
+ closedir((DIR *)G.wild_dir); /* at least one entry read; nothing left */
+ G.wild_dir = (zvoid *)NULL;
+ G.notfirstcall = FALSE; /* reset for new wildspec */
+ if (G.have_dirname)
+ free(G.dirname);
+ return (char *)NULL;
+
+} /* end function do_wild() */
+
+#endif /* !SFX */
+
+
+
+
+#ifndef S_ISUID
+# define S_ISUID 0004000 /* set user id on execution */
+#endif
+#ifndef S_ISGID
+# define S_ISGID 0002000 /* set group id on execution */
+#endif
+#ifndef S_ISVTX
+# define S_ISVTX 0001000 /* save swapped text even after use */
+#endif
+
+/************************/
+/* Function filtattr() */
+/************************/
+/* This is used to clear or keep the SUID and SGID bits on file permissions.
+ * It's possible that a file in an archive could have one of these bits set
+ * and, unknown to the person unzipping, could allow others to execute the
+ * file as the user or group. The new option -K bypasses this check.
+ */
+
+static unsigned filtattr(__G__ perms)
+ __GDEF
+ unsigned perms;
+{
+ /* keep setuid/setgid/tacky perms? */
+ if (!uO.K_flag)
+ perms &= ~(S_ISUID | S_ISGID | S_ISVTX);
+
+ return (0xffff & perms);
+} /* end function filtattr() */
+
+
+
+
+
+/**********************/
+/* Function mapattr() */
+/**********************/
+
+int mapattr(__G)
+ __GDEF
+{
+ int r;
+ ulg tmp = G.crec.external_file_attributes;
+
+ G.pInfo->file_attr = 0;
+ /* initialized to 0 for check in "default" branch below... */
+
+ switch (G.pInfo->hostnum) {
+ case AMIGA_:
+ tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
+ G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
+ break;
+ case THEOS_:
+ tmp &= 0xF1FFFFFFL;
+ if ((tmp & 0xF0000000L) != 0x40000000L)
+ tmp &= 0x01FFFFFFL; /* not a dir, mask all ftype bits */
+ else
+ tmp &= 0x41FFFFFFL; /* leave directory bit as set */
+ /* fall through! */
+ case UNIX_:
+ case VMS_:
+ case ACORN_:
+ case ATARI_:
+ case ATHEOS_:
+ case BEOS_:
+ case QDOS_:
+ case TANDEM_:
+ r = FALSE;
+ G.pInfo->file_attr = (unsigned)(tmp >> 16);
+ if (G.pInfo->file_attr == 0 && G.extra_field) {
+ /* Some (non-Info-ZIP) implementations of Zip for Unix and
+ * VMS (and probably others ??) leave 0 in the upper 16-bit
+ * part of the external_file_attributes field. Instead, they
+ * store file permission attributes in some extra field.
+ * As a work-around, we search for the presence of one of
+ * these extra fields and fall back to the MSDOS compatible
+ * part of external_file_attributes if one of the known
+ * e.f. types has been detected.
+ * Later, we might implement extraction of the permission
+ * bits from the VMS extra field. But for now, the work-around
+ * should be sufficient to provide "readable" extracted files.
+ * (For ASI Unix e.f., an experimental remap of the e.f.
+ * mode value IS already provided!)
+ */
+ ush ebID;
+ unsigned ebLen;
+ uch *ef = G.extra_field;
+ unsigned ef_len = G.crec.extra_field_length;
+
+ while (!r && ef_len >= EB_HEADSIZE) {
+ ebID = makeword(ef);
+ ebLen = (unsigned)makeword(ef+EB_LEN);
+ if (ebLen > (ef_len - EB_HEADSIZE))
+ /* discoverd some e.f. inconsistency! */
+ break;
+ switch (ebID) {
+ case EF_ASIUNIX:
+ if (ebLen >= (EB_ASI_MODE+2)) {
+ G.pInfo->file_attr =
+ (unsigned)makeword(ef+(EB_HEADSIZE+EB_ASI_MODE));
+ /* force stop of loop: */
+ ef_len = (ebLen + EB_HEADSIZE);
+ break;
+ }
+ /* else: fall through! */
+ case EF_PKVMS:
+ /* "found nondecypherable e.f. with perm. attr" */
+ r = TRUE;
+ default:
+ break;
+ }
+ ef_len -= (ebLen + EB_HEADSIZE);
+ ef += (ebLen + EB_HEADSIZE);
+ }
+ }
+ if (!r) {
+#ifdef SYMLINKS
+ /* Check if the file is a (POSIX-compatible) symbolic link.
+ * We restrict symlink support to those "made-by" hosts that
+ * are known to support symbolic links.
+ */
+ G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
+ SYMLINK_HOST(G.pInfo->hostnum);
+#endif
+ return 0;
+ }
+ /* fall through! */
+ /* all remaining cases: expand MSDOS read-only bit into write perms */
+ case FS_FAT_:
+ /* PKWARE's PKZip for Unix marks entries as FS_FAT_, but stores the
+ * Unix attributes in the upper 16 bits of the external attributes
+ * field, just like Info-ZIP's Zip for Unix. We try to use that
+ * value, after a check for consistency with the MSDOS attribute
+ * bits (see below).
+ */
+ G.pInfo->file_attr = (unsigned)(tmp >> 16);
+ /* fall through! */
+ case FS_HPFS_:
+ case FS_NTFS_:
+ case MAC_:
+ case TOPS20_:
+ default:
+ /* Ensure that DOS subdir bit is set when the entry's name ends
+ * in a '/'. Some third-party Zip programs fail to set the subdir
+ * bit for directory entries.
+ */
+ if ((tmp & 0x10) == 0) {
+ extent fnlen = strlen(G.filename);
+ if (fnlen > 0 && G.filename[fnlen-1] == '/')
+ tmp |= 0x10;
+ }
+ /* read-only bit --> write perms; subdir bit --> dir exec bit */
+ tmp = !(tmp & 1) << 1 | (tmp & 0x10) >> 4;
+ if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6)) {
+ /* keep previous G.pInfo->file_attr setting, when its "owner"
+ * part appears to be consistent with DOS attribute flags!
+ */
+#ifdef SYMLINKS
+ /* Entries "made by FS_FAT_" could have been zipped on a
+ * system that supports POSIX-style symbolic links.
+ */
+ G.pInfo->symlink = S_ISLNK(G.pInfo->file_attr) &&
+ (G.pInfo->hostnum == FS_FAT_);
+#endif
+ return 0;
+ }
+ G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
+ break;
+ } /* end switch (host-OS-created-by) */
+
+ /* for originating systems with no concept of "group," "other," "system": */
+ umask( (int)(tmp=umask(0)) ); /* apply mask to expanded r/w(/x) perms */
+ G.pInfo->file_attr &= ~tmp;
+
+ return 0;
+
+} /* end function mapattr() */
+
+
+
+
+
+/************************/
+/* Function mapname() */
+/************************/
+
+int mapname(__G__ renamed)
+ __GDEF
+ int renamed;
+/*
+ * returns:
+ * MPN_OK - no problem detected
+ * MPN_INF_TRUNC - caution (truncated filename)
+ * MPN_INF_SKIP - info "skip entry" (dir doesn't exist)
+ * MPN_ERR_SKIP - error -> skip entry
+ * MPN_ERR_TOOLONG - error -> path is too long
+ * MPN_NOMEM - error (memory allocation failed) -> skip entry
+ * [also MPN_VOL_LABEL, MPN_CREATED_DIR]
+ */
+{
+ char pathcomp[FILNAMSIZ]; /* path-component buffer */
+ char *pp, *cp=(char *)NULL; /* character pointers */
+ char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */
+#ifdef ACORN_FTYPE_NFS
+ char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */
+ RO_extra_block *ef_spark; /* pointer Acorn FTYPE ef block */
+#endif
+ int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */
+ int error = MPN_OK;
+ register unsigned workch; /* hold the character being tested */
+
+
+/*---------------------------------------------------------------------------
+ Initialize various pointers and counters and stuff.
+ ---------------------------------------------------------------------------*/
+
+ if (G.pInfo->vollabel)
+ return MPN_VOL_LABEL; /* can't set disk volume labels in Unix */
+
+ /* can create path as long as not just freshening, or if user told us */
+ G.create_dirs = (!uO.fflag || renamed);
+
+ G.created_dir = FALSE; /* not yet */
+
+ /* user gave full pathname: don't prepend rootpath */
+ G.renamed_fullpath = (renamed && (*G.filename == '/'));
+
+ if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
+ return MPN_NOMEM; /* initialize path buffer, unless no memory */
+
+ *pathcomp = '\0'; /* initialize translation buffer */
+ pp = pathcomp; /* point to translation buffer */
+ if (uO.jflag) /* junking directories */
+ cp = (char *)strrchr(G.filename, '/');
+ if (cp == (char *)NULL) /* no '/' or not junking dirs */
+ cp = G.filename; /* point to internal zipfile-member pathname */
+ else
+ ++cp; /* point to start of last component of path */
+
+/*---------------------------------------------------------------------------
+ Begin main loop through characters in filename.
+ ---------------------------------------------------------------------------*/
+
+ while ((workch = (uch)*cp++) != 0) {
+
+ switch (workch) {
+ case '/': /* can assume -j flag not given */
+ *pp = '\0';
+ if (strcmp(pathcomp, ".") == 0) {
+ /* don't bother appending "./" to the path */
+ *pathcomp = '\0';
+ } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {
+ /* "../" dir traversal detected, skip over it */
+ *pathcomp = '\0';
+ killed_ddot = TRUE; /* set "show message" flag */
+ }
+ /* when path component is not empty, append it now */
+ if (*pathcomp != '\0' &&
+ ((error = checkdir(__G__ pathcomp, APPEND_DIR))
+ & MPN_MASK) > MPN_INF_TRUNC)
+ return error;
+ pp = pathcomp; /* reset conversion buffer for next piece */
+ lastsemi = (char *)NULL; /* leave direct. semi-colons alone */
+ break;
+
+#ifdef __CYGWIN__ /* Cygwin runs on Win32, apply FAT/NTFS filename rules */
+ case ':': /* drive spec not stored, so no colon allowed */
+ case '\\': /* '\\' may come as normal filename char (not */
+ case '<': /* dir sep char!) from unix-like file system */
+ case '>': /* no redirection symbols allowed either */
+ case '|': /* no pipe signs allowed */
+ case '"': /* no double quotes allowed */
+ case '?': /* no wildcards allowed */
+ case '*':
+ *pp++ = '_'; /* these rules apply equally to FAT and NTFS */
+ break;
+#endif
+
+ case ';': /* VMS version (or DEC-20 attrib?) */
+ lastsemi = pp;
+ *pp++ = ';'; /* keep for now; remove VMS ";##" */
+ break; /* later, if requested */
+
+#ifdef ACORN_FTYPE_NFS
+ case ',': /* NFS filetype extension */
+ lastcomma = pp;
+ *pp++ = ','; /* keep for now; may need to remove */
+ break; /* later, if requested */
+#endif
+
+#ifdef MTS
+ case ' ': /* change spaces to underscore under */
+ *pp++ = '_'; /* MTS; leave as spaces under Unix */
+ break;
+#endif
+
+ default:
+ /* disable control character filter when requested,
+ * else allow 8-bit characters (e.g. UTF-8) in filenames:
+ */
+ if (uO.cflxflag ||
+ (isprint(workch) || (128 <= workch && workch <= 254)))
+ *pp++ = (char)workch;
+ } /* end switch */
+
+ } /* end while loop */
+
+ /* Show warning when stripping insecure "parent dir" path components */
+ if (killed_ddot && QCOND2) {
+ Info(slide, 0, ((char *)slide,
+ "warning: skipped \"../\" path component(s) in %s\n",
+ FnFilter1(G.filename)));
+ if (!(error & ~MPN_MASK))
+ error = (error & MPN_MASK) | PK_WARN;
+ }
+
+/*---------------------------------------------------------------------------
+ Report if directory was created (and no file to create: filename ended
+ in '/'), check name to be sure it exists, and combine path and name be-
+ fore exiting.
+ ---------------------------------------------------------------------------*/
+
+ if (G.filename[strlen(G.filename) - 1] == '/') {
+ checkdir(__G__ G.filename, GETPATH);
+ if (G.created_dir) {
+ if (QCOND2) {
+ Info(slide, 0, ((char *)slide, " creating: %s\n",
+ FnFilter1(G.filename)));
+ }
+#ifndef NO_CHMOD
+ /* Filter out security-relevant attributes bits. */
+ G.pInfo->file_attr = filtattr(__G__ G.pInfo->file_attr);
+ /* When extracting non-UNIX directories or when extracting
+ * without UID/GID restoration or SGID preservation, any
+ * SGID flag inherited from the parent directory should be
+ * maintained to allow files extracted into this new folder
+ * to inherit the GID setting from the parent directory.
+ */
+ if (G.pInfo->hostnum != UNIX_ || !(uO.X_flag || uO.K_flag)) {
+ /* preserve SGID bit when inherited from parent dir */
+ if (!SSTAT(G.filename, &G.statbuf)) {
+ G.pInfo->file_attr |= G.statbuf.st_mode & S_ISGID;
+ } else {
+ perror("Could not read directory attributes");
+ }
+ }
+
+ /* set approx. dir perms (make sure can still read/write in dir) */
+ if (chmod(G.filename, G.pInfo->file_attr | 0700))
+ perror("chmod (directory attributes) error");
+#endif
+ /* set dir time (note trailing '/') */
+ return (error & ~MPN_MASK) | MPN_CREATED_DIR;
+ }
+ /* dir existed already; don't look for data to extract */
+ return (error & ~MPN_MASK) | MPN_INF_SKIP;
+ }
+
+ *pp = '\0'; /* done with pathcomp: terminate it */
+
+ /* if not saving them, remove VMS version numbers (appended ";###") */
+ if (!uO.V_flag && lastsemi) {
+ pp = lastsemi + 1;
+ while (isdigit((uch)(*pp)))
+ ++pp;
+ if (*pp == '\0') /* only digits between ';' and end: nuke */
+ *lastsemi = '\0';
+ }
+
+ /* On UNIX (and compatible systems), "." and ".." are reserved for
+ * directory navigation and cannot be used as regular file names.
+ * These reserved one-dot and two-dot names are mapped to "_" and "__".
+ */
+ if (strcmp(pathcomp, ".") == 0)
+ *pathcomp = '_';
+ else if (strcmp(pathcomp, "..") == 0)
+ strcpy(pathcomp, "__");
+
+#ifdef ACORN_FTYPE_NFS
+ /* translate Acorn filetype information if asked to do so */
+ if (uO.acorn_nfs_ext &&
+ (ef_spark = (RO_extra_block *)
+ getRISCOSexfield(G.extra_field, G.lrec.extra_field_length))
+ != (RO_extra_block *)NULL)
+ {
+ /* file *must* have a RISC OS extra field */
+ long ft = (long)makelong(ef_spark->loadaddr);
+ /*32-bit*/
+ if (lastcomma) {
+ pp = lastcomma + 1;
+ while (isxdigit((uch)(*pp))) ++pp;
+ if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */
+ }
+ if ((ft & 1<<31)==0) ft=0x000FFD00;
+ sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF);
+ }
+#endif /* ACORN_FTYPE_NFS */
+
+ if (*pathcomp == '\0') {
+ Info(slide, 1, ((char *)slide, "mapname: conversion of %s failed\n",
+ FnFilter1(G.filename)));
+ return (error & ~MPN_MASK) | MPN_ERR_SKIP;
+ }
+
+ checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
+ checkdir(__G__ G.filename, GETPATH);
+
+ return error;
+
+} /* end function mapname() */
+
+
+
+
+#if 0 /*========== NOTES ==========*/
+
+ extract-to dir: a:path/
+ buildpath: path1/path2/ ... (NULL-terminated)
+ pathcomp: filename
+
+ mapname():
+ loop over chars in zipfile member name
+ checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
+ (d:/tmp/unzip/) (disk:[tmp.unzip.)
+ (d:/tmp/unzip/jj/) (disk:[tmp.unzip.jj.)
+ (d:/tmp/unzip/jj/temp/) (disk:[tmp.unzip.jj.temp.)
+ finally add filename itself and check for existence? (could use with rename)
+ (d:/tmp/unzip/jj/temp/msg.outdir) (disk:[tmp.unzip.jj.temp]msg.outdir)
+ checkdir(name, GETPATH) --> copy path to name and free space
+
+#endif /* 0 */
+
+
+
+
+/***********************/
+/* Function checkdir() */
+/***********************/
+
+int checkdir(__G__ pathcomp, flag)
+ __GDEF
+ char *pathcomp;
+ int flag;
+/*
+ * returns:
+ * MPN_OK - no problem detected
+ * MPN_INF_TRUNC - (on APPEND_NAME) truncated filename
+ * MPN_INF_SKIP - path doesn't exist, not allowed to create
+ * MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path
+ * exists and is not a directory, but is supposed to be
+ * MPN_ERR_TOOLONG - path is too long
+ * MPN_NOMEM - can't allocate memory for filename buffers
+ */
+{
+ /* static int rootlen = 0; */ /* length of rootpath */
+ /* static char *rootpath; */ /* user's "extract-to" directory */
+ /* static char *buildpath; */ /* full path (so far) to extracted file */
+ /* static char *end; */ /* pointer to end of buildpath ('\0') */
+
+# define FN_MASK 7
+# define FUNCTION (flag & FN_MASK)
+
+
+
+/*---------------------------------------------------------------------------
+ APPEND_DIR: append the path component to the path being built and check
+ for its existence. If doesn't exist and we are creating directories, do
+ so for this one; else signal success or error as appropriate.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == APPEND_DIR) {
+ int too_long = FALSE;
+#ifdef SHORT_NAMES
+ char *old_end = end;
+#endif
+
+ Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
+ while ((*G.end = *pathcomp++) != '\0')
+ ++G.end;
+#ifdef SHORT_NAMES /* path components restricted to 14 chars, typically */
+ if ((G.end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
+ *(G.end = old_end + FILENAME_MAX) = '\0';
+#endif
+
+ /* GRR: could do better check, see if overrunning buffer as we go:
+ * check end-buildpath after each append, set warning variable if
+ * within 20 of FILNAMSIZ; then if var set, do careful check when
+ * appending. Clear variable when begin new path. */
+
+ /* next check: need to append '/', at least one-char name, '\0' */
+ if ((G.end-G.buildpath) > FILNAMSIZ-3)
+ too_long = TRUE; /* check if extracting dir? */
+ if (SSTAT(G.buildpath, &G.statbuf)) { /* path doesn't exist */
+ if (!G.create_dirs) { /* told not to create (freshening) */
+ free(G.buildpath);
+ return MPN_INF_SKIP; /* path doesn't exist: nothing to do */
+ }
+ if (too_long) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: path too long: %s\n",
+ FnFilter1(G.buildpath)));
+ free(G.buildpath);
+ /* no room for filenames: fatal */
+ return MPN_ERR_TOOLONG;
+ }
+ if (mkdir(G.buildpath, 0777) == -1) { /* create the directory */
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: cannot create %s\n\
+ %s\n\
+ unable to process %s.\n",
+ FnFilter2(G.buildpath),
+ strerror(errno),
+ FnFilter1(G.filename)));
+ free(G.buildpath);
+ /* path didn't exist, tried to create, failed */
+ return MPN_ERR_SKIP;
+ }
+ G.created_dir = TRUE;
+ } else if (!S_ISDIR(G.statbuf.st_mode)) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: %s exists but is not directory\n\
+ unable to process %s.\n",
+ FnFilter2(G.buildpath), FnFilter1(G.filename)));
+ free(G.buildpath);
+ /* path existed but wasn't dir */
+ return MPN_ERR_SKIP;
+ }
+ if (too_long) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: path too long: %s\n", FnFilter1(G.buildpath)));
+ free(G.buildpath);
+ /* no room for filenames: fatal */
+ return MPN_ERR_TOOLONG;
+ }
+ *G.end++ = '/';
+ *G.end = '\0';
+ Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
+ return MPN_OK;
+
+ } /* end if (FUNCTION == APPEND_DIR) */
+
+/*---------------------------------------------------------------------------
+ GETPATH: copy full path to the string pointed at by pathcomp, and free
+ G.buildpath.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == GETPATH) {
+ strcpy(pathcomp, G.buildpath);
+ Trace((stderr, "getting and freeing path [%s]\n",
+ FnFilter1(pathcomp)));
+ free(G.buildpath);
+ G.buildpath = G.end = (char *)NULL;
+ return MPN_OK;
+ }
+
+/*---------------------------------------------------------------------------
+ APPEND_NAME: assume the path component is the filename; append it and
+ return without checking for existence.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == APPEND_NAME) {
+#ifdef SHORT_NAMES
+ char *old_end = end;
+#endif
+
+ Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
+ while ((*G.end = *pathcomp++) != '\0') {
+ ++G.end;
+#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */
+ if ((G.end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
+ *(G.end = old_end + FILENAME_MAX) = '\0';
+#endif
+ if ((G.end-G.buildpath) >= FILNAMSIZ) {
+ *--G.end = '\0';
+ Info(slide, 0x201, ((char *)slide,
+ "checkdir warning: path too long; truncating\n\
+ %s\n -> %s\n",
+ FnFilter1(G.filename), FnFilter2(G.buildpath)));
+ return MPN_INF_TRUNC; /* filename truncated */
+ }
+ }
+ Trace((stderr, "buildpath now = [%s]\n", FnFilter1(G.buildpath)));
+ /* could check for existence here, prompt for new name... */
+ return MPN_OK;
+ }
+
+/*---------------------------------------------------------------------------
+ INIT: allocate and initialize buffer space for the file currently being
+ extracted. If file was renamed with an absolute path, don't prepend the
+ extract-to path.
+ ---------------------------------------------------------------------------*/
+
+/* GRR: for VMS and TOPS-20, add up to 13 to strlen */
+
+ if (FUNCTION == INIT) {
+ Trace((stderr, "initializing buildpath to "));
+#ifdef ACORN_FTYPE_NFS
+ if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+
+ (uO.acorn_nfs_ext ? 5 : 1)))
+#else
+ if ((G.buildpath = (char *)malloc(strlen(G.filename)+G.rootlen+1))
+#endif
+ == (char *)NULL)
+ return MPN_NOMEM;
+ if ((G.rootlen > 0) && !G.renamed_fullpath) {
+ strcpy(G.buildpath, G.rootpath);
+ G.end = G.buildpath + G.rootlen;
+ } else {
+ *G.buildpath = '\0';
+ G.end = G.buildpath;
+ }
+ Trace((stderr, "[%s]\n", FnFilter1(G.buildpath)));
+ return MPN_OK;
+ }
+
+/*---------------------------------------------------------------------------
+ ROOT: if appropriate, store the path in rootpath and create it if
+ necessary; else assume it's a zipfile member and return. This path
+ segment gets used in extracting all members from every zipfile specified
+ on the command line.
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ if (FUNCTION == ROOT) {
+ Trace((stderr, "initializing root path to [%s]\n",
+ FnFilter1(pathcomp)));
+ if (pathcomp == (char *)NULL) {
+ G.rootlen = 0;
+ return MPN_OK;
+ }
+ if (G.rootlen > 0) /* rootpath was already set, nothing to do */
+ return MPN_OK;
+ if ((G.rootlen = strlen(pathcomp)) > 0) {
+ char *tmproot;
+
+ if ((tmproot = (char *)malloc(G.rootlen+2)) == (char *)NULL) {
+ G.rootlen = 0;
+ return MPN_NOMEM;
+ }
+ strcpy(tmproot, pathcomp);
+ if (tmproot[G.rootlen-1] == '/') {
+ tmproot[--G.rootlen] = '\0';
+ }
+ if (G.rootlen > 0 && (SSTAT(tmproot, &G.statbuf) ||
+ !S_ISDIR(G.statbuf.st_mode)))
+ { /* path does not exist */
+ if (!G.create_dirs /* || iswild(tmproot) */ ) {
+ free(tmproot);
+ G.rootlen = 0;
+ /* skip (or treat as stored file) */
+ return MPN_INF_SKIP;
+ }
+ /* create the directory (could add loop here scanning tmproot
+ * to create more than one level, but why really necessary?) */
+ if (mkdir(tmproot, 0777) == -1) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir: cannot create extraction directory: %s\n\
+ %s\n",
+ FnFilter1(tmproot), strerror(errno)));
+ free(tmproot);
+ G.rootlen = 0;
+ /* path didn't exist, tried to create, and failed: */
+ /* file exists, or 2+ subdir levels required */
+ return MPN_ERR_SKIP;
+ }
+ }
+ tmproot[G.rootlen++] = '/';
+ tmproot[G.rootlen] = '\0';
+ if ((G.rootpath = (char *)realloc(tmproot, G.rootlen+1)) == NULL) {
+ free(tmproot);
+ G.rootlen = 0;
+ return MPN_NOMEM;
+ }
+ Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath)));
+ }
+ return MPN_OK;
+ }
+#endif /* !SFX || SFX_EXDIR */
+
+/*---------------------------------------------------------------------------
+ END: free rootpath, immediately prior to program exit.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == END) {
+ Trace((stderr, "freeing rootpath\n"));
+ if (G.rootlen > 0) {
+ free(G.rootpath);
+ G.rootlen = 0;
+ }
+ return MPN_OK;
+ }
+
+ return MPN_INVALID; /* should never reach */
+
+} /* end function checkdir() */
+
+
+
+
+
+#ifdef NO_MKDIR
+
+/********************/
+/* Function mkdir() */
+/********************/
+
+int mkdir(path, mode)
+ ZCONST char *path;
+ int mode; /* ignored */
+/*
+ * returns: 0 - successful
+ * -1 - failed (errno not set, however)
+ */
+{
+ char command[FILNAMSIZ+40]; /* buffer for system() call */
+
+ /* GRR 930416: added single quotes around path to avoid bug with
+ * creating directories with ampersands in name; not yet tested */
+ sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
+ if (system(command))
+ return -1;
+ return 0;
+}
+
+#endif /* NO_MKDIR */
+
+
+
+
+#if (!defined(MTS) || defined(SET_DIR_ATTRIB))
+static int get_extattribs OF((__GPRO__ iztimes *pzt, ulg z_uidgid[2]));
+
+static int get_extattribs(__G__ pzt, z_uidgid)
+ __GDEF
+ iztimes *pzt;
+ ulg z_uidgid[2];
+{
+/*---------------------------------------------------------------------------
+ Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
+ time: adjust base year from 1980 to 1970, do usual conversions from
+ yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
+ light savings time differences. If we have a Unix extra field, however,
+ we're laughing: both mtime and atime are ours. On the other hand, we
+ then have to check for restoration of UID/GID.
+ ---------------------------------------------------------------------------*/
+ int have_uidgid_flg;
+ unsigned eb_izux_flg;
+
+ eb_izux_flg = (G.extra_field ? ef_scan_for_izux(G.extra_field,
+ G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
+#ifdef IZ_CHECK_TZ
+ (G.tz_is_valid ? pzt : NULL),
+#else
+ pzt,
+#endif
+ z_uidgid) : 0);
+ if (eb_izux_flg & EB_UT_FL_MTIME) {
+ TTrace((stderr, "\nget_extattribs: Unix e.f. modif. time = %ld\n",
+ pzt->mtime));
+ } else {
+ pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+ }
+ if (eb_izux_flg & EB_UT_FL_ATIME) {
+ TTrace((stderr, "get_extattribs: Unix e.f. access time = %ld\n",
+ pzt->atime));
+ } else {
+ pzt->atime = pzt->mtime;
+ TTrace((stderr, "\nget_extattribs: modification/access times = %ld\n",
+ pzt->mtime));
+ }
+
+ /* if -X option was specified and we have UID/GID info, restore it */
+ have_uidgid_flg =
+#ifdef RESTORE_UIDGID
+ (uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
+#else
+ 0;
+#endif
+ return have_uidgid_flg;
+}
+#endif /* !MTS || SET_DIR_ATTRIB */
+
+
+
+#ifndef MTS
+
+/****************************/
+/* Function CloseError() */
+/***************************/
+
+int CloseError(__G)
+ __GDEF
+{
+ int errval = PK_OK;
+
+ if (fclose(G.outfile) < 0) {
+ switch (errno) {
+ case ENOSPC:
+ /* Do we need this on fileio.c? */
+ Info(slide, 0x4a1, ((char *)slide, "%s: write error (disk full?). Continue? (y/n/^C) ",
+ FnFilter1(G.filename)));
+ fgets(G.answerbuf, 9, stdin);
+ if (*G.answerbuf == 'y') /* stop writing to this file */
+ G.disk_full = 1; /* pass to next */
+ else
+ G.disk_full = 2; /* no: exit program */
+
+ errval = PK_DISK;
+ break;
+
+ default:
+ errval = PK_WARN;
+ }
+ }
+ return errval;
+} /* End of CloseError() */
+
+/****************************/
+/* Function close_outfile() */
+/****************************/
+
+int close_outfile(__G)
+ __GDEF
+{
+ union {
+ iztimes t3; /* mtime, atime, ctime */
+ ztimbuf t2; /* modtime, actime */
+ } zt;
+ ulg z_uidgid[2];
+ int have_uidgid_flg;
+ int errval = PK_OK;
+
+ have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
+
+/*---------------------------------------------------------------------------
+ If symbolic links are supported, allocate storage for a symlink control
+ structure, put the uncompressed "data" and other required info in it, and
+ add the structure to the "deferred symlinks" chain. Since we know it's a
+ symbolic link to start with, we shouldn't have to worry about overflowing
+ unsigned ints with unsigned longs.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SYMLINKS
+ if (G.symlnk) {
+ extent ucsize = (extent)G.lrec.ucsize;
+# ifdef SET_SYMLINK_ATTRIBS
+ extent attribsize = sizeof(unsigned) +
+ (have_uidgid_flg ? sizeof(z_uidgid) : 0);
+# else
+ extent attribsize = 0;
+# endif
+ /* size of the symlink entry is the sum of
+ * (struct size (includes 1st '\0') + 1 additional trailing '\0'),
+ * system specific attribute data size (might be 0),
+ * and the lengths of name and link target.
+ */
+ extent slnk_entrysize = (sizeof(slinkentry) + 1) + attribsize +
+ ucsize + strlen(G.filename);
+ slinkentry *slnk_entry;
+
+ if (slnk_entrysize < ucsize) {
+ Info(slide, 0x201, ((char *)slide,
+ "warning: symbolic link (%s) failed: mem alloc overflow\n",
+ FnFilter1(G.filename)));
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
+ }
+
+ if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
+ Info(slide, 0x201, ((char *)slide,
+ "warning: symbolic link (%s) failed: no mem\n",
+ FnFilter1(G.filename)));
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
+ }
+ slnk_entry->next = NULL;
+ slnk_entry->targetlen = ucsize;
+ slnk_entry->attriblen = attribsize;
+# ifdef SET_SYMLINK_ATTRIBS
+ memcpy(slnk_entry->buf, &(G.pInfo->file_attr),
+ sizeof(unsigned));
+ if (have_uidgid_flg)
+ memcpy(slnk_entry->buf + 4, z_uidgid, sizeof(z_uidgid));
+# endif
+ slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen;
+ slnk_entry->fname = slnk_entry->target + ucsize + 1;
+ strcpy(slnk_entry->fname, G.filename);
+
+ /* move back to the start of the file to re-read the "link data" */
+ rewind(G.outfile);
+
+ if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
+ {
+ Info(slide, 0x201, ((char *)slide,
+ "warning: symbolic link (%s) failed\n",
+ FnFilter1(G.filename)));
+ free(slnk_entry);
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
+ }
+ errval = CloseError(G.outfile, G.filename); /* close "link" file for good... */
+ slnk_entry->target[ucsize] = '\0';
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, "-> %s ",
+ FnFilter1(slnk_entry->target)));
+ /* add this symlink record to the list of deferred symlinks */
+ if (G.slink_last != NULL)
+ G.slink_last->next = slnk_entry;
+ else
+ G.slink_head = slnk_entry;
+ G.slink_last = slnk_entry;
+ return errval;
+ }
+#endif /* SYMLINKS */
+
+#ifdef QLZIP
+ if (G.extra_field) {
+ static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len));
+
+ qlfix(__G__ G.extra_field, G.lrec.extra_field_length);
+ }
+#endif
+
+#if (defined(NO_FCHOWN))
+ errval = CloseError(G.outfile, G.filename);
+#endif
+
+ /* if -X option was specified and we have UID/GID info, restore it */
+ if (have_uidgid_flg
+ /* check that both uid and gid values fit into their data sizes */
+ && ((ulg)(uid_t)(z_uidgid[0]) == z_uidgid[0])
+ && ((ulg)(gid_t)(z_uidgid[1]) == z_uidgid[1])) {
+ TTrace((stderr, "close_outfile: restoring Unix UID/GID info\n"));
+#if (defined(NO_FCHOWN))
+ if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
+#else
+ if (fchown(fileno(G.outfile), (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
+#endif
+ {
+ if (uO.qflag)
+ Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+ z_uidgid[0], z_uidgid[1], FnFilter1(G.filename),
+ strerror(errno)));
+ else
+ Info(slide, 0x201, ((char *)slide, CannotSetUidGid,
+ z_uidgid[0], z_uidgid[1], strerror(errno)));
+ }
+ }
+
+#if (!defined(NO_FCHOWN) && defined(NO_FCHMOD))
+ errval = CloseError(G.outfile, G.filename);
+#endif
+
+#if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
+/*---------------------------------------------------------------------------
+ Change the file permissions from default ones to those stored in the
+ zipfile.
+ ---------------------------------------------------------------------------*/
+
+ if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
+ perror("fchmod (file attributes) error");
+
+ errval = CloseError(G.outfile, G.filename);
+#endif /* !NO_FCHOWN && !NO_FCHMOD */
+
+ /* skip restoring time stamps on user's request */
+ if (uO.D_flag <= 1) {
+ /* set the file's access and modification times */
+ if (utime(G.filename, &(zt.t2))) {
+ if (uO.qflag)
+ Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
+ FnFilter1(G.filename), strerror(errno)));
+ else
+ Info(slide, 0x201, ((char *)slide, CannotSetTimestamps,
+ strerror(errno)));
+ }
+ }
+
+#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
+/*---------------------------------------------------------------------------
+ Change the file permissions from default ones to those stored in the
+ zipfile.
+ ---------------------------------------------------------------------------*/
+
+#ifndef NO_CHMOD
+ if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr)))
+ perror("chmod (file attributes) error");
+#endif
+#endif /* NO_FCHOWN || NO_FCHMOD */
+
+ return errval;
+} /* end function close_outfile() */
+
+#endif /* !MTS */
+
+
+#if (defined(SYMLINKS) && defined(SET_SYMLINK_ATTRIBS))
+int set_symlnk_attribs(__G__ slnk_entry)
+ __GDEF
+ slinkentry *slnk_entry;
+{
+ if (slnk_entry->attriblen > 0) {
+# if (!defined(NO_LCHOWN))
+ if (slnk_entry->attriblen > sizeof(unsigned)) {
+ ulg *z_uidgid_p = (zvoid *)(slnk_entry->buf + sizeof(unsigned));
+ /* check that both uid and gid values fit into their data sizes */
+ if (((ulg)(uid_t)(z_uidgid_p[0]) == z_uidgid_p[0]) &&
+ ((ulg)(gid_t)(z_uidgid_p[1]) == z_uidgid_p[1])) {
+ TTrace((stderr,
+ "set_symlnk_attribs: restoring Unix UID/GID info for\n\
+ %s\n",
+ FnFilter1(slnk_entry->fname)));
+ if (lchown(slnk_entry->fname,
+ (uid_t)z_uidgid_p[0], (gid_t)z_uidgid_p[1]))
+ {
+ Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+ z_uidgid_p[0], z_uidgid_p[1], FnFilter1(slnk_entry->fname),
+ strerror(errno)));
+ }
+ }
+ }
+# endif /* !NO_LCHOWN */
+# if (!defined(NO_LCHMOD))
+ TTrace((stderr,
+ "set_symlnk_attribs: restoring Unix attributes for\n %s\n",
+ FnFilter1(slnk_entry->fname)));
+ if (lchmod(slnk_entry->fname,
+ filtattr(__G__ *(unsigned *)(zvoid *)slnk_entry->buf)))
+ perror("lchmod (file attributes) error");
+# endif /* !NO_LCHMOD */
+ }
+ /* currently, no error propagation... */
+ return PK_OK;
+} /* end function set_symlnk_attribs() */
+#endif /* SYMLINKS && SET_SYMLINK_ATTRIBS */
+
+
+#ifdef SET_DIR_ATTRIB
+/* messages of code for setting directory attributes */
+# ifndef NO_CHMOD
+ static ZCONST char DirlistChmodFailed[] =
+ "warning: cannot set permissions for %s\n %s\n";
+# endif
+
+
+int defer_dir_attribs(__G__ pd)
+ __GDEF
+ direntry **pd;
+{
+ uxdirattr *d_entry;
+
+ d_entry = (uxdirattr *)malloc(sizeof(uxdirattr) + strlen(G.filename));
+ *pd = (direntry *)d_entry;
+ if (d_entry == (uxdirattr *)NULL) {
+ return PK_MEM;
+ }
+ d_entry->fn = d_entry->fnbuf;
+ strcpy(d_entry->fn, G.filename);
+
+ d_entry->perms = G.pInfo->file_attr;
+
+ d_entry->have_uidgid = get_extattribs(__G__ &(d_entry->u.t3),
+ d_entry->uidgid);
+ return PK_OK;
+} /* end function defer_dir_attribs() */
+
+
+int set_direc_attribs(__G__ d)
+ __GDEF
+ direntry *d;
+{
+ int errval = PK_OK;
+
+ if (UxAtt(d)->have_uidgid &&
+ /* check that both uid and gid values fit into their data sizes */
+ ((ulg)(uid_t)(UxAtt(d)->uidgid[0]) == UxAtt(d)->uidgid[0]) &&
+ ((ulg)(gid_t)(UxAtt(d)->uidgid[1]) == UxAtt(d)->uidgid[1]) &&
+ chown(UxAtt(d)->fn, (uid_t)UxAtt(d)->uidgid[0],
+ (gid_t)UxAtt(d)->uidgid[1]))
+ {
+ Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
+ UxAtt(d)->uidgid[0], UxAtt(d)->uidgid[1], FnFilter1(d->fn),
+ strerror(errno)));
+ if (!errval)
+ errval = PK_WARN;
+ }
+ /* Skip restoring directory time stamps on user' request. */
+ if (uO.D_flag <= 0) {
+ /* restore directory timestamps */
+ if (utime(d->fn, &UxAtt(d)->u.t2)) {
+ Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
+ FnFilter1(d->fn), strerror(errno)));
+ if (!errval)
+ errval = PK_WARN;
+ }
+ }
+#ifndef NO_CHMOD
+ if (chmod(d->fn, UxAtt(d)->perms)) {
+ Info(slide, 0x201, ((char *)slide, DirlistChmodFailed,
+ FnFilter1(d->fn), strerror(errno)));
+ if (!errval)
+ errval = PK_WARN;
+ }
+#endif /* !NO_CHMOD */
+ return errval;
+} /* end function set_direc_attribs() */
+
+#endif /* SET_DIR_ATTRIB */
+
+
+
+
+#ifdef TIMESTAMP
+
+/***************************/
+/* Function stamp_file() */
+/***************************/
+
+int stamp_file(fname, modtime)
+ ZCONST char *fname;
+ time_t modtime;
+{
+ ztimbuf tp;
+
+ tp.modtime = tp.actime = modtime;
+ return (utime(fname, &tp));
+
+} /* end function stamp_file() */
+
+#endif /* TIMESTAMP */
+
+
+
+
+#ifndef SFX
+
+/************************/
+/* Function version() */
+/************************/
+
+void version(__G)
+ __GDEF
+{
+#if (defined(__GNUC__) && defined(NX_CURRENT_COMPILER_RELEASE))
+ char cc_namebuf[40];
+ char cc_versbuf[40];
+#else
+#if (defined(__SUNPRO_C))
+ char cc_versbuf[17];
+#else
+#if (defined(__HP_cc) || defined(__IBMC__))
+ char cc_versbuf[25];
+#else
+#if (defined(__DECC_VER))
+ char cc_versbuf[17];
+ int cc_verstyp;
+#else
+#if (defined(CRAY) && defined(_RELEASE))
+ char cc_versbuf[40];
+#endif /* (CRAY && _RELEASE) */
+#endif /* __DECC_VER */
+#endif /* __HP_cc || __IBMC__ */
+#endif /* __SUNPRO_C */
+#endif /* (__GNUC__ && NX_CURRENT_COMPILER_RELEASE) */
+
+#if ((defined(CRAY) || defined(cray)) && defined(_UNICOS))
+ char os_namebuf[40];
+#else
+#if defined(__NetBSD__)
+ char os_namebuf[40];
+#endif
+#endif
+
+ /* Pyramid, NeXT have problems with huge macro expansion, too: no Info() */
+ sprintf((char *)slide, LoadFarString(CompiledWith),
+
+#ifdef __GNUC__
+# ifdef NX_CURRENT_COMPILER_RELEASE
+ (sprintf(cc_namebuf, "NeXT DevKit %d.%02d ",
+ NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100),
+ cc_namebuf),
+ (strlen(__VERSION__) > 8)? "(gcc)" :
+ (sprintf(cc_versbuf, "(gcc %s)", __VERSION__), cc_versbuf),
+# else
+ "gcc ", __VERSION__,
+# endif
+#else
+#if defined(__SUNPRO_C)
+ "Sun C ", (sprintf(cc_versbuf, "version %x", __SUNPRO_C), cc_versbuf),
+#else
+#if (defined(__HP_cc))
+ "HP C ",
+ (((__HP_cc% 100) == 0) ?
+ (sprintf(cc_versbuf, "version A.%02d.%02d",
+ (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100))) :
+ (sprintf(cc_versbuf, "version A.%02d.%02d.%02d",
+ (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100), (__HP_cc% 100))),
+ cc_versbuf),
+#else
+#if (defined(__DECC_VER))
+ "DEC C ",
+ (sprintf(cc_versbuf, "%c%d.%d-%03d",
+ ((cc_verstyp = (__DECC_VER / 10000) % 10) == 6 ? 'T' :
+ (cc_verstyp == 8 ? 'S' : 'V')),
+ __DECC_VER / 10000000,
+ (__DECC_VER % 10000000) / 100000, __DECC_VER % 1000),
+ cc_versbuf),
+#else
+#if defined(CRAY) && defined(_RELEASE)
+ "cc ", (sprintf(cc_versbuf, "version %d", _RELEASE), cc_versbuf),
+#else
+#ifdef __IBMC__
+ "IBM C ",
+ (sprintf(cc_versbuf, "version %d.%d.%d",
+ (__IBMC__ / 100), ((__IBMC__ / 10) % 10), (__IBMC__ % 10)),
+ cc_versbuf),
+#else
+#ifdef __VERSION__
+# ifndef IZ_CC_NAME
+# define IZ_CC_NAME "cc "
+# endif
+ IZ_CC_NAME, __VERSION__
+#else
+# ifndef IZ_CC_NAME
+# define IZ_CC_NAME "cc"
+# endif
+ IZ_CC_NAME, "",
+#endif /* ?__VERSION__ */
+#endif /* ?__IBMC__ */
+#endif /* ?(CRAY && _RELEASE) */
+#endif /* ?__DECC_VER */
+#endif /* ?__HP_cc */
+#endif /* ?__SUNPRO_C */
+#endif /* ?__GNUC__ */
+
+#ifndef IZ_OS_NAME
+# define IZ_OS_NAME "Unix"
+#endif
+ IZ_OS_NAME,
+
+#if defined(sgi) || defined(__sgi)
+ " (Silicon Graphics IRIX)",
+#else
+#ifdef sun
+# ifdef sparc
+# ifdef __SVR4
+ " (Sun SPARC/Solaris)",
+# else /* may or may not be SunOS */
+ " (Sun SPARC)",
+# endif
+# else
+# if defined(sun386) || defined(i386)
+ " (Sun 386i)",
+# else
+# if defined(mc68020) || defined(__mc68020__)
+ " (Sun 3)",
+# else /* mc68010 or mc68000: Sun 2 or earlier */
+ " (Sun 2)",
+# endif
+# endif
+# endif
+#else
+#ifdef __hpux
+ " (HP-UX)",
+#else
+#ifdef __osf__
+ " (DEC OSF/1)",
+#else
+#ifdef _AIX
+ " (IBM AIX)",
+#else
+#ifdef aiws
+ " (IBM RT/AIX)",
+#else
+#if defined(CRAY) || defined(cray)
+# ifdef _UNICOS
+ (sprintf(os_namebuf, " (Cray UNICOS release %d)", _UNICOS), os_namebuf),
+# else
+ " (Cray UNICOS)",
+# endif
+#else
+#if defined(uts) || defined(UTS)
+ " (Amdahl UTS)",
+#else
+#ifdef NeXT
+# ifdef mc68000
+ " (NeXTStep/black)",
+# else
+ " (NeXTStep for Intel)",
+# endif
+#else /* the next dozen or so are somewhat order-dependent */
+#ifdef LINUX
+# ifdef __ELF__
+ " (Linux ELF)",
+# else
+ " (Linux a.out)",
+# endif
+#else
+#ifdef MINIX
+ " (Minix)",
+#else
+#ifdef M_UNIX
+ " (SCO Unix)",
+#else
+#ifdef M_XENIX
+ " (SCO Xenix)",
+#else
+#ifdef __NetBSD__
+# ifdef NetBSD0_8
+ (sprintf(os_namebuf, " (NetBSD 0.8%c)", (char)(NetBSD0_8 - 1 + 'A')),
+ os_namebuf),
+# else
+# ifdef NetBSD0_9
+ (sprintf(os_namebuf, " (NetBSD 0.9%c)", (char)(NetBSD0_9 - 1 + 'A')),
+ os_namebuf),
+# else
+# ifdef NetBSD1_0
+ (sprintf(os_namebuf, " (NetBSD 1.0%c)", (char)(NetBSD1_0 - 1 + 'A')),
+ os_namebuf),
+# else
+ (BSD4_4 == 0.5)? " (NetBSD before 0.9)" : " (NetBSD 1.1 or later)",
+# endif
+# endif
+# endif
+#else
+#ifdef __FreeBSD__
+ (BSD4_4 == 0.5)? " (FreeBSD 1.x)" : " (FreeBSD 2.0 or later)",
+#else
+#ifdef __bsdi__
+ (BSD4_4 == 0.5)? " (BSD/386 1.0)" : " (BSD/386 1.1 or later)",
+#else
+#ifdef __386BSD__
+ (BSD4_4 == 1)? " (386BSD, post-4.4 release)" : " (386BSD)",
+#else
+#ifdef __CYGWIN__
+ " (Cygwin)",
+#else
+#if defined(i686) || defined(__i686) || defined(__i686__)
+ " (Intel 686)",
+#else
+#if defined(i586) || defined(__i586) || defined(__i586__)
+ " (Intel 586)",
+#else
+#if defined(i486) || defined(__i486) || defined(__i486__)
+ " (Intel 486)",
+#else
+#if defined(i386) || defined(__i386) || defined(__i386__)
+ " (Intel 386)",
+#else
+#ifdef pyr
+ " (Pyramid)",
+#else
+#ifdef ultrix
+# ifdef mips
+ " (DEC/MIPS)",
+# else
+# ifdef vax
+ " (DEC/VAX)",
+# else /* __alpha? */
+ " (DEC/Alpha)",
+# endif
+# endif
+#else
+#ifdef gould
+ " (Gould)",
+#else
+#ifdef MTS
+ " (MTS)",
+#else
+#ifdef __convexc__
+ " (Convex)",
+#else
+#ifdef __QNX__
+ " (QNX 4)",
+#else
+#ifdef __QNXNTO__
+ " (QNX Neutrino)",
+#else
+#ifdef Lynx
+ " (LynxOS)",
+#else
+#ifdef __APPLE__
+# ifdef __i386__
+ " Mac OS X Intel i32",
+# else
+# ifdef __ppc__
+ " Mac OS X PowerPC",
+# else
+# ifdef __ppc64__
+ " Mac OS X PowerPC64",
+# else
+ " Mac OS X",
+# endif /* __ppc64__ */
+# endif /* __ppc__ */
+# endif /* __i386__ */
+#else
+ "",
+#endif /* Apple */
+#endif /* Lynx */
+#endif /* QNX Neutrino */
+#endif /* QNX 4 */
+#endif /* Convex */
+#endif /* MTS */
+#endif /* Gould */
+#endif /* DEC */
+#endif /* Pyramid */
+#endif /* 386 */
+#endif /* 486 */
+#endif /* 586 */
+#endif /* 686 */
+#endif /* Cygwin */
+#endif /* 386BSD */
+#endif /* BSDI BSD/386 */
+#endif /* NetBSD */
+#endif /* FreeBSD */
+#endif /* SCO Xenix */
+#endif /* SCO Unix */
+#endif /* Minix */
+#endif /* Linux */
+#endif /* NeXT */
+#endif /* Amdahl */
+#endif /* Cray */
+#endif /* RT/AIX */
+#endif /* AIX */
+#endif /* OSF/1 */
+#endif /* HP-UX */
+#endif /* Sun */
+#endif /* SGI */
+
+#ifdef __DATE__
+ " on ", __DATE__
+#else
+ "", ""
+#endif
+ );
+
+ (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
+
+} /* end function version() */
+
+#endif /* !SFX */
+
+
+
+
+#ifdef QLZIP
+
+struct qdirect {
+ long d_length __attribute__ ((packed)); /* file length */
+ unsigned char d_access __attribute__ ((packed)); /* file access type */
+ unsigned char d_type __attribute__ ((packed)); /* file type */
+ long d_datalen __attribute__ ((packed)); /* data length */
+ long d_reserved __attribute__ ((packed));/* Unused */
+ short d_szname __attribute__ ((packed)); /* size of name */
+ char d_name[36] __attribute__ ((packed));/* name area */
+ long d_update __attribute__ ((packed)); /* last update */
+ long d_refdate __attribute__ ((packed));
+ long d_backup __attribute__ ((packed)); /* EOD */
+};
+
+#define LONGID "QDOS02"
+#define EXTRALEN (sizeof(struct qdirect) + 8)
+#define JBLONGID "QZHD"
+#define JBEXTRALEN (sizeof(jbextra) - 4 * sizeof(char))
+
+typedef struct {
+ char eb_header[4] __attribute__ ((packed)); /* place_holder */
+ char longid[8] __attribute__ ((packed));
+ struct qdirect header __attribute__ ((packed));
+} qdosextra;
+
+typedef struct {
+ char eb_header[4]; /* place_holder */
+ char longid[4];
+ struct qdirect header;
+} jbextra;
+
+
+
+/* The following two functions SH() and LG() convert big-endian short
+ * and long numbers into native byte order. They are some kind of
+ * counterpart to the generic UnZip's makeword() and makelong() functions.
+ */
+static ush SH(ush val)
+{
+ uch swapbuf[2];
+
+ swapbuf[1] = (uch)(val & 0xff);
+ swapbuf[0] = (uch)(val >> 8);
+ return (*(ush *)swapbuf);
+}
+
+
+
+static ulg LG(ulg val)
+{
+ /* convert the big-endian unsigned long number `val' to the machine
+ * dependent representation
+ */
+ ush swapbuf[2];
+
+ swapbuf[1] = SH((ush)(val & 0xffff));
+ swapbuf[0] = SH((ush)(val >> 16));
+ return (*(ulg *)swapbuf);
+}
+
+
+
+static void qlfix(__G__ ef_ptr, ef_len)
+ __GDEF
+ uch *ef_ptr;
+ unsigned ef_len;
+{
+ while (ef_len >= EB_HEADSIZE)
+ {
+ unsigned eb_id = makeword(EB_ID + ef_ptr);
+ unsigned eb_len = makeword(EB_LEN + ef_ptr);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "qlfix: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id) {
+ case EF_QDOS:
+ {
+ struct _ntc_
+ {
+ long id;
+ long dlen;
+ } ntc;
+ long dlen = 0;
+
+ qdosextra *extra = (qdosextra *)ef_ptr;
+ jbextra *jbp = (jbextra *)ef_ptr;
+
+ if (!strncmp(extra->longid, LONGID, strlen(LONGID)))
+ {
+ if (eb_len != EXTRALEN)
+ if (uO.qflag)
+ Info(slide, 0x201, ((char *)slide,
+ "warning: invalid length in Qdos field for %s\n",
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x201, ((char *)slide,
+ "warning: invalid length in Qdos field"));
+
+ if (extra->header.d_type)
+ {
+ dlen = extra->header.d_datalen;
+ }
+ }
+
+ if (!strncmp(jbp->longid, JBLONGID, strlen(JBLONGID)))
+ {
+ if (eb_len != JBEXTRALEN)
+ if (uO.qflag)
+ Info(slide, 0x201, ((char *)slide,
+ "warning: invalid length in QZ field for %s\n",
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x201, ((char *)slide,
+ "warning: invalid length in QZ field"));
+ if (jbp->header.d_type)
+ {
+ dlen = jbp->header.d_datalen;
+ }
+ }
+
+ if ((long)LG(dlen) > 0)
+ {
+ zfseeko(G.outfile, -8, SEEK_END);
+ fread(&ntc, 8, 1, G.outfile);
+ if (ntc.id != *(long *)"XTcc")
+ {
+ ntc.id = *(long *)"XTcc";
+ ntc.dlen = dlen;
+ fwrite (&ntc, 8, 1, G.outfile);
+ }
+ Info(slide, 0x201, ((char *)slide, "QData = %d", LG(dlen)));
+ }
+ return; /* finished, cancel further extra field scanning */
+ }
+
+ default:
+ Trace((stderr,"qlfix: unknown extra field block, ID=%d\n",
+ eb_id));
+ }
+
+ /* Skip this extra field block */
+ ef_ptr += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+}
+#endif /* QLZIP */
+
+
+typedef struct {
+ char *local_charset;
+ char *archive_charset;
+} CHARSET_MAP;
+
+/* A mapping of local <-> archive charsets used by default to convert filenames
+ * of DOS/Windows Zip archives. Currently very basic. */
+static CHARSET_MAP dos_charset_map[] = {
+ { "ANSI_X3.4-1968", "CP850" },
+ { "ISO-8859-1", "CP850" },
+ { "CP1252", "CP850" },
+ { "UTF-8", "CP866" },
+ { "KOI8-R", "CP866" },
+ { "KOI8-U", "CP866" },
+ { "ISO-8859-5", "CP866" }
+};
+
+char OEM_CP[MAX_CP_NAME] = "";
+char ISO_CP[MAX_CP_NAME] = "";
+
+/* Try to guess the default value of OEM_CP based on the current locale.
+ * ISO_CP is left alone for now. */
+void init_conversion_charsets()
+{
+ const char *local_charset;
+ int i;
+
+ /* Make a guess only if OEM_CP not already set. */
+ if(*OEM_CP == '\0') {
+ local_charset = nl_langinfo(CODESET);
+ for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
+ if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
+ strncpy(OEM_CP, dos_charset_map[i].archive_charset,
+ MAX_CP_NAME - 1);
+
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
+ break;
+ }
+ }
+}
+
+/* Convert a string from one encoding to the current locale using iconv().
+ * Be as non-intrusive as possible. If error is encountered during covertion
+ * just leave the string intact. */
+static void charset_to_intern(char *string, char *from_charset)
+{
+ iconv_t cd;
+ char *s,*d, *buf;
+ size_t slen, dlen, buflen;
+ const char *local_charset;
+
+ if(*from_charset == '\0')
+ return;
+
+ buf = NULL;
+ local_charset = nl_langinfo(CODESET);
+
+ if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
+ return;
+
+ slen = strlen(string);
+ s = string;
+
+ /* Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
+ * as this function also gets called with G.outbuf in fileio.c
+ */
+ buflen = FILNAMSIZ;
+ if (OUTBUFSIZ + 1 < FILNAMSIZ)
+ {
+ buflen = OUTBUFSIZ + 1;
+ }
+
+ d = buf = malloc(buflen);
+ if(!d)
+ goto cleanup;
+
+ bzero(buf,buflen);
+ dlen = buflen - 1;
+
+ if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
+ goto cleanup;
+ strncpy(string, buf, buflen);
+
+ cleanup:
+ free(buf);
+ iconv_close(cd);
+}
+
+/* Convert a string from OEM_CP to the current locale charset. */
+inline void oem_intern(char *string)
+{
+ charset_to_intern(string, OEM_CP);
+}
+
+/* Convert a string from ISO_CP to the current locale charset. */
+inline void iso_intern(char *string)
+{
+ charset_to_intern(string, ISO_CP);
+}
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix/unxcfg.h (revision 5)
@@ -0,0 +1,256 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+ Unix specific configuration section:
+ ---------------------------------------------------------------------------*/
+
+#ifndef __unxcfg_h
+#define __unxcfg_h
+
+
+/* LARGE FILE SUPPORT - 10/6/04 EG */
+/* This needs to be set before the includes so they set the right sizes */
+
+#if (defined(NO_LARGE_FILE_SUPPORT) && defined(LARGE_FILE_SUPPORT))
+# undef LARGE_FILE_SUPPORT
+#endif
+
+/* Automatically set ZIP64_SUPPORT if LFS */
+#ifdef LARGE_FILE_SUPPORT
+# if (!defined(NO_ZIP64_SUPPORT) && !defined(ZIP64_SUPPORT))
+# define ZIP64_SUPPORT
+# endif
+#endif
+
+/* NO_ZIP64_SUPPORT takes preceedence over ZIP64_SUPPORT */
+#if defined(NO_ZIP64_SUPPORT) && defined(ZIP64_SUPPORT)
+# undef ZIP64_SUPPORT
+#endif
+
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+ /* The following Large File Summit (LFS) defines turn on large file support
+ on Linux (probably 2.4 or later kernel) and many other unixen */
+
+ /* These have to be before any include that sets types so the large file
+ versions of the types are set in the includes */
+
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+# define __USE_LARGEFILE64
+#endif /* LARGE_FILE_SUPPORT */
+
+
+#include <sys/types.h> /* off_t, time_t, dev_t, ... */
+#include <sys/stat.h>
+
+#ifdef NO_OFF_T
+ typedef long zoff_t;
+#else
+ typedef off_t zoff_t;
+#endif
+#define ZOFF_T_DEFINED
+typedef struct stat z_stat;
+#define Z_STAT_DEFINED
+
+#ifndef COHERENT
+# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
+#else /* COHERENT */
+# ifdef _I386
+# include <fcntl.h> /* Coherent 4.0.x, Mark Williams C */
+# else
+# include <sys/fcntl.h> /* Coherent 3.10, Mark Williams C */
+# endif
+# define SHORT_SYMS
+# ifndef __COHERENT__ /* Coherent 4.2 has tzset() */
+# define tzset settz
+# endif
+#endif /* ?COHERENT */
+
+#ifndef NO_PARAM_H
+# ifdef NGROUPS_MAX
+# undef NGROUPS_MAX /* SCO bug: defined again in <sys/param.h> */
+# endif
+# ifdef BSD
+# define TEMP_BSD /* may be defined again in <sys/param.h> */
+# undef BSD
+# endif
+# include <sys/param.h> /* conflict with <sys/types.h>, some systems? */
+# ifdef TEMP_BSD
+# undef TEMP_BSD
+# ifndef BSD
+# define BSD
+# endif
+# endif
+#endif /* !NO_PARAM_H */
+
+#ifdef __osf__
+# define DIRENT
+# ifdef BSD
+# undef BSD
+# endif
+#endif /* __osf__ */
+
+#ifdef __CYGWIN__
+# include <unistd.h>
+# define DIRENT
+# define HAVE_TERMIOS_H
+# ifndef timezone
+# define timezone _timezone
+# endif
+#endif
+
+#ifdef BSD
+# include <sys/time.h>
+# include <sys/timeb.h>
+# if (defined(_AIX) || defined(__GLIBC__) || defined(__GNU__))
+# include <time.h>
+# endif
+#else
+# include <time.h>
+ struct tm *gmtime(), *localtime();
+#endif
+
+#if (defined(BSD4_4) || (defined(SYSV) && defined(MODERN)))
+# include <unistd.h> /* this includes utime.h on SGIs */
+# if (defined(BSD4_4) || defined(linux) || defined(__GLIBC__))
+# include <utime.h>
+# define GOT_UTIMBUF
+# endif
+# if (!defined(GOT_UTIMBUF) && (defined(__hpux) || defined(__SUNPRO_C)))
+# include <utime.h>
+# define GOT_UTIMBUF
+# endif
+# if (!defined(GOT_UTIMBUF) && defined(__GNU__))
+# include <utime.h>
+# define GOT_UTIMBUF
+# endif
+#endif
+#if (defined(__DGUX__) && !defined(GOT_UTIMBUF))
+ /* DG/UX requires this because of a non-standard struct utimebuf */
+# include <utime.h>
+# define GOT_UTIMBUF
+#endif
+
+#if (defined(V7) || defined(pyr_bsd))
+# define strchr index
+# define strrchr rindex
+#endif
+#ifdef V7
+# define O_RDONLY 0
+# define O_WRONLY 1
+# define O_RDWR 2
+#endif
+
+#if defined(NO_UNICODE_SUPPORT) && defined(UNICODE_SUPPORT)
+ /* disable Unicode (UTF-8) support when requested */
+# undef UNICODE_SUPPORT
+#endif
+
+#if (defined(_MBCS) && defined(NO_MBCS))
+ /* disable MBCS support when requested */
+# undef _MBCS
+#endif
+
+#if (!defined(NO_SETLOCALE) && !defined(_MBCS))
+# if (!defined(UNICODE_SUPPORT) || !defined(UTF8_MAYBE_NATIVE))
+ /* enable setlocale here, unless this happens later for UTF-8 and/or
+ * MBCS support */
+# include <locale.h>
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale) setlocale(category, locale)
+# endif
+# endif
+#endif
+#ifndef NO_SETLOCALE
+# if (!defined(NO_WORKING_ISPRINT) && !defined(HAVE_WORKING_ISPRINT))
+ /* enable "enhanced" unprintable chars detection in fnfilter() */
+# define HAVE_WORKING_ISPRINT
+# endif
+#endif
+
+#ifdef MINIX
+# include <stdio.h>
+#endif
+#if (!defined(HAVE_STRNICMP) & !defined(NO_STRNICMP))
+# define NO_STRNICMP
+#endif
+#ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY /* GRR: customize with locale.h somehow? */
+#endif
+#define lenEOL 1
+#ifdef EBCDIC
+# define PutNativeEOL *q++ = '\n';
+#else
+# define PutNativeEOL *q++ = native(LF);
+#endif
+#define SCREENSIZE(ttrows, ttcols) screensize(ttrows, ttcols)
+#define SCREENWIDTH 80
+#define SCREENLWRAP 1
+#define USE_EF_UT_TIME
+#if (!defined(NO_LCHOWN) || !defined(NO_LCHMOD))
+# define SET_SYMLINK_ATTRIBS
+#endif
+#ifdef MTS
+# ifdef SET_DIR_ATTRIB
+# undef SET_DIR_ATTRIB
+# endif
+#else /* !MTS */
+# define SET_DIR_ATTRIB
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP)) /* GRR 970513 */
+# define TIMESTAMP
+# endif
+# define RESTORE_UIDGID
+#endif /* ?MTS */
+
+/* Static variables that we have to add to Uz_Globs: */
+#define SYSTEM_SPECIFIC_GLOBALS \
+ int created_dir, renamed_fullpath;\
+ char *rootpath, *buildpath, *end;\
+ ZCONST char *wildname;\
+ char *dirname, matchname[FILNAMSIZ];\
+ int rootlen, have_dirname, dirnamelen, notfirstcall;\
+ zvoid *wild_dir;
+
+/* created_dir, and renamed_fullpath are used by both mapname() and */
+/* checkdir(). */
+/* rootlen, rootpath, buildpath and end are used by checkdir(). */
+/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
+/* and notfirstcall are used by do_wild(). */
+
+
+#define MAX_CP_NAME 25 + 1
+
+#ifdef SETLOCALE
+# undef SETLOCALE
+#endif
+#define SETLOCALE(category, locale) setlocale(category, locale)
+#include <locale.h>
+
+#ifdef _ISO_INTERN
+# undef _ISO_INTERN
+#endif
+#define _ISO_INTERN(str1) iso_intern(str1)
+
+#ifdef _OEM_INTERN
+# undef _OEM_INTERN
+#endif
+#ifndef IZ_OEM2ISO_ARRAY
+# define IZ_OEM2ISO_ARRAY
+#endif
+#define _OEM_INTERN(str1) oem_intern(str1)
+
+void iso_intern(char *);
+void oem_intern(char *);
+void init_conversion_charsets(void);
+
+#endif /* !__unxcfg_h */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unix
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unix (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unix (revision 5)
Property changes on: unzip/create-6.0-slackware-patch/unzip60-new/unix
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch/unzip60-new/unzip.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unzip.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unzip.c (revision 5)
@@ -0,0 +1,2747 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unzip.c
+
+ UnZip - a zipfile extraction utility. See below for make instructions, or
+ read the comments in Makefile and the various Contents files for more de-
+ tailed explanations. To report a bug, submit a *complete* description via
+ //www.info-zip.org/zip-bug.html; include machine type, operating system and
+ version, compiler and version, and reasonably detailed error messages or
+ problem report. To join Info-ZIP, see the instructions in README.
+
+ UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
+ which in turn was almost a complete rewrite of version 3.x. For a detailed
+ revision history, see UnzpHist.zip at quest.jpl.nasa.gov. For a list of
+ the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
+ distribution.
+
+ UnZip 6.0 adds support for archives larger than 4 GiB using the Zip64
+ extensions as well as support for Unicode information embedded per the
+ latest zip standard additions.
+
+ ---------------------------------------------------------------------------
+
+ [from original zipinfo.c]
+
+ This program reads great gobs of totally nifty information, including the
+ central directory stuff, from ZIP archives ("zipfiles" for short). It
+ started as just a testbed for fooling with zipfiles, but at this point it
+ is actually a useful utility. It also became the basis for the rewrite of
+ UnZip (3.16 -> 4.0), using the central directory for processing rather than
+ the individual (local) file headers.
+
+ As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
+ If the executable is named "unzip" (or "unzip.exe", depending), it behaves
+ like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
+ ZipInfo. The ZipInfo behavior may also be triggered by use of unzip's -Z
+ option; for example, "unzip -Z [zipinfo_options] archive.zip".
+
+ Another dandy product from your buddies at Newtware!
+
+ Author: Greg Roelofs, newt@pobox.com, http://pobox.com/~newt/
+ 23 August 1990 -> April 1997
+
+ ---------------------------------------------------------------------------
+
+ Version: unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
+ Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
+ AtheOS, BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos
+ and TOPS-20.
+
+ Copyrights: see accompanying file "LICENSE" in UnZip source distribution.
+ (This software is free but NOT IN THE PUBLIC DOMAIN.)
+
+ ---------------------------------------------------------------------------*/
+
+
+
+#define __UNZIP_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h" /* includes, typedefs, macros, prototypes, etc. */
+#include "crypt.h"
+#include "unzvers.h"
+
+#ifndef WINDLL /* The WINDLL port uses windll/windll.c instead... */
+
+/***************************/
+/* Local type declarations */
+/***************************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+typedef struct _sign_info
+ {
+ struct _sign_info *previous;
+ void (*sighandler)(int);
+ int sigtype;
+ } savsigs_info;
+#endif
+
+/*******************/
+/* Local Functions */
+/*******************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
+ int signal_type, void (*newhandler)(int)));
+#endif
+#ifndef SFX
+static void help_extended OF((__GPRO));
+static void show_version_info OF((__GPRO));
+#endif
+
+
+/*************/
+/* Constants */
+/*************/
+
+#include "consts.h" /* all constant global variables are in here */
+ /* (non-constant globals were moved to globals.c) */
+
+/* constant local variables: */
+
+#ifndef SFX
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
+ static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
+ static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
+ static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
+#ifdef RISCOS
+ static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
+#endif /* RISCOS */
+ static ZCONST char Far NoMemEnvArguments[] =
+ "envargs: cannot get memory for arguments";
+#endif /* !_WIN32_WCE */
+ static ZCONST char Far CmdLineParamTooLong[] =
+ "error: command line parameter #%d exceeds internal size limit\n";
+#endif /* !SFX */
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+ static ZCONST char Far CantSaveSigHandler[] =
+ "error: cannot save signal handler settings\n";
+#endif
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ static ZCONST char Far NotExtracting[] =
+ "caution: not extracting; -d ignored\n";
+ static ZCONST char Far MustGiveExdir[] =
+ "error: must specify directory to which to extract with -d option\n";
+ static ZCONST char Far OnlyOneExdir[] =
+ "error: -d option used more than once (only one exdir allowed)\n";
+#endif
+#if (defined(UNICODE_SUPPORT) && !defined(UNICODE_WCHAR))
+ static ZCONST char Far UTF8EscapeUnSupp[] =
+ "warning: -U \"escape all non-ASCII UTF-8 chars\" is not supported\n";
+#endif
+
+#if CRYPT
+ static ZCONST char Far MustGivePasswd[] =
+ "error: must give decryption password with -P option\n";
+#endif
+
+#ifndef SFX
+ static ZCONST char Far Zfirst[] =
+ "error: -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
+#endif
+static ZCONST char Far InvalidOptionsMsg[] = "error:\
+ -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
+static ZCONST char Far IgnoreOOptionMsg[] =
+ "caution: both -n and -o specified; ignoring -o\n";
+
+/* usage() strings */
+#ifndef SFX
+#ifdef VMS
+ static ZCONST char Far Example3[] = "vms.c";
+ static ZCONST char Far Example2[] = " unzip \"-V\" foo \"Bar\"\
+ (Quote names to preserve case, unless SET PROC/PARS=EXT)\n";
+#else /* !VMS */
+ static ZCONST char Far Example3[] = "ReadMe";
+#ifdef RISCOS
+ static ZCONST char Far Example2[] =
+" unzip foo -d RAM:$ => extract all files from foo into RAMDisc\n";
+#else /* !RISCOS */
+#if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
+ static ZCONST char Far Example2[] =
+ ""; /* no room: too many local3[] items */
+#else /* !OS2 */
+#ifdef MACOS
+ static ZCONST char Far Example2[] = ""; /* not needed */
+#else /* !MACOS */
+ static ZCONST char Far Example2[] = " \
+ unzip -p foo | more => send contents of foo.zip via pipe into program more\n";
+#endif /* ?MACOS */
+#endif /* ?OS2 */
+#endif /* ?RISCOS */
+#endif /* ?VMS */
+
+/* local1[]: command options */
+#if defined(TIMESTAMP)
+ static ZCONST char Far local1[] =
+ " -T timestamp archive to latest";
+#else /* !TIMESTAMP */
+ static ZCONST char Far local1[] = "";
+#endif /* ?TIMESTAMP */
+
+/* local2[] and local3[]: modifier options */
+#ifdef DOS_FLX_H68_OS2_W32
+#ifdef FLEXOS
+ static ZCONST char Far local2[] = "";
+#else
+ static ZCONST char Far local2[] =
+ " -$ label removables (-$$ => fixed disks)";
+#endif
+#ifdef OS2
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -X restore ACLs if supported -s spaces in filenames => '_'\n\
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -X restore ACLs if supported -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !OS2 */
+#ifdef WIN32
+#ifdef NTSD_EAS
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -X restore ACLs (-XX => use privileges) -s spaces in filenames => '_'\n\
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -X restore ACLs (-XX => use privileges) -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !NTSD_EAS */
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -M pipe through \"more\" pager \
+ -s spaces in filenames => '_'\n\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#endif /* ?NTSD_EAS */
+#else /* !WIN32 */
+#ifdef MORE
+ static ZCONST char Far local3[] = " -\
+M pipe through \"more\" pager -s spaces in filenames => '_'\n\n";
+#else
+ static ZCONST char Far local3[] = "\
+ -s spaces in filenames => '_'\n";
+#endif
+#endif /* ?WIN32 */
+#endif /* ?OS2 || ?WIN32 */
+#else /* !DOS_FLX_OS2_W32 */
+#ifdef VMS
+ static ZCONST char Far local2[] = " -X restore owner/ACL protection info";
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -Y treat \".nnn\" as \";nnn\" version -2 force ODS2 names\n\
+ --D restore dir (-D: no) timestamps -M pipe through \"more\" pager\n\
+ (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
+\n\n";
+#else
+ static ZCONST char Far local3[] = "\n\
+ -Y treat \".nnn\" as \";nnn\" version -2 force ODS2 names\n\
+ --D restore dir (-D: no) timestamps\n\
+ (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
+\n\n";
+#endif
+#else /* !VMS */
+#ifdef ATH_BEO_UNX
+ static ZCONST char Far local2[] = " -X restore UID/GID info";
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -K keep setuid/setgid/tacky permissions -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\
+ -K keep setuid/setgid/tacky permissions\n";
+#endif
+#else /* !ATH_BEO_UNX */
+#ifdef TANDEM
+ static ZCONST char Far local2[] = "\
+ -X restore Tandem User ID -r remove file extensions\n\
+ -b create 'C' (180) text files ";
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !TANDEM */
+#ifdef AMIGA
+ static ZCONST char Far local2[] = " -N restore comments as filenotes";
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !AMIGA */
+#ifdef MACOS
+ static ZCONST char Far local2[] = " -E show Mac info during extraction";
+ static ZCONST char Far local3[] = " \
+ -i ignore filenames in mac extra info -J junk (ignore) Mac extra info\n\
+\n";
+#else /* !MACOS */
+#ifdef MORE
+ static ZCONST char Far local2[] = " -M pipe through \"more\" pager";
+ static ZCONST char Far local3[] = "\n";
+#else
+ static ZCONST char Far local2[] = ""; /* Atari, Mac, CMS/MVS etc. */
+ static ZCONST char Far local3[] = "";
+#endif
+#endif /* ?MACOS */
+#endif /* ?AMIGA */
+#endif /* ?TANDEM */
+#endif /* ?ATH_BEO_UNX */
+#endif /* ?VMS */
+#endif /* ?DOS_FLX_OS2_W32 */
+#endif /* !SFX */
+
+#ifndef NO_ZIPINFO
+#ifdef VMS
+ static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
+#else
+ static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
+#endif
+
+static ZCONST char Far ZipInfoUsageLine1[] = "\
+ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
+\n\
+List name, date/time, attribute, size, compression method, etc., about files\n\
+in list (excluding those in xlist) contained in the specified .zip archive(s).\
+\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
+ usage: zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
+ or: unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
+
+static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
+ listing-format options: -s short Unix \"ls -l\" format (def.)\n\
+ -1 filenames ONLY, one per line -m medium Unix \"ls -l\" format\n\
+ -2 just filenames but allow -h/-t/-z -l long Unix \"ls -l\" format\n\
+ -v verbose, multi-page format\n";
+
+#ifndef UNIX
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+ -h print header line -t print totals for listed files or for all\n\
+ -z print zipfile comment -T print file times in sortable decimal format\
+\n -C be case-insensitive %s\
+ -x exclude filenames that follow from listing\n";
+#else /* UNIX */
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+ -h print header line -t print totals for listed files or for all\n\
+ -z print zipfile comment %c-T%c print file times in sortable decimal format\
+\n %c-C%c be case-insensitive %s\
+ -x exclude filenames that follow from listing\n\
+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\
+ -I CHARSET specify a character encoding for UNIX and other archives\n";
+#endif /* !UNIX */
+#ifdef MORE
+ static ZCONST char Far ZipInfoUsageLine4[] =
+ " -M page output through built-in \"more\"\n";
+#else /* !MORE */
+ static ZCONST char Far ZipInfoUsageLine4[] = "";
+#endif /* ?MORE */
+#endif /* !NO_ZIPINFO */
+
+#ifdef BETA
+# ifdef VMSCLI
+ /* BetaVersion[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far BetaVersion[] = "%s\
+ THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+# else
+ static ZCONST char Far BetaVersion[] = "%s\
+ THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+# endif
+#endif
+
+#ifdef SFX
+# ifdef VMSCLI
+ /* UnzipSFXBanner[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far UnzipSFXBanner[] =
+# else
+ static ZCONST char Far UnzipSFXBanner[] =
+# endif
+ "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (http://www.info-zip.org).\n";
+# ifdef SFX_EXDIR
+ static ZCONST char Far UnzipSFXOpts[] =
+ "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
+# else
+ static ZCONST char Far UnzipSFXOpts[] =
+ "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
+# endif
+#else /* !SFX */
+ static ZCONST char Far CompileOptions[] =
+ "UnZip special compilation options:\n";
+ static ZCONST char Far CompileOptFormat[] = " %s\n";
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ static ZCONST char Far EnvOptions[] =
+ "\nUnZip and ZipInfo environment options:\n";
+ static ZCONST char Far EnvOptFormat[] = "%16s: %.1024s\n";
+#endif
+ static ZCONST char Far None[] = "[none]";
+# ifdef ACORN_FTYPE_NFS
+ static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
+# endif
+# ifdef ASM_CRC
+ static ZCONST char Far AsmCRC[] = "ASM_CRC";
+# endif
+# ifdef ASM_INFLATECODES
+ static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
+# endif
+# ifdef CHECK_VERSIONS
+ static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
+# endif
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far Copyright_Clean[] =
+ "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
+# endif
+# ifdef DEBUG
+ static ZCONST char Far UDebug[] = "DEBUG";
+# endif
+# ifdef DEBUG_TIME
+ static ZCONST char Far DebugTime[] = "DEBUG_TIME";
+# endif
+# ifdef DLL
+ static ZCONST char Far Dll[] = "DLL";
+# endif
+# ifdef DOSWILD
+ static ZCONST char Far DosWild[] = "DOSWILD";
+# endif
+# ifdef LZW_CLEAN
+ static ZCONST char Far LZW_Clean[] =
+ "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
+# endif
+# ifndef MORE
+ static ZCONST char Far No_More[] = "NO_MORE";
+# endif
+# ifdef NO_ZIPINFO
+ static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
+# endif
+# ifdef NTSD_EAS
+ static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
+# endif
+# if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+ static ZCONST char Far W32NoIZTimeFix[] = "NO_W32TIMES_IZFIX";
+# endif
+# ifdef OLD_THEOS_EXTRA
+ static ZCONST char Far OldTheosExtra[] =
+ "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
+# endif
+# ifdef OS2_EAS
+ static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
+# endif
+# ifdef QLZIP
+ static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
+# endif
+# ifdef REENTRANT
+ static ZCONST char Far Reentrant[] = "REENTRANT";
+# endif
+# ifdef REGARGS
+ static ZCONST char Far RegArgs[] = "REGARGS";
+# endif
+# ifdef RETURN_CODES
+ static ZCONST char Far Return_Codes[] = "RETURN_CODES";
+# endif
+# ifdef SET_DIR_ATTRIB
+ static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
+# endif
+# ifdef SYMLINKS
+ static ZCONST char Far SymLinkSupport[] =
+ "SYMLINKS (symbolic links supported, if RTL and file system permit)";
+# endif
+# ifdef TIMESTAMP
+ static ZCONST char Far TimeStamp[] = "TIMESTAMP";
+# endif
+# ifdef UNIXBACKUP
+ static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
+# endif
+# ifdef USE_EF_UT_TIME
+ static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
+# endif
+# ifndef LZW_CLEAN
+ static ZCONST char Far Use_Unshrink[] =
+ "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
+# endif
+# ifndef COPYRIGHT_CLEAN
+ static ZCONST char Far Use_Smith_Code[] =
+ "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
+# endif
+# ifdef USE_DEFLATE64
+ static ZCONST char Far Use_Deflate64[] =
+ "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
+# endif
+# ifdef UNICODE_SUPPORT
+# ifdef UTF8_MAYBE_NATIVE
+# ifdef UNICODE_WCHAR
+ /* direct native UTF-8 check AND charset transform via wchar_t */
+ static ZCONST char Far Use_Unicode[] =
+ "UNICODE_SUPPORT [wide-chars, char coding: %s] (handle UTF-8 paths)";
+# else
+ /* direct native UTF-8 check, only */
+ static ZCONST char Far Use_Unicode[] =
+ "UNICODE_SUPPORT [char coding: %s] (handle UTF-8 paths)";
+# endif
+ static ZCONST char Far SysChUTF8[] = "UTF-8";
+ static ZCONST char Far SysChOther[] = "other";
+# else /* !UTF8_MAYBE_NATIVE */
+ /* charset transform via wchar_t, no native UTF-8 support */
+ static ZCONST char Far Use_Unicode[] =
+ "UNICODE_SUPPORT [wide-chars] (handle UTF-8 paths)";
+# endif /* ?UTF8_MAYBE_NATIVE */
+# endif /* UNICODE_SUPPORT */
+# ifdef _MBCS
+ static ZCONST char Far Have_MBCS_Support[] =
+ "MBCS-support (multibyte character support, MB_CUR_MAX = %u)";
+# endif
+# ifdef MULT_VOLUME
+ static ZCONST char Far Use_MultiVol[] =
+ "MULT_VOLUME (multi-volume archives supported)";
+# endif
+# ifdef LARGE_FILE_SUPPORT
+ static ZCONST char Far Use_LFS[] =
+ "LARGE_FILE_SUPPORT (large files over 2 GiB supported)";
+# endif
+# ifdef ZIP64_SUPPORT
+ static ZCONST char Far Use_Zip64[] =
+ "ZIP64_SUPPORT (archives using Zip64 for large files supported)";
+# endif
+# if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+# ifdef USE_DJGPP_ENV
+ static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
+# endif
+# ifdef USE_DJGPP_GLOB
+ static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
+# endif
+# endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+# ifdef USE_VFAT
+ static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
+# endif
+# ifdef USE_ZLIB
+ static ZCONST char Far UseZlib[] =
+ "USE_ZLIB (compiled with version %s; using version %s)";
+# endif
+# ifdef USE_BZIP2
+ static ZCONST char Far UseBZip2[] =
+ "USE_BZIP2 (PKZIP 4.6+, using bzip2 lib version %s)";
+# endif
+# ifdef VMS_TEXT_CONV
+ static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
+# endif
+# ifdef VMSCLI
+ static ZCONST char Far VmsCLI[] = "VMSCLI";
+# endif
+# ifdef VMSWILD
+ static ZCONST char Far VmsWild[] = "VMSWILD";
+# endif
+# ifdef WILD_STOP_AT_DIR
+ static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
+# endif
+# if CRYPT
+# ifdef PASSWD_FROM_STDIN
+ static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
+# endif
+ static ZCONST char Far Decryption[] =
+ " [decryption, version %d.%d%s of %s]\n";
+ static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
+# endif
+# ifndef __RSXNT__
+# ifdef __EMX__
+ static ZCONST char Far EnvEMX[] = "EMX";
+ static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
+# endif
+# if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+ static ZCONST char Far EnvGO32[] = "GO32";
+ static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
+# endif
+# endif /* !__RSXNT__ */
+
+#ifdef VMS
+/* UnzipUsageLine1[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. For more details see: unzip -v.\n\n";
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+ static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+#else /* !VMS */
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+ static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+# define UnzipUsageLine1v UnzipUsageLine1
+#endif /* ?VMS */
+
+static ZCONST char Far UnzipUsageLine2v[] = "\
+Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
+\nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
+\n\n";
+
+#ifdef MACOS
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n \
+ Default action is to extract files in list, to exdir;\n\
+ file[.zip] may be a wildcard. %s\n";
+#else /* !MACOS */
+#ifdef VM_CMS
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n \
+ Default action is to extract files in list, except those in xlist, to disk fm;\
+\n file[.zip] may be a wildcard. %s\n";
+#else /* !VM_CMS */
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
+ Default action is to extract files in list, except those in xlist, to exdir;\n\
+ file[.zip] may be a wildcard. %s\n";
+#endif /* ?VM_CMS */
+#endif /* ?MACOS */
+
+#ifdef NO_ZIPINFO
+# define ZIPINFO_MODE_OPTION ""
+ static ZCONST char Far ZipInfoMode[] =
+ "(ZipInfo mode is disabled in this version.)";
+#else
+# define ZIPINFO_MODE_OPTION "[-Z] "
+ static ZCONST char Far ZipInfoMode[] =
+ "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
+#endif /* ?NO_ZIPINFO */
+
+#ifdef VMS
+ static ZCONST char Far VMSusageLine2b[] = "\
+=> define foreign command symbol in LOGIN.COM: $ unzip :== $dev:[dir]unzip.exe\
+\n";
+#endif
+
+#ifdef MACOS
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -d extract files into exdir -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment only\n\
+ -v list verbosely/show version info %s\n";
+#else /* !MACOS */
+#ifdef VM_CMS
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -p extract files to pipe, no messages -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment only\n\
+ -v list verbosely/show version info %s\n\
+ -x exclude files that follow (in xlist) -d extract files onto disk fm\n";
+#else /* !VM_CMS */
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -p extract files to pipe, no messages -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment only\n\
+ -v list verbosely/show version info %s\n\
+ -x exclude files that follow (in xlist) -d extract files into exdir\n";
+#endif /* ?VM_CMS */
+#endif /* ?MACOS */
+
+/* There is not enough space on a standard 80x25 Windows console screen for
+ * the additional line advertising the UTF-8 debugging options. This may
+ * eventually also be the case for other ports. Probably, the -U option need
+ * not be shown on the introductory screen at all. [Chr. Spieler, 2008-02-09]
+ *
+ * Likely, other advanced options should be moved to an extended help page and
+ * the option to list that page put here. [E. Gordon, 2008-3-16]
+ */
+#if (defined(UNICODE_SUPPORT) && !defined(WIN32))
+#ifdef VMS
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite or make a new version of an existing file\n\
+ -o always make a new version (-oo: overwrite original) of an existing file\n\
+ -q quiet mode (-qq => quieter) -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s";
+#elif (defined UNIX)
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite existing files -q quiet mode (-qq => quieter)\n\
+ -o overwrite files WITHOUT prompting -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s\
+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\
+ -I CHARSET specify a character encoding for UNIX and other archives\n\n";
+#else /* !VMS */
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite existing files -q quiet mode (-qq => quieter)\n\
+ -o overwrite files WITHOUT prompting -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s";
+#endif /* ?VMS */
+#else /* !UNICODE_SUPPORT */
+#ifdef VMS
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite or make a new version of an existing file\n\
+ -o always make a new version (-oo: overwrite original) of an existing file\n\
+ -q quiet mode (-qq => quieter) -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s";
+#else /* !VMS */
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite existing files -q quiet mode (-qq => quieter)\n\
+ -o overwrite files WITHOUT prompting -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s";
+#endif /* ?VMS */
+#endif /* ?UNICODE_SUPPORT */
+
+static ZCONST char Far UnzipUsageLine5[] = "\
+See \"unzip -hh\" or unzip.txt for more help. Examples:\n\
+ unzip data1 -x joe => extract all files except joe from zipfile data1.zip\n\
+%s\
+ unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
+#endif /* ?SFX */
+
+
+
+
+
+/*****************************/
+/* main() / UzpMain() stub */
+/*****************************/
+
+int MAIN(argc, argv) /* return PK-type error code (except under VMS) */
+ int argc;
+ char *argv[];
+{
+ int r;
+
+ CONSTRUCTGLOBALS();
+ r = unzip(__G__ argc, argv);
+ DESTROYGLOBALS();
+ RETURN(r);
+}
+
+
+
+
+/*******************************/
+/* Primary UnZip entry point */
+/*******************************/
+
+int unzip(__G__ argc, argv)
+ __GDEF
+ int argc;
+ char *argv[];
+{
+#ifndef NO_ZIPINFO
+ char *p;
+#endif
+#if (defined(DOS_FLX_H68_NLM_OS2_W32) || !defined(SFX))
+ int i;
+#endif
+ int retcode, error=FALSE;
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef REENTRANT
+ savsigs_info *oldsighandlers = NULL;
+# define SET_SIGHANDLER(sigtype, newsighandler) \
+ if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
+ (newsighandler))) > PK_WARN) \
+ goto cleanup_and_exit
+#else
+# define SET_SIGHANDLER(sigtype, newsighandler) \
+ signal((sigtype), (newsighandler))
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+ /* initialize international char support to the current environment */
+ SETLOCALE(LC_CTYPE, "");
+
+#ifdef UNICODE_SUPPORT
+ /* see if can use UTF-8 Unicode locale */
+# ifdef UTF8_MAYBE_NATIVE
+ {
+ char *codeset;
+# if !(defined(NO_NL_LANGINFO) || defined(NO_LANGINFO_H))
+ /* get the codeset (character set encoding) currently used */
+# include <langinfo.h>
+
+ codeset = nl_langinfo(CODESET);
+# else /* NO_NL_LANGINFO || NO_LANGINFO_H */
+ /* query the current locale setting for character classification */
+ codeset = setlocale(LC_CTYPE, NULL);
+ if (codeset != NULL) {
+ /* extract the codeset portion of the locale name */
+ codeset = strchr(codeset, '.');
+ if (codeset != NULL) ++codeset;
+ }
+# endif /* ?(NO_NL_LANGINFO || NO_LANGINFO_H) */
+ /* is the current codeset UTF-8 ? */
+ if ((codeset != NULL) && (strcmp(codeset, "UTF-8") == 0)) {
+ /* successfully found UTF-8 char coding */
+ G.native_is_utf8 = TRUE;
+ } else {
+ /* Current codeset is not UTF-8 or cannot be determined. */
+ G.native_is_utf8 = FALSE;
+ }
+ /* Note: At least for UnZip, trying to change the process codeset to
+ * UTF-8 does not work. For the example Linux setup of the
+ * UnZip maintainer, a successful switch to "en-US.UTF-8"
+ * resulted in garbage display of all non-basic ASCII characters.
+ */
+ }
+# endif /* UTF8_MAYBE_NATIVE */
+
+ /* initialize Unicode */
+ G.unicode_escape_all = 0;
+ G.unicode_mismatch = 0;
+
+ G.unipath_version = 0;
+ G.unipath_checksum = 0;
+ G.unipath_filename = NULL;
+#endif /* UNICODE_SUPPORT */
+
+
+#ifdef UNIX
+ init_conversion_charsets();
+#endif
+
+#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
+ extern void DebugMalloc(void);
+
+ atexit(DebugMalloc);
+#endif
+
+#ifdef MALLOC_WORK
+ /* The following (rather complex) expression determines the allocation
+ size of the decompression work area. It simulates what the
+ combined "union" and "struct" declaration of the "static" work
+ area reservation achieves automatically at compile time.
+ Any decent compiler should evaluate this expression completely at
+ compile time and provide constants to the zcalloc() call.
+ (For better readability, some subexpressions are encapsulated
+ in temporarly defined macros.)
+ */
+# define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
+# define UZ_NUMOF_CHUNKS \
+ (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
+ (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
+ G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
+# undef UZ_SLIDE_CHUNK
+# undef UZ_NUMOF_CHUNKS
+ G.area.shrink.Parent = (shrint *)G.area.Slide;
+ G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
+ G.area.shrink.Stack = G.area.Slide +
+ (sizeof(shrint) + sizeof(uch))*(HSIZE);
+#endif
+
+/*---------------------------------------------------------------------------
+ Set signal handler for restoring echo, warn of zipfile corruption, etc.
+ ---------------------------------------------------------------------------*/
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef SIGINT
+ SET_SIGHANDLER(SIGINT, handler);
+#endif
+#ifdef SIGTERM /* some systems really have no SIGTERM */
+ SET_SIGHANDLER(SIGTERM, handler);
+#endif
+#if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
+ SET_SIGHANDLER(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+ SET_SIGHANDLER(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+ SET_SIGHANDLER(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+ SET_SIGHANDLER(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+ SET_SIGHANDLER(SIGSEGV, handler);
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+#if (defined(WIN32) && defined(__RSXNT__))
+ for (i = 0 ; i < argc; i++) {
+ _ISO_INTERN(argv[i]);
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ Macintosh initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+ {
+ int a;
+
+ for (a = 0; a < 4; ++a)
+ G.rghCursor[a] = GetCursor(a+128);
+ G.giCursor = 0;
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ NetWare initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+ InitUnZipConsole();
+#endif
+
+/*---------------------------------------------------------------------------
+ Acorn RISC OS initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+ set_prefix();
+#endif
+
+/*---------------------------------------------------------------------------
+ Theos initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+ /* The easiest way found to force creation of libraries when selected
+ * members are to be unzipped. Explicitly add libraries names to the
+ * arguments list before the first member of the library.
+ */
+ if (! _setargv(&argc, &argv)) {
+ Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
+ retcode = PK_MEM;
+ goto cleanup_and_exit;
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ Sanity checks. Commentary by Otis B. Driftwood and Fiorello:
+
+ D: It's all right. That's in every contract. That's what they
+ call a sanity clause.
+
+ F: Ha-ha-ha-ha-ha. You can't fool me. There ain't no Sanity
+ Claus.
+ ---------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+# ifdef LARGE_FILE_SUPPORT
+ /* test if we can support large files - 10/6/04 EG */
+ if (sizeof(zoff_t) < 8) {
+ Info(slide, 0x401, ((char *)slide, "LARGE_FILE_SUPPORT set but not supported\n"));
+ retcode = PK_BADERR;
+ goto cleanup_and_exit;
+ }
+ /* test if we can show 64-bit values */
+ {
+ zoff_t z = ~(zoff_t)0; /* z should be all 1s now */
+ char *sz;
+
+ sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
+ if ((sz[0] != 'F') || (strlen(sz) != 16))
+ {
+ z = 0;
+ }
+
+ /* shift z so only MSB is set */
+ z <<= 63;
+ sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
+ if ((sz[0] != '8') || (strlen(sz) != 16))
+ {
+ Info(slide, 0x401, ((char *)slide,
+ "Can't show 64-bit values correctly\n"));
+ retcode = PK_BADERR;
+ goto cleanup_and_exit;
+ }
+ }
+# endif /* LARGE_FILE_SUPPORT */
+
+ /* 2004-11-30 SMS.
+ Test the NEXTBYTE macro for proper operation.
+ */
+ {
+ int test_char;
+ static uch test_buf[2] = { 'a', 'b' };
+
+ G.inptr = test_buf;
+ G.incnt = 1;
+
+ test_char = NEXTBYTE; /* Should get 'a'. */
+ if (test_char == 'a')
+ {
+ test_char = NEXTBYTE; /* Should get EOF, not 'b'. */
+ }
+ if (test_char != EOF)
+ {
+ Info(slide, 0x401, ((char *)slide,
+ "NEXTBYTE macro failed. Try compiling with ALT_NEXTBYTE defined?"));
+
+ retcode = PK_BADERR;
+ goto cleanup_and_exit;
+ }
+ }
+#endif /* DEBUG */
+
+/*---------------------------------------------------------------------------
+ First figure out if we're running in UnZip mode or ZipInfo mode, and put
+ the appropriate environment-variable options into the queue. Then rip
+ through any command-line options lurking about...
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+ G.argv0 = argv[0];
+#if (defined(OS2) || defined(WIN32))
+ G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
+#else
+ G.zipfn = G.argv0;
+#endif
+
+#ifdef VMSCLI
+ {
+ ulg status = vms_unzip_cmdline(&argc, &argv);
+ if (!(status & 1)) {
+ retcode = (int)status;
+ goto cleanup_and_exit;
+ }
+ }
+#endif /* VMSCLI */
+
+ uO.zipinfo_mode = FALSE;
+ error = uz_opts(__G__ &argc, &argv); /* UnZipSFX call only */
+
+#else /* !SFX */
+
+#ifdef RISCOS
+ /* get the extensions to swap from environment */
+ getRISCOSexts(ENV_UNZIPEXTS);
+#endif
+
+#ifdef MSDOS
+ /* extract MKS extended argument list from environment (before envargs!) */
+ mksargs(&argc, &argv);
+#endif
+
+#ifdef VMSCLI
+ {
+ ulg status = vms_unzip_cmdline(&argc, &argv);
+ if (!(status & 1)) {
+ retcode = (int)status;
+ goto cleanup_and_exit;
+ }
+ }
+#endif /* VMSCLI */
+
+ G.noargs = (argc == 1); /* no options, no zipfile, no anything */
+
+#ifndef NO_ZIPINFO
+ for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
+ if (*p == DIR_END
+#ifdef DIR_END2
+ || *p == DIR_END2
+#endif
+ )
+ break;
+ }
+ ++p;
+
+#ifdef THEOS
+ if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
+ strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
+#else
+ if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
+ STRNICMP(p, "ii", 2) == 0 ||
+#endif
+ (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
+ {
+ uO.zipinfo_mode = TRUE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
+ LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
+ perror(LoadFarString(NoMemEnvArguments));
+#endif
+ } else
+#endif /* !NO_ZIPINFO */
+ {
+ uO.zipinfo_mode = FALSE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
+ LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
+ perror(LoadFarString(NoMemEnvArguments));
+#endif
+ }
+
+ if (!error) {
+ /* Check the length of all passed command line parameters.
+ * Command arguments might get sent through the Info() message
+ * system, which uses the sliding window area as string buffer.
+ * As arguments may additionally get fed through one of the FnFilter
+ * macros, we require all command line arguments to be shorter than
+ * WSIZE/4 (and ca. 2 standard line widths for fixed message text).
+ */
+ for (i = 1 ; i < argc; i++) {
+ if (strlen(argv[i]) > ((WSIZE>>2) - 160)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CmdLineParamTooLong), i));
+ retcode = PK_PARAM;
+ goto cleanup_and_exit;
+ }
+ }
+#ifndef NO_ZIPINFO
+ if (uO.zipinfo_mode)
+ error = zi_opts(__G__ &argc, &argv);
+ else
+#endif /* !NO_ZIPINFO */
+ error = uz_opts(__G__ &argc, &argv);
+ }
+
+#endif /* ?SFX */
+
+ if ((argc < 0) || error) {
+ retcode = error;
+ goto cleanup_and_exit;
+ }
+
+/*---------------------------------------------------------------------------
+ Now get the zipfile name from the command line and then process any re-
+ maining options and file specifications.
+ ---------------------------------------------------------------------------*/
+
+#ifdef DOS_FLX_H68_NLM_OS2_W32
+ /* convert MSDOS-style 'backward slash' directory separators to Unix-style
+ * 'forward slashes' for user's convenience (include zipfile name itself)
+ */
+#ifdef SFX
+ for (G.pfnames = argv, i = argc; i > 0; --i) {
+#else
+ /* argc does not include the zipfile specification */
+ for (G.pfnames = argv, i = argc+1; i > 0; --i) {
+#endif
+#ifdef __human68k__
+ extern char *_toslash(char *);
+ _toslash(*G.pfnames);
+#else /* !__human68k__ */
+ char *q = *G.pfnames;
+
+ while (*q != '\0') {
+ if (*q == '\\')
+ *q = '/';
+ INCSTR(q);
+ }
+#endif /* ?__human68k__ */
+ ++G.pfnames;
+ }
+#endif /* DOS_FLX_H68_NLM_OS2_W32 */
+
+#ifndef SFX
+ G.wildzipfn = *argv++;
+#endif
+
+#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
+
+ G.filespecs = argc;
+ G.xfilespecs = 0;
+
+ if (argc > 0) {
+ char **pp = argv-1;
+
+ G.pfnames = argv;
+ while (*++pp)
+ if (strcmp(*pp, "-x") == 0) {
+ if (pp > argv) {
+ *pp = 0; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames;
+ } else {
+ G.pfnames = (char **)fnames; /* defaults */
+ G.filespecs = 0;
+ }
+ G.pxnames = pp + 1; /* excluded-names ptr: _after_ -x */
+ G.xfilespecs = argc - G.filespecs - 1;
+ break; /* skip rest of args */
+ }
+ G.process_all_files = FALSE;
+ } else
+ G.process_all_files = TRUE; /* for speed */
+
+#else /* !SFX || SFX_EXDIR */ /* check for -x or -d */
+
+ G.filespecs = argc;
+ G.xfilespecs = 0;
+
+ if (argc > 0) {
+ int in_files=FALSE, in_xfiles=FALSE;
+ char **pp = argv-1;
+
+ G.process_all_files = FALSE;
+ G.pfnames = argv;
+ while (*++pp) {
+ Trace((stderr, "pp - argv = %d\n", pp-argv));
+#ifdef CMS_MVS
+ if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
+#else
+ if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
+#endif
+ int firstarg = (pp == argv);
+
+ uO.exdir = (*pp) + 2;
+ if (in_files) { /* ... zipfile ... -d exdir ... */
+ *pp = (char *)NULL; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames;
+ in_files = FALSE;
+ } else if (in_xfiles) {
+ *pp = (char *)NULL; /* terminate G.pxnames */
+ G.xfilespecs = pp - G.pxnames;
+ /* "... -x xlist -d exdir": nothing left */
+ }
+ /* first check for "-dexdir", then for "-d exdir" */
+ if (*uO.exdir == '\0') {
+ if (*++pp)
+ uO.exdir = *pp;
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ /* don't extract here by accident */
+ retcode = PK_PARAM;
+ goto cleanup_and_exit;
+ }
+ }
+ if (firstarg) { /* ... zipfile -d exdir ... */
+ if (pp[1]) {
+ G.pfnames = pp + 1; /* argv+2 */
+ G.filespecs = argc - (G.pfnames-argv); /* for now... */
+ } else {
+ G.process_all_files = TRUE;
+ G.pfnames = (char **)fnames; /* GRR: necessary? */
+ G.filespecs = 0; /* GRR: necessary? */
+ break;
+ }
+ }
+ } else if (!in_xfiles) {
+ if (strcmp(*pp, "-x") == 0) {
+ in_xfiles = TRUE;
+ if (pp == G.pfnames) {
+ G.pfnames = (char **)fnames; /* defaults */
+ G.filespecs = 0;
+ } else if (in_files) {
+ *pp = 0; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames; /* adjust count */
+ in_files = FALSE;
+ }
+ G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
+ G.xfilespecs = argc - (G.pxnames-argv); /* anything left */
+ } else
+ in_files = TRUE;
+ }
+ }
+ } else
+ G.process_all_files = TRUE; /* for speed */
+
+ if (uO.exdir != (char *)NULL && !G.extract_flag) /* -d ignored */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
+#endif /* ?(SFX && !SFX_EXDIR) */
+
+#ifdef UNICODE_SUPPORT
+ /* set Unicode-escape-all if option -U used */
+ if (uO.U_flag == 1)
+# ifdef UNICODE_WCHAR
+ G.unicode_escape_all = TRUE;
+# else
+ Info(slide, 0x401, ((char *)slide, LoadFarString(UTF8EscapeUnSupp)));
+# endif
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Okey dokey, we have everything we need to get started. Let's roll.
+ ---------------------------------------------------------------------------*/
+
+ retcode = process_zipfiles(__G);
+
+cleanup_and_exit:
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+ /* restore all signal handlers back to their state at function entry */
+ while (oldsighandlers != NULL) {
+ savsigs_info *thissigsav = oldsighandlers;
+
+ signal(thissigsav->sigtype, thissigsav->sighandler);
+ oldsighandlers = thissigsav->previous;
+ free(thissigsav);
+ }
+#endif
+#if (defined(MALLOC_WORK) && !defined(REENTRANT))
+ if (G.area.Slide != (uch *)NULL) {
+ free(G.area.Slide);
+ G.area.Slide = (uch *)NULL;
+ }
+#endif
+#if (defined(MSDOS) && !defined(SFX) && !defined(WINDLL))
+ if (retcode != PK_OK)
+ check_for_windows("UnZip");
+#endif
+ return(retcode);
+
+} /* end main()/unzip() */
+
+
+
+
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+/*******************************/
+/* Function setsignalhandler() */
+/*******************************/
+
+static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
+ newhandler)
+ __GDEF
+ savsigs_info **p_savedhandler_chain;
+ int signal_type;
+ void (*newhandler)(int);
+{
+ savsigs_info *savsig;
+
+ savsig = malloc(sizeof(savsigs_info));
+ if (savsig == NULL) {
+ /* error message and break */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
+ return PK_MEM;
+ }
+ savsig->sigtype = signal_type;
+ savsig->sighandler = signal(SIGINT, newhandler);
+ if (savsig->sighandler == SIG_ERR) {
+ free(savsig);
+ } else {
+ savsig->previous = *p_savedhandler_chain;
+ *p_savedhandler_chain = savsig;
+ }
+ return PK_OK;
+
+} /* end function setsignalhandler() */
+
+#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
+
+
+
+
+
+/**********************/
+/* Function uz_opts() */
+/**********************/
+
+int uz_opts(__G__ pargc, pargv)
+ __GDEF
+ int *pargc;
+ char ***pargv;
+{
+ char **argv, *s;
+ int argc, c, error=FALSE, negative=0, showhelp=0;
+
+
+ argc = *pargc;
+ argv = *pargv;
+
+#ifdef UNIX
+ extern char OEM_CP[MAX_CP_NAME];
+ extern char ISO_CP[MAX_CP_NAME];
+#endif
+
+ while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
+ s = *argv + 1;
+ while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
+#ifdef CMS_MVS
+ switch (tolower(c))
+#else
+ switch (c)
+#endif
+ {
+ case ('-'):
+ ++negative;
+ break;
+#ifdef RISCOS
+ case ('/'):
+ if (negative) { /* negative not allowed with -/ swap */
+ Info(slide, 0x401, ((char *)slide,
+ "error: must give extensions list"));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ exts2swap = s; /* override Unzip$Exts */
+ s += strlen(s);
+ break;
+#endif
+ case ('a'):
+ if (negative) {
+ uO.aflag = MAX(uO.aflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.aflag;
+ break;
+#if (defined(DLL) && defined(API_DOC))
+ case ('A'): /* extended help for API */
+ APIhelp(__G__ argc, argv);
+ *pargc = -1; /* signal to exit successfully */
+ return 0;
+#endif
+ case ('b'):
+ if (negative) {
+#if (defined(TANDEM) || defined(VMS))
+ uO.bflag = MAX(uO.bflag-negative,0);
+#endif
+ negative = 0; /* do nothing: "-b" is default */
+ } else {
+#ifdef VMS
+ if (uO.aflag == 0)
+ ++uO.bflag;
+#endif
+#ifdef TANDEM
+ ++uO.bflag;
+#endif
+ uO.aflag = 0;
+ }
+ break;
+#ifdef UNIXBACKUP
+ case ('B'): /* -B: back up existing files */
+ if (negative)
+ uO.B_flag = FALSE, negative = 0;
+ else
+ uO.B_flag = TRUE;
+ break;
+#endif
+ case ('c'):
+ if (negative) {
+ uO.cflag = FALSE, negative = 0;
+#ifdef NATIVE
+ uO.aflag = 0;
+#endif
+ } else {
+ uO.cflag = TRUE;
+#ifdef NATIVE
+ uO.aflag = 2; /* so you can read it on the screen */
+#endif
+#ifdef DLL
+ if (G.redirect_text)
+ G.redirect_data = 2;
+#endif
+ }
+ break;
+#ifndef CMS_MVS
+ case ('C'): /* -C: match filenames case-insensitively */
+ if (negative)
+ uO.C_flag = FALSE, negative = 0;
+ else
+ uO.C_flag = TRUE;
+ break;
+#endif /* !CMS_MVS */
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ case ('d'):
+ if (negative) { /* negative not allowed with -d exdir */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ if (uO.exdir != (char *)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OnlyOneExdir)));
+ return(PK_PARAM); /* GRR: stupid restriction? */
+ } else {
+ /* first check for "-dexdir", then for "-d exdir" */
+ uO.exdir = s;
+ if (*uO.exdir == '\0') {
+ if (argc > 1) {
+ --argc;
+ uO.exdir = *++argv;
+ if (*uO.exdir == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM);
+ }
+ /* else uO.exdir points at extraction dir */
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM);
+ }
+ }
+ /* uO.exdir now points at extraction dir (-dexdir or
+ * -d exdir); point s at end of exdir to avoid mis-
+ * interpretation of exdir characters as more options
+ */
+ if (*s != 0)
+ while (*++s != 0)
+ ;
+ }
+ break;
+#endif /* !SFX || SFX_EXDIR */
+#if (!defined(NO_TIMESTAMPS))
+ case ('D'): /* -D: Skip restoring dir (or any) timestamp. */
+ if (negative) {
+ uO.D_flag = MAX(uO.D_flag-negative,0);
+ negative = 0;
+ } else
+ uO.D_flag++;
+ break;
+#endif /* (!NO_TIMESTAMPS) */
+ case ('e'): /* just ignore -e, -x options (extract) */
+ break;
+#ifdef MACOS
+ case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
+ if( negative ) {
+ uO.E_flag = FALSE, negative = 0;
+ } else {
+ uO.E_flag = TRUE;
+ }
+ break;
+#endif /* MACOS */
+ case ('f'): /* "freshen" (extract only newer files) */
+ if (negative)
+ uO.fflag = uO.uflag = FALSE, negative = 0;
+ else
+ uO.fflag = uO.uflag = TRUE;
+ break;
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+ case ('F'): /* Acorn filetype & NFS extension handling */
+ if (negative)
+ uO.acorn_nfs_ext = FALSE, negative = 0;
+ else
+ uO.acorn_nfs_ext = TRUE;
+ break;
+#endif /* RISCOS || ACORN_FTYPE_NFS */
+ case ('h'): /* just print help message and quit */
+ if (showhelp == 0) {
+#ifndef SFX
+ if (*s == 'h')
+ showhelp = 2;
+ else
+#endif /* !SFX */
+ {
+ showhelp = 1;
+ }
+ }
+ break;
+#ifdef MACOS
+ case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
+ if( negative ) {
+ uO.i_flag = FALSE, negative = 0;
+ } else {
+ uO.i_flag = TRUE;
+ }
+ break;
+#endif /* MACOS */
+#ifdef UNIX
+ case ('I'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Icharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
+ } else { /* -I charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
+ case ('j'): /* junk pathnames/directory structure */
+ if (negative)
+ uO.jflag = FALSE, negative = 0;
+ else
+ uO.jflag = TRUE;
+ break;
+#if (defined(ATH_BEO) || defined(MACOS))
+ case ('J'): /* Junk AtheOS, BeOS or MacOS file attributes */
+ if( negative ) {
+ uO.J_flag = FALSE, negative = 0;
+ } else {
+ uO.J_flag = TRUE;
+ }
+ break;
+#endif /* ATH_BEO || MACOS */
+#ifdef ATH_BEO_UNX
+ case ('K'):
+ if (negative) {
+ uO.K_flag = FALSE, negative = 0;
+ } else {
+ uO.K_flag = TRUE;
+ }
+ break;
+#endif /* ATH_BEO_UNX */
+#ifndef SFX
+ case ('l'):
+ if (negative) {
+ uO.vflag = MAX(uO.vflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.vflag;
+ break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+ case ('L'): /* convert (some) filenames to lowercase */
+ if (negative) {
+ uO.L_flag = MAX(uO.L_flag-negative,0);
+ negative = 0;
+ } else
+ ++uO.L_flag;
+ break;
+#endif /* !CMS_MVS */
+#ifdef MORE
+#ifdef CMS_MVS
+ case ('m'):
+#endif
+ case ('M'): /* send all screen output through "more" fn. */
+/* GRR: eventually check for numerical argument => height */
+ if (negative)
+ G.M_flag = FALSE, negative = 0;
+ else
+ G.M_flag = TRUE;
+ break;
+#endif /* MORE */
+ case ('n'): /* don't overwrite any files */
+ if (negative)
+ uO.overwrite_none = FALSE, negative = 0;
+ else
+ uO.overwrite_none = TRUE;
+ break;
+#ifdef AMIGA
+ case ('N'): /* restore comments as filenotes */
+ if (negative)
+ uO.N_flag = FALSE, negative = 0;
+ else
+ uO.N_flag = TRUE;
+ break;
+#endif /* AMIGA */
+ case ('o'): /* OK to overwrite files without prompting */
+ if (negative) {
+ uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
+ negative = 0;
+ } else
+ ++uO.overwrite_all;
+ break;
+#ifdef UNIX
+ case ('O'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Ocharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
+ } else { /* -O charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -O argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
+ case ('p'): /* pipes: extract to stdout, no messages */
+ if (negative) {
+ uO.cflag = FALSE;
+ uO.qflag = MAX(uO.qflag-999,0);
+ negative = 0;
+ } else {
+ uO.cflag = TRUE;
+ uO.qflag += 999;
+ }
+ break;
+#if CRYPT
+ /* GRR: yes, this is highly insecure, but dozens of people
+ * have pestered us for this, so here we go... */
+ case ('P'):
+ if (negative) { /* negative not allowed with -P passwd */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ if (uO.pwdarg != (char *)NULL) {
+/*
+ GRR: eventually support multiple passwords?
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OnlyOnePasswd)));
+ return(PK_PARAM);
+ */
+ } else {
+ /* first check for "-Ppasswd", then for "-P passwd" */
+ uO.pwdarg = s;
+ if (*uO.pwdarg == '\0') {
+ if (argc > 1) {
+ --argc;
+ uO.pwdarg = *++argv;
+ if (*uO.pwdarg == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM);
+ }
+ /* else pwdarg points at decryption password */
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM);
+ }
+ }
+ /* pwdarg now points at decryption password (-Ppasswd or
+ * -P passwd); point s at end of passwd to avoid mis-
+ * interpretation of passwd characters as more options
+ */
+ if (*s != 0)
+ while (*++s != 0)
+ ;
+ }
+ break;
+#endif /* CRYPT */
+ case ('q'): /* quiet: fewer comments/messages */
+ if (negative) {
+ uO.qflag = MAX(uO.qflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.qflag;
+ break;
+#ifdef QDOS
+ case ('Q'): /* QDOS flags */
+ qlflag ^= strtol(s, &s, 10);
+ break; /* we XOR this as we can config qlflags */
+#endif
+#ifdef TANDEM
+ case ('r'): /* remove file extensions */
+ if (negative)
+ uO.rflag = FALSE, negative = 0;
+ else
+ uO.rflag = TRUE;
+ break;
+#endif /* TANDEM */
+#ifdef DOS_FLX_NLM_OS2_W32
+ case ('s'): /* spaces in filenames: allow by default */
+ if (negative)
+ uO.sflag = FALSE, negative = 0;
+ else
+ uO.sflag = TRUE;
+ break;
+#endif /* DOS_FLX_NLM_OS2_W32 */
+#ifdef VMS
+ /* VMS: extract "text" files in Stream_LF format (-a[a]) */
+ case ('S'):
+ if (negative)
+ uO.S_flag = FALSE, negative = 0;
+ else
+ uO.S_flag = TRUE;
+ break;
+#endif /* VMS */
+ case ('t'):
+ if (negative)
+ uO.tflag = FALSE, negative = 0;
+ else
+ uO.tflag = TRUE;
+ break;
+#ifdef TIMESTAMP
+ case ('T'):
+ if (negative)
+ uO.T_flag = FALSE, negative = 0;
+ else
+ uO.T_flag = TRUE;
+ break;
+#endif
+ case ('u'): /* update (extract only new and newer files) */
+ if (negative)
+ uO.uflag = FALSE, negative = 0;
+ else
+ uO.uflag = TRUE;
+ break;
+#ifdef UNICODE_SUPPORT
+ case ('U'): /* escape UTF-8, or disable UTF-8 support */
+ if (negative) {
+ uO.U_flag = MAX(uO.U_flag-negative,0);
+ negative = 0;
+ } else
+ uO.U_flag++;
+ break;
+#else /* !UNICODE_SUPPORT */
+#ifndef CMS_MVS
+ case ('U'): /* obsolete; to be removed in version 6.0 */
+ if (negative)
+ uO.L_flag = TRUE, negative = 0;
+ else
+ uO.L_flag = FALSE;
+ break;
+#endif /* !CMS_MVS */
+#endif /* ?UNICODE_SUPPORT */
+#ifndef SFX
+ case ('v'): /* verbose */
+ if (negative) {
+ uO.vflag = MAX(uO.vflag-negative,0);
+ negative = 0;
+ } else if (uO.vflag)
+ ++uO.vflag;
+ else
+ uO.vflag = 2;
+ break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+ case ('V'): /* Version (retain VMS/DEC-20 file versions) */
+ if (negative)
+ uO.V_flag = FALSE, negative = 0;
+ else
+ uO.V_flag = TRUE;
+ break;
+#endif /* !CMS_MVS */
+#ifdef WILD_STOP_AT_DIR
+ case ('W'): /* Wildcard interpretation (stop at '/'?) */
+ if (negative)
+ uO.W_flag = FALSE, negative = 0;
+ else
+ uO.W_flag = TRUE;
+ break;
+#endif /* WILD_STOP_AT_DIR */
+ case ('x'): /* extract: default */
+#ifdef SFX
+ /* when 'x' is the only option in this argument, and the
+ * next arg is not an option, assume this initiates an
+ * exclusion list (-x xlist): terminate option-scanning
+ * and leave uz_opts with argv still pointing to "-x";
+ * the xlist is processed later
+ */
+ if (s - argv[0] == 2 && *s == '\0' &&
+ argc > 1 && argv[1][0] != '-') {
+ /* break out of nested loops without "++argv;--argc" */
+ goto opts_done;
+ }
+#endif /* SFX */
+ break;
+#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
+ case ('X'): /* restore owner/protection info (need privs?) */
+ if (negative) {
+ uO.X_flag = MAX(uO.X_flag-negative,0);
+ negative = 0;
+ } else
+ ++uO.X_flag;
+ break;
+#endif /* RESTORE_UIDGID || RESTORE_ACL */
+#ifdef VMS
+ case ('Y'): /* Treat ".nnn" as ";nnn" version. */
+ if (negative)
+ uO.Y_flag = FALSE, negative = 0;
+ else
+ uO.Y_flag = TRUE;
+ break;
+#endif /* VMS */
+ case ('z'): /* display only the archive comment */
+ if (negative) {
+ uO.zflag = MAX(uO.zflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.zflag;
+ break;
+#ifndef SFX
+ case ('Z'): /* should have been first option (ZipInfo) */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
+ error = TRUE;
+ break;
+#endif /* !SFX */
+#ifdef VMS
+ case ('2'): /* Force ODS2-compliant names. */
+ if (negative)
+ uO.ods2_flag = FALSE, negative = 0;
+ else
+ uO.ods2_flag = TRUE;
+ break;
+#endif /* VMS */
+#ifdef DOS_H68_OS2_W32
+ case ('$'):
+ if (negative) {
+ uO.volflag = MAX(uO.volflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.volflag;
+ break;
+#endif /* DOS_H68_OS2_W32 */
+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
+ case (':'): /* allow "parent dir" path components */
+ if (negative) {
+ uO.ddotflag = MAX(uO.ddotflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.ddotflag;
+ break;
+#endif /* !RISCOS && !CMS_MVS && !TANDEM */
+#ifdef UNIX
+ case ('^'): /* allow control chars in filenames */
+ if (negative) {
+ uO.cflxflag = MAX(uO.cflxflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.cflxflag;
+ break;
+#endif /* UNIX */
+ default:
+ error = TRUE;
+ break;
+
+ } /* end switch */
+ } /* end while (not end of argument string) */
+ } /* end while (not done with switches) */
+
+/*---------------------------------------------------------------------------
+ Check for nonsensical combinations of options.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */
+#endif
+
+ if (showhelp > 0) { /* just print help message and quit */
+ *pargc = -1;
+#ifndef SFX
+ if (showhelp == 2) {
+ help_extended(__G);
+ return PK_OK;
+ } else
+#endif /* !SFX */
+ {
+ return USAGE(PK_OK);
+ }
+ }
+
+ if ((uO.cflag && (uO.tflag || uO.uflag)) ||
+ (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
+ error = TRUE;
+ }
+ if (uO.aflag > 2)
+ uO.aflag = 2;
+#ifdef VMS
+ if (uO.bflag > 2)
+ uO.bflag = 2;
+ /* Clear -s flag when converting text files. */
+ if (uO.aflag <= 0)
+ uO.S_flag = 0;
+#endif /* VMS */
+ if (uO.overwrite_all && uO.overwrite_none) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
+ uO.overwrite_all = FALSE;
+ }
+#ifdef MORE
+ if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func. useless */
+ G.M_flag = 0;
+#endif
+
+#ifdef SFX
+ if (error)
+#else
+ if ((argc-- == 0) || error)
+#endif
+ {
+ *pargc = argc;
+ *pargv = argv;
+#ifndef SFX
+ if (uO.vflag >= 2 && argc == -1) { /* "unzip -v" */
+ show_version_info(__G);
+ return PK_OK;
+ }
+ if (!G.noargs && !error)
+ error = TRUE; /* had options (not -h or -v) but no zipfile */
+#endif /* !SFX */
+ return USAGE(error);
+ }
+
+#ifdef SFX
+ /* print our banner unless we're being fairly quiet */
+ if (uO.qflag < 2)
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+ /* always print the beta warning: no unauthorized distribution!! */
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+ "SFX"));
+#endif
+#endif /* SFX */
+
+ if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
+#ifdef TIMESTAMP
+ || uO.T_flag
+#endif
+ )
+ G.extract_flag = FALSE;
+ else
+ G.extract_flag = TRUE;
+
+ *pargc = argc;
+ *pargv = argv;
+ return PK_OK;
+
+} /* end function uz_opts() */
+
+
+
+
+/********************/
+/* Function usage() */
+/********************/
+
+#ifdef SFX
+# ifdef VMS
+# define LOCAL "X.\n\
+(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
+# endif
+# ifdef UNIX
+# define LOCAL "X"
+# endif
+# ifdef DOS_OS2_W32
+# define LOCAL "s$"
+# endif
+# if (defined(FLEXOS) || defined(NLM))
+# define LOCAL "s"
+# endif
+# ifdef AMIGA
+# define LOCAL "N"
+# endif
+ /* Default for all other systems: */
+# ifndef LOCAL
+# define LOCAL ""
+# endif
+
+# ifndef NO_TIMESTAMP
+# ifdef MORE
+# define SFXOPT1 "DM"
+# else
+# define SFXOPT1 "D"
+# endif
+# else
+# ifdef MORE
+# define SFXOPT1 "M"
+# else
+# define SFXOPT1 ""
+# endif
+# endif
+
+int usage(__G__ error) /* return PK-type error code */
+ __GDEF
+ int error;
+{
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
+ SFXOPT1, LOCAL));
+#ifdef BETA
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+ "SFX"));
+#endif
+
+ if (error)
+ return PK_PARAM;
+ else
+ return PK_COOL; /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+
+
+
+
+#else /* !SFX */
+# ifdef VMS
+# define QUOT '\"'
+# define QUOTS "\""
+# else
+# define QUOT ' '
+# define QUOTS ""
+# endif
+
+int usage(__G__ error) /* return PK-type error code */
+ __GDEF
+ int error;
+{
+ int flag = (error? 1 : 0);
+
+
+/*---------------------------------------------------------------------------
+ Print either ZipInfo usage or UnZip usage, depending on incantation.
+ (Strings must be no longer than 512 bytes for Turbo C, apparently.)
+ ---------------------------------------------------------------------------*/
+
+ if (uO.zipinfo_mode) {
+
+#ifndef NO_ZIPINFO
+
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
+ ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate),
+ LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
+ LoadFarStringSmall(ZipInfoUsageLine4)));
+#ifdef VMS
+ Info(slide, flag, ((char *)slide, "\n\
+You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
+\n"));
+#endif
+
+#endif /* !NO_ZIPINFO */
+
+ } else { /* UnZip mode */
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+ Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
+#endif
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
+ ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
+#ifdef VMS
+ if (!error) /* maybe no command-line tail found; show extra help */
+ Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
+#endif
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
+ LoadFarStringSmall(local1)));
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
+ LoadFarStringSmall(local2), LoadFarStringSmall2(local3)));
+
+ /* This is extra work for SMALL_MEM, but it will work since
+ * LoadFarStringSmall2 uses the same buffer. Remember, this
+ * is a hack. */
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
+ LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
+ LoadFarStringSmall2(Example3)));
+
+ } /* end if (uO.zipinfo_mode) */
+
+ if (error)
+ return PK_PARAM;
+ else
+ return PK_COOL; /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+#endif /* ?SFX */
+
+
+
+
+#ifndef SFX
+
+/* Print extended help to stdout. */
+static void help_extended(__G)
+ __GDEF
+{
+ extent i; /* counter for help array */
+
+ /* help array */
+ static ZCONST char *text[] = {
+ "",
+ "Extended Help for UnZip",
+ "",
+ "See the UnZip Manual for more detailed help",
+ "",
+ "",
+ "UnZip lists and extracts files in zip archives. The default action is to",
+ "extract zipfile entries to the current directory, creating directories as",
+ "needed. With appropriate options, UnZip lists the contents of archives",
+ "instead.",
+ "",
+ "Basic unzip command line:",
+ " unzip [-Z] options archive[.zip] [file ...] [-x xfile ...] [-d exdir]",
+ "",
+ "Some examples:",
+ " unzip -l foo.zip - list files in short format in archive foo.zip",
+ "",
+ " unzip -t foo - test the files in archive foo",
+ "",
+ " unzip -Z foo - list files using more detailed zipinfo format",
+ "",
+ " unzip foo - unzip the contents of foo in current dir",
+ "",
+ " unzip -a foo - unzip foo and convert text files to local OS",
+ "",
+ "If unzip is run in zipinfo mode, a more detailed list of archive contents",
+ "is provided. The -Z option sets zipinfo mode and changes the available",
+ "options.",
+ "",
+ "Basic zipinfo command line:",
+ " zipinfo options archive[.zip] [file ...] [-x xfile ...]",
+ " unzip -Z options archive[.zip] [file ...] [-x xfile ...]",
+ "",
+ "Below, Mac OS refers to Mac OS before Mac OS X. Mac OS X is a Unix based",
+ "port and is referred to as Unix Apple.",
+ "",
+ "",
+ "unzip options:",
+ " -Z Switch to zipinfo mode. Must be first option.",
+ " -hh Display extended help.",
+ " -A [OS/2, Unix DLL] Print extended help for DLL.",
+ " -c Extract files to stdout/screen. As -p but include names. Also,",
+ " -a allowed and EBCDIC conversions done if needed.",
+ " -f Freshen by extracting only if older file on disk.",
+ " -l List files using short form.",
+ " -p Extract files to pipe (stdout). Only file data is output and all",
+ " files extracted in binary mode (as stored).",
+ " -t Test archive files.",
+ " -T Set timestamp on archive(s) to that of newest file. Similar to",
+ " zip -o but faster.",
+ " -u Update existing older files on disk as -f and extract new files.",
+ " -v Use verbose list format. If given alone as unzip -v show version",
+ " information. Also can be added to other list commands for more",
+ " verbose output.",
+ " -z Display only archive comment.",
+ "",
+ "unzip modifiers:",
+ " -a Convert text files to local OS format. Convert line ends, EOF",
+ " marker, and from or to EBCDIC character set as needed.",
+ " -b Treat all files as binary. [Tandem] Force filecode 180 ('C').",
+ " [VMS] Autoconvert binary files. -bb forces convert of all files.",
+ " -B [UNIXBACKUP compile option enabled] Save a backup copy of each",
+ " overwritten file in foo~ or foo~99999 format.",
+ " -C Use case-insensitive matching.",
+ " -D Skip restoration of timestamps for extracted directories. On VMS this",
+ " is on by default and -D essentially becames -DD.",
+ " -DD Skip restoration of timestamps for all entries.",
+ " -E [MacOS (not Unix Apple)] Display contents of MacOS extra field during",
+ " restore.",
+ " -F [Acorn] Suppress removal of NFS filetype extension. [Non-Acorn if",
+ " ACORN_FTYPE_NFS] Translate filetype and append to name.",
+ " -i [MacOS] Ignore filenames in MacOS extra field. Instead, use name in",
+ " standard header.",
+ " -j Junk paths and deposit all files in extraction directory.",
+ " -J [BeOS] Junk file attributes. [MacOS] Ignore MacOS specific info.",
+ " -K [AtheOS, BeOS, Unix] Restore SUID/SGID/Tacky file attributes.",
+ " -L Convert to lowercase any names from uppercase only file system.",
+ " -LL Convert all files to lowercase.",
+ " -M Pipe all output through internal pager similar to Unix more(1).",
+ " -n Never overwrite existing files. Skip extracting that file, no prompt.",
+ " -N [Amiga] Extract file comments as Amiga filenotes.",
+ " -o Overwrite existing files without prompting. Useful with -f. Use with",
+ " care.",
+ " -P p Use password p to decrypt files. THIS IS INSECURE! Some OS show",
+ " command line to other users.",
+ " -q Perform operations quietly. The more q (as in -qq) the quieter.",
+ " -s [OS/2, NT, MS-DOS] Convert spaces in filenames to underscores.",
+ " -S [VMS] Convert text files (-a, -aa) into Stream_LF format.",
+ " -U [UNICODE enabled] Show non-local characters as #Uxxxx or #Lxxxxxx ASCII",
+ " text escapes where x is hex digit. [Old] -U used to leave names",
+ " uppercase if created on MS-DOS, VMS, etc. See -L.",
+ " -UU [UNICODE enabled] Disable use of stored UTF-8 paths. Note that UTF-8",
+ " paths stored as native local paths are still processed as Unicode.",
+ " -V Retain VMS file version numbers.",
+ " -W [Only if WILD_STOP_AT_DIR] Modify pattern matching so ? and * do not",
+ " match directory separator /, but ** does. Allows matching at specific",
+ " directory levels.",
+ " -X [VMS, Unix, OS/2, NT, Tandem] Restore UICs and ACL entries under VMS,",
+ " or UIDs/GIDs under Unix, or ACLs under certain network-enabled",
+ " versions of OS/2, or security ACLs under Windows NT. Can require",
+ " user privileges.",
+ " -XX [NT] Extract NT security ACLs after trying to enable additional",
+ " system privileges.",
+ " -Y [VMS] Treat archived name endings of .nnn as VMS version numbers.",
+ " -$ [MS-DOS, OS/2, NT] Restore volume label if extraction medium is",
+ " removable. -$$ allows fixed media (hard drives) to be labeled.",
+ " -/ e [Acorn] Use e as extension list.",
+ " -: [All but Acorn, VM/CMS, MVS, Tandem] Allow extract archive members into",
+ " locations outside of current extraction root folder. This allows",
+ " paths such as ../foo to be extracted above the current extraction",
+ " directory, which can be a security problem.",
+ " -^ [Unix] Allow control characters in names of extracted entries. Usually",
+ " this is not a good thing and should be avoided.",
+ " -2 [VMS] Force unconditional conversion of names to ODS-compatible names.",
+ " Default is to exploit destination file system, preserving cases and",
+ " extended name characters on ODS5 and applying ODS2 filtering on ODS2.",
+ "",
+ "",
+ "Wildcards:",
+ " Internally unzip supports the following wildcards:",
+ " ? (or %% or #, depending on OS) matches any single character",
+ " * matches any number of characters, including zero",
+ " [list] matches char in list (regex), can do range [ac-f], all but [!bf]",
+ " If port supports [], must escape [ as [[]",
+ " For shells that expand wildcards, escape (\\* or \"*\") so unzip can recurse.",
+ "",
+ "Include and Exclude:",
+ " -i pattern pattern ... include files that match a pattern",
+ " -x pattern pattern ... exclude files that match a pattern",
+ " Patterns are paths with optional wildcards and match paths as stored in",
+ " archive. Exclude and include lists end at next option or end of line.",
+ " unzip archive -x pattern pattern ...",
+ "",
+ "Multi-part (split) archives (archives created as a set of split files):",
+ " Currently split archives are not readable by unzip. A workaround is",
+ " to use zip to convert the split archive to a single-file archive and",
+ " use unzip on that. See the manual page for Zip 3.0 or later.",
+ "",
+ "Streaming (piping into unzip):",
+ " Currently unzip does not support streaming. The funzip utility can be",
+ " used to process the first entry in a stream.",
+ " cat archive | funzip",
+ "",
+ "Testing archives:",
+ " -t test contents of archive",
+ " This can be modified using -q for quieter operation, and -qq for even",
+ " quieter operation.",
+ "",
+ "Unicode:",
+ " If compiled with Unicode support, unzip automatically handles archives",
+ " with Unicode entries. Currently Unicode on Win32 systems is limited.",
+ " Characters not in the current character set are shown as ASCII escapes",
+ " in the form #Uxxxx where the Unicode character number fits in 16 bits,",
+ " or #Lxxxxxx where it doesn't, where x is the ASCII character for a hex",
+ " digit.",
+ "",
+ "",
+ "zipinfo options (these are used in zipinfo mode (unzip -Z ...)):",
+ " -1 List names only, one per line. No headers/trailers. Good for scripts.",
+ " -2 List names only as -1, but include headers, trailers, and comments.",
+ " -s List archive entries in short Unix ls -l format. Default list format.",
+ " -m List in long Unix ls -l format. As -s, but includes compression %.",
+ " -l List in long Unix ls -l format. As -m, but compression in bytes.",
+ " -v List zipfile information in verbose, multi-page format.",
+ " -h List header line. Includes archive name, actual size, total files.",
+ " -M Pipe all output through internal pager similar to Unix more(1) command.",
+ " -t List totals for files listed or for all files. Includes uncompressed",
+ " and compressed sizes, and compression factors.",
+ " -T Print file dates and times in a sortable decimal format (yymmdd.hhmmss)",
+ " Default date and time format is a more human-readable version.",
+ " -U [UNICODE] If entry has a UTF-8 Unicode path, display any characters",
+ " not in current character set as text #Uxxxx and #Lxxxxxx escapes",
+ " representing the Unicode character number of the character in hex.",
+ " -UU [UNICODE] Disable use of any UTF-8 path information.",
+ " -z Include archive comment if any in listing.",
+ "",
+ "",
+ "funzip stream extractor:",
+ " funzip extracts the first member in an archive to stdout. Typically",
+ " used to unzip the first member of a stream or pipe. If a file argument",
+ " is given, read from that file instead of stdin.",
+ "",
+ "funzip command line:",
+ " funzip [-password] [input[.zip|.gz]]",
+ "",
+ "",
+ "unzipsfx self extractor:",
+ " Self-extracting archives made with unzipsfx are no more (or less)",
+ " portable across different operating systems than unzip executables.",
+ " In general, a self-extracting archive made on a particular Unix system,",
+ " for example, will only self-extract under the same flavor of Unix.",
+ " Regular unzip may still be used to extract embedded archive however.",
+ "",
+ "unzipsfx command line:",
+ " <unzipsfx+archive_filename> [-options] [file(s) ... [-x xfile(s) ...]]",
+ "",
+ "unzipsfx options:",
+ " -c, -p - Output to pipe. (See above for unzip.)",
+ " -f, -u - Freshen and Update, as for unzip.",
+ " -t - Test embedded archive. (Can be used to list contents.)",
+ " -z - Print archive comment. (See unzip above.)",
+ "",
+ "unzipsfx modifiers:",
+ " Most unzip modifiers are supported. These include",
+ " -a - Convert text files.",
+ " -n - Never overwrite.",
+ " -o - Overwrite without prompting.",
+ " -q - Quiet operation.",
+ " -C - Match names case-insensitively.",
+ " -j - Junk paths.",
+ " -V - Keep version numbers.",
+ " -s - Convert spaces to underscores.",
+ " -$ - Restore volume label.",
+ "",
+ "If unzipsfx compiled with SFX_EXDIR defined, -d option also available:",
+ " -d exd - Extract to directory exd.",
+ "By default, all files extracted to current directory. This option",
+ "forces extraction to specified directory.",
+ "",
+ "See unzipsfx manual page for more information.",
+ ""
+ };
+
+ for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+ {
+ Info(slide, 0, ((char *)slide, "%s\n", text[i]));
+ }
+} /* end function help_extended() */
+
+
+
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+#if (!defined(MODERN) || defined(NO_STDLIB_H))
+/* Declare getenv() to be sure (might be missing in some environments) */
+extern char *getenv();
+#endif
+#endif
+
+/********************************/
+/* Function show_version_info() */
+/********************************/
+
+static void show_version_info(__G)
+ __GDEF
+{
+ if (uO.qflag > 3) /* "unzip -vqqqq" */
+ Info(slide, 0, ((char *)slide, "%d\n",
+ (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
+ else {
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ char *envptr;
+#endif
+ int numopts = 0;
+
+ Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(UnzipUsageLine2v)));
+ version(__G);
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
+#ifdef ACORN_FTYPE_NFS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AcornFtypeNFS)));
+ ++numopts;
+#endif
+#ifdef ASM_CRC
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AsmCRC)));
+ ++numopts;
+#endif
+#ifdef ASM_INFLATECODES
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AsmInflateCodes)));
+ ++numopts;
+#endif
+#ifdef CHECK_VERSIONS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Check_Versions)));
+ ++numopts;
+#endif
+#ifdef COPYRIGHT_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Copyright_Clean)));
+ ++numopts;
+#endif
+#ifdef DEBUG
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(UDebug)));
+ ++numopts;
+#endif
+#ifdef DEBUG_TIME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(DebugTime)));
+ ++numopts;
+#endif
+#ifdef DLL
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Dll)));
+ ++numopts;
+#endif
+#ifdef DOSWILD
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(DosWild)));
+ ++numopts;
+#endif
+#ifdef LZW_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(LZW_Clean)));
+ ++numopts;
+#endif
+#ifndef MORE
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(No_More)));
+ ++numopts;
+#endif
+#ifdef NO_ZIPINFO
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(No_ZipInfo)));
+ ++numopts;
+#endif
+#ifdef NTSD_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(NTSDExtAttrib)));
+ ++numopts;
+#endif
+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(W32NoIZTimeFix)));
+ ++numopts;
+#endif
+#ifdef OLD_THEOS_EXTRA
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(OldTheosExtra)));
+ ++numopts;
+#endif
+#ifdef OS2_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(OS2ExtAttrib)));
+ ++numopts;
+#endif
+#ifdef QLZIP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(SMSExFldOnUnix)));
+ ++numopts;
+#endif
+#ifdef REENTRANT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Reentrant)));
+ ++numopts;
+#endif
+#ifdef REGARGS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(RegArgs)));
+ ++numopts;
+#endif
+#ifdef RETURN_CODES
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Return_Codes)));
+ ++numopts;
+#endif
+#ifdef SET_DIR_ATTRIB
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(SetDirAttrib)));
+ ++numopts;
+#endif
+#ifdef SYMLINKS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(SymLinkSupport)));
+ ++numopts;
+#endif
+#ifdef TIMESTAMP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(TimeStamp)));
+ ++numopts;
+#endif
+#ifdef UNIXBACKUP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(UnixBackup)));
+ ++numopts;
+#endif
+#ifdef USE_EF_UT_TIME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_EF_UT_time)));
+ ++numopts;
+#endif
+#ifndef COPYRIGHT_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Smith_Code)));
+ ++numopts;
+#endif
+#ifndef LZW_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Unshrink)));
+ ++numopts;
+#endif
+#ifdef USE_DEFLATE64
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Deflate64)));
+ ++numopts;
+#endif
+#ifdef UNICODE_SUPPORT
+# ifdef UTF8_MAYBE_NATIVE
+ sprintf((char *)(slide+256), LoadFarStringSmall(Use_Unicode),
+ LoadFarStringSmall2(G.native_is_utf8 ? SysChUTF8 : SysChOther));
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ (char *)(slide+256)));
+# else
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Unicode)));
+# endif
+ ++numopts;
+#endif
+#ifdef _MBCS
+ sprintf((char *)(slide+256), LoadFarStringSmall(Have_MBCS_Support),
+ (unsigned int)MB_CUR_MAX);
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ (char *)(slide+256)));
+ ++numopts;
+#endif
+#ifdef MULT_VOLUME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_MultiVol)));
+ ++numopts;
+#endif
+#ifdef LARGE_FILE_SUPPORT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_LFS)));
+ ++numopts;
+#endif
+#ifdef ZIP64_SUPPORT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Zip64)));
+ ++numopts;
+#endif
+#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+# ifdef USE_DJGPP_ENV
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_DJGPP_Env)));
+ ++numopts;
+# endif
+# ifdef USE_DJGPP_GLOB
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_DJGPP_Glob)));
+ ++numopts;
+# endif
+#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+#ifdef USE_VFAT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_VFAT_support)));
+ ++numopts;
+#endif
+#ifdef USE_ZLIB
+ sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
+ ZLIB_VERSION, zlibVersion());
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ (char *)(slide+256)));
+ ++numopts;
+#endif
+#ifdef USE_BZIP2
+ sprintf((char *)(slide+256), LoadFarStringSmall(UseBZip2),
+ BZ2_bzlibVersion());
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ (char *)(slide+256)));
+ ++numopts;
+#endif
+#ifdef VMS_TEXT_CONV
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsTextConv)));
+ ++numopts;
+#endif
+#ifdef VMSCLI
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsCLI)));
+ ++numopts;
+#endif
+#ifdef VMSWILD
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsWild)));
+ ++numopts;
+#endif
+#ifdef WILD_STOP_AT_DIR
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(WildStopAtDir)));
+ ++numopts;
+#endif
+#if CRYPT
+# ifdef PASSWD_FROM_STDIN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(PasswdStdin)));
+# endif
+ Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
+ CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
+ LoadFarStringSmall(CryptDate)));
+ ++numopts;
+#endif /* CRYPT */
+ if (numopts == 0)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(None)));
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
+ envptr = getenv(LoadFarStringSmall(EnvUnZip));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZip),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvUnZip2));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZip2),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvZipInfo));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvZipInfo),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvZipInfo2),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#ifndef __RSXNT__
+#ifdef __EMX__
+ envptr = getenv(LoadFarStringSmall(EnvEMX));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvEMX),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvEMXOPT),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* __EMX__ */
+#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+ envptr = getenv(LoadFarStringSmall(EnvGO32));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvGO32),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvGO32TMP),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* __GO32__ && !(__DJGPP__ >= 2) */
+#endif /* !__RSXNT__ */
+#ifdef RISCOS
+ envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZipExts),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* RISCOS */
+#endif /* !_WIN32_WCE */
+ }
+} /* end function show_version() */
+
+#endif /* !SFX */
+#endif /* !WINDLL */
Index: unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/unzpriv.h (revision 5)
@@ -0,0 +1,3132 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unzpriv.h
+
+ This header file contains private (internal) macros, typedefs, prototypes
+ and global-variable declarations used by all of the UnZip source files.
+ In a prior life it was part of the main unzip.h header, but now it is only
+ included by that header if UNZIP_INTERNAL is defined.
+
+ ---------------------------------------------------------------------------*/
+
+
+
+#ifndef __unzpriv_h /* prevent multiple inclusions */
+#define __unzpriv_h
+
+/* First thing: Signal all following code that we compile UnZip utilities! */
+#ifndef UNZIP
+# define UNZIP
+#endif
+
+/* GRR 960204: MORE defined here in preparation for removal altogether */
+#ifndef MORE
+# ifndef RISCOS
+# define MORE
+# endif
+#endif
+
+/* fUnZip should never need to be reentrant */
+#ifdef FUNZIP
+# ifdef REENTRANT
+# undef REENTRANT
+# endif
+# ifdef DLL
+# undef DLL
+# endif
+# ifdef SFX /* fUnZip is NOT the sfx stub! */
+# undef SFX
+# endif
+# ifdef USE_BZIP2 /* fUnZip does not support bzip2 decompression */
+# undef USE_BZIP2
+# endif
+#endif
+
+#if (defined(USE_ZLIB) && !defined(HAVE_ZL_INFLAT64) && !defined(NO_DEFLATE64))
+ /* zlib does not (yet?) provide Deflate64(tm) support */
+# define NO_DEFLATE64
+#endif
+
+#ifdef NO_DEFLATE64
+ /* disable support for Deflate64(tm) */
+# ifdef USE_DEFLATE64
+# undef USE_DEFLATE64
+# endif
+#else
+ /* enable Deflate64(tm) support unless compiling for SFX stub */
+# if (!defined(USE_DEFLATE64) && !defined(SFX))
+# define USE_DEFLATE64
+# endif
+#endif
+
+/* disable bzip2 support for SFX stub, unless explicitly requested */
+#if (defined(SFX) && !defined(BZIP2_SFX) && defined(USE_BZIP2))
+# undef USE_BZIP2
+#endif
+
+#if (defined(NO_VMS_TEXT_CONV) || defined(VMS))
+# ifdef VMS_TEXT_CONV
+# undef VMS_TEXT_CONV
+# endif
+#else
+# if (!defined(VMS_TEXT_CONV) && !defined(SFX))
+# define VMS_TEXT_CONV
+# endif
+#endif
+
+/* Enable -B option per default on specific systems, to allow backing up
+ * files that would be overwritten.
+ * (This list of systems must be kept in sync with the list of systems
+ * that add the B_flag to the UzpOpts structure, see unzip.h.)
+ */
+#if (!defined(NO_UNIXBACKUP) && !defined(UNIXBACKUP))
+# if defined(UNIX) || defined(OS2) || defined(WIN32)
+# define UNIXBACKUP
+# endif
+#endif
+
+#if (defined(DLL) && !defined(REENTRANT))
+# define REENTRANT
+#endif
+
+#if (!defined(DYNAMIC_CRC_TABLE) && !defined(FUNZIP))
+# define DYNAMIC_CRC_TABLE
+#endif
+
+#if (defined(DYNAMIC_CRC_TABLE) && !defined(REENTRANT))
+# ifndef DYNALLOC_CRCTAB
+# define DYNALLOC_CRCTAB
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ OS-dependent configuration for UnZip internals
+ ---------------------------------------------------------------------------*/
+
+/* Some compiler distributions for Win32/i386 systems try to emulate
+ * a Unix (POSIX-compatible) environment.
+ */
+#if (defined(WIN32) && defined(UNIX))
+ /* UnZip does not support merging both ports in a single executable. */
+# if (defined(FORCE_WIN32_OVER_UNIX) && defined(FORCE_UNIX_OVER_WIN32))
+ /* conflicting choice requests -> we prefer the Win32 environment */
+# undef FORCE_UNIX_OVER_WIN32
+# endif
+# ifdef FORCE_WIN32_OVER_UNIX
+ /* native Win32 support was explicitly requested... */
+# undef UNIX
+# else
+ /* use the POSIX (Unix) emulation features by default... */
+# undef WIN32
+# endif
+#endif
+
+/* bad or (occasionally?) missing stddef.h: */
+#if (defined(M_XENIX) || defined(DNIX))
+# define NO_STDDEF_H
+#endif
+
+#if (defined(M_XENIX) && !defined(M_UNIX)) /* SCO Xenix only, not SCO Unix */
+# define SCO_XENIX
+# define NO_LIMITS_H /* no limits.h, but MODERN defined */
+# define NO_UID_GID /* no uid_t/gid_t */
+# define size_t int
+#endif
+
+#ifdef realix /* Modcomp Real/IX, real-time SysV.3 variant */
+# define SYSV
+# define NO_UID_GID /* no uid_t/gid_t */
+#endif
+
+#if (defined(_AIX) && !defined(_ALL_SOURCE))
+# define _ALL_SOURCE
+#endif
+
+#if defined(apollo) /* defines __STDC__ */
+# define NO_STDLIB_H
+#endif
+
+#ifdef DNIX
+# define SYSV
+# define SHORT_NAMES /* 14-char limitation on path components */
+/* # define FILENAME_MAX 14 */
+# define FILENAME_MAX NAME_MAX /* GRR: experiment */
+#endif
+
+#if (defined(SYSTEM_FIVE) || defined(__SYSTEM_FIVE))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* SYSTEM_FIVE || __SYSTEM_FIVE */
+#if (defined(M_SYSV) || defined(M_SYS5))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* M_SYSV || M_SYS5 */
+/* __SVR4 and __svr4__ catch Solaris on at least some combos of compiler+OS */
+#if (defined(__SVR4) || defined(__svr4__) || defined(sgi) || defined(__hpux))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* __SVR4 || __svr4__ || sgi || __hpux */
+#if (defined(LINUX) || defined(__QNX__))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* LINUX || __QNX__ */
+
+#if (defined(ultrix) || defined(__ultrix) || defined(bsd4_2))
+# if (!defined(BSD) && !defined(SYSV))
+# define BSD
+# endif
+#endif /* ultrix || __ultrix || bsd4_2 */
+#if (defined(sun) || defined(pyr) || defined(CONVEX))
+# if (!defined(BSD) && !defined(SYSV))
+# define BSD
+# endif
+#endif /* sun || pyr || CONVEX */
+
+#ifdef pyr /* Pyramid: has BSD and AT&T "universes" */
+# ifdef BSD
+# define pyr_bsd
+# define USE_STRINGS_H /* instead of more common string.h */
+# define ZMEM /* ZMEM now uses bcopy/bzero: not in AT&T universe */
+# endif /* (AT&T memcpy claimed to be very slow, though) */
+# define DECLARE_ERRNO
+#endif /* pyr */
+
+/* stat() bug for Borland, VAX C RTL, and Atari ST MiNT on TOS
+ * filesystems: returns 0 for wildcards! (returns 0xffffffff on Minix
+ * filesystem or `U:' drive under Atari MiNT.) Watcom C was previously
+ * included on this list; it would be good to know what version the problem
+ * was fixed at, if it did exist. */
+#if (defined(__TURBOC__) && !defined(WIN32))
+/*# define WILD_STAT_BUG*/
+#endif
+#if (defined(VMS) || defined(__MINT__))
+# define WILD_STAT_BUG
+#endif
+
+/*---------------------------------------------------------------------------
+ OS-dependent includes
+ ---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------
+ API (DLL) section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+# define MAIN UZ_EXP UzpMain /* was UzpUnzip */
+# ifdef OS2DLL
+# undef Info
+# define REDIRECTC(c) varputchar(__G__ c)
+# define REDIRECTPRINT(buf,size) varmessage(__G__ buf, size)
+# define FINISH_REDIRECT() finish_REXX_redirect(__G)
+# else
+# define REDIRECTC(c)
+# define REDIRECTPRINT(buf,size) 0
+# define FINISH_REDIRECT() close_redirect(__G)
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Acorn RISCOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+# include "acorn/riscos.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Amiga section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef AMIGA
+# include "amiga/amiga.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ AOS/VS section (somewhat similar to Unix, apparently):
+ ---------------------------------------------------------------------------*/
+
+#ifdef AOS_VS
+# ifdef __FILEIO_C
+# include "aosvs/aosvs.h"
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Atari ST section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef ATARI
+# include <time.h>
+# include <stat.h>
+# include <fcntl.h>
+# include <limits.h>
+# define SYMLINKS
+# define EXE_EXTENSION ".tos"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_DMY
+# endif
+# define DIR_END '/'
+# define INT_SPRINTF
+# define timezone _timezone
+# define lenEOL 2
+# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
+# undef SHORT_NAMES
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ AtheOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __ATHEOS__
+# include "atheos/athcfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ BeOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __BEOS__
+# include "beos/beocfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Human68k/X680x0 section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __human68k__
+ /* DO NOT DEFINE DOS_OS2 HERE! If Human68k is so much */
+ /* like MS-DOS and/or OS/2, create DOS_H68_OS2 macro. */
+# if (!defined(_MBCS) && !defined(NO_MBCS))
+ /* enable MBCS support by default for this system */
+# define _MBCS
+# endif
+# if (defined(_MBCS) && defined(NO_MBCS))
+ /* disable MBCS support when explicitely requested */
+# undef _MBCS
+# endif
+# include <time.h>
+# include <fcntl.h>
+# include <io.h>
+# include <conio.h>
+# include <sys/stat.h>
+# ifdef HAVE_MBSTRING_H
+# include <mbstring.h>
+# endif
+# ifdef HAVE_MBCTYPE_H
+# include <mbctype.h>
+# else
+# ifndef _ismbblead
+# define _ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c)))
+# endif
+# endif
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_YMD /* Japanese standard */
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+# define INT_SPRINTF
+# define SYMLINKS
+# ifdef SFX
+# define MAIN main_sfx
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Mac section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+# include "maccfg.h"
+#endif /* MACOS */
+
+/*---------------------------------------------------------------------------
+ MS-DOS, OS/2, FLEXOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+# ifdef MORE
+# undef MORE
+# endif
+# ifdef OS2_EAS
+# undef OS2_EAS
+# endif
+#endif
+
+#if (defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)))
+# ifndef MSC
+# define MSC /* This should work for older MSC, too! */
+# endif
+#endif
+
+#if (defined(MSDOS) || defined(OS2) || defined(FLEXOS))
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <io.h> /* lseek(), open(), setftime(), dup(), creat() */
+# include <time.h> /* localtime() */
+# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
+
+# ifdef OS2 /* defined for all OS/2 compilers */
+# include "os2/os2cfg.h"
+# else
+# ifdef FLEXOS
+# include "flexos/flxcfg.h"
+# else
+# include "msdos/doscfg.h"
+# endif
+# endif
+
+# if (defined(_MSC_VER) && (_MSC_VER == 700) && !defined(GRR))
+ /*
+ * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not
+ * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add or
+ * subtract 70 years' worth of seconds; i.e., number of days times 86400;
+ * i.e., (70*365 regular days + 17 leap days + 1 1899 day) * 86400 ==
+ * (25550 + 17 + 1) * 86400 == 2209075200 seconds. We know time_t is an
+ * unsigned long (ulg) on the only system with this bug.
+ */
+# define TIMET_TO_NATIVE(x) (x) += (ulg)2209075200L;
+# define NATIVE_TO_TIMET(x) (x) -= (ulg)2209075200L;
+# endif
+# if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0450))
+# define timezone _timezone
+# endif
+# if (defined(__GO32__) || defined(FLEXOS))
+# define DIR_END '/'
+# else
+# define DIR_END '\\' /* OS uses '\\' as directory separator */
+# define DIR_END2 '/' /* also check for '/' (RTL may convert) */
+# endif
+# ifdef DATE_FORMAT
+# undef DATE_FORMAT
+# endif
+# define DATE_FORMAT dateformat()
+# define lenEOL 2
+# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
+# if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
+# define USE_EF_UT_TIME
+# endif
+#endif /* MSDOS || OS2 || FLEXOS */
+
+/*---------------------------------------------------------------------------
+ MTS section (piggybacks UNIX, I think):
+ ---------------------------------------------------------------------------*/
+
+#ifdef MTS
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <sys/file.h> /* MTS uses this instead of fcntl.h */
+# include <timeb.h>
+# include <time.h>
+# include <unix.h> /* some important non-ANSI routines */
+# define mkdir(s,n) (-1) /* no "make directory" capability */
+# define EBCDIC /* set EBCDIC conversion on */
+# define NO_STRNICMP /* unzip's is as good the one in MTS */
+# define USE_FWRITE
+# define close_outfile() fclose(G.outfile) /* can't set time on files */
+# define umask(n) /* don't have umask() on MTS */
+# define FOPWT "w" /* open file for writing in TEXT mode */
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+#endif /* MTS */
+
+ /*---------------------------------------------------------------------------
+ Novell Netware NLM section
+ ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+# include "netware/nlmcfg.h"
+#endif
+
+ /*---------------------------------------------------------------------------
+ QDOS section
+ ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+# define DIRENT
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/stat.h>
+# include <time.h>
+# include "qdos/izqdos.h"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+# define DIR_END '_'
+# define RETURN QReturn
+# undef PATH_MAX
+# define PATH_MAX 36
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+# endif
+# define SCREENSIZE(ttrows, ttcols) screensize(ttrows, ttcols)
+# define SCREENWIDTH 80
+#endif
+
+/*---------------------------------------------------------------------------
+ Tandem NSK section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TANDEM
+# include "tandem.h"
+# include <fcntl.h>
+# ifndef __INT32
+ /* We are compiling with non-WIDE memory model, int = 16 bits */
+# ifndef INT_16BIT
+# define INT_16BIT /* report "int" size is 16-bit to inflate setup */
+# endif
+# ifdef USE_DEFLATE64
+ /* Following required for 64k WSIZE of Deflate64 support */
+# define MED_MEM /* else OUTBUFSIZ is 64K and fails in do_string */
+# define INBUFSIZ 8192 /* but larger buffer for real OSes */
+# endif
+# endif
+ /* use a single LF delimiter so that writes to 101 text files work */
+# define PutNativeEOL *q++ = native(LF);
+# define lenEOL 1
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_DMY
+# endif
+# define SCREENLINES 25
+ /* USE_EF_UT_TIME is set in tandem.h */
+# define RESTORE_UIDGID
+# define NO_STRNICMP
+#endif
+
+/*---------------------------------------------------------------------------
+ THEOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+# include "theos/thscfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ TOPS-20 section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <sys/param.h>
+# include <sys/time.h>
+# include <sys/timeb.h>
+# include <sys/file.h>
+# include <timex.h>
+# include <monsym.h> /* get amazing monsym() macro */
+ extern int open(), close(), read();
+ extern int stat(), unlink(), jsys(), fcntl();
+ extern long lseek(), dup(), creat();
+# define strchr index /* GRR: necessary? */
+# define strrchr rindex
+# define REALLY_SHORT_SYMS
+# define NO_MKDIR
+# ifndef HAVE_STRNICMP
+# define NO_STRNICMP /* probably not provided by TOPS20 C RTL */
+# endif
+# define DIR_BEG '<'
+# define DIR_END '>'
+# define DIR_EXT ".directory"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define EXE_EXTENSION ".exe" /* just a guess... */
+#endif /* TOPS20 */
+
+/*---------------------------------------------------------------------------
+ Unix section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef UNIX
+# include "unix/unxcfg.h"
+#endif /* UNIX */
+
+/*---------------------------------------------------------------------------
+ VM/CMS and MVS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+# include "vmmvs.h"
+# define CLOSE_INFILE() close_infile(__G)
+#endif
+
+/*---------------------------------------------------------------------------
+ VMS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+# include "vms/vmscfg.h"
+#endif /* VMS */
+
+/*---------------------------------------------------------------------------
+ Win32 (Windows 95/NT) section:
+ ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && !defined(POCKET_UNZIP) && !defined(_WIN32_WCE))
+# include "win32/w32cfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Win32 Windows CE section (also POCKET_UNZIP)
+ ---------------------------------------------------------------------------*/
+
+#if (defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+# include "wince/wcecfg.h"
+#endif
+
+
+
+/* ----------------------------------------------------------------------------
+ MUST BE AFTER LARGE FILE INCLUDES
+ ---------------------------------------------------------------------------- */
+/* This stuff calls in types and messes up large file includes. It needs to
+ go after large file defines in local includes.
+ I am guessing that moving them here probably broke some ports, but hey.
+ 10/31/2004 EG */
+/* ----------------------------------------------------------------------------
+ Common includes
+ ---------------------------------------------------------------------------- */
+
+/* Some ports apply specific adjustments which must be in effect before
+ reading the "standard" include headers.
+ */
+
+#ifdef EFT
+# define Z_OFF_T off_t /* Amdahl UTS nonsense ("extended file types") */
+#else
+#if (defined(UNIX) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64))
+# define Z_OFF_T off_t /* 64bit offsets to support 2GB < zipfile size < 4GB */
+#else
+# define Z_OFF_T long
+#endif
+#endif
+
+#ifndef ZOFF_T_DEFINED
+ typedef Z_OFF_T zoff_t;
+# define ZOFF_T_DEFINED
+#endif
+#ifndef Z_STAT_DEFINED
+ typedef struct stat z_stat;
+# define Z_STAT_DEFINED
+#endif
+
+#ifndef MINIX /* Minix needs it after all the other includes (?) */
+# include <stdio.h>
+#endif
+
+#include <ctype.h> /* skip for VMS, to use tolower() function? */
+#include <errno.h> /* used in mapname() */
+#ifdef USE_STRINGS_H
+# include <strings.h> /* strcpy, strcmp, memcpy, index/rindex, etc. */
+#else
+# include <string.h> /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */
+#endif
+#if (defined(MODERN) && !defined(NO_LIMITS_H))
+# include <limits.h> /* MAX/MIN constant symbols for system types... */
+#endif
+
+/* this include must be down here for SysV.4, for some reason... */
+#include <signal.h> /* used in unzip.c, fileio.c */
+
+
+#ifdef MODERN
+# ifndef NO_STDDEF_H
+# include <stddef.h>
+# endif
+# ifndef NO_STDLIB_H
+# include <stdlib.h> /* standard library prototypes, malloc(), etc. */
+# endif
+ typedef size_t extent;
+#else /* !MODERN */
+# ifndef AOS_VS /* mostly modern? */
+ Z_OFF_T lseek();
+# ifdef VAXC /* not fully modern, but has stdlib.h and void */
+# include <stdlib.h>
+# else
+ char *malloc();
+# endif /* ?VAXC */
+# endif /* !AOS_VS */
+ typedef unsigned int extent;
+#endif /* ?MODERN */
+
+
+
+
+/*************/
+/* Defines */
+/*************/
+
+#define UNZIP_BZ2VERS 46
+#ifdef ZIP64_SUPPORT
+# ifdef USE_BZIP2
+# define UNZIP_VERSION UNZIP_BZ2VERS
+# else
+# define UNZIP_VERSION 45
+# endif
+#else
+#ifdef USE_DEFLATE64
+# define UNZIP_VERSION 21 /* compatible with PKUNZIP 4.0 */
+#else
+# define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */
+#endif
+#endif
+#define VMS_UNZIP_VERSION 42 /* if OS-needed-to-extract is VMS: can do */
+
+#if (defined(MSDOS) || defined(OS2))
+# define DOS_OS2
+#endif
+
+#if (defined(OS2) || defined(WIN32))
+# define OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(WIN32))
+# define DOS_OS2_W32
+# define DOS_W32_OS2 /* historical: don't use */
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(__human68k__))
+# define DOS_H68_OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(FLEXOS))
+# define DOS_FLX_OS2
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(FLEXOS))
+# define DOS_FLX_OS2_W32
+#endif
+
+#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS))
+# define DOS_FLX_H68_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_OS2) || defined(NLM))
+# define DOS_FLX_NLM_OS2
+#endif
+
+#if (defined(DOS_FLX_OS2_W32) || defined(NLM))
+# define DOS_FLX_NLM_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_H68_OS2_W32) || defined(NLM))
+# define DOS_FLX_H68_NLM_OS2_W32
+#endif
+
+#if (defined(TOPS20) || defined(VMS))
+# define T20_VMS
+#endif
+
+#if (defined(MSDOS) || defined(T20_VMS))
+# define DOS_T20_VMS
+#endif
+
+#if (defined(__ATHEOS__) || defined(__BEOS__))
+# define ATH_BEO
+#endif
+
+#if (defined(ATH_BEO) || defined(UNIX))
+# define ATH_BEO_UNX
+#endif
+
+#if (defined(ATH_BEO_UNX) || defined(THEOS))
+# define ATH_BEO_THS_UNX
+#endif
+
+/* clean up with a few defaults */
+#ifndef DIR_END
+# define DIR_END '/' /* last char before program name or filename */
+#endif
+#ifndef DATE_FORMAT
+# ifdef DATEFMT_ISO_DEFAULT
+# define DATE_FORMAT DF_YMD /* defaults to invariant ISO-style */
+# else
+# define DATE_FORMAT DF_MDY /* defaults to US convention */
+# endif
+#endif
+#ifndef DATE_SEPCHAR
+# define DATE_SEPCHAR '-'
+#endif
+#ifndef CLOSE_INFILE
+# define CLOSE_INFILE() close(G.zipfd)
+#endif
+#ifndef RETURN
+# define RETURN return /* only used in main() */
+#endif
+#ifndef EXIT
+# define EXIT exit
+#endif
+#ifndef USAGE
+# define USAGE(ret) usage(__G__ (ret)) /* used in unzip.c, zipinfo.c */
+#endif
+#ifndef TIMET_TO_NATIVE /* everybody but MSC 7.0 and Macintosh */
+# define TIMET_TO_NATIVE(x)
+# define NATIVE_TO_TIMET(x)
+#endif
+#ifndef STRNICMP
+# ifdef NO_STRNICMP
+# define STRNICMP zstrnicmp
+# else
+# define STRNICMP strnicmp
+# endif
+#endif
+
+
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_UNX) || defined(RISCOS))
+# ifndef HAVE_UNLINK
+# define HAVE_UNLINK
+# endif
+#endif
+#if (defined(AOS_VS) || defined(ATARI)) /* GRR: others? */
+# ifndef HAVE_UNLINK
+# define HAVE_UNLINK
+# endif
+#endif
+
+/* OS-specific exceptions to the "ANSI <--> INT_SPRINTF" rule */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+# if (defined(SYSV) || defined(CONVEX) || defined(NeXT) || defined(BSD4_4))
+# define INT_SPRINTF /* sprintf() returns int: SysVish/Posix */
+# endif
+# if (defined(DOS_FLX_NLM_OS2_W32) || defined(VMS) || defined(AMIGA))
+# define INT_SPRINTF /* sprintf() returns int: ANSI */
+# endif
+# if (defined(ultrix) || defined(__ultrix)) /* Ultrix 4.3 and newer */
+# if (defined(POSIX) || defined(__POSIX))
+# define INT_SPRINTF /* sprintf() returns int: ANSI/Posix */
+# endif
+# ifdef __GNUC__
+# define PCHAR_SPRINTF /* undetermined actual return value */
+# endif
+# endif
+# if (defined(__osf__) || defined(_AIX) || defined(CMS_MVS) || defined(THEOS))
+# define INT_SPRINTF /* sprintf() returns int: ANSI/Posix */
+# endif
+# if defined(sun)
+# define PCHAR_SPRINTF /* sprintf() returns char *: SunOS cc *and* gcc */
+# endif
+#endif
+
+/* defaults that we hope will take care of most machines in the future */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+# ifdef __STDC__
+# define INT_SPRINTF /* sprintf() returns int: ANSI */
+# endif
+# ifndef INT_SPRINTF
+# define PCHAR_SPRINTF /* sprintf() returns char *: BSDish */
+# endif
+#endif
+
+#define MSG_STDERR(f) (f & 1) /* bit 0: 0 = stdout, 1 = stderr */
+#define MSG_INFO(f) ((f & 6) == 0) /* bits 1 and 2: 0 = info */
+#define MSG_WARN(f) ((f & 6) == 2) /* bits 1 and 2: 1 = warning */
+#define MSG_ERROR(f) ((f & 6) == 4) /* bits 1 and 2: 2 = error */
+#define MSG_FATAL(f) ((f & 6) == 6) /* bits 1 and 2: (3 = fatal error) */
+#define MSG_ZFN(f) (f & 0x0008) /* bit 3: 1 = print zipfile name */
+#define MSG_FN(f) (f & 0x0010) /* bit 4: 1 = print filename */
+#define MSG_LNEWLN(f) (f & 0x0020) /* bit 5: 1 = leading newline if !SOL */
+#define MSG_TNEWLN(f) (f & 0x0040) /* bit 6: 1 = trailing newline if !SOL */
+#define MSG_MNEWLN(f) (f & 0x0080) /* bit 7: 1 = trailing NL for prompts */
+/* the following are subject to change */
+#define MSG_NO_WGUI(f) (f & 0x0100) /* bit 8: 1 = skip if Windows GUI */
+#define MSG_NO_AGUI(f) (f & 0x0200) /* bit 9: 1 = skip if Acorn GUI */
+#define MSG_NO_DLL2(f) (f & 0x0400) /* bit 10: 1 = skip if OS/2 DLL */
+#define MSG_NO_NDLL(f) (f & 0x0800) /* bit 11: 1 = skip if WIN32 DLL */
+#define MSG_NO_WDLL(f) (f & 0x1000) /* bit 12: 1 = skip if Windows DLL */
+
+#if (defined(MORE) && !defined(SCREENLINES))
+# ifdef DOS_FLX_NLM_OS2_W32
+# define SCREENLINES 25 /* can be (should be) a function instead */
+# else
+# define SCREENLINES 24 /* VT-100s are assumed to be minimal hardware */
+# endif
+#endif
+#if (defined(MORE) && !defined(SCREENSIZE))
+# ifndef SCREENWIDTH
+# define SCREENSIZE(scrrows, scrcols) { \
+ if ((scrrows) != NULL) *(scrrows) = SCREENLINES; }
+# else
+# define SCREENSIZE(scrrows, scrcols) { \
+ if ((scrrows) != NULL) *(scrrows) = SCREENLINES; \
+ if ((scrcols) != NULL) *(scrcols) = SCREENWIDTH; }
+# endif
+#endif
+
+#if (defined(__16BIT__) || defined(MED_MEM) || defined(SMALL_MEM))
+# define DIR_BLKSIZ 64 /* number of directory entries per block
+ * (should fit in 4096 bytes, usually) */
+#else
+# define DIR_BLKSIZ 16384 /* use more memory, to reduce long-range seeks */
+#endif
+
+#ifndef WSIZE
+# ifdef USE_DEFLATE64
+# define WSIZE 65536L /* window size--must be a power of two, and */
+# else /* at least 64K for PKZip's deflate64 method */
+# define WSIZE 0x8000 /* window size--must be a power of two, and */
+# endif /* at least 32K for zip's deflate method */
+#endif
+
+#ifdef __16BIT__
+# ifndef INT_16BIT
+# define INT_16BIT /* on 16-bit systems int size is 16 bits */
+# endif
+#else
+# define nearmalloc malloc
+# define nearfree free
+# if (!defined(__IBMC__) || !defined(OS2))
+# ifndef near
+# define near
+# endif
+# ifndef far
+# define far
+# endif
+# endif
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && !defined(DYNAMIC_CRC_TABLE))
+# undef DYNALLOC_CRCTAB
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
+# undef DYNALLOC_CRCTAB /* not safe with reentrant code */
+#endif
+
+#if (defined(USE_ZLIB) && !defined(USE_OWN_CRCTAB))
+# ifdef DYNALLOC_CRCTAB
+# undef DYNALLOC_CRCTAB
+# endif
+#endif
+
+#if (defined(USE_ZLIB) && defined(ASM_CRC))
+# undef ASM_CRC
+#endif
+
+#ifdef USE_ZLIB
+# ifdef IZ_CRC_BE_OPTIMIZ
+# undef IZ_CRC_BE_OPTIMIZ
+# endif
+# ifdef IZ_CRC_LE_OPTIMIZ
+# undef IZ_CRC_LE_OPTIMIZ
+# endif
+#endif
+#if (!defined(IZ_CRC_BE_OPTIMIZ) && !defined(IZ_CRC_LE_OPTIMIZ))
+# ifdef IZ_CRCOPTIM_UNFOLDTBL
+# undef IZ_CRCOPTIM_UNFOLDTBL
+# endif
+#endif
+
+#ifndef INBUFSIZ
+# if (defined(MED_MEM) || defined(SMALL_MEM))
+# define INBUFSIZ 2048 /* works for MS-DOS small model */
+# else
+# define INBUFSIZ 8192 /* larger buffers for real OSes */
+# endif
+#endif
+
+#if (defined(INT_16BIT) && (defined(USE_DEFLATE64) || lenEOL > 1))
+ /* For environments using 16-bit integers OUTBUFSIZ must be limited to
+ * less than 64k (do_string() uses "unsigned" in calculations involving
+ * OUTBUFSIZ). This is achieved by defining MED_MEM when WSIZE = 64k (aka
+ * Deflate64 support enabled) or EOL markers contain multiple characters.
+ * (The rule gets applied AFTER the default rule for INBUFSIZ because it
+ * is not neccessary to reduce INBUFSIZE in this case.)
+ */
+# if (!defined(SMALL_MEM) && !defined(MED_MEM))
+# define MED_MEM
+# endif
+#endif
+
+/* Logic for case of small memory, length of EOL > 1: if OUTBUFSIZ == 2048,
+ * OUTBUFSIZ>>1 == 1024 and OUTBUFSIZ>>7 == 16; therefore rawbuf is 1008 bytes
+ * and transbuf 1040 bytes. Have room for 32 extra EOL chars; 1008/32 == 31.5
+ * chars/line, smaller than estimated 35-70 characters per line for C source
+ * and normal text. Hence difference is sufficient for most "average" files.
+ * (Argument scales for larger OUTBUFSIZ.)
+ */
+#ifdef SMALL_MEM /* i.e., 16-bit OSes: MS-DOS, OS/2 1.x, etc. */
+# define LoadFarString(x) fLoadFarString(__G__ (x))
+# define LoadFarStringSmall(x) fLoadFarStringSmall(__G__ (x))
+# define LoadFarStringSmall2(x) fLoadFarStringSmall2(__G__ (x))
+# if (defined(_MSC_VER) && (_MSC_VER >= 600))
+# define zfstrcpy(dest, src) _fstrcpy((dest), (src))
+# define zfstrcmp(s1, s2) _fstrcmp((s1), (s2))
+# endif
+# if !(defined(SFX) || defined(FUNZIP))
+# if (defined(_MSC_VER))
+# define zfmalloc(sz) _fmalloc((sz))
+# define zffree(x) _ffree(x)
+# endif
+# if (defined(__TURBOC__))
+# include <alloc.h>
+# define zfmalloc(sz) farmalloc((unsigned long)(sz))
+# define zffree(x) farfree(x)
+# endif
+# endif /* !(SFX || FUNZIP) */
+# ifndef Far
+# define Far far /* __far only works for MSC 6.00, not 6.0a or Borland */
+# endif
+# define OUTBUFSIZ INBUFSIZ
+# if (lenEOL == 1)
+# define RAWBUFSIZ (OUTBUFSIZ>>1)
+# else
+# define RAWBUFSIZ ((OUTBUFSIZ>>1) - (OUTBUFSIZ>>7))
+# endif
+# define TRANSBUFSIZ (OUTBUFSIZ-RAWBUFSIZ)
+ typedef short shrint; /* short/int or "shrink int" (unshrink) */
+#else
+# define zfstrcpy(dest, src) strcpy((dest), (src))
+# define zfstrcmp(s1, s2) strcmp((s1), (s2))
+# define zfmalloc malloc
+# define zffree(x) free(x)
+# ifdef QDOS
+# define LoadFarString(x) Qstrfix(x) /* fix up _ for '.' */
+# define LoadFarStringSmall(x) Qstrfix(x)
+# define LoadFarStringSmall2(x) Qstrfix(x)
+# else
+# define LoadFarString(x) (char *)(x)
+# define LoadFarStringSmall(x) (char *)(x)
+# define LoadFarStringSmall2(x) (char *)(x)
+# endif
+# ifdef MED_MEM
+# define OUTBUFSIZ 0xFF80 /* can't malloc arrays of 0xFFE8 or more */
+# define TRANSBUFSIZ 0xFF80
+ typedef short shrint;
+# else
+# define OUTBUFSIZ (lenEOL*WSIZE) /* more efficient text conversion */
+# define TRANSBUFSIZ (lenEOL*OUTBUFSIZ)
+# ifdef AMIGA
+ typedef short shrint;
+# else
+ typedef int shrint; /* for efficiency/speed, we hope... */
+# endif
+# endif /* ?MED_MEM */
+# define RAWBUFSIZ OUTBUFSIZ
+#endif /* ?SMALL_MEM */
+
+#ifndef Far
+# define Far
+#endif
+
+#ifndef Cdecl
+# define Cdecl
+#endif
+
+#ifndef MAIN
+# define MAIN main
+#endif
+
+#ifdef SFX /* disable some unused features for SFX executables */
+# ifndef NO_ZIPINFO
+# define NO_ZIPINFO
+# endif
+# ifdef TIMESTAMP
+# undef TIMESTAMP
+# endif
+#endif
+
+#ifdef SFX
+# ifdef CHEAP_SFX_AUTORUN
+# ifndef NO_SFX_EXDIR
+# define NO_SFX_EXDIR
+# endif
+# endif
+# ifndef NO_SFX_EXDIR
+# ifndef SFX_EXDIR
+# define SFX_EXDIR
+# endif
+# else
+# ifdef SFX_EXDIR
+# undef SFX_EXDIR
+# endif
+# endif
+#endif
+
+/* user may have defined both by accident... NOTIMESTAMP takes precedence */
+#if (defined(TIMESTAMP) && defined(NOTIMESTAMP))
+# undef TIMESTAMP
+#endif
+
+#if (!defined(COPYRIGHT_CLEAN) && !defined(USE_SMITH_CODE))
+# define COPYRIGHT_CLEAN
+#endif
+
+/* The LZW patent is expired worldwide since 2004-Jul-07, so USE_UNSHRINK
+ * is now enabled by default. See unshrink.c.
+ */
+#if (!defined(LZW_CLEAN) && !defined(USE_UNSHRINK))
+# define USE_UNSHRINK
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#ifndef PIPE_ERROR
+# ifndef EPIPE
+# define EPIPE -1
+# endif
+# define PIPE_ERROR (errno == EPIPE)
+#endif
+
+/* File operations--use "b" for binary if allowed or fixed length 512 on VMS */
+#ifdef VMS
+# define FOPR "r","ctx=stm"
+# define FOPM "r+","ctx=stm","rfm=fix","mrs=512"
+# define FOPW "w","ctx=stm","rfm=fix","mrs=512"
+# define FOPWR "w+","ctx=stm","rfm=fix","mrs=512"
+#endif /* VMS */
+
+#ifdef CMS_MVS
+/* Binary files must be RECFM=F,LRECL=1 for ftell() to get correct pos */
+/* ...unless byteseek is used. Let's try that for a while. */
+# define FOPR "rb,byteseek"
+# define FOPM "r+b,byteseek"
+# ifdef MVS
+# define FOPW "wb,recfm=u,lrecl=32760,byteseek" /* New binary files */
+# define FOPWE "wb" /* Existing binary files */
+# define FOPWT "w,lrecl=133" /* New text files */
+# define FOPWTE "w" /* Existing text files */
+# else
+# define FOPW "wb,recfm=v,lrecl=32760"
+# define FOPWT "w"
+# endif
+#endif /* CMS_MVS */
+
+#ifdef TOPS20 /* TOPS-20 MODERN? You kidding? */
+# define FOPW "w8"
+#endif /* TOPS20 */
+
+/* Defaults when nothing special has been defined previously. */
+#ifdef MODERN
+# ifndef FOPR
+# define FOPR "rb"
+# endif
+# ifndef FOPM
+# define FOPM "r+b"
+# endif
+# ifndef FOPW
+# define FOPW "wb"
+# endif
+# ifndef FOPWT
+# define FOPWT "wt"
+# endif
+# ifndef FOPWR
+# define FOPWR "w+b"
+# endif
+#else /* !MODERN */
+# ifndef FOPR
+# define FOPR "r"
+# endif
+# ifndef FOPM
+# define FOPM "r+"
+# endif
+# ifndef FOPW
+# define FOPW "w"
+# endif
+# ifndef FOPWT
+# define FOPWT "w"
+# endif
+# ifndef FOPWR
+# define FOPWR "w+"
+# endif
+#endif /* ?MODERN */
+
+/*
+ * If <limits.h> exists on most systems, should include that, since it may
+ * define some or all of the following: NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
+ * _POSIX_PATH_MAX.
+ */
+#ifdef DOS_FLX_NLM_OS2_W32
+# include <limits.h>
+#endif
+
+/* 2008-07-22 SMS.
+ * Unfortunately, on VMS, <limits.h> exists, and is included by <stdlib.h>
+ * (so it's pretty much unavoidable), and it defines PATH_MAX to a fixed
+ * short value (256, correct only for older systems without ODS-5 support),
+ * rather than one based on the real RMS NAM[L] situation. So, we
+ * artificially undefine it here, to allow our better-defined _MAX_PATH
+ * (see vms/vmscfg.h) to be used.
+ */
+#ifdef VMS
+# undef PATH_MAX
+#endif
+
+#ifndef PATH_MAX
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN /* in <sys/param.h> on some systems */
+# else
+# ifdef _MAX_PATH
+# define PATH_MAX _MAX_PATH
+# else
+# if FILENAME_MAX > 255
+# define PATH_MAX FILENAME_MAX /* used like PATH_MAX on some systems */
+# else
+# define PATH_MAX 1024
+# endif
+# endif /* ?_MAX_PATH */
+# endif /* ?MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+/*
+ * buffer size required to hold the longest legal local filepath
+ * (including the trailing '\0')
+ */
+#define FILNAMSIZ PATH_MAX
+
+#ifdef UNICODE_SUPPORT
+# if !(defined(UTF8_MAYBE_NATIVE) || defined(UNICODE_WCHAR))
+# undef UNICODE_SUPPORT
+# endif
+#endif
+/* 2007-09-18 SMS.
+ * Include <locale.h> here if it will be needed later for Unicode.
+ * Otherwise, SETLOCALE may be defined here, and then defined again
+ * (differently) when <locale.h> is read later.
+ */
+#ifdef UNICODE_SUPPORT
+# ifdef UNICODE_WCHAR
+# if !(defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+# include <wchar.h>
+# include <wctype.h>
+# endif
+# endif
+# ifndef _MBCS /* no need to include <locale.h> twice, see below */
+# include <locale.h>
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale) setlocale(category, locale)
+# endif
+# endif
+#endif /* UNICODE_SUPPORT */
+
+/* DBCS support for Info-ZIP (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ */
+#ifdef _MBCS
+# include <locale.h>
+ /* Multi Byte Character Set */
+# define ___MBS_TMP_DEF char *___tmp_ptr;
+# define ___TMP_PTR ___tmp_ptr
+# ifndef CLEN
+# define NEED_UZMBCLEN
+# define CLEN(ptr) (int)uzmbclen((ZCONST unsigned char *)(ptr))
+# endif
+# ifndef PREINCSTR
+# define PREINCSTR(ptr) (ptr += CLEN(ptr))
+# endif
+# define POSTINCSTR(ptr) (___TMP_PTR=(char *)(ptr), PREINCSTR(ptr),___TMP_PTR)
+ char *plastchar OF((ZCONST char *ptr, extent len));
+# define lastchar(ptr, len) ((int)(unsigned)*plastchar(ptr, len))
+# ifndef MBSCHR
+# define NEED_UZMBSCHR
+# define MBSCHR(str,c) (char *)uzmbschr((ZCONST unsigned char *)(str), c)
+# endif
+# ifndef MBSRCHR
+# define NEED_UZMBSRCHR
+# define MBSRCHR(str,c) (char *)uzmbsrchr((ZCONST unsigned char *)(str), c)
+# endif
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale) setlocale(category, locale)
+# endif
+#else /* !_MBCS */
+# define ___MBS_TMP_DEF
+# define ___TMP_PTR
+# define CLEN(ptr) 1
+# define PREINCSTR(ptr) (++(ptr))
+# define POSTINCSTR(ptr) ((ptr)++)
+# define plastchar(ptr, len) (&ptr[(len)-1])
+# define lastchar(ptr, len) (ptr[(len)-1])
+# define MBSCHR(str, c) strchr(str, c)
+# define MBSRCHR(str, c) strrchr(str, c)
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale)
+# endif
+#endif /* ?_MBCS */
+#define INCSTR(ptr) PREINCSTR(ptr)
+
+
+#if (defined(MALLOC_WORK) && !defined(MY_ZCALLOC))
+ /* Any system without a special calloc function */
+# ifndef zcalloc
+# define zcalloc(items, size) \
+ (zvoid far *)calloc((unsigned)(items), (unsigned)(size))
+# endif
+# ifndef zcfree
+# define zcfree free
+# endif
+#endif /* MALLOC_WORK && !MY_ZCALLOC */
+
+#if (defined(CRAY) && defined(ZMEM))
+# undef ZMEM
+#endif
+
+#ifdef ZMEM
+# undef ZMEM
+# define memcmp(b1,b2,len) bcmp(b2,b1,len)
+# define memcpy(dest,src,len) bcopy(src,dest,len)
+# define memzero bzero
+#else
+# define memzero(dest,len) memset(dest,0,len)
+#endif
+
+#ifndef TRUE
+# define TRUE 1 /* sort of obvious */
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+
+#if (!defined(S_IEXEC) && defined(S_IXUSR))
+# define S_IEXEC S_IXUSR
+#endif
+
+#if (defined(UNIX) && defined(S_IFLNK) && !defined(MTS))
+# define SYMLINKS
+# ifndef S_ISLNK
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# endif
+#endif /* UNIX && S_IFLNK && !MTS */
+
+#ifndef S_ISDIR
+# ifdef CMS_MVS
+# define S_ISDIR(m) (FALSE)
+# else
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# endif
+#endif
+
+#ifndef IS_VOLID
+# define IS_VOLID(m) ((m) & 0x08)
+#endif
+
+/***********************************/
+/* LARGE_FILE_SUPPORT */
+/***********************************/
+/* This whole section lifted from Zip 3b tailor.h
+
+ * Types are in OS dependent headers (eg, w32cfg.h)
+ *
+ * LARGE_FILE_SUPPORT and ZIP64_SUPPORT are automatically
+ * set in OS dependent headers (for some ports) based on the port and compiler.
+ *
+ * Function prototypes are below as OF is defined earlier in this file
+ * but after OS dependent header is included.
+ *
+ * E. Gordon 9/21/2003
+ * Updated 1/28/2004
+ * Lifted and placed here 6/7/2004 - Myles Bennett
+ */
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+/* ---------------------------- */
+
+# if defined(UNIX) || defined(VMS)
+
+ /* 64-bit stat functions */
+# define zstat stat
+# define zfstat fstat
+
+ /* 64-bit fseeko */
+# define zlseek lseek
+# define zfseeko fseeko
+
+ /* 64-bit ftello */
+# define zftello ftello
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif /* UNIX || VMS */
+
+/* ---------------------------- */
+
+# ifdef WIN32
+
+# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__LCC__)
+ /* MS C (VC), MinGW GCC port and LCC-32 use the MS C Runtime lib */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# define zfstat _fstati64
+
+ /* 64-bit lseek */
+# define zlseek _lseeki64
+
+# if defined(_MSC_VER) && (_MSC_VER >= 1400)
+ /* Beginning with VS 8.0 (Visual Studio 2005, MSC 14), the Microsoft
+ C rtl publishes its (previously internal) implmentations of
+ "fseeko" and "ftello" for 64-bit file offsets. */
+ /* 64-bit fseeko */
+# define zfseeko _fseeki64
+ /* 64-bit ftello */
+# define zftello _ftelli64
+
+# else /* not (defined(_MSC_VER) && (_MSC_VER >= 1400)) */
+
+# if defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__ >= 0x800)
+ /* Up-to-date versions of MinGW define the macro __MSVCRT_VERSION__
+ to denote the version of the MS C rtl dll used for linking. When
+ configured to link against the runtime of MS Visual Studio 8 (or
+ newer), the built-in 64-bit fseek/ftell functions are available. */
+ /* 64-bit fseeko */
+# define zfseeko _fseeki64
+ /* 64-bit ftello */
+# define zftello _ftelli64
+
+# else /* !(defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__>=0x800)) */
+ /* The version of the C runtime is lower than MSC 14 or unknown. */
+
+ /* The newest MinGW port contains built-in extensions to the MSC rtl
+ that provide fseeko and ftello, but our implementations will do
+ for now. */
+ /* 64-bit fseeko */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ zoff_t zftello OF((FILE *));
+
+# endif /* ? (__MSVCRT_VERSION__ >= 0x800) */
+# endif /* ? (_MSC_VER >= 1400) */
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif /* _MSC_VER || __MINGW__ || __LCC__ */
+
+# ifdef __CYGWIN__
+ /* CYGWIN GCC Posix emulator on Windows
+ (configuration not yet finished/tested) */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# define zfstat _fstati64
+
+ /* 64-bit lseek */
+# define zlseek _lseeki64
+
+ /* 64-bit fseeko */
+# define zfseeko fseeko
+
+ /* 64-bit ftello */
+# define zftello ftello
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+# if defined(__WATCOMC__) || defined(__BORLANDC__)
+ /* WATCOM C and Borland C provide their own C runtime libraries,
+ but they are sufficiently compatible with MS CRTL. */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# define zfstat _fstati64
+
+# ifdef __WATCOMC__
+ /* 64-bit lseek */
+# define zlseek _lseeki64
+# endif
+
+ /* 64-bit fseeko */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ zoff_t zftello OF((FILE *));
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+# ifdef __IBMC__
+ /* IBM C */
+
+ /* 64-bit stat functions */
+
+ /* 64-bit fseeko */
+
+ /* 64-bit ftello */
+
+ /* 64-bit fopen */
+
+# endif
+
+# endif /* WIN32 */
+
+#else
+ /* No Large File Support */
+
+# ifndef REGULUS /* returns the inode number on success(!)...argh argh argh */
+# define zstat stat
+# endif
+# define zfstat fstat
+# define zlseek lseek
+# define zfseeko fseek
+# define zftello ftell
+# define zfopen fopen
+# define zfdopen fdopen
+
+# if defined(UNIX) || defined(VMS) || defined(WIN32)
+ /* For these systems, implement "64bit file vs. 32bit prog" check */
+# ifndef DO_SAFECHECK_2GB
+# define DO_SAFECHECK_2GB
+# endif
+# endif
+
+#endif
+
+/* No "64bit file vs. 32bit prog" check for SFX stub, to save space */
+#if (defined(DO_SAFECHECK_2GB) && defined(SFX))
+# undef DO_SAFECHECK_2GB
+#endif
+
+#ifndef SSTAT
+# ifdef WILD_STAT_BUG
+# define SSTAT(path,pbuf) (iswild(path) || zstat(path,pbuf))
+# else
+# define SSTAT zstat
+# endif
+#endif
+
+
+/* Default fzofft() format selection. */
+
+#ifndef FZOFFT_FMT
+
+# ifdef LARGE_FILE_SUPPORT
+# define FZOFFT_FMT "ll"
+# define FZOFFT_HEX_WID_VALUE "16"
+# else /* def LARGE_FILE_SUPPORT */
+# define FZOFFT_FMT "l"
+# define FZOFFT_HEX_WID_VALUE "8"
+# endif /* def LARGE_FILE_SUPPORT */
+
+#endif /* ndef FZOFFT_FMT */
+
+#define FZOFFT_HEX_WID ((char *) -1)
+#define FZOFFT_HEX_DOT_WID ((char *) -2)
+
+#define FZOFFT_NUM 4 /* Number of chambers. */
+#define FZOFFT_LEN 24 /* Number of characters/chamber. */
+
+
+#ifdef SHORT_SYMS /* Mark Williams C, ...? */
+# define extract_or_test_files xtr_or_tst_files
+# define extract_or_test_member xtr_or_tst_member
+#endif
+
+#ifdef REALLY_SHORT_SYMS /* TOPS-20 linker: first 6 chars */
+# define process_cdir_file_hdr XXpcdfh
+# define process_local_file_hdr XXplfh
+# define extract_or_test_files XXxotf /* necessary? */
+# define extract_or_test_member XXxotm /* necessary? */
+# define check_for_newer XXcfn
+# define overwrite_all XXoa
+# define process_all_files XXpaf
+# define extra_field XXef
+# define explode_lit8 XXel8
+# define explode_lit4 XXel4
+# define explode_nolit8 XXnl8
+# define explode_nolit4 XXnl4
+# define cpdist8 XXcpdist8
+# define inflate_codes XXic
+# define inflate_stored XXis
+# define inflate_fixed XXif
+# define inflate_dynamic XXid
+# define inflate_block XXib
+# define maxcodemax XXmax
+#endif
+
+#ifndef S_TIME_T_MAX /* max value of signed (>= 32-bit) time_t */
+# define S_TIME_T_MAX ((time_t)(ulg)0x7fffffffL)
+#endif
+#ifndef U_TIME_T_MAX /* max value of unsigned (>= 32-bit) time_t */
+# define U_TIME_T_MAX ((time_t)(ulg)0xffffffffL)
+#endif
+#ifdef DOSTIME_MINIMUM /* min DOSTIME value (1980-01-01) */
+# undef DOSTIME_MINIMUM
+#endif
+#define DOSTIME_MINIMUM ((ulg)0x00210000L)
+#ifdef DOSTIME_2038_01_18 /* approximate DOSTIME equivalent of */
+# undef DOSTIME_2038_01_18 /* the signed-32-bit time_t limit */
+#endif
+#define DOSTIME_2038_01_18 ((ulg)0x74320000L)
+
+#ifdef QDOS
+# define ZSUFX "_zip"
+# define ALT_ZSUFX ".zip"
+#else
+# ifdef RISCOS
+# define ZSUFX "/zip"
+# else
+# define ZSUFX ".zip"
+# endif
+# define ALT_ZSUFX ".ZIP" /* Unix-only so far (only case-sensitive fs) */
+#endif
+
+#define CENTRAL_HDR_SIG "\001\002" /* the infamous "PK" signature bytes, */
+#define LOCAL_HDR_SIG "\003\004" /* w/o "PK" (so unzip executable not */
+#define END_CENTRAL_SIG "\005\006" /* mistaken for zipfile itself) */
+#define EXTD_LOCAL_SIG "\007\010" /* [ASCII "\113" == EBCDIC "\080" ??] */
+
+/** internal-only return codes **/
+#define IZ_DIR 76 /* potential zipfile is a directory */
+/* special return codes for mapname() */
+#define MPN_OK 0 /* mapname successful */
+#define MPN_INF_TRUNC (1<<8) /* caution - filename truncated */
+#define MPN_INF_SKIP (2<<8) /* info - skipped because nothing to do */
+#define MPN_ERR_SKIP (3<<8) /* error - entry skipped */
+#define MPN_ERR_TOOLONG (4<<8) /* error - path too long */
+#define MPN_NOMEM (10<<8) /* error - out of memory, file skipped */
+#define MPN_CREATED_DIR (16<<8) /* directory created: set time & permission */
+#define MPN_VOL_LABEL (17<<8) /* volume label, but can't set on hard disk */
+#define MPN_INVALID (99<<8) /* internal logic error, should never reach */
+/* mask for internal mapname&checkdir return codes */
+#define MPN_MASK 0x7F00
+/* error code for extracting/testing extra field blocks */
+#define IZ_EF_TRUNC 79 /* local extra field truncated (PKZIP'd) */
+
+/* choice of activities for do_string() */
+#define SKIP 0 /* skip header block */
+#define DISPLAY 1 /* display archive comment (ASCII) */
+#define DISPL_8 5 /* display file comment (ext. ASCII) */
+#define DS_FN 2 /* read filename (ext. ASCII, chead) */
+#define DS_FN_C 2 /* read filename from central header */
+#define DS_FN_L 6 /* read filename from local header */
+#define EXTRA_FIELD 3 /* copy extra field into buffer */
+#define DS_EF 3
+#ifdef AMIGA
+# define FILENOTE 4 /* convert file comment to filenote */
+#endif
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+# define CHECK_AUTORUN 7 /* copy command, display remainder */
+# define CHECK_AUTORUN_Q 8 /* copy command, skip remainder */
+#endif
+
+#define DOES_NOT_EXIST -1 /* return values for check_for_newer() */
+#define EXISTS_AND_OLDER 0
+#define EXISTS_AND_NEWER 1
+
+#define OVERWRT_QUERY 0 /* status values for G.overwrite_mode */
+#define OVERWRT_ALWAYS 1
+#define OVERWRT_NEVER 2
+
+#define IS_OVERWRT_ALL (G.overwrite_mode == OVERWRT_ALWAYS)
+#define IS_OVERWRT_NONE (G.overwrite_mode == OVERWRT_NEVER)
+
+#ifdef VMS
+ /* return codes for VMS-specific open_outfile() function */
+# define OPENOUT_OK 0 /* file openend normally */
+# define OPENOUT_FAILED 1 /* file open failed */
+# define OPENOUT_SKIPOK 2 /* file not opened, skip at error level OK */
+# define OPENOUT_SKIPWARN 3 /* file not opened, skip at error level WARN */
+#endif /* VMS */
+
+#define ROOT 0 /* checkdir() extract-to path: called once */
+#define INIT 1 /* allocate buildpath: called once per member */
+#define APPEND_DIR 2 /* append a dir comp.: many times per member */
+#define APPEND_NAME 3 /* append actual filename: once per member */
+#define GETPATH 4 /* retrieve the complete path and free it */
+#define END 5 /* free root path prior to exiting program */
+
+/* version_made_by codes (central dir): make sure these */
+/* are not defined on their respective systems!! */
+#define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, Win32 */
+#define AMIGA_ 1
+#define VMS_ 2
+#define UNIX_ 3
+#define VM_CMS_ 4
+#define ATARI_ 5 /* what if it's a minix filesystem? [cjh] */
+#define FS_HPFS_ 6 /* filesystem used by OS/2 (and NT 3.x) */
+#define MAC_ 7 /* HFS filesystem used by MacOS */
+#define Z_SYSTEM_ 8
+#define CPM_ 9
+#define TOPS20_ 10
+#define FS_NTFS_ 11 /* filesystem used by Windows NT */
+#define QDOS_ 12
+#define ACORN_ 13 /* Archimedes Acorn RISC OS */
+#define FS_VFAT_ 14 /* filesystem used by Windows 95, NT */
+#define MVS_ 15
+#define BEOS_ 16 /* hybrid POSIX/database filesystem */
+#define TANDEM_ 17 /* Tandem NSK */
+#define THEOS_ 18 /* THEOS */
+#define MAC_OSX_ 19 /* Mac OS/X (Darwin) */
+#define ATHEOS_ 30 /* AtheOS */
+#define NUM_HOSTS 31 /* index of last system + 1 */
+/* don't forget to update zipinfo.c appropiately if NUM_HOSTS changes! */
+
+#define STORED 0 /* compression methods */
+#define SHRUNK 1
+#define REDUCED1 2
+#define REDUCED2 3
+#define REDUCED3 4
+#define REDUCED4 5
+#define IMPLODED 6
+#define TOKENIZED 7
+#define DEFLATED 8
+#define ENHDEFLATED 9
+#define DCLIMPLODED 10
+#define BZIPPED 12
+#define LZMAED 14
+#define IBMTERSED 18
+#define IBMLZ77ED 19
+#define WAVPACKED 97
+#define PPMDED 98
+#define NUM_METHODS 17 /* number of known method IDs */
+/* don't forget to update list.c (list_files()), extract.c and zipinfo.c
+ * appropriately if NUM_METHODS changes */
+
+/* (the PK-class error codes are public and have been moved into unzip.h) */
+
+#define DF_MDY 0 /* date format 10/26/91 (USA only) */
+#define DF_DMY 1 /* date format 26/10/91 (most of the world) */
+#define DF_YMD 2 /* date format 91/10/26 (a few countries) */
+
+/*---------------------------------------------------------------------------
+ Extra-field block ID values and offset info.
+ ---------------------------------------------------------------------------*/
+/* extra-field ID values, all little-endian: */
+#define EF_PKSZ64 0x0001 /* PKWARE's 64-bit filesize extensions */
+#define EF_AV 0x0007 /* PKWARE's authenticity verification */
+#define EF_EFS 0x0008 /* PKWARE's extended language encoding */
+#define EF_OS2 0x0009 /* OS/2 extended attributes */
+#define EF_PKW32 0x000a /* PKWARE's Win95/98/WinNT filetimes */
+#define EF_PKVMS 0x000c /* PKWARE's VMS */
+#define EF_PKUNIX 0x000d /* PKWARE's Unix */
+#define EF_PKFORK 0x000e /* PKWARE's future stream/fork descriptors */
+#define EF_PKPATCH 0x000f /* PKWARE's patch descriptor */
+#define EF_PKPKCS7 0x0014 /* PKWARE's PKCS#7 store for X.509 Certs */
+#define EF_PKFX509 0x0015 /* PKWARE's file X.509 Cert&Signature ID */
+#define EF_PKCX509 0x0016 /* PKWARE's central dir X.509 Cert ID */
+#define EF_PKENCRHD 0x0017 /* PKWARE's Strong Encryption header */
+#define EF_PKRMCTL 0x0018 /* PKWARE's Record Management Controls*/
+#define EF_PKLSTCS7 0x0019 /* PKWARE's PKCS#7 Encr. Recipient Cert List */
+#define EF_PKIBM 0x0065 /* PKWARE's IBM S/390 & AS/400 attributes */
+#define EF_PKIBM2 0x0066 /* PKWARE's IBM S/390 & AS/400 compr. attribs */
+#define EF_IZVMS 0x4d49 /* Info-ZIP's VMS ("IM") */
+#define EF_IZUNIX 0x5855 /* Info-ZIP's first Unix[1] ("UX") */
+#define EF_IZUNIX2 0x7855 /* Info-ZIP's second Unix[2] ("Ux") */
+#define EF_IZUNIX3 0x7875 /* Info-ZIP's newest Unix[3] ("ux") */
+#define EF_TIME 0x5455 /* universal timestamp ("UT") */
+#define EF_UNIPATH 0x7075 /* Info-ZIP Unicode Path ("up") */
+#define EF_UNICOMNT 0x6375 /* Info-ZIP Unicode Comment ("uc") */
+#define EF_MAC3 0x334d /* Info-ZIP's new Macintosh (= "M3") */
+#define EF_JLMAC 0x07c8 /* Johnny Lee's old Macintosh (= 1992) */
+#define EF_ZIPIT 0x2605 /* Thomas Brown's Macintosh (ZipIt) */
+#define EF_ZIPIT2 0x2705 /* T. Brown's Mac (ZipIt) v 1.3.8 and newer ? */
+#define EF_SMARTZIP 0x4d63 /* Mac SmartZip by Marco Bambini */
+#define EF_VMCMS 0x4704 /* Info-ZIP's VM/CMS ("\004G") */
+#define EF_MVS 0x470f /* Info-ZIP's MVS ("\017G") */
+#define EF_ACL 0x4c41 /* (OS/2) access control list ("AL") */
+#define EF_NTSD 0x4453 /* NT security descriptor ("SD") */
+#define EF_ATHEOS 0x7441 /* AtheOS ("At") */
+#define EF_BEOS 0x6542 /* BeOS ("Be") */
+#define EF_QDOS 0xfb4a /* SMS/QDOS ("J\373") */
+#define EF_AOSVS 0x5356 /* AOS/VS ("VS") */
+#define EF_SPARK 0x4341 /* David Pilling's Acorn/SparkFS ("AC") */
+#define EF_TANDEM 0x4154 /* Tandem NSK ("TA") */
+#define EF_THEOS 0x6854 /* Jean-Michel Dubois' Theos "Th" */
+#define EF_THEOSO 0x4854 /* old Theos port */
+#define EF_MD5 0x4b46 /* Fred Kantor's MD5 ("FK") */
+#define EF_ASIUNIX 0x756e /* ASi's Unix ("nu") */
+
+#define EB_HEADSIZE 4 /* length of extra field block header */
+#define EB_ID 0 /* offset of block ID in header */
+#define EB_LEN 2 /* offset of data length field in header */
+#define EB_UCSIZE_P 0 /* offset of ucsize field in compr. data */
+#define EB_CMPRHEADLEN 6 /* lenght of compression header */
+
+#define EB_UX_MINLEN 8 /* minimal "UX" field contains atime, mtime */
+#define EB_UX_FULLSIZE 12 /* full "UX" field (atime, mtime, uid, gid) */
+#define EB_UX_ATIME 0 /* offset of atime in "UX" extra field data */
+#define EB_UX_MTIME 4 /* offset of mtime in "UX" extra field data */
+#define EB_UX_UID 8 /* byte offset of UID in "UX" field data */
+#define EB_UX_GID 10 /* byte offset of GID in "UX" field data */
+
+#define EB_UX2_MINLEN 4 /* minimal "Ux" field contains UID/GID */
+#define EB_UX2_UID 0 /* byte offset of UID in "Ux" field data */
+#define EB_UX2_GID 2 /* byte offset of GID in "Ux" field data */
+#define EB_UX2_VALID (1 << 8) /* UID/GID present */
+
+#define EB_UX3_MINLEN 7 /* minimal "ux" field size (2-byte UID/GID) */
+
+#define EB_UT_MINLEN 1 /* minimal UT field contains Flags byte */
+#define EB_UT_FLAGS 0 /* byte offset of Flags field */
+#define EB_UT_TIME1 1 /* byte offset of 1st time value */
+#define EB_UT_FL_MTIME (1 << 0) /* mtime present */
+#define EB_UT_FL_ATIME (1 << 1) /* atime present */
+#define EB_UT_FL_CTIME (1 << 2) /* ctime present */
+
+#define EB_FLGS_OFFS 4 /* offset of flags area in generic compressed
+ extra field blocks (BEOS, MAC, and others) */
+#define EB_OS2_HLEN 4 /* size of OS2/ACL compressed data header */
+#define EB_BEOS_HLEN 5 /* length of BeOS&AtheOS e.f attribute header */
+#define EB_BE_FL_UNCMPR 0x01 /* "BeOS&AtheOS attribs uncompr." bit flag */
+#define EB_MAC3_HLEN 14 /* length of Mac3 attribute block header */
+#define EB_SMARTZIP_HLEN 64 /* fixed length of the SmartZip extra field */
+#define EB_M3_FL_DATFRK 0x01 /* "this entry is data fork" flag */
+#define EB_M3_FL_UNCMPR 0x04 /* "Mac3 attributes uncompressed" bit flag */
+#define EB_M3_FL_TIME64 0x08 /* "Mac3 time fields are 64 bit wide" flag */
+#define EB_M3_FL_NOUTC 0x10 /* "Mac3 timezone offset fields missing" flag */
+
+#define EB_NTSD_C_LEN 4 /* length of central NT security data */
+#define EB_NTSD_L_LEN 5 /* length of minimal local NT security data */
+#define EB_NTSD_VERSION 4 /* offset of NTSD version byte */
+#define EB_NTSD_MAX_VER (0) /* maximum version # we know how to handle */
+
+#define EB_PKVMS_MINLEN 4 /* minimum data length of PKVMS extra block */
+
+#define EB_ASI_CRC32 0 /* offset of ASI Unix field's crc32 checksum */
+#define EB_ASI_MODE 4 /* offset of ASI Unix permission mode field */
+
+#define EB_IZVMS_HLEN 12 /* length of IZVMS attribute block header */
+#define EB_IZVMS_FLGS 4 /* offset of compression type flag */
+#define EB_IZVMS_UCSIZ 6 /* offset of ucsize field in IZVMS header */
+#define EB_IZVMS_BCMASK 07 /* 3 bits for compression type */
+#define EB_IZVMS_BCSTOR 0 /* Stored */
+#define EB_IZVMS_BC00 1 /* 0byte -> 0bit compression */
+#define EB_IZVMS_BCDEFL 2 /* Deflated */
+
+
+/*---------------------------------------------------------------------------
+ True sizes of the various headers (excluding their 4-byte signatures),
+ as defined by PKWARE--so it is not likely that these will ever change.
+ But if they do, make sure both these defines AND the typedefs below get
+ updated accordingly.
+
+ 12/27/2006
+ The Zip64 End Of Central Directory record is variable size and now
+ comes in two flavors, version 1 and the new version 2 that supports
+ central directory encryption. We only use the old fields at the
+ top of the Zip64 EOCDR, and this block is a fixed size still, but
+ need to be aware of the stuff following.
+ ---------------------------------------------------------------------------*/
+#define LREC_SIZE 26 /* lengths of local file headers, central */
+#define CREC_SIZE 42 /* directory headers, end-of-central-dir */
+#define ECREC_SIZE 18 /* record, zip64 end-of-cent-dir locator */
+#define ECLOC64_SIZE 16 /* and zip64 end-of-central-dir record, */
+#define ECREC64_SIZE 52 /* respectively */
+
+#define MAX_BITS 13 /* used in unshrink() */
+#define HSIZE (1 << MAX_BITS) /* size of global work area */
+
+#define LF 10 /* '\n' on ASCII machines; must be 10 due to EBCDIC */
+#define CR 13 /* '\r' on ASCII machines; must be 13 due to EBCDIC */
+#define CTRLZ 26 /* DOS & OS/2 EOF marker (used in fileio.c, vms.c) */
+
+#ifdef EBCDIC
+# define foreign(c) ascii[(uch)(c)]
+# define native(c) ebcdic[(uch)(c)]
+# define NATIVE "EBCDIC"
+# define NOANSIFILT
+#endif
+
+#ifdef VMS
+# define ENV_UNZIP "UNZIP_OPTS" /* names of environment variables */
+# define ENV_ZIPINFO "ZIPINFO_OPTS"
+#endif /* VMS */
+#ifdef RISCOS
+# define ENV_UNZIP "Unzip$Options"
+# define ENV_ZIPINFO "Zipinfo$Options"
+# define ENV_UNZIPEXTS "Unzip$Exts"
+#endif /* RISCOS */
+#ifndef ENV_UNZIP
+# define ENV_UNZIP "UNZIP" /* the standard names */
+# define ENV_ZIPINFO "ZIPINFO"
+#endif
+#define ENV_UNZIP2 "UNZIPOPT" /* alternate names, for zip compat. */
+#define ENV_ZIPINFO2 "ZIPINFOOPT"
+
+#if (!defined(QQ) && !defined(NOQQ))
+# define QQ
+#endif
+
+#ifdef QQ /* Newtware version: no file */
+# define QCOND (!uO.qflag) /* comments with -vq or -vqq */
+#else /* Bill Davidsen version: no way to */
+# define QCOND (longhdr) /* kill file comments when listing */
+#endif
+
+#ifdef OLD_QQ
+# define QCOND2 (uO.qflag < 2)
+#else
+# define QCOND2 (!uO.qflag)
+#endif
+
+#ifdef WILD_STOP_AT_DIR
+# define __WDLPRO , int sepc
+# define __WDL , sepc
+# define __WDLDEF int sepc;
+# define WISEP , (uO.W_flag ? '/' : '\0')
+#else
+# define __WDLPRO
+# define __WDL
+# define __WDLDEF
+# define WISEP
+#endif
+
+
+
+
+/**************/
+/* Typedefs */
+/**************/
+
+#ifdef ZIP64_SUPPORT
+# ifndef Z_UINT8_DEFINED
+# if (defined(__GNUC__) || defined(__hpux) || defined(__SUNPRO_C))
+ typedef unsigned long long z_uint8;
+# else
+ typedef unsigned __int64 z_uint8;
+# endif
+# define Z_UINT8_DEFINED
+# endif
+#endif
+#ifndef Z_UINT4_DEFINED
+# if (defined(MODERN) && !defined(NO_LIMITS_H))
+# if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
+ typedef unsigned int z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
+ typedef unsigned long z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
+ typedef unsigned short z_uint4;
+# define Z_UINT4_DEFINED
+# endif
+# endif
+# endif
+# endif /* MODERN && !NO_LIMITS_H */
+#endif /* !Z_UINT4_DEFINED */
+#ifndef Z_UINT4_DEFINED
+ typedef ulg z_uint4;
+# define Z_UINT4_DEFINED
+#endif
+
+/* The following three user-defined unsigned integer types are used for
+ holding zipfile entities (required widths without / with Zip64 support):
+ a) sizes and offset of zipfile entries
+ (4 bytes / 8 bytes)
+ b) enumeration and counts of zipfile entries
+ (2 bytes / 8 bytes)
+ Remark: internally, we use 4 bytes for archive member counting in the
+ No-Zip64 case, because UnZip supports more than 64k entries for
+ classic Zip archives without Zip64 extensions.
+ c) enumeration and counts of zipfile volumes of multivolume archives
+ (2 bytes / 4 bytes)
+ */
+#ifdef ZIP64_SUPPORT
+ typedef z_uint8 zusz_t; /* zipentry sizes & offsets */
+ typedef z_uint8 zucn_t; /* archive entry counts */
+ typedef z_uint4 zuvl_t; /* multivolume numbers */
+# define MASK_ZUCN64 (~(zucn_t)0)
+/* In case we ever get to support an environment where z_uint8 may be WIDER
+ than 64 bit wide, we will have to apply a construct similar to
+ #define MASK_ZUCN64 (~(zucn_t)0 & (zucn_t)0xffffffffffffffffULL)
+ for the 64-bit mask.
+ */
+#else
+ typedef ulg zusz_t; /* zipentry sizes & offsets */
+ typedef unsigned int zucn_t; /* archive entry counts */
+ typedef unsigned short zuvl_t; /* multivolume numbers */
+# define MASK_ZUCN64 (~(zucn_t)0)
+#endif
+#define MASK_ZUCN16 ((zucn_t)0xFFFF)
+
+#ifdef NO_UID_GID
+# ifdef UID_USHORT
+ typedef unsigned short uid_t; /* TI SysV.3 */
+ typedef unsigned short gid_t;
+# else
+ typedef unsigned int uid_t; /* SCO Xenix */
+ typedef unsigned int gid_t;
+# endif
+#endif
+
+#if (defined(GOT_UTIMBUF) || defined(sgi) || defined(ATARI))
+ typedef struct utimbuf ztimbuf;
+#else
+ typedef struct ztimbuf {
+ time_t actime; /* new access time */
+ time_t modtime; /* new modification time */
+ } ztimbuf;
+#endif
+
+typedef struct iztimes {
+ time_t atime; /* new access time */
+ time_t mtime; /* new modification time */
+ time_t ctime; /* used for creation time; NOT same as st_ctime */
+} iztimes;
+
+#ifdef SET_DIR_ATTRIB
+ typedef struct direntry { /* head of system-specific struct holding */
+ struct direntry *next; /* defered directory attributes info */
+ char *fn; /* filename of directory */
+ char buf[1]; /* start of system-specific internal data */
+ } direntry;
+#endif /* SET_DIR_ATTRIB */
+
+#ifdef SYMLINKS
+ typedef struct slinkentry { /* info for deferred symlink creation */
+ struct slinkentry *next; /* pointer to next entry in chain */
+ extent targetlen; /* length of target filespec */
+ extent attriblen; /* length of system-specific attrib data */
+ char *target; /* pointer to target filespec */
+ char *fname; /* pointer to name of link */
+ char buf[1]; /* data/name/link buffer */
+ } slinkentry;
+#endif /* SYMLINKS */
+
+typedef struct min_info {
+ zoff_t offset;
+ zusz_t compr_size; /* compressed size (needed if extended header) */
+ zusz_t uncompr_size; /* uncompressed size (needed if extended header) */
+ ulg crc; /* crc (needed if extended header) */
+ zuvl_t diskstart; /* no of volume where this entry starts */
+ uch hostver;
+ uch hostnum;
+ unsigned file_attr; /* local flavor, as used by creat(), chmod()... */
+ unsigned encrypted : 1; /* file encrypted: decrypt before uncompressing */
+ unsigned ExtLocHdr : 1; /* use time instead of CRC for decrypt check */
+ unsigned textfile : 1; /* file is text (according to zip) */
+ unsigned textmode : 1; /* file is to be extracted as text */
+ unsigned lcflag : 1; /* convert filename to lowercase */
+ unsigned vollabel : 1; /* "file" is an MS-DOS volume (disk) label */
+#ifdef SYMLINKS
+ unsigned symlink : 1; /* file is a symbolic link */
+#endif
+ unsigned HasUxAtt : 1; /* crec ext_file_attr has Unix style mode bits */
+#ifdef UNICODE_SUPPORT
+ unsigned GPFIsUTF8: 1; /* crec gen_purpose_flag UTF-8 bit 11 is set */
+#endif
+#ifndef SFX
+ char Far *cfilname; /* central header version of filename */
+#endif
+} min_info;
+
+typedef struct VMStimbuf {
+ char *revdate; /* (both roughly correspond to Unix modtime/st_mtime) */
+ char *credate;
+} VMStimbuf;
+
+/*---------------------------------------------------------------------------
+ Zipfile work area declarations.
+ ---------------------------------------------------------------------------*/
+
+#ifdef MALLOC_WORK
+ union work {
+ struct { /* unshrink(): */
+ shrint *Parent; /* pointer to (8192 * sizeof(shrint)) */
+ uch *value; /* pointer to 8KB char buffer */
+ uch *Stack; /* pointer to another 8KB char buffer */
+ } shrink;
+ uch *Slide; /* explode(), inflate(), unreduce() */
+ };
+#else /* !MALLOC_WORK */
+ union work {
+ struct { /* unshrink(): */
+ shrint Parent[HSIZE]; /* (8192 * sizeof(shrint)) == 16KB minimum */
+ uch value[HSIZE]; /* 8KB */
+ uch Stack[HSIZE]; /* 8KB */
+ } shrink; /* total = 32KB minimum; 80KB on Cray/Alpha */
+ uch Slide[WSIZE]; /* explode(), inflate(), unreduce() */
+ };
+#endif /* ?MALLOC_WORK */
+
+#define slide G.area.Slide
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+# define redirSlide G.redirect_sldptr
+#else
+# define redirSlide G.area.Slide
+#endif
+
+/*---------------------------------------------------------------------------
+ Zipfile layout declarations. If these headers ever change, make sure the
+ xxREC_SIZE defines (above) change with them!
+ ---------------------------------------------------------------------------*/
+
+ typedef uch local_byte_hdr[ LREC_SIZE ];
+# define L_VERSION_NEEDED_TO_EXTRACT_0 0
+# define L_VERSION_NEEDED_TO_EXTRACT_1 1
+# define L_GENERAL_PURPOSE_BIT_FLAG 2
+# define L_COMPRESSION_METHOD 4
+# define L_LAST_MOD_DOS_DATETIME 6
+# define L_CRC32 10
+# define L_COMPRESSED_SIZE 14
+# define L_UNCOMPRESSED_SIZE 18
+# define L_FILENAME_LENGTH 22
+# define L_EXTRA_FIELD_LENGTH 24
+
+ typedef uch cdir_byte_hdr[ CREC_SIZE ];
+# define C_VERSION_MADE_BY_0 0
+# define C_VERSION_MADE_BY_1 1
+# define C_VERSION_NEEDED_TO_EXTRACT_0 2
+# define C_VERSION_NEEDED_TO_EXTRACT_1 3
+# define C_GENERAL_PURPOSE_BIT_FLAG 4
+# define C_COMPRESSION_METHOD 6
+# define C_LAST_MOD_DOS_DATETIME 8
+# define C_CRC32 12
+# define C_COMPRESSED_SIZE 16
+# define C_UNCOMPRESSED_SIZE 20
+# define C_FILENAME_LENGTH 24
+# define C_EXTRA_FIELD_LENGTH 26
+# define C_FILE_COMMENT_LENGTH 28
+# define C_DISK_NUMBER_START 30
+# define C_INTERNAL_FILE_ATTRIBUTES 32
+# define C_EXTERNAL_FILE_ATTRIBUTES 34
+# define C_RELATIVE_OFFSET_LOCAL_HEADER 38
+
+ typedef uch ec_byte_rec[ ECREC_SIZE+4 ];
+/* define SIGNATURE 0 space-holder only */
+# define NUMBER_THIS_DISK 4
+# define NUM_DISK_WITH_START_CEN_DIR 6
+# define NUM_ENTRIES_CEN_DIR_THS_DISK 8
+# define TOTAL_ENTRIES_CENTRAL_DIR 10
+# define SIZE_CENTRAL_DIRECTORY 12
+# define OFFSET_START_CENTRAL_DIRECTORY 16
+# define ZIPFILE_COMMENT_LENGTH 20
+
+ typedef uch ec_byte_loc64[ ECLOC64_SIZE+4 ];
+# define NUM_DISK_START_EOCDR64 4
+# define OFFSET_START_EOCDR64 8
+# define NUM_THIS_DISK_LOC64 16
+
+ typedef uch ec_byte_rec64[ ECREC64_SIZE+4 ];
+# define ECREC64_LENGTH 4
+# define EC_VERSION_MADE_BY_0 12
+# define EC_VERSION_NEEDED_0 14
+# define NUMBER_THIS_DSK_REC64 16
+# define NUM_DISK_START_CEN_DIR64 20
+# define NUM_ENTRIES_CEN_DIR_THS_DISK64 24
+# define TOTAL_ENTRIES_CENTRAL_DIR64 32
+# define SIZE_CENTRAL_DIRECTORY64 40
+# define OFFSET_START_CENTRAL_DIRECT64 48
+
+
+/* The following structs are used to hold all header data of a zip entry.
+ Traditionally, the structs' layouts followed the data layout of the
+ corresponding zipfile header structures. However, the zipfile header
+ layouts were designed in the old ages of 16-bit CPUs, they are subject
+ to structure padding and/or alignment issues on newer systems with a
+ "natural word width" of more than 2 bytes.
+ Please note that the structure members are now reordered by size
+ (top-down), to prevent internal padding and optimize memory usage!
+ */
+ typedef struct local_file_header { /* LOCAL */
+ zusz_t csize;
+ zusz_t ucsize;
+ ulg last_mod_dos_datetime;
+ ulg crc32;
+ uch version_needed_to_extract[2];
+ ush general_purpose_bit_flag;
+ ush compression_method;
+ ush filename_length;
+ ush extra_field_length;
+ } local_file_hdr;
+
+ typedef struct central_directory_file_header { /* CENTRAL */
+ zusz_t csize;
+ zusz_t ucsize;
+ zusz_t relative_offset_local_header;
+ ulg last_mod_dos_datetime;
+ ulg crc32;
+ ulg external_file_attributes;
+ zuvl_t disk_number_start;
+ ush internal_file_attributes;
+ uch version_made_by[2];
+ uch version_needed_to_extract[2];
+ ush general_purpose_bit_flag;
+ ush compression_method;
+ ush filename_length;
+ ush extra_field_length;
+ ush file_comment_length;
+ } cdir_file_hdr;
+
+ typedef struct end_central_dir_record { /* END CENTRAL */
+ zusz_t size_central_directory;
+ zusz_t offset_start_central_directory;
+ zucn_t num_entries_centrl_dir_ths_disk;
+ zucn_t total_entries_central_dir;
+ zuvl_t number_this_disk;
+ zuvl_t num_disk_start_cdir;
+ int have_ecr64; /* valid Zip64 ecdir-record exists */
+ int is_zip64_archive; /* Zip64 ecdir-record is mandatory */
+ ush zipfile_comment_length;
+ } ecdir_rec;
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model).
+ Valid extra bits are 0..16. e == 31 is EOB (end of block), e == 32
+ means that v is a literal, 32 < e < 64 means that v is a pointer to
+ the next table, which codes (e & 31) bits, and lastly e == 99 indicates
+ an unused code. If a code with e == 99 is looked up, this implies an
+ error in the data. */
+
+struct huft {
+ uch e; /* number of extra bits or operation */
+ uch b; /* number of bits in this code or subcode */
+ union {
+ ush n; /* literal, length base, or distance base */
+ struct huft *t; /* pointer to next level of table */
+ } v;
+};
+
+
+typedef struct _APIDocStruct {
+ char *compare;
+ char *function;
+ char *syntax;
+ char *purpose;
+} APIDocStruct;
+
+
+
+
+/*************/
+/* Globals */
+/*************/
+
+#if (defined(OS2) && !defined(FUNZIP))
+# include "os2/os2data.h"
+#endif
+
+#include "globals.h"
+
+
+
+/*************************/
+/* Function Prototypes */
+/*************************/
+
+/*---------------------------------------------------------------------------
+ Functions in unzip.c (initialization routines):
+ ---------------------------------------------------------------------------*/
+
+#ifndef WINDLL
+ int MAIN OF((int argc, char **argv));
+ int unzip OF((__GPRO__ int argc, char **argv));
+ int uz_opts OF((__GPRO__ int *pargc, char ***pargv));
+ int usage OF((__GPRO__ int error));
+#endif /* !WINDLL */
+
+/*---------------------------------------------------------------------------
+ Functions in process.c (main driver routines):
+ ---------------------------------------------------------------------------*/
+
+int process_zipfiles OF((__GPRO));
+void free_G_buffers OF((__GPRO));
+/* static int do_seekable OF((__GPRO__ int lastchance)); */
+/* static int find_ecrec OF((__GPRO__ long searchlen)); */
+/* static int process_central_comment OF((__GPRO)); */
+int process_cdir_file_hdr OF((__GPRO));
+int process_local_file_hdr OF((__GPRO));
+int getZip64Data OF((__GPRO__ ZCONST uch *ef_buf,
+ unsigned ef_len));
+#ifdef UNICODE_SUPPORT
+ int getUnicodeData OF((__GPRO__ ZCONST uch *ef_buf,
+ unsigned ef_len));
+#endif
+unsigned ef_scan_for_izux OF((ZCONST uch *ef_buf, unsigned ef_len,
+ int ef_is_c, ulg dos_mdatetime,
+ iztimes *z_utim, ulg *z_uidgid));
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+ zvoid *getRISCOSexfield OF((ZCONST uch *ef_buf, unsigned ef_len));
+#endif
+
+#ifndef SFX
+
+/*---------------------------------------------------------------------------
+ Functions in zipinfo.c (`zipinfo-style' listing routines):
+ ---------------------------------------------------------------------------*/
+
+#ifndef NO_ZIPINFO
+#ifndef WINDLL
+ int zi_opts OF((__GPRO__ int *pargc, char ***pargv));
+#endif
+void zi_end_central OF((__GPRO));
+int zipinfo OF((__GPRO));
+/* static int zi_long OF((__GPRO__ zusz_t *pEndprev)); */
+/* static int zi_short OF((__GPRO)); */
+/* static char *zi_time OF((__GPRO__ ZCONST ulg *datetimez,
+ ZCONST time_t *modtimez, char *d_t_str));*/
+#endif /* !NO_ZIPINFO */
+
+/*---------------------------------------------------------------------------
+ Functions in list.c (generic zipfile-listing routines):
+ ---------------------------------------------------------------------------*/
+
+int list_files OF((__GPRO));
+#ifdef TIMESTAMP
+ int get_time_stamp OF((__GPRO__ time_t *last_modtime,
+ ulg *nmember));
+#endif
+int ratio OF((zusz_t uc, zusz_t c));
+void fnprint OF((__GPRO));
+
+#endif /* !SFX */
+
+/*---------------------------------------------------------------------------
+ Functions in fileio.c:
+ ---------------------------------------------------------------------------*/
+
+int open_input_file OF((__GPRO));
+int open_outfile OF((__GPRO)); /* also vms.c */
+void undefer_input OF((__GPRO));
+void defer_leftover_input OF((__GPRO));
+unsigned readbuf OF((__GPRO__ char *buf, register unsigned len));
+int readbyte OF((__GPRO));
+int fillinbuf OF((__GPRO));
+int seek_zipf OF((__GPRO__ zoff_t abs_offset));
+#ifdef FUNZIP
+ int flush OF((__GPRO__ ulg size)); /* actually funzip.c */
+#else
+ int flush OF((__GPRO__ uch *buf, ulg size, int unshrink));
+#endif
+/* static int disk_error OF((__GPRO)); */
+void handler OF((int signal));
+time_t dos_to_unix_time OF((ulg dos_datetime));
+int check_for_newer OF((__GPRO__ char *filename)); /* os2,vmcms,vms */
+int do_string OF((__GPRO__ unsigned int length, int option));
+ush makeword OF((ZCONST uch *b));
+ulg makelong OF((ZCONST uch *sig));
+zusz_t makeint64 OF((ZCONST uch *sig));
+char *fzofft OF((__GPRO__ zoff_t val,
+ ZCONST char *pre, ZCONST char *post));
+#if (!defined(STR_TO_ISO) || defined(NEED_STR2ISO))
+ char *str2iso OF((char *dst, ZCONST char *src));
+#endif
+#if (!defined(STR_TO_OEM) || defined(NEED_STR2OEM))
+ char *str2oem OF((char *dst, ZCONST char *src));
+#endif
+#ifdef NO_STRNICMP
+ int zstrnicmp OF((register ZCONST char *s1,
+ register ZCONST char *s2,
+ register unsigned n));
+#endif
+#ifdef REGULUS
+ int zstat OF((ZCONST char *p, struct stat *s));
+#endif
+#ifdef ZMEM /* MUST be ifdef'd because of conflicts with the standard def. */
+ zvoid *memset OF((register zvoid *, register int, register unsigned int));
+ int memcmp OF((register ZCONST zvoid*, register ZCONST zvoid *,
+ register unsigned int));
+ zvoid *memcpy OF((register zvoid *, register ZCONST zvoid *,
+ register unsigned int));
+#endif
+#ifdef NEED_UZMBCLEN
+ extent uzmbclen OF((ZCONST unsigned char *ptr));
+#endif
+#ifdef NEED_UZMBSCHR
+ unsigned char *uzmbschr OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef NEED_UZMBSRCHR
+ unsigned char *uzmbsrchr OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef SMALL_MEM
+ char *fLoadFarString OF((__GPRO__ const char Far *sz));
+ char *fLoadFarStringSmall OF((__GPRO__ const char Far *sz));
+ char *fLoadFarStringSmall2 OF((__GPRO__ const char Far *sz));
+ #ifndef zfstrcpy
+ char Far * Far zfstrcpy OF((char Far *s1, const char Far *s2));
+ #endif
+ #if (!defined(SFX) && !defined(zfstrcmp))
+ int Far zfstrcmp OF((const char Far *s1, const char Far *s2));
+ #endif
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Functions in extract.c:
+ ---------------------------------------------------------------------------*/
+
+int extract_or_test_files OF((__GPRO));
+/* static int store_info OF((void)); */
+/* static int extract_or_test_member OF((__GPRO)); */
+/* static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len)); */
+/* static int test_OS2 OF((__GPRO__ uch *eb, unsigned eb_size)); */
+/* static int test_NT OF((__GPRO__ uch *eb, unsigned eb_size)); */
+#ifndef SFX
+ unsigned find_compr_idx OF((unsigned compr_methodnum));
+#endif
+int memextract OF((__GPRO__ uch *tgt, ulg tgtsize,
+ ZCONST uch *src, ulg srcsize));
+int memflush OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+ uch *extract_izvms_block OF((__GPRO__ ZCONST uch *ebdata,
+ unsigned size, unsigned *retlen,
+ ZCONST uch *init, unsigned needlen));
+#endif
+char *fnfilter OF((ZCONST char *raw, uch *space,
+ extent size));
+
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+wchar_t *fnfilterw OF((ZCONST wchar_t *src, wchar_t *dst,
+ extent siz));
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Decompression functions:
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) && !defined(FUNZIP))
+int explode OF((__GPRO)); /* explode.c */
+#endif
+int huft_free OF((struct huft *t)); /* inflate.c */
+int huft_build OF((__GPRO__ ZCONST unsigned *b, unsigned n,
+ unsigned s, ZCONST ush *d, ZCONST uch *e,
+ struct huft **t, unsigned *m));
+#ifdef USE_ZLIB
+ int UZinflate OF((__GPRO__ int is_defl64)); /* inflate.c */
+# define inflate_free(x) inflateEnd(&((Uz_Globs *)(&G))->dstrm)
+#else
+ int inflate OF((__GPRO__ int is_defl64)); /* inflate.c */
+ int inflate_free OF((__GPRO)); /* inflate.c */
+#endif /* ?USE_ZLIB */
+#if (!defined(SFX) && !defined(FUNZIP))
+#ifndef COPYRIGHT_CLEAN
+ int unreduce OF((__GPRO)); /* unreduce.c */
+/* static void LoadFollowers OF((__GPRO__ f_array *follower, uch *Slen));
+ * unreduce.c */
+#endif /* !COPYRIGHT_CLEAN */
+#ifndef LZW_CLEAN
+ int unshrink OF((__GPRO)); /* unshrink.c */
+/* static void partial_clear OF((__GPRO)); * unshrink.c */
+#endif /* !LZW_CLEAN */
+#endif /* !SFX && !FUNZIP */
+#ifdef USE_BZIP2
+ int UZbunzip2 OF((__GPRO)); /* extract.c */
+ void bz_internal_error OF((int bzerrcode)); /* ubz2err.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ Internal API functions (only included in DLL versions):
+ ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+ void setFileNotFound OF((__GPRO)); /* api.c */
+ int unzipToMemory OF((__GPRO__ char *zip, char *file,
+ UzpBuffer *retstr)); /* api.c */
+ int redirect_outfile OF((__GPRO)); /* api.c */
+ int writeToMemory OF((__GPRO__ ZCONST uch *rawbuf,
+ extent size)); /* api.c */
+ int close_redirect OF((__GPRO)); /* api.c */
+ /* this obsolescent entry point kept for compatibility: */
+ int UzpUnzip OF((int argc, char **argv));/* use UzpMain */
+#ifdef OS2DLL
+ int varmessage OF((__GPRO__ ZCONST uch *buf, ulg size));
+ int varputchar OF((__GPRO__ int c)); /* rexxapi.c */
+ int finish_REXX_redirect OF((__GPRO)); /* rexxapi.c */
+#endif
+#ifdef API_DOC
+ void APIhelp OF((__GPRO__ int argc, char **argv));
+#endif /* apihelp.c */
+#endif /* DLL */
+
+/*---------------------------------------------------------------------------
+ MSDOS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef MSDOS
+#if (!defined(FUNZIP) && !defined(SFX) && !defined(WINDLL))
+ void check_for_windows OF((ZCONST char *app)); /* msdos.c */
+#endif
+#if (defined(__GO32__) || defined(__EMX__))
+ unsigned _dos_getcountryinfo(void *); /* msdos.c */
+#if (!defined(__DJGPP__) || (__DJGPP__ < 2))
+ unsigned _dos_setftime(int, unsigned, unsigned); /* msdos.c */
+ unsigned _dos_setfileattr(const char *, unsigned); /* msdos.c */
+ unsigned _dos_creat(const char *, unsigned, int *); /* msdos.c */
+ void _dos_getdrive(unsigned *); /* msdos.c */
+ unsigned _dos_close(int); /* msdos.c */
+#endif /* !__DJGPP__ || (__DJGPP__ < 2) */
+#endif /* __GO32__ || __EMX__ */
+#endif
+
+/*---------------------------------------------------------------------------
+ OS/2-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef OS2 /* GetFileTime conflicts with something in Win32 header files */
+#if (defined(REENTRANT) && defined(USETHREADID))
+ ulg GetThreadId OF((void));
+#endif
+ int GetCountryInfo OF((void)); /* os2.c */
+ long GetFileTime OF((ZCONST char *name)); /* os2.c */
+/* static void SetPathAttrTimes OF((__GPRO__ int flags, int dir)); os2.c */
+/* static int SetEAs OF((__GPRO__ const char *path,
+ void *eablock)); os2.c */
+/* static int SetACL OF((__GPRO__ const char *path,
+ void *eablock)); os2.c */
+/* static int IsFileNameValid OF((const char *name)); os2.c */
+/* static void map2fat OF((char *pathcomp, char **pEndFAT)); os2.c */
+/* static int SetLongNameEA OF((char *name, char *longname)); os2.c */
+/* static void InitNLS OF((void)); os2.c */
+ int IsUpperNLS OF((int nChr)); /* os2.c */
+ int ToLowerNLS OF((int nChr)); /* os2.c */
+ void DebugMalloc OF((void)); /* os2.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ QDOS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+ int QMatch (uch, uch);
+ void QFilename (__GPRO__ char *);
+ char *Qstrfix (char *);
+ int QReturn (int zip_error);
+#endif
+
+/*---------------------------------------------------------------------------
+ TOPS20-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+ int upper OF((char *s)); /* tops20.c */
+ int enquote OF((char *s)); /* tops20.c */
+ int dequote OF((char *s)); /* tops20.c */
+ int fnlegal OF(()); /* error if prototyped? */ /* tops20.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ VM/CMS- and MVS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+ extent getVMMVSexfield OF((char *type, uch *ef_block, unsigned datalen));
+ FILE *vmmvs_open_infile OF((__GPRO)); /* vmmvs.c */
+ void close_infile OF((__GPRO)); /* vmmvs.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ VMS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+ int check_format OF((__GPRO)); /* vms.c */
+/* int open_outfile OF((__GPRO)); * (see fileio.c) vms.c */
+/* int flush OF((__GPRO__ uch *rawbuf, unsigned size,
+ int final_flag)); * (see fileio.c) vms.c */
+ char *vms_msg_text OF((void)); /* vms.c */
+#ifdef RETURN_CODES
+ void return_VMS OF((__GPRO__ int zip_error)); /* vms.c */
+#else
+ void return_VMS OF((int zip_error)); /* vms.c */
+#endif
+#ifdef VMSCLI
+ ulg vms_unzip_cmdline OF((int *, char ***)); /* cmdline.c */
+ int VMSCLI_usage OF((__GPRO__ int error)); /* cmdline.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+ WIN32-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef WIN32
+ int IsWinNT OF((void)); /* win32.c */
+#ifdef NTSD_EAS
+ void process_defer_NT OF((__GPRO)); /* win32.c */
+ int test_NTSD OF((__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize)); /* win32.c */
+# define TEST_NTSD test_NTSD
+#endif
+#ifdef W32_STAT_BANDAID
+ int zstat_win32 OF((__W32STAT_GLOBALS__
+ const char *path, z_stat *buf)); /* win32.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Miscellaneous/shared functions:
+ ---------------------------------------------------------------------------*/
+
+Uz_Globs *globalsCtor OF((void)); /* globals.c */
+
+int envargs OF((int *Pargc, char ***Pargv,
+ ZCONST char *envstr, ZCONST char *envstr2));
+ /* envargs.c */
+void mksargs OF((int *argcp, char ***argvp)); /* envargs.c */
+
+int match OF((ZCONST char *s, ZCONST char *p,
+ int ic __WDLPRO)); /* match.c */
+int iswild OF((ZCONST char *p)); /* match.c */
+
+/* declarations of public CRC-32 functions have been moved into crc32.h
+ (free_crc_table(), get_crc_table(), crc32()) crc32.c */
+
+int dateformat OF((void)); /* local */
+char dateseparator OF((void)); /* local */
+#ifndef WINDLL
+ void version OF((__GPRO)); /* local */
+#endif
+int mapattr OF((__GPRO)); /* local */
+int mapname OF((__GPRO__ int renamed)); /* local */
+int checkdir OF((__GPRO__ char *pathcomp, int flag)); /* local */
+char *do_wild OF((__GPRO__ ZCONST char *wildzipfn)); /* local */
+char *GetLoadPath OF((__GPRO)); /* local */
+#if (defined(MORE) && (defined(ATH_BEO_UNX) || defined(QDOS) || defined(VMS)))
+ int screensize OF((int *tt_rows, int *tt_cols)); /* local */
+# if defined(VMS)
+ int screenlinewrap OF((void)); /* local */
+# endif
+#endif /* MORE && (ATH_BEO_UNX || QDOS || VMS) */
+#ifdef OS2_W32
+ int SetFileSize OF((FILE *file, zusz_t filesize)); /* local */
+#endif
+#ifndef MTS /* macro in MTS */
+ int close_outfile OF((__GPRO)); /* local */
+#endif
+#ifdef SET_SYMLINK_ATTRIBS
+ int set_symlnk_attribs OF((__GPRO__ slinkentry *slnk_entry)); /* local */
+#endif
+#ifdef SET_DIR_ATTRIB
+ int defer_dir_attribs OF((__GPRO__ direntry **pd)); /* local */
+ int set_direc_attribs OF((__GPRO__ direntry *d)); /* local */
+#endif
+#ifdef TIMESTAMP
+# ifdef WIN32
+ int stamp_file OF((__GPRO__
+ ZCONST char *fname, time_t modtime)); /* local */
+# else
+ int stamp_file OF((ZCONST char *fname, time_t modtime)); /* local */
+# endif
+#endif
+#ifdef NEED_ISO_OEM_INIT
+ void prepare_ISO_OEM_translat OF((__GPRO)); /* local */
+#endif
+#if (defined(MALLOC_WORK) && defined(MY_ZCALLOC))
+ zvoid far *zcalloc OF((unsigned int, unsigned int));
+ zvoid zcfree OF((zvoid far *));
+#endif /* MALLOC_WORK && MY_ZCALLOC */
+#ifdef SYSTEM_SPECIFIC_CTOR
+ void SYSTEM_SPECIFIC_CTOR OF((__GPRO)); /* local */
+#endif
+#ifdef SYSTEM_SPECIFIC_DTOR
+ void SYSTEM_SPECIFIC_DTOR OF((__GPRO)); /* local */
+#endif
+
+
+
+
+
+/************/
+/* Macros */
+/************/
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifdef DEBUG
+# if (defined(THEOS) && defined(NO_BOGUS_SPC))
+# define NO_DEBUG_IN_MACROS
+# define Trace(x) _fprintf x
+# else
+# define Trace(x) fprintf x
+# endif
+#else
+# define Trace(x)
+#endif
+
+#ifdef DEBUG_TIME
+# define TTrace(x) fprintf x
+#else
+# define TTrace(x)
+#endif
+
+#ifdef NO_DEBUG_IN_MACROS
+# define MTrace(x)
+#else
+# define MTrace(x) Trace(x)
+#endif
+
+#if (defined(UNIX) || defined(T20_VMS)) /* generally old systems */
+# define ToLower(x) ((char)(isupper((int)x)? tolower((int)x) : x))
+#else
+# define ToLower tolower /* assumed "smart"; used in match() */
+#endif
+
+#ifdef USE_STRM_INPUT
+ /* ``Replace'' the unbuffered UNIX style I/O function with similar
+ * standard C functions from <stdio.h>.
+ */
+# define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
+# ifdef zlseek
+# undef zlseek
+# endif
+# define zlseek(fd,o,w) zfseeko((FILE *)(fd),(o),(w))
+# define close(fd) fclose((FILE *)(fd))
+#endif /* USE_STRM_INPUT */
+
+/* The return value of the Info() "macro function" is never checked in
+ * UnZip. Otherwise, to get the same behaviour as for (*G.message)(), the
+ * Info() definition for "FUNZIP" would have to be corrected:
+ * #define Info(buf,flag,sprf_arg) \
+ * (fputs((char *)(sprintf sprf_arg, (buf)), \
+ * (flag)&1? stderr : stdout) < 0)
+ */
+#ifndef Info /* may already have been defined for redirection */
+# ifdef FUNZIP
+# define Info(buf,flag,sprf_arg) \
+ fputs((char *)(sprintf sprf_arg, (buf)), (flag)&1? stderr : stdout)
+# else
+# ifdef INT_SPRINTF /* optimized version for "int sprintf()" flavour */
+# define Info(buf,flag,sprf_arg) \
+ (*G.message)((zvoid *)&G, (uch *)(buf), (ulg)sprintf sprf_arg, (flag))
+# else /* generic version, does not use sprintf() return value */
+# define Info(buf,flag,sprf_arg) \
+ (*G.message)((zvoid *)&G, (uch *)(buf), \
+ (ulg)(sprintf sprf_arg, strlen((char *)(buf))), (flag))
+# endif
+# endif
+#endif /* !Info */
+
+/* This wrapper macro around fzofft() is just defined to "hide" the
+ * argument needed to reference the global storage buffers.
+ */
+#define FmZofft(val, pre, post) fzofft(__G__ val, pre, post)
+
+/* The following macro wrappers around the fnfilter function are used many
+ * times to prepare archive entry names or name components for displaying
+ * listings and (warning/error) messages. They use sections in the upper half
+ * of 'slide' as buffer, since their output is normally fed through the
+ * Info() macro with 'slide' (the start of this area) as message buffer.
+ */
+#define FnFilter1(fname) \
+ fnfilter((fname), slide + (extent)(WSIZE>>1), (extent)(WSIZE>>2))
+#define FnFilter2(fname) \
+ fnfilter((fname), slide + (extent)((WSIZE>>1) + (WSIZE>>2)),\
+ (extent)(WSIZE>>2))
+
+#ifndef FUNZIP /* used only in inflate.c */
+# define MESSAGE(str,len,flag) (*G.message)((zvoid *)&G,(str),(len),(flag))
+#endif
+
+#if 0 /* Optimization: use the (const) result of crc32(0L,NULL,0) */
+# define CRCVAL_INITIAL crc32(0L, NULL, 0)
+#else
+# define CRCVAL_INITIAL 0L
+#endif
+
+#ifdef SYMLINKS
+ /* This macro defines the Zip "made by" hosts that are considered
+ to support storing symbolic link entries. */
+# define SYMLINK_HOST(hn) ((hn) == UNIX_ || (hn) == ATARI_ || \
+ (hn) == ATHEOS_ || (hn) == BEOS_ || (hn) == VMS_)
+#endif
+
+#ifndef TEST_NTSD /* "NTSD valid?" checking function */
+# define TEST_NTSD NULL /* ... is not available */
+#endif
+
+#define SKIP_(length) if(length&&((error=do_string(__G__ length,SKIP))!=0))\
+ {error_in_archive=error; if(error>1) return error;}
+
+/*
+ * Skip a variable-length field, and report any errors. Used in zipinfo.c
+ * and unzip.c in several functions.
+ *
+ * macro SKIP_(length)
+ * ush length;
+ * {
+ * if (length && ((error = do_string(length, SKIP)) != 0)) {
+ * error_in_archive = error; /-* might be warning *-/
+ * if (error > 1) /-* fatal *-/
+ * return (error);
+ * }
+ * }
+ *
+ */
+
+
+#ifdef FUNZIP
+# define FLUSH(w) flush(__G__ (ulg)(w))
+# define NEXTBYTE getc(G.in) /* redefined in crypt.h if full version */
+#else
+# define FLUSH(w) ((G.mem_mode) ? memflush(__G__ redirSlide,(ulg)(w)) \
+ : flush(__G__ redirSlide,(ulg)(w),0))
+# define NEXTBYTE (G.incnt-- > 0 ? (int)(*G.inptr++) : readbyte(__G))
+#endif
+
+
+#define READBITS(nbits,zdest) {if(nbits>G.bits_left) {int temp; G.zipeof=1;\
+ while (G.bits_left<=8*(int)(sizeof(G.bitbuf)-1) && (temp=NEXTBYTE)!=EOF) {\
+ G.bitbuf|=(ulg)temp<<G.bits_left; G.bits_left+=8; G.zipeof=0;}}\
+ zdest=(shrint)((unsigned)G.bitbuf&mask_bits[nbits]);G.bitbuf>>=nbits;\
+ G.bits_left-=nbits;}
+
+/*
+ * macro READBITS(nbits,zdest) * only used by unreduce and unshrink *
+ * {
+ * if (nbits > G.bits_left) { * fill G.bitbuf, 8*sizeof(ulg) bits *
+ * int temp;
+ *
+ * G.zipeof = 1;
+ * while (G.bits_left <= 8*(int)(sizeof(G.bitbuf)-1) &&
+ * (temp = NEXTBYTE) != EOF) {
+ * G.bitbuf |= (ulg)temp << G.bits_left;
+ * G.bits_left += 8;
+ * G.zipeof = 0;
+ * }
+ * }
+ * zdest = (shrint)((unsigned)G.bitbuf & mask_bits[nbits]);
+ * G.bitbuf >>= nbits;
+ * G.bits_left -= nbits;
+ * }
+ *
+ */
+
+
+/* GRR: should use StringLower for STRLOWER macro if possible */
+
+/*
+ * Copy the zero-terminated string in str1 into str2, converting any
+ * uppercase letters to lowercase as we go. str2 gets zero-terminated
+ * as well, of course. str1 and str2 may be the same character array.
+ */
+#ifdef _MBCS
+# define STRLOWER(str1, str2) \
+ { \
+ char *p, *q, c; unsigned i; \
+ p = (char *)(str1); \
+ q = (char *)(str2); \
+ while ((c = *p) != '\0') { \
+ if ((i = CLEN(p)) > 1) { \
+ while (i--) *q++ = *p++; \
+ } else { \
+ *q++ = (char)(isupper((int)(c))? tolower((int)(c)) : c); \
+ p++; \
+ } \
+ } \
+ *q = '\0'; \
+ }
+#else
+# define STRLOWER(str1, str2) \
+ { \
+ char *p, *q; \
+ p = (char *)(str1) - 1; \
+ q = (char *)(str2); \
+ while (*++p) \
+ *q++ = (char)(isupper((int)(*p))? tolower((int)(*p)) : *p); \
+ *q = '\0'; \
+ }
+#endif
+/*
+ * NOTES: This macro makes no assumptions about the characteristics of
+ * the tolower() function or macro (beyond its existence), nor does it
+ * make assumptions about the structure of the character set (i.e., it
+ * should work on EBCDIC machines, too). The fact that either or both
+ * of isupper() and tolower() may be macros has been taken into account;
+ * watch out for "side effects" (in the C sense) when modifying this
+ * macro.
+ */
+
+#ifndef foreign
+# define foreign(c) (c)
+#endif
+
+#ifndef native
+# define native(c) (c)
+# define A_TO_N(str1)
+#else
+# ifndef NATIVE
+# define NATIVE "native chars"
+# endif
+# define A_TO_N(str1) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++) *p=native(*p);}
+#endif
+/*
+ * Translate the zero-terminated string in str1 from ASCII to the native
+ * character set. The translation is performed in-place and uses the
+ * "native" macro to translate each character.
+ *
+ * NOTE: Using the "native" macro means that is it the only part of unzip
+ * which knows which translation table (if any) is actually in use to
+ * produce the native character set. This makes adding new character set
+ * translation tables easy, insofar as all that is needed is an appropriate
+ * "native" macro definition and the translation table itself. Currently,
+ * the only non-ASCII native character set implemented is EBCDIC, but this
+ * may not always be so.
+ */
+
+
+/* default setup for internal codepage: assume ISO 8859-1 compatibility!! */
+#if (!defined(NATIVE) && !defined(CRTL_CP_IS_ISO) && !defined(CRTL_CP_IS_OEM))
+# define CRTL_CP_IS_ISO
+#endif
+
+
+/* Translate "extended ASCII" chars (OEM coding for DOS and OS/2; else
+ * ISO-8859-1 [ISO Latin 1, Win Ansi,...]) into the internal "native"
+ * code page. As with A_TO_N(), conversion is done in place.
+ */
+#ifndef _ISO_INTERN
+# ifdef CRTL_CP_IS_OEM
+# ifndef IZ_ISO2OEM_ARRAY
+# define IZ_ISO2OEM_ARRAY
+# endif
+# define _ISO_INTERN(str1) if (iso2oem) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++)\
+ *p = native((*p & 0x80) ? iso2oem[*p & 0x7f] : *p);}
+# else
+# define _ISO_INTERN(str1) A_TO_N(str1)
+# endif
+#endif
+
+#ifndef _OEM_INTERN
+# ifdef CRTL_CP_IS_OEM
+# define _OEM_INTERN(str1) A_TO_N(str1)
+# else
+# ifndef IZ_OEM2ISO_ARRAY
+# define IZ_OEM2ISO_ARRAY
+# endif
+# define _OEM_INTERN(str1) if (oem2iso) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++)\
+ *p = native((*p & 0x80) ? oem2iso[*p & 0x7f] : *p);}
+# endif
+#endif
+
+#ifndef STR_TO_ISO
+# ifdef CRTL_CP_IS_ISO
+# define STR_TO_ISO strcpy
+# else
+# define STR_TO_ISO str2iso
+# define NEED_STR2ISO
+# endif
+#endif
+
+#ifndef STR_TO_OEM
+# ifdef CRTL_CP_IS_OEM
+# define STR_TO_OEM strcpy
+# else
+# define STR_TO_OEM str2oem
+# define NEED_STR2OEM
+# endif
+#endif
+
+#if (!defined(INTERN_TO_ISO) && !defined(ASCII2ISO))
+# ifdef CRTL_CP_IS_OEM
+ /* know: "ASCII" is "OEM" */
+# define ASCII2ISO(c) \
+ ((((c) & 0x80) && oem2iso) ? oem2iso[(c) & 0x7f] : (c))
+# if (defined(NEED_STR2ISO) && !defined(CRYP_USES_OEM2ISO))
+# define CRYP_USES_OEM2ISO
+# endif
+# else
+ /* assume: "ASCII" is "ISO-ANSI" */
+# define ASCII2ISO(c) (c)
+# endif
+#endif
+
+#if (!defined(INTERN_TO_OEM) && !defined(ASCII2OEM))
+# ifdef CRTL_CP_IS_OEM
+ /* know: "ASCII" is "OEM" */
+# define ASCII2OEM(c) (c)
+# else
+ /* assume: "ASCII" is "ISO-ANSI" */
+# define ASCII2OEM(c) \
+ ((((c) & 0x80) && iso2oem) ? iso2oem[(c) & 0x7f] : (c))
+# if (defined(NEED_STR2OEM) && !defined(CRYP_USES_ISO2OEM))
+# define CRYP_USES_ISO2OEM
+# endif
+# endif
+#endif
+
+/* codepage conversion setup for testp() in crypt.c */
+#ifdef CRTL_CP_IS_ISO
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_OEM
+# endif
+#else
+# ifdef CRTL_CP_IS_OEM
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_ISO
+# endif
+# else /* native internal CP is neither ISO nor OEM */
+# ifndef STR_TO_CP1
+# define STR_TO_CP1 STR_TO_ISO
+# endif
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_OEM
+# endif
+# endif
+#endif
+
+
+/* Convert filename (and file comment string) into "internal" charset.
+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
+ * codepage when made on
+ * -> DOS (this includes 16-bit Windows 3.1) (FS_FAT_)
+ * -> OS/2 (FS_HPFS_)
+ * -> Win95/WinNT with Nico Mak's WinZip (FS_NTFS_ && hostver == "5.0")
+ * EXCEPTIONS:
+ * PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
+ * the filename stored in the local header is coded in Windows ANSI (CP 1252
+ * resp. ISO 8859-1 on US and western Europe locale settings).
+ * Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
+ * filenames stored in BOTH the local and the central header are coded
+ * in the local system's codepage (usually ANSI codings like ISO 8859-1).
+ *
+ * All other ports are assumed to code zip entry filenames in ISO 8859-1.
+ */
+#ifndef Ext_ASCII_TO_Native
+# define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
+ if (((hostnum) == FS_FAT_ && \
+ !(((islochdr) || (isuxatt)) && \
+ ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+ (hostnum) == FS_HPFS_ || \
+ ((hostnum) == FS_NTFS_ /* && (hostver) == 50 */ )) { \
+ _OEM_INTERN((string)); \
+ } else { \
+ _ISO_INTERN((string)); \
+ }
+#endif
+
+
+
+/**********************/
+/* Global constants */
+/**********************/
+
+ extern ZCONST unsigned near mask_bits[17];
+ extern ZCONST char *fnames[2];
+
+#ifdef EBCDIC
+ extern ZCONST uch ebcdic[];
+#endif
+#ifdef IZ_ISO2OEM_ARRAY
+ extern ZCONST uch Far *iso2oem;
+ extern ZCONST uch Far iso2oem_850[];
+#endif
+#ifdef IZ_OEM2ISO_ARRAY
+ extern ZCONST uch Far *oem2iso;
+ extern ZCONST uch Far oem2iso_850[];
+#endif
+
+ extern ZCONST char Far VersionDate[];
+ extern ZCONST char Far CentSigMsg[];
+#ifndef SFX
+ extern ZCONST char Far EndSigMsg[];
+#endif
+ extern ZCONST char Far SeekMsg[];
+ extern ZCONST char Far FilenameNotMatched[];
+ extern ZCONST char Far ExclFilenameNotMatched[];
+ extern ZCONST char Far ReportMsg[];
+
+#ifndef SFX
+ extern ZCONST char Far Zipnfo[];
+ extern ZCONST char Far CompiledWith[];
+#endif /* !SFX */
+
+
+
+/***********************************/
+/* Global (shared?) RTL variables */
+/***********************************/
+
+#ifdef DECLARE_ERRNO
+ extern int errno;
+#endif
+
+/*---------------------------------------------------------------------
+ Unicode Support
+ 28 August 2005
+ ---------------------------------------------------------------------*/
+#if (defined(UNICODE_SUPPORT) && defined(UNICODE_WCHAR))
+
+ /* Default character when a zwchar too big for wchar_t */
+# define zwchar_to_wchar_t_default_char '_'
+
+ /* Default character string when wchar_t does not convert to mb */
+# define wide_to_mb_default_string "_"
+
+ /* wide character type */
+ typedef unsigned long zwchar;
+
+ /* UTF-8 related conversion functions, currently found in process.c */
+
+# if 0 /* currently unused */
+ /* check if string is all ASCII */
+ int is_ascii_string OF((ZCONST char *mbstring));
+# endif /* unused */
+
+ /* convert UTF-8 string to multi-byte string */
+ char *utf8_to_local_string OF((ZCONST char *utf8_string, int escape_all));
+
+ /* convert UTF-8 string to wide string */
+ zwchar *utf8_to_wide_string OF((ZCONST char *utf8_string));
+
+ /* convert wide string to multi-byte string */
+ char *wide_to_local_string OF((ZCONST zwchar *wide_string, int escape_all));
+
+# if 0 /* currently unused */
+ /* convert local string to multi-byte display string */
+ char *local_to_display_string OF((ZCONST char *local_string));
+# endif /* unused */
+
+ /* convert wide character to escape string */
+ char *wide_to_escape_string OF((unsigned long));
+
+# define utf8_to_escaped_string(utf8_string) \
+ utf8_to_local_string(utf8_string, TRUE)
+
+# if 0 /* currently unused */
+ /* convert escape string to wide character */
+ unsigned long escape_string_to_wide OF((ZCONST char *escape_string));
+
+ /* convert local to UTF-8 */
+ char *local_to_utf8_string OF ((ZCONST char *local_string));
+
+ /* convert local to wide string */
+ zwchar *local_to_wide_string OF ((ZCONST char *local_string));
+
+ /* convert wide string to UTF-8 */
+ char *wide_to_utf8_string OF((ZCONST zwchar *wide_string));
+# endif /* unused */
+
+#endif /* UNICODE_SUPPORT && UNICODE_WCHAR */
+
+
+#endif /* !__unzpriv_h */
Index: unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new/zipinfo.c (revision 5)
@@ -0,0 +1,2394 @@
+/*
+ Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ zipinfo.c Greg Roelofs et al.
+
+ This file contains all of the ZipInfo-specific listing routines for UnZip.
+
+ Contains: zi_opts()
+ zi_end_central()
+ zipinfo()
+ zi_long()
+ zi_short()
+ zi_time()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+
+#ifndef NO_ZIPINFO /* strings use up too much space in small-memory systems */
+
+/* Define OS-specific attributes for use on ALL platforms--the S_xxxx
+ * versions of these are defined differently (or not defined) by different
+ * compilers and operating systems. */
+
+#define UNX_IFMT 0170000 /* Unix file type mask */
+#define UNX_IFREG 0100000 /* Unix regular file */
+#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
+#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
+#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
+#define UNX_IFDIR 0040000 /* Unix directory */
+#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
+#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
+#define UNX_ISUID 04000 /* Unix set user id on execution */
+#define UNX_ISGID 02000 /* Unix set group id on execution */
+#define UNX_ISVTX 01000 /* Unix directory permissions control */
+#define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */
+#define UNX_IRWXU 00700 /* Unix read, write, execute: owner */
+#define UNX_IRUSR 00400 /* Unix read permission: owner */
+#define UNX_IWUSR 00200 /* Unix write permission: owner */
+#define UNX_IXUSR 00100 /* Unix execute permission: owner */
+#define UNX_IRWXG 00070 /* Unix read, write, execute: group */
+#define UNX_IRGRP 00040 /* Unix read permission: group */
+#define UNX_IWGRP 00020 /* Unix write permission: group */
+#define UNX_IXGRP 00010 /* Unix execute permission: group */
+#define UNX_IRWXO 00007 /* Unix read, write, execute: other */
+#define UNX_IROTH 00004 /* Unix read permission: other */
+#define UNX_IWOTH 00002 /* Unix write permission: other */
+#define UNX_IXOTH 00001 /* Unix execute permission: other */
+
+#define VMS_IRUSR UNX_IRUSR /* VMS read/owner */
+#define VMS_IWUSR UNX_IWUSR /* VMS write/owner */
+#define VMS_IXUSR UNX_IXUSR /* VMS execute/owner */
+#define VMS_IRGRP UNX_IRGRP /* VMS read/group */
+#define VMS_IWGRP UNX_IWGRP /* VMS write/group */
+#define VMS_IXGRP UNX_IXGRP /* VMS execute/group */
+#define VMS_IROTH UNX_IROTH /* VMS read/other */
+#define VMS_IWOTH UNX_IWOTH /* VMS write/other */
+#define VMS_IXOTH UNX_IXOTH /* VMS execute/other */
+
+#define AMI_IFMT 06000 /* Amiga file type mask */
+#define AMI_IFDIR 04000 /* Amiga directory */
+#define AMI_IFREG 02000 /* Amiga regular file */
+#define AMI_IHIDDEN 00200 /* to be supported in AmigaDOS 3.x */
+#define AMI_ISCRIPT 00100 /* executable script (text command file) */
+#define AMI_IPURE 00040 /* allow loading into resident memory */
+#define AMI_IARCHIVE 00020 /* not modified since bit was last set */
+#define AMI_IREAD 00010 /* can be opened for reading */
+#define AMI_IWRITE 00004 /* can be opened for writing */
+#define AMI_IEXECUTE 00002 /* executable image, a loadable runfile */
+#define AMI_IDELETE 00001 /* can be deleted */
+
+#define THS_IFMT 0xF000 /* Theos file type mask */
+#define THS_IFIFO 0x1000 /* pipe */
+#define THS_IFCHR 0x2000 /* char device */
+#define THS_IFSOCK 0x3000 /* socket */
+#define THS_IFDIR 0x4000 /* directory */
+#define THS_IFLIB 0x5000 /* library */
+#define THS_IFBLK 0x6000 /* block device */
+#define THS_IFREG 0x8000 /* regular file */
+#define THS_IFREL 0x9000 /* relative (direct) */
+#define THS_IFKEY 0xA000 /* keyed */
+#define THS_IFIND 0xB000 /* indexed */
+#define THS_IFRND 0xC000 /* ???? */
+#define THS_IFR16 0xD000 /* 16 bit real mode program */
+#define THS_IFP16 0xE000 /* 16 bit protected mode prog */
+#define THS_IFP32 0xF000 /* 32 bit protected mode prog */
+#define THS_IMODF 0x0800 /* modified */
+#define THS_INHID 0x0400 /* not hidden */
+#define THS_IEUSR 0x0200 /* erase permission: owner */
+#define THS_IRUSR 0x0100 /* read permission: owner */
+#define THS_IWUSR 0x0080 /* write permission: owner */
+#define THS_IXUSR 0x0040 /* execute permission: owner */
+#define THS_IROTH 0x0004 /* read permission: other */
+#define THS_IWOTH 0x0002 /* write permission: other */
+#define THS_IXOTH 0x0001 /* execute permission: other */
+
+#ifdef OLD_THEOS_EXTRA
+# include "theos/oldstat.h"
+#endif
+
+#ifndef NSK_UNSTRUCTURED
+# define NSK_UNSTRUCTURED 0
+#endif
+#ifndef NSK_OBJECTFILECODE
+# define NSK_OBJECTFILECODE 100
+#endif
+#ifndef NSK_EDITFILECODE
+# define NSK_EDITFILECODE 101
+#endif
+
+#define LFLAG 3 /* short "ls -l" type listing */
+
+static int zi_long OF((__GPRO__ zusz_t *pEndprev, int error_in_archive));
+static int zi_short OF((__GPRO));
+static void zi_showMacTypeCreator
+ OF((__GPRO__ uch *ebfield));
+static char *zi_time OF((__GPRO__ ZCONST ulg *datetimez,
+ ZCONST time_t *modtimez, char *d_t_str));
+
+
+/**********************************************/
+/* Strings used in zipinfo.c (ZipInfo half) */
+/**********************************************/
+
+static ZCONST char nullStr[] = "";
+static ZCONST char PlurSufx[] = "s";
+
+static ZCONST char Far ZipInfHeader2[] =
+ "Zip file size: %s bytes, number of entries: %s\n";
+static ZCONST char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n";
+static ZCONST char Far LineSeparators[] = "-------------------------------\n\n";
+static ZCONST char Far ZipFSizeVerbose[] = "\
+ Zip archive file size: %s (%sh)\n";
+static ZCONST char Far ActOffsetCentDir[] = "\
+ Actual end-cent-dir record offset: %s (%sh)\n\
+ Expected end-cent-dir record offset: %s (%sh)\n\
+ (based on the length of the central directory and its expected offset)\n\n";
+static ZCONST char Far SinglePartArchive1[] = "\
+ This zipfile constitutes the sole disk of a single-part archive; its\n\
+ central directory contains %s %s.\n\
+ The central directory is %s (%sh) bytes long,\n";
+static ZCONST char Far SinglePartArchive2[] = "\
+ and its (expected) offset in bytes from the beginning of the zipfile\n\
+ is %s (%sh).\n\n";
+static ZCONST char Far MultiPartArchive1[] = "\
+ This zipfile constitutes disk %lu of a multi-part archive. The central\n\
+ directory starts on disk %lu at an offset within that archive part\n";
+static ZCONST char Far MultiPartArchive2[] = "\
+ of %s (%sh) bytes. The entire\n\
+ central directory is %s (%sh) bytes long.\n";
+static ZCONST char Far MultiPartArchive3[] = "\
+ %s of the archive entries %s contained within this zipfile volume,\n\
+ out of a total of %s %s.\n\n";
+
+static ZCONST char Far CentralDirEntry[] =
+ "\nCentral directory entry #%lu:\n---------------------------\n\n";
+static ZCONST char Far ZipfileStats[] =
+ "%lu file%s, %s bytes uncompressed, %s bytes compressed: %s%d.%d%%\n";
+
+/* zi_long() strings */
+static ZCONST char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT";
+static ZCONST char Far OS_Amiga[] = "Amiga";
+static ZCONST char Far OS_VMS[] = "VMS";
+static ZCONST char Far OS_Unix[] = "Unix";
+static ZCONST char Far OS_VMCMS[] = "VM/CMS";
+static ZCONST char Far OS_AtariST[] = "Atari ST";
+static ZCONST char Far OS_HPFS[] = "OS/2 or NT HPFS";
+static ZCONST char Far OS_Macintosh[] = "Macintosh HFS";
+static ZCONST char Far OS_ZSystem[] = "Z-System";
+static ZCONST char Far OS_CPM[] = "CP/M";
+static ZCONST char Far OS_TOPS20[] = "TOPS-20";
+static ZCONST char Far OS_NTFS[] = "NTFS";
+static ZCONST char Far OS_QDOS[] = "SMS/QDOS";
+static ZCONST char Far OS_Acorn[] = "Acorn RISC OS";
+static ZCONST char Far OS_MVS[] = "MVS";
+static ZCONST char Far OS_VFAT[] = "Win32 VFAT";
+static ZCONST char Far OS_AtheOS[] = "AtheOS";
+static ZCONST char Far OS_BeOS[] = "BeOS";
+static ZCONST char Far OS_Tandem[] = "Tandem NSK";
+static ZCONST char Far OS_Theos[] = "Theos";
+static ZCONST char Far OS_MacDarwin[] = "Mac OS/X (Darwin)";
+#ifdef OLD_THEOS_EXTRA
+ static ZCONST char Far OS_TheosOld[] = "Theos (Old)";
+#endif /* OLD_THEOS_EXTRA */
+
+static ZCONST char Far MthdNone[] = "none (stored)";
+static ZCONST char Far MthdShrunk[] = "shrunk";
+static ZCONST char Far MthdRedF1[] = "reduced (factor 1)";
+static ZCONST char Far MthdRedF2[] = "reduced (factor 2)";
+static ZCONST char Far MthdRedF3[] = "reduced (factor 3)";
+static ZCONST char Far MthdRedF4[] = "reduced (factor 4)";
+static ZCONST char Far MthdImplode[] = "imploded";
+static ZCONST char Far MthdToken[] = "tokenized";
+static ZCONST char Far MthdDeflate[] = "deflated";
+static ZCONST char Far MthdDeflat64[] = "deflated (enhanced-64k)";
+static ZCONST char Far MthdDCLImplode[] = "imploded (PK DCL)";
+static ZCONST char Far MthdBZip2[] = "bzipped";
+static ZCONST char Far MthdLZMA[] = "LZMA-ed";
+static ZCONST char Far MthdTerse[] = "tersed (IBM)";
+static ZCONST char Far MthdLZ77[] = "LZ77-compressed (IBM)";
+static ZCONST char Far MthdWavPack[] = "WavPacked";
+static ZCONST char Far MthdPPMd[] = "PPMd-ed";
+
+static ZCONST char Far DeflNorm[] = "normal";
+static ZCONST char Far DeflMax[] = "maximum";
+static ZCONST char Far DeflFast[] = "fast";
+static ZCONST char Far DeflSFast[] = "superfast";
+
+static ZCONST char Far ExtraBytesPreceding[] =
+ " There are an extra %s bytes preceding this file.\n\n";
+
+static ZCONST char Far UnknownNo[] = "unknown (%d)";
+
+#ifdef ZIP64_SUPPORT
+ static ZCONST char Far LocalHeaderOffset[] =
+ "\n offset of local header from start of archive: %s\n\
+ (%sh) bytes\n";
+#else
+ static ZCONST char Far LocalHeaderOffset[] =
+ "\n offset of local header from start of archive: %s (%sh) bytes\n";
+#endif
+static ZCONST char Far HostOS[] =
+ " file system or operating system of origin: %s\n";
+static ZCONST char Far EncodeSWVer[] =
+ " version of encoding software: %u.%u\n";
+static ZCONST char Far MinOSCompReq[] =
+ " minimum file system compatibility required: %s\n";
+static ZCONST char Far MinSWVerReq[] =
+ " minimum software version required to extract: %u.%u\n";
+static ZCONST char Far CompressMethod[] =
+ " compression method: %s\n";
+static ZCONST char Far SlideWindowSizeImplode[] =
+ " size of sliding dictionary (implosion): %cK\n";
+static ZCONST char Far ShannonFanoTrees[] =
+ " number of Shannon-Fano trees (implosion): %c\n";
+static ZCONST char Far CompressSubtype[] =
+ " compression sub-type (deflation): %s\n";
+static ZCONST char Far FileSecurity[] =
+ " file security status: %sencrypted\n";
+static ZCONST char Far ExtendedLocalHdr[] =
+ " extended local header: %s\n";
+static ZCONST char Far FileModDate[] =
+ " file last modified on (DOS date/time): %s\n";
+#ifdef USE_EF_UT_TIME
+ static ZCONST char Far UT_FileModDate[] =
+ " file last modified on (UT extra field modtime): %s %s\n";
+ static ZCONST char Far LocalTime[] = "local";
+#ifndef NO_GMTIME
+ static ZCONST char Far GMTime[] = "UTC";
+#endif
+#endif /* USE_EF_UT_TIME */
+static ZCONST char Far CRC32Value[] =
+ " 32-bit CRC value (hex): %.8lx\n";
+static ZCONST char Far CompressedFileSize[] =
+ " compressed size: %s bytes\n";
+static ZCONST char Far UncompressedFileSize[] =
+ " uncompressed size: %s bytes\n";
+static ZCONST char Far FilenameLength[] =
+ " length of filename: %u characters\n";
+static ZCONST char Far ExtraFieldLength[] =
+ " length of extra field: %u bytes\n";
+static ZCONST char Far FileCommentLength[] =
+ " length of file comment: %u characters\n";
+static ZCONST char Far FileDiskNum[] =
+ " disk number on which file begins: disk %lu\n";
+static ZCONST char Far ApparentFileType[] =
+ " apparent file type: %s\n";
+static ZCONST char Far VMSFileAttributes[] =
+ " VMS file attributes (%06o octal): %s\n";
+static ZCONST char Far AmigaFileAttributes[] =
+ " Amiga file attributes (%06o octal): %s\n";
+static ZCONST char Far UnixFileAttributes[] =
+ " Unix file attributes (%06o octal): %s\n";
+static ZCONST char Far NonMSDOSFileAttributes[] =
+ " non-MSDOS external file attributes: %06lX hex\n";
+static ZCONST char Far MSDOSFileAttributes[] =
+ " MS-DOS file attributes (%02X hex): none\n";
+static ZCONST char Far MSDOSFileAttributesRO[] =
+ " MS-DOS file attributes (%02X hex): read-only\n";
+static ZCONST char Far MSDOSFileAttributesAlpha[] =
+ " MS-DOS file attributes (%02X hex): %s%s%s%s%s%s%s%s\n";
+static ZCONST char Far TheosFileAttributes[] =
+ " Theos file attributes (%04X hex): %s\n";
+
+static ZCONST char Far TheosFTypLib[] = "Library ";
+static ZCONST char Far TheosFTypDir[] = "Directory ";
+static ZCONST char Far TheosFTypReg[] = "Sequential ";
+static ZCONST char Far TheosFTypRel[] = "Direct ";
+static ZCONST char Far TheosFTypKey[] = "Keyed ";
+static ZCONST char Far TheosFTypInd[] = "Indexed ";
+static ZCONST char Far TheosFTypR16[] = " 86 program ";
+static ZCONST char Far TheosFTypP16[] = "286 program ";
+static ZCONST char Far TheosFTypP32[] = "386 program ";
+static ZCONST char Far TheosFTypUkn[] = "??? ";
+
+static ZCONST char Far ExtraFieldTrunc[] = "\n\
+ error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\
+ space %u; block length has been truncated.\n";
+static ZCONST char Far ExtraFields[] = "\n\
+ The central-directory extra field contains:";
+static ZCONST char Far ExtraFieldType[] = "\n\
+ - A subfield with ID 0x%04x (%s) and %u data bytes";
+static ZCONST char Far efPKSZ64[] = "PKWARE 64-bit sizes";
+static ZCONST char Far efAV[] = "PKWARE AV";
+static ZCONST char Far efOS2[] = "OS/2";
+static ZCONST char Far efPKVMS[] = "PKWARE VMS";
+static ZCONST char Far efPKWin32[] = "PKWARE Win32";
+static ZCONST char Far efPKUnix[] = "PKWARE Unix";
+static ZCONST char Far efIZVMS[] = "Info-ZIP VMS";
+static ZCONST char Far efIZUnix[] = "old Info-ZIP Unix/OS2/NT";
+static ZCONST char Far efIZUnix2[] = "Unix UID/GID (16-bit)";
+static ZCONST char Far efIZUnix3[] = "Unix UID/GID (any size)";
+static ZCONST char Far efTime[] = "universal time";
+static ZCONST char Far efU8Path[] = "UTF8 path name";
+static ZCONST char Far efU8Commnt[] = "UTF8 entry comment";
+static ZCONST char Far efJLMac[] = "old Info-ZIP Macintosh";
+static ZCONST char Far efMac3[] = "new Info-ZIP Macintosh";
+static ZCONST char Far efZipIt[] = "ZipIt Macintosh";
+static ZCONST char Far efSmartZip[] = "SmartZip Macintosh";
+static ZCONST char Far efZipIt2[] = "ZipIt Macintosh (short)";
+static ZCONST char Far efVMCMS[] = "VM/CMS";
+static ZCONST char Far efMVS[] = "MVS";
+static ZCONST char Far efACL[] = "OS/2 ACL";
+static ZCONST char Far efNTSD[] = "Security Descriptor";
+static ZCONST char Far efAtheOS[] = "AtheOS";
+static ZCONST char Far efBeOS[] = "BeOS";
+static ZCONST char Far efQDOS[] = "SMS/QDOS";
+static ZCONST char Far efAOSVS[] = "AOS/VS";
+static ZCONST char Far efSpark[] = "Acorn SparkFS";
+static ZCONST char Far efMD5[] = "Fred Kantor MD5";
+static ZCONST char Far efASiUnix[] = "ASi Unix";
+static ZCONST char Far efTandem[] = "Tandem NSK";
+static ZCONST char Far efTheos[] = "Theos";
+static ZCONST char Far efUnknown[] = "unknown";
+
+static ZCONST char Far OS2EAs[] = ".\n\
+ The local extra field has %lu bytes of OS/2 extended attributes.\n\
+ (May not match OS/2 \"dir\" amount due to storage method)";
+static ZCONST char Far izVMSdata[] = ". The extra\n\
+ field is %s and has %u bytes of VMS %s information%s";
+static ZCONST char Far izVMSstored[] = "stored";
+static ZCONST char Far izVMSrleenc[] = "run-length encoded";
+static ZCONST char Far izVMSdeflat[] = "deflated";
+static ZCONST char Far izVMScunknw[] = "compressed(?)";
+static ZCONST char Far *izVMScomp[4] =
+ {izVMSstored, izVMSrleenc, izVMSdeflat, izVMScunknw};
+static ZCONST char Far ACLdata[] = ".\n\
+ The local extra field has %lu bytes of access control list information";
+static ZCONST char Far NTSDData[] = ".\n\
+ The local extra field has %lu bytes of NT security descriptor data";
+static ZCONST char Far UTdata[] = ".\n\
+ The local extra field has UTC/GMT %s time%s";
+static ZCONST char Far UTmodification[] = "modification";
+static ZCONST char Far UTaccess[] = "access";
+static ZCONST char Far UTcreation[] = "creation";
+static ZCONST char Far U8PthCmnComplete[] = ".\n\
+ The UTF8 data of the extra field (V%u, ASCII name CRC `%.8lx') are:\n ";
+static ZCONST char Far U8PthCmnF24[] = ". The first\n\
+ 24 UTF8 bytes in the extra field (V%u, ASCII name CRC `%.8lx') are:\n ";
+static ZCONST char Far ZipItFname[] = ".\n\
+ The Mac long filename is %s";
+static ZCONST char Far Mac3data[] = ".\n\
+ The local extra field has %lu bytes of %scompressed Macintosh\n\
+ finder attributes";
+ /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */
+static ZCONST char Far MacOSdata[] = ".\n\
+ The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'";
+static ZCONST char Far MacOSdata1[] = ".\n\
+ The associated file has type code `0x%lx' and creator code `0x%lx'";
+static ZCONST char Far MacOSJLEEflags[] = ".\n File is marked as %s";
+static ZCONST char Far MacOS_RF[] = "Resource-fork";
+static ZCONST char Far MacOS_DF[] = "Data-fork";
+static ZCONST char Far MacOSMAC3flags[] = ".\n\
+ File is marked as %s, File Dates are in %d Bit";
+static ZCONST char Far AtheOSdata[] = ".\n\
+ The local extra field has %lu bytes of %scompressed AtheOS file attributes";
+static ZCONST char Far BeOSdata[] = ".\n\
+ The local extra field has %lu bytes of %scompressed BeOS file attributes";
+ /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */
+static ZCONST char Far QDOSdata[] = ".\n\
+ The QDOS extra field subtype is `%c%c%c%c'";
+static ZCONST char Far AOSVSdata[] = ".\n\
+ The AOS/VS extra field revision is %d.%d";
+static ZCONST char Far TandemUnstr[] = "Unstructured";
+static ZCONST char Far TandemRel[] = "Relative";
+static ZCONST char Far TandemEntry[] = "Entry Sequenced";
+static ZCONST char Far TandemKey[] = "Key Sequenced";
+static ZCONST char Far TandemEdit[] = "Edit";
+static ZCONST char Far TandemObj[] = "Object";
+static ZCONST char Far *TandemFileformat[6] =
+ {TandemUnstr, TandemRel, TandemEntry, TandemKey, TandemEdit, TandemObj};
+static ZCONST char Far Tandemdata[] = ".\n\
+ The file was originally a Tandem %s file, with file code %u";
+static ZCONST char Far MD5data[] = ".\n\
+ The 128-bit MD5 signature is %s";
+#ifdef CMS_MVS
+ static ZCONST char Far VmMvsExtraField[] = ".\n\
+ The stored file open mode (FLDATA TYPE) is \"%s\"";
+ static ZCONST char Far VmMvsInvalid[] = "[invalid]";
+#endif /* CMS_MVS */
+
+static ZCONST char Far First20[] = ". The first\n 20 are: ";
+static ZCONST char Far ColonIndent[] = ":\n ";
+static ZCONST char Far efFormat[] = " %02x";
+
+static ZCONST char Far lExtraFieldType[] = "\n\
+ There %s a local extra field with ID 0x%04x (%s) and\n\
+ %u data bytes (%s).\n";
+static ZCONST char Far efIZuid[] =
+ "GMT modification/access times and Unix UID/GID";
+static ZCONST char Far efIZnouid[] = "GMT modification/access times only";
+
+
+static ZCONST char Far NoFileComment[] = "\n There is no file comment.\n";
+static ZCONST char Far FileCommBegin[] = "\n\
+------------------------- file comment begins ----------------------------\n";
+static ZCONST char Far FileCommEnd[] = "\
+-------------------------- file comment ends -----------------------------\n";
+
+/* zi_time() strings */
+static ZCONST char Far BogusFmt[] = "%03d";
+static ZCONST char Far shtYMDHMTime[] = "%02u-%s-%02u %02u:%02u";
+static ZCONST char Far lngYMDHMSTime[] = "%u %s %u %02u:%02u:%02u";
+static ZCONST char Far DecimalTime[] = "%04u%02u%02u.%02u%02u%02u";
+#ifdef USE_EF_UT_TIME
+ static ZCONST char Far lngYMDHMSTimeError[] = "???? ??? ?? ??:??:??";
+#endif
+
+
+
+
+
+#ifndef WINDLL
+
+/************************/
+/* Function zi_opts() */
+/************************/
+
+int zi_opts(__G__ pargc, pargv)
+ int *pargc;
+ char ***pargv;
+ __GDEF
+{
+ char **argv, *s;
+ int argc, c, error=FALSE, negative=0;
+ int hflag_slmv=TRUE, hflag_2=FALSE; /* diff options => diff defaults */
+ int tflag_slm=TRUE, tflag_2v=FALSE;
+ int explicit_h=FALSE, explicit_t=FALSE;
+
+#ifdef UNIX
+ extern char OEM_CP[MAX_CP_NAME];
+ extern char ISO_CP[MAX_CP_NAME];
+#endif
+
+#ifdef MACOS
+ uO.lflag = LFLAG; /* reset default on each call */
+#endif
+ G.extract_flag = FALSE; /* zipinfo does not extract to disk */
+ argc = *pargc;
+ argv = *pargv;
+
+ while (--argc > 0 && (*++argv)[0] == '-') {
+ s = argv[0] + 1;
+ while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
+ switch (c) {
+ case '-':
+ ++negative;
+ break;
+ case '1': /* shortest listing: JUST filenames */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 1;
+ break;
+ case '2': /* just filenames, plus headers if specified */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 2;
+ break;
+#ifndef CMS_MVS
+ case ('C'): /* -C: match filenames case-insensitively */
+ if (negative)
+ uO.C_flag = FALSE, negative = 0;
+ else
+ uO.C_flag = TRUE;
+ break;
+#endif /* !CMS_MVS */
+ case 'h': /* header line */
+ if (negative)
+ hflag_2 = hflag_slmv = FALSE, negative = 0;
+ else {
+ hflag_2 = hflag_slmv = explicit_h = TRUE;
+ if (uO.lflag == -1)
+ uO.lflag = 0;
+ }
+ break;
+#ifdef UNIX
+ case ('I'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Icharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
+ } else { /* -I charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
+ case 'l': /* longer form of "ls -l" type listing */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 5;
+ break;
+ case 'm': /* medium form of "ls -l" type listing */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 4;
+ break;
+#ifdef MORE
+ case 'M': /* send output through built-in "more" */
+ if (negative)
+ G.M_flag = FALSE, negative = 0;
+ else
+ G.M_flag = TRUE;
+ break;
+#endif
+#ifdef UNIX
+ case ('O'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Ocharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
+ } else { /* -O charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -O argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
+ case 's': /* default: shorter "ls -l" type listing */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 3;
+ break;
+ case 't': /* totals line */
+ if (negative)
+ tflag_2v = tflag_slm = FALSE, negative = 0;
+ else {
+ tflag_2v = tflag_slm = explicit_t = TRUE;
+ if (uO.lflag == -1)
+ uO.lflag = 0;
+ }
+ break;
+ case ('T'): /* use (sortable) decimal time format */
+ if (negative)
+ uO.T_flag = FALSE, negative = 0;
+ else
+ uO.T_flag = TRUE;
+ break;
+#ifdef UNICODE_SUPPORT
+ case ('U'): /* escape UTF-8, or disable UTF-8 support */
+ if (negative) {
+ uO.U_flag = MAX(uO.U_flag-negative,0);
+ negative = 0;
+ } else
+ uO.U_flag++;
+ break;
+#endif /* UNICODE_SUPPORT */
+ case 'v': /* turbo-verbose listing */
+ if (negative)
+ uO.lflag = -2, negative = 0;
+ else
+ uO.lflag = 10;
+ break;
+#ifdef WILD_STOP_AT_DIR
+ case ('W'): /* Wildcard interpretation (stop at '/'?) */
+ if (negative)
+ uO.W_flag = FALSE, negative = 0;
+ else
+ uO.W_flag = TRUE;
+ break;
+#endif /* WILD_STOP_AT_DIR */
+ case 'z': /* print zipfile comment */
+ if (negative)
+ uO.zflag = negative = 0;
+ else
+ uO.zflag = 1;
+ break;
+ case 'Z': /* ZipInfo mode: ignore */
+ break;
+ default:
+ error = TRUE;
+ break;
+ }
+ }
+ }
+ if ((argc-- == 0) || error) {
+ *pargc = argc;
+ *pargv = argv;
+ return USAGE(error);
+ }
+
+#ifdef MORE
+ if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func useless */
+ G.M_flag = 0;
+#endif
+
+ /* if no listing options given (or all negated), or if only -h/-t given
+ * with individual files specified, use default listing format */
+ if ((uO.lflag < 0) || ((argc > 0) && (uO.lflag == 0)))
+ uO.lflag = LFLAG;
+
+ /* set header and totals flags to default or specified values */
+ switch (uO.lflag) {
+ case 0: /* 0: can only occur if either -t or -h explicitly given; */
+ case 2: /* therefore set both flags equal to normally false value */
+ uO.hflag = hflag_2;
+ uO.tflag = tflag_2v;
+ break;
+ case 1: /* only filenames, *always* */
+ uO.hflag = FALSE;
+ uO.tflag = FALSE;
+ uO.zflag = FALSE;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ uO.hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
+ uO.tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
+ break;
+ case 10:
+ uO.hflag = hflag_slmv;
+ uO.tflag = tflag_2v;
+ break;
+ }
+
+ *pargc = argc;
+ *pargv = argv;
+ return 0;
+
+} /* end function zi_opts() */
+
+#endif /* !WINDLL */
+
+
+
+
+
+/*******************************/
+/* Function zi_end_central() */
+/*******************************/
+
+void zi_end_central(__G)
+ __GDEF
+{
+/*---------------------------------------------------------------------------
+ Print out various interesting things about the zipfile.
+ ---------------------------------------------------------------------------*/
+
+ if (uO.lflag > 9) {
+ /* verbose format */
+ Info(slide, 0, ((char *)slide, LoadFarString(EndCentDirRec)));
+ Info(slide, 0, ((char *)slide, LoadFarString(LineSeparators)));
+
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipFSizeVerbose),
+ FmZofft(G.ziplen, "11", NULL),
+ FmZofft(G.ziplen, FZOFFT_HEX_DOT_WID, "X")));
+ Info(slide, 0, ((char *)slide, LoadFarString(ActOffsetCentDir),
+ FmZofft(G.real_ecrec_offset, "11", "u"),
+ FmZofft(G.real_ecrec_offset, FZOFFT_HEX_DOT_WID, "X"),
+ FmZofft(G.expect_ecrec_offset, "11", "u"),
+ FmZofft(G.expect_ecrec_offset, FZOFFT_HEX_DOT_WID, "X")));
+
+ if (G.ecrec.number_this_disk == 0) {
+ Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive1),
+ FmZofft(G.ecrec.total_entries_central_dir, NULL, "u"),
+ (G.ecrec.total_entries_central_dir == 1)? "entry" : "entries",
+ FmZofft(G.ecrec.size_central_directory, NULL, "u"),
+ FmZofft(G.ecrec.size_central_directory,
+ FZOFFT_HEX_DOT_WID, "X")));
+ Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive2),
+ FmZofft(G.ecrec.offset_start_central_directory, NULL, "u"),
+ FmZofft(G.ecrec.offset_start_central_directory,
+ FZOFFT_HEX_DOT_WID, "X")));
+ } else {
+ Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive1),
+ (ulg)(G.ecrec.number_this_disk + 1),
+ (ulg)(G.ecrec.num_disk_start_cdir + 1)));
+ Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive2),
+ FmZofft(G.ecrec.offset_start_central_directory, NULL, "u"),
+ FmZofft(G.ecrec.offset_start_central_directory,
+ FZOFFT_HEX_DOT_WID, "X"),
+ FmZofft(G.ecrec.size_central_directory, NULL, "u"),
+ FmZofft(G.ecrec.size_central_directory,
+ FZOFFT_HEX_DOT_WID, "X")));
+ Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive3),
+ FmZofft(G.ecrec.num_entries_centrl_dir_ths_disk, NULL, "u"),
+ (G.ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are",
+ FmZofft(G.ecrec.total_entries_central_dir, NULL, "u"),
+ (G.ecrec.total_entries_central_dir == 1) ? "entry" : "entries"));
+ }
+ }
+ else if (uO.hflag) {
+ /* print zip file size and number of contained entries: */
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipInfHeader2),
+ FmZofft(G.ziplen, NULL, NULL),
+ FmZofft(G.ecrec.total_entries_central_dir, NULL, "u")));
+ }
+
+} /* end function zi_end_central() */
+
+
+
+
+
+/************************/
+/* Function zipinfo() */
+/************************/
+
+int zipinfo(__G) /* return PK-type error code */
+ __GDEF
+{
+ int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+ int *fn_matched=NULL, *xn_matched=NULL;
+ ulg j, members=0L;
+ zusz_t tot_csize=0L, tot_ucsize=0L;
+ zusz_t endprev; /* buffers end of previous entry for zi_long()'s check
+ * of extra bytes */
+
+
+/*---------------------------------------------------------------------------
+ Malloc space for check on unmatched filespecs (no big deal if one or both
+ are NULL).
+ ---------------------------------------------------------------------------*/
+
+ if (G.filespecs > 0 &&
+ (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != NULL)
+ for (j = 0; j < G.filespecs; ++j)
+ fn_matched[j] = FALSE;
+
+ if (G.xfilespecs > 0 &&
+ (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != NULL)
+ for (j = 0; j < G.xfilespecs; ++j)
+ xn_matched[j] = FALSE;
+
+/*---------------------------------------------------------------------------
+ Set file pointer to start of central directory, then loop through cen-
+ tral directory entries. Check that directory-entry signature bytes are
+ actually there (just a precaution), then process the entry. We know
+ the entire central directory is on this disk: we wouldn't have any of
+ this information unless the end-of-central-directory record was on this
+ disk, and we wouldn't have gotten to this routine unless this is also
+ the disk on which the central directory starts. In practice, this had
+ better be the *only* disk in the archive, but maybe someday we'll add
+ multi-disk support.
+ ---------------------------------------------------------------------------*/
+
+ uO.L_flag = FALSE; /* zipinfo mode: never convert name to lowercase */
+ G.pInfo = G.info; /* (re-)initialize, (just to make sure) */
+ G.pInfo->textmode = 0; /* so one can read on screen (is this ever used?) */
+
+ /* reset endprev for new zipfile; account for multi-part archives (?) */
+ endprev = (G.crec.relative_offset_local_header == 4L)? 4L : 0L;
+
+
+ for (j = 1L;; j++) {
+ if (readbuf(__G__ G.sig, 4) == 0) {
+ error_in_archive = PK_EOF;
+ break;
+ }
+ if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a CentDir entry? */
+ /* no new central directory entry
+ * -> is the number of processed entries compatible with the
+ * number of entries as stored in the end_central record?
+ */
+ if (((j - 1) &
+ (ulg)(G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
+ == (ulg)G.ecrec.total_entries_central_dir)
+ {
+ /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
+ * number of directory entries -> probably, the regular
+ * end of the central directory has been reached
+ */
+ break;
+ } else {
+ Info(slide, 0x401,
+ ((char *)slide, LoadFarString(CentSigMsg), j));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
+ error_in_archive = PK_BADERR; /* sig not found */
+ break;
+ }
+ }
+ /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
+ if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
+ error_in_archive = error; /* only PK_EOF defined */
+ break;
+ }
+
+ if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+ PK_COOL)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) /* fatal */
+ break;
+ }
+
+ if (!G.process_all_files) { /* check if specified on command line */
+ unsigned i;
+
+ if (G.filespecs == 0)
+ do_this_file = TRUE;
+ else { /* check if this entry matches an `include' argument */
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+ do_this_file = TRUE;
+ if (fn_matched)
+ fn_matched[i] = TRUE;
+ break; /* found match, so stop looping */
+ }
+ }
+ if (do_this_file) { /* check if this is an excluded file */
+ for (i = 0; i < G.xfilespecs; i++)
+ if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+ do_this_file = FALSE; /* ^-- ignore case in match */
+ if (xn_matched)
+ xn_matched[i] = TRUE;
+ break;
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------------
+ If current file was specified on command line, or if no names were
+ specified, do the listing for this file. Otherwise, get rid of the
+ file comment and go back for the next file.
+ -----------------------------------------------------------------------*/
+
+ if (G.process_all_files || do_this_file) {
+
+ /* Read the extra field, if any. The extra field info is required
+ * for resolving the Zip64 sizes/offsets and may be used in more
+ * analysis of the entry below.
+ */
+ if ((error = do_string(__G__ G.crec.extra_field_length,
+ EXTRA_FIELD)) != 0)
+ {
+ if (G.extra_field != NULL) {
+ free(G.extra_field);
+ G.extra_field = NULL;
+ }
+ error_in_archive = error;
+ /* The premature return in case of a "fatal" error (PK_EOF) is
+ * delayed until we analyze the extra field contents.
+ * This allows us to display all the other info that has been
+ * successfully read in.
+ */
+ }
+
+ switch (uO.lflag) {
+ case 1:
+ case 2:
+ fnprint(__G);
+ SKIP_(G.crec.file_comment_length)
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ if ((error = zi_short(__G)) != PK_COOL) {
+ error_in_archive = error; /* might be warning */
+ }
+ break;
+
+ case 10:
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(CentralDirEntry), j));
+ if ((error = zi_long(__G__ &endprev,
+ error_in_archive)) != PK_COOL) {
+ error_in_archive = error; /* might be warning */
+ }
+ break;
+
+ default:
+ SKIP_(G.crec.file_comment_length)
+ break;
+
+ } /* end switch (lflag) */
+ if (error > PK_WARN) /* fatal */
+ break;
+
+ tot_csize += G.crec.csize;
+ tot_ucsize += G.crec.ucsize;
+ if (G.crec.general_purpose_bit_flag & 1)
+ tot_csize -= 12; /* don't count encryption header */
+ ++members;
+
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
+ G.filename, (zvoid *)&G.crec.ucsize)) {
+ /* cancel operation by user request */
+ error_in_archive = IZ_CTRLC;
+ break;
+ }
+#endif
+#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+#endif
+
+ } else { /* not listing this file */
+ SKIP_(G.crec.extra_field_length)
+ SKIP_(G.crec.file_comment_length)
+ if (endprev != 0) endprev = 0;
+
+ } /* end if (list member?) */
+
+ } /* end for-loop (j: member files) */
+
+/*---------------------------------------------------------------------------
+ Check that we actually found requested files; if so, print totals.
+ ---------------------------------------------------------------------------*/
+
+ if ((error_in_archive <= PK_WARN) && uO.tflag) {
+ char *sgn = "";
+ int cfactor = ratio(tot_ucsize, tot_csize);
+
+ if (cfactor < 0) {
+ sgn = "-";
+ cfactor = -cfactor;
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(ZipfileStats),
+ members, (members==1L)? nullStr:PlurSufx,
+ FmZofft(tot_ucsize, NULL, "u"),
+ FmZofft(tot_csize, NULL, "u"),
+ sgn, cfactor/10, cfactor%10));
+ }
+
+/*---------------------------------------------------------------------------
+ Check for unmatched filespecs on command line and print warning if any
+ found.
+ ---------------------------------------------------------------------------*/
+
+ if (fn_matched) {
+ if (error_in_archive <= PK_WARN)
+ for (j = 0; j < G.filespecs; ++j)
+ if (!fn_matched[j])
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameNotMatched), G.pfnames[j]));
+ free((zvoid *)fn_matched);
+ }
+ if (xn_matched) {
+ if (error_in_archive <= PK_WARN)
+ for (j = 0; j < G.xfilespecs; ++j)
+ if (!xn_matched[j])
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExclFilenameNotMatched), G.pxnames[j]));
+ free((zvoid *)xn_matched);
+ }
+
+
+ /* Skip the following checks in case of a premature listing break. */
+ if (error_in_archive <= PK_WARN) {
+
+/*---------------------------------------------------------------------------
+ Double check that we're back at the end-of-central-directory record.
+ ---------------------------------------------------------------------------*/
+
+ if ( (memcmp(G.sig,
+ (G.ecrec.have_ecr64 ?
+ end_central64_sig : end_central_sig),
+ 4) != 0)
+ && (!G.ecrec.is_zip64_archive)
+ && (memcmp(G.sig, end_central_sig, 4) != 0)
+ ) { /* just to make sure again */
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+ error_in_archive = PK_WARN; /* didn't find sig */
+ }
+
+ /* Set specific return code when no files have been found. */
+ if (members == 0L && error_in_archive <= PK_WARN)
+ error_in_archive = PK_FIND;
+
+ if (uO.lflag >= 10)
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+ }
+
+ return error_in_archive;
+
+} /* end function zipinfo() */
+
+
+
+
+
+/************************/
+/* Function zi_long() */
+/************************/
+
+static int zi_long(__G__ pEndprev, error_in_archive)
+ /* return PK-type error code */
+ __GDEF
+ zusz_t *pEndprev; /* for zi_long() check of extra bytes */
+ int error_in_archive; /* may signal premature return */
+{
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+#endif
+ int error;
+ unsigned hostnum, hostver, extnum, extver, methid, methnum, xattr;
+ char workspace[12], attribs[22];
+ ZCONST char *varmsg_str;
+ char unkn[16];
+ static ZCONST char Far *os[NUM_HOSTS] = {
+ OS_FAT, OS_Amiga, OS_VMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS,
+ OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS,
+ OS_Acorn, OS_VFAT, OS_MVS, OS_BeOS, OS_Tandem, OS_Theos, OS_MacDarwin,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ OS_AtheOS
+ };
+ static ZCONST char Far *method[NUM_METHODS] = {
+ MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4,
+ MthdImplode, MthdToken, MthdDeflate, MthdDeflat64, MthdDCLImplode,
+ MthdBZip2, MthdLZMA, MthdTerse, MthdLZ77, MthdWavPack, MthdPPMd
+ };
+ static ZCONST char Far *dtypelng[4] = {
+ DeflNorm, DeflMax, DeflFast, DeflSFast
+ };
+
+
+/*---------------------------------------------------------------------------
+ Check whether there's any extra space inside the zipfile. If *pEndprev is
+ zero, it's probably a signal that OS/2 extra fields are involved (with
+ unknown compressed size). We won't worry about prepended junk here...
+ ---------------------------------------------------------------------------*/
+
+ if (G.crec.relative_offset_local_header != *pEndprev && *pEndprev > 0L) {
+ /* GRR DEBUG
+ Info(slide, 0, ((char *)slide,
+ " [crec.relative_offset_local_header = %lu, endprev = %lu]\n",
+ G.crec.relative_offset_local_header, *pEndprev));
+ */
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtraBytesPreceding),
+ FmZofft((G.crec.relative_offset_local_header - (*pEndprev)),
+ NULL, NULL)));
+ }
+
+ /* calculate endprev for next time around (problem: extra fields may
+ * differ in length between local and central-directory records) */
+ *pEndprev = G.crec.relative_offset_local_header + (4L + LREC_SIZE) +
+ G.crec.filename_length + G.crec.extra_field_length + G.crec.csize;
+
+/*---------------------------------------------------------------------------
+ Print out various interesting things about the compressed file.
+ ---------------------------------------------------------------------------*/
+
+ hostnum = (unsigned)(G.pInfo->hostnum);
+ hostver = (unsigned)(G.pInfo->hostver);
+ extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
+ extver = (unsigned)G.crec.version_needed_to_extract[0];
+ methid = (unsigned)G.crec.compression_method;
+ methnum = find_compr_idx(G.crec.compression_method);
+
+ (*G.message)((zvoid *)&G, (uch *)" ", 2L, 0); fnprint(__G);
+
+ Info(slide, 0, ((char *)slide, LoadFarString(LocalHeaderOffset),
+ FmZofft(G.crec.relative_offset_local_header, NULL, "u"),
+ FmZofft(G.crec.relative_offset_local_header, FZOFFT_HEX_DOT_WID, "X")));
+
+ if (hostnum >= NUM_HOSTS) {
+ sprintf(unkn, LoadFarString(UnknownNo),
+ (int)G.crec.version_made_by[1]);
+ varmsg_str = unkn;
+ } else {
+ varmsg_str = LoadFarStringSmall(os[hostnum]);
+#ifdef OLD_THEOS_EXTRA
+ if (hostnum == FS_VFAT_ && hostver == 20) {
+ /* entry made by old non-official THEOS port zip archive */
+ varmsg_str = LoadFarStringSmall(OS_TheosOld);
+ }
+#endif /* OLD_THEOS_EXTRA */
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(HostOS), varmsg_str));
+ Info(slide, 0, ((char *)slide, LoadFarString(EncodeSWVer), hostver/10,
+ hostver%10));
+
+ if ((extnum >= NUM_HOSTS) || (os[extnum] == NULL)) {
+ sprintf(unkn, LoadFarString(UnknownNo),
+ (int)G.crec.version_needed_to_extract[1]);
+ varmsg_str = unkn;
+ } else {
+ varmsg_str = LoadFarStringSmall(os[extnum]);
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(MinOSCompReq), varmsg_str));
+ Info(slide, 0, ((char *)slide, LoadFarString(MinSWVerReq), extver/10,
+ extver%10));
+
+ if (methnum >= NUM_METHODS) {
+ sprintf(unkn, LoadFarString(UnknownNo), G.crec.compression_method);
+ varmsg_str = unkn;
+ } else {
+ varmsg_str = LoadFarStringSmall(method[methnum]);
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(CompressMethod), varmsg_str));
+ if (methid == IMPLODED) {
+ Info(slide, 0, ((char *)slide, LoadFarString(SlideWindowSizeImplode),
+ (G.crec.general_purpose_bit_flag & 2)? '8' : '4'));
+ Info(slide, 0, ((char *)slide, LoadFarString(ShannonFanoTrees),
+ (G.crec.general_purpose_bit_flag & 4)? '3' : '2'));
+ } else if (methid == DEFLATED || methid == ENHDEFLATED) {
+ ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+
+ Info(slide, 0, ((char *)slide, LoadFarString(CompressSubtype),
+ LoadFarStringSmall(dtypelng[dnum])));
+ }
+
+ Info(slide, 0, ((char *)slide, LoadFarString(FileSecurity),
+ (G.crec.general_purpose_bit_flag & 1) ? nullStr : "not "));
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtendedLocalHdr),
+ (G.crec.general_purpose_bit_flag & 8) ? "yes" : "no"));
+ /* print upper 3 bits for amusement? */
+
+ /* For printing of date & time, a "char d_t_buf[21]" is required.
+ * To save stack space, we reuse the "char attribs[22]" buffer which
+ * is not used yet.
+ */
+# define d_t_buf attribs
+
+ zi_time(__G__ &G.crec.last_mod_dos_datetime, NULL, d_t_buf);
+ Info(slide, 0, ((char *)slide, LoadFarString(FileModDate), d_t_buf));
+#ifdef USE_EF_UT_TIME
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+ G.crec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME))
+ {
+ TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0 or Macintosh */
+ d_t_buf[0] = (char)0; /* signal "show local time" */
+ zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
+ Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
+ d_t_buf, LoadFarStringSmall(LocalTime)));
+#ifndef NO_GMTIME
+ d_t_buf[0] = (char)1; /* signal "show UTC (GMT) time" */
+ zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf);
+ Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate),
+ d_t_buf, LoadFarStringSmall(GMTime)));
+#endif /* !NO_GMTIME */
+ }
+#endif /* USE_EF_UT_TIME */
+
+ Info(slide, 0, ((char *)slide, LoadFarString(CRC32Value), G.crec.crc32));
+ Info(slide, 0, ((char *)slide, LoadFarString(CompressedFileSize),
+ FmZofft(G.crec.csize, NULL, "u")));
+ Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize),
+ FmZofft(G.crec.ucsize, NULL, "u")));
+ Info(slide, 0, ((char *)slide, LoadFarString(FilenameLength),
+ G.crec.filename_length));
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldLength),
+ G.crec.extra_field_length));
+ Info(slide, 0, ((char *)slide, LoadFarString(FileCommentLength),
+ G.crec.file_comment_length));
+ Info(slide, 0, ((char *)slide, LoadFarString(FileDiskNum),
+ (ulg)(G.crec.disk_number_start + 1)));
+ Info(slide, 0, ((char *)slide, LoadFarString(ApparentFileType),
+ (G.crec.internal_file_attributes & 1)? "text"
+ : (G.crec.internal_file_attributes & 2)? "ebcdic"
+ : "binary")); /* changed to accept EBCDIC */
+#ifdef ATARI
+ printf(" external file attributes (hex): %.8lx\n",
+ G.crec.external_file_attributes);
+#endif
+ xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
+ if (hostnum == VMS_) {
+ char *p=attribs, *q=attribs+1;
+ int i, j, k;
+
+ for (k = 0; k < 12; ++k)
+ workspace[k] = 0;
+ if (xattr & VMS_IRUSR)
+ workspace[0] = 'R';
+ if (xattr & VMS_IWUSR) {
+ workspace[1] = 'W';
+ workspace[3] = 'D';
+ }
+ if (xattr & VMS_IXUSR)
+ workspace[2] = 'E';
+ if (xattr & VMS_IRGRP)
+ workspace[4] = 'R';
+ if (xattr & VMS_IWGRP) {
+ workspace[5] = 'W';
+ workspace[7] = 'D';
+ }
+ if (xattr & VMS_IXGRP)
+ workspace[6] = 'E';
+ if (xattr & VMS_IROTH)
+ workspace[8] = 'R';
+ if (xattr & VMS_IWOTH) {
+ workspace[9] = 'W';
+ workspace[11] = 'D';
+ }
+ if (xattr & VMS_IXOTH)
+ workspace[10] = 'E';
+
+ *p++ = '(';
+ for (k = j = 0; j < 3; ++j) { /* loop over groups of permissions */
+ for (i = 0; i < 4; ++i, ++k) /* loop over perms within a group */
+ if (workspace[k])
+ *p++ = workspace[k];
+ *p++ = ','; /* group separator */
+ if (j == 0)
+ while ((*p++ = *q++) != ',')
+ ; /* system, owner perms are same */
+ }
+ *p-- = '\0';
+ *p = ')'; /* overwrite last comma */
+ Info(slide, 0, ((char *)slide, LoadFarString(VMSFileAttributes), xattr,
+ attribs));
+
+ } else if (hostnum == AMIGA_) {
+ switch (xattr & AMI_IFMT) {
+ case AMI_IFDIR: attribs[0] = 'd'; break;
+ case AMI_IFREG: attribs[0] = '-'; break;
+ default: attribs[0] = '?'; break;
+ }
+ attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-';
+ attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-';
+ attribs[3] = (xattr & AMI_IPURE)? 'p' : '-';
+ attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-';
+ attribs[5] = (xattr & AMI_IREAD)? 'r' : '-';
+ attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-';
+ attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-';
+ attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-';
+ attribs[9] = 0; /* better dlm the string */
+ Info(slide, 0, ((char *)slide, LoadFarString(AmigaFileAttributes),
+ xattr, attribs));
+
+ } else if (hostnum == THEOS_) {
+ ZCONST char Far *fpFtyp;
+
+ switch (xattr & THS_IFMT) {
+ case THS_IFLIB: fpFtyp = TheosFTypLib; break;
+ case THS_IFDIR: fpFtyp = TheosFTypDir; break;
+ case THS_IFREG: fpFtyp = TheosFTypReg; break;
+ case THS_IFREL: fpFtyp = TheosFTypRel; break;
+ case THS_IFKEY: fpFtyp = TheosFTypKey; break;
+ case THS_IFIND: fpFtyp = TheosFTypInd; break;
+ case THS_IFR16: fpFtyp = TheosFTypR16; break;
+ case THS_IFP16: fpFtyp = TheosFTypP16; break;
+ case THS_IFP32: fpFtyp = TheosFTypP32; break;
+ default: fpFtyp = TheosFTypUkn; break;
+ }
+ strcpy(attribs, LoadFarStringSmall(fpFtyp));
+ attribs[12] = (xattr & THS_INHID) ? '.' : 'H';
+ attribs[13] = (xattr & THS_IMODF) ? '.' : 'M';
+ attribs[14] = (xattr & THS_IWOTH) ? '.' : 'W';
+ attribs[15] = (xattr & THS_IROTH) ? '.' : 'R';
+ attribs[16] = (xattr & THS_IEUSR) ? '.' : 'E';
+ attribs[17] = (xattr & THS_IXUSR) ? '.' : 'X';
+ attribs[18] = (xattr & THS_IWUSR) ? '.' : 'W';
+ attribs[19] = (xattr & THS_IRUSR) ? '.' : 'R';
+ attribs[20] = 0;
+ Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
+ xattr, attribs));
+
+#ifdef OLD_THEOS_EXTRA
+ } else if (hostnum == FS_VFAT_ && hostver == 20) {
+ /* process old non-official THEOS port zip archive */
+ ZCONST char Far *fpFtyp;
+
+ switch (xattr & _THS_IFMT) {
+ case _THS_IFLIB: fpFtyp = TheosFTypLib; break;
+ case _THS_IFDIR: fpFtyp = TheosFTypDir; break;
+ case _THS_IFREG: fpFtyp = TheosFTypReg; break;
+ case _THS_IODRC: fpFtyp = TheosFTypRel; break;
+ case _THS_IOKEY: fpFtyp = TheosFTypKey; break;
+ case _THS_IOIND: fpFtyp = TheosFTypInd; break;
+ case _THS_IOPRG: fpFtyp = TheosFTypR16; break;
+ case _THS_IO286: fpFtyp = TheosFTypP16; break;
+ case _THS_IO386: fpFtyp = TheosFTypP32; break;
+ default: fpFtyp = TheosFTypUkn; break;
+ }
+ strcpy(attribs, LoadFarStringSmall(fpFtyp));
+ attribs[12] = (xattr & _THS_HIDDN) ? 'H' : '.';
+ attribs[13] = (xattr & _THS_IXOTH) ? '.' : 'X';
+ attribs[14] = (xattr & _THS_IWOTH) ? '.' : 'W';
+ attribs[15] = (xattr & _THS_IROTH) ? '.' : 'R';
+ attribs[16] = (xattr & _THS_IEUSR) ? '.' : 'E';
+ attribs[17] = (xattr & _THS_IXUSR) ? '.' : 'X';
+ attribs[18] = (xattr & _THS_IWUSR) ? '.' : 'W';
+ attribs[19] = (xattr & _THS_IRUSR) ? '.' : 'R';
+ attribs[20] = 0;
+ Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
+ xattr, attribs));
+#endif /* OLD_THEOS_EXTRA */
+
+ } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) &&
+ (hostnum != FS_NTFS_) && (hostnum != FS_VFAT_) &&
+ (hostnum != ACORN_) &&
+ (hostnum != VM_CMS_) && (hostnum != MVS_))
+ { /* assume Unix-like */
+ switch ((unsigned)(xattr & UNX_IFMT)) {
+ case (unsigned)UNX_IFDIR: attribs[0] = 'd'; break;
+ case (unsigned)UNX_IFREG: attribs[0] = '-'; break;
+ case (unsigned)UNX_IFLNK: attribs[0] = 'l'; break;
+ case (unsigned)UNX_IFBLK: attribs[0] = 'b'; break;
+ case (unsigned)UNX_IFCHR: attribs[0] = 'c'; break;
+ case (unsigned)UNX_IFIFO: attribs[0] = 'p'; break;
+ case (unsigned)UNX_IFSOCK: attribs[0] = 's'; break;
+ default: attribs[0] = '?'; break;
+ }
+ attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
+ attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
+ attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
+
+ attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
+ attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
+ attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
+
+ if (xattr & UNX_IXUSR)
+ attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
+ else
+ attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S = undefined */
+ if (xattr & UNX_IXGRP)
+ attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
+ else
+ attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
+ if (xattr & UNX_IXOTH)
+ attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */
+ else
+ attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T = undefined */
+ attribs[10] = 0;
+
+ Info(slide, 0, ((char *)slide, LoadFarString(UnixFileAttributes), xattr,
+ attribs));
+
+ } else {
+ Info(slide, 0, ((char *)slide, LoadFarString(NonMSDOSFileAttributes),
+ G.crec.external_file_attributes >> 8));
+
+ } /* endif (hostnum: external attributes format) */
+
+ if ((xattr=(unsigned)(G.crec.external_file_attributes & 0xFF)) == 0)
+ Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributes),
+ xattr));
+ else if (xattr == 1)
+ Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesRO),
+ xattr));
+ else
+ Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesAlpha),
+ xattr, (xattr&1)? "rdo " : nullStr,
+ (xattr&2)? "hid " : nullStr,
+ (xattr&4)? "sys " : nullStr,
+ (xattr&8)? "lab " : nullStr,
+ (xattr&16)? "dir " : nullStr,
+ (xattr&32)? "arc " : nullStr,
+ (xattr&64)? "lnk " : nullStr,
+ (xattr&128)? "exe" : nullStr));
+
+/*---------------------------------------------------------------------------
+ Analyze the extra field, if any, and print the file comment, if any (the
+ filename has already been printed, above). That finishes up this file
+ entry...
+ ---------------------------------------------------------------------------*/
+
+ if (G.crec.extra_field_length > 0) {
+ uch *ef_ptr = G.extra_field;
+ ush ef_len = G.crec.extra_field_length;
+ ush eb_id, eb_datalen;
+ ZCONST char Far *ef_fieldname;
+
+ if (error_in_archive > PK_WARN) /* fatal: can't continue */
+ /* delayed "fatal error" return from extra field reading */
+ return error_in_archive;
+ if (G.extra_field == (uch *)NULL)
+ return PK_ERR; /* not consistent with crec length */
+
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtraFields)));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(&ef_ptr[EB_ID]);
+ eb_datalen = makeword(&ef_ptr[EB_LEN]);
+ ef_ptr += EB_HEADSIZE;
+ ef_len -= EB_HEADSIZE;
+
+ if (eb_datalen > (ush)ef_len) {
+ Info(slide, 0x421, ((char *)slide,
+ LoadFarString(ExtraFieldTrunc), eb_id, eb_datalen, ef_len));
+ eb_datalen = ef_len;
+ }
+
+ switch (eb_id) {
+ case EF_PKSZ64:
+ ef_fieldname = efPKSZ64;
+ if ((G.crec.relative_offset_local_header
+ & (~(zusz_t)0xFFFFFFFFL)) != 0) {
+ /* Subtract the size of the 64bit local offset from
+ the local e.f. size, local Z64 e.f. block has no
+ offset; when only local offset present, the entire
+ local PKSZ64 block is missing. */
+ *pEndprev -= (eb_datalen == 8 ? 12 : 8);
+ }
+ break;
+ case EF_AV:
+ ef_fieldname = efAV;
+ break;
+ case EF_OS2:
+ ef_fieldname = efOS2;
+ break;
+ case EF_ACL:
+ ef_fieldname = efACL;
+ break;
+ case EF_NTSD:
+ ef_fieldname = efNTSD;
+ break;
+ case EF_PKVMS:
+ ef_fieldname = efPKVMS;
+ break;
+ case EF_IZVMS:
+ ef_fieldname = efIZVMS;
+ break;
+ case EF_PKW32:
+ ef_fieldname = efPKWin32;
+ break;
+ case EF_PKUNIX:
+ ef_fieldname = efPKUnix;
+ break;
+ case EF_IZUNIX:
+ ef_fieldname = efIZUnix;
+ if (hostnum == UNIX_ && *pEndprev > 0L)
+ *pEndprev += 4L; /* also have UID/GID in local copy */
+ break;
+ case EF_IZUNIX2:
+ ef_fieldname = efIZUnix2;
+ if (*pEndprev > 0L)
+ *pEndprev += 4L; /* 4 byte UID/GID in local copy */
+ break;
+ case EF_IZUNIX3:
+ ef_fieldname = efIZUnix3;
+#if 0
+ if (*pEndprev > 0L)
+ *pEndprev += 4L; /* 4 byte UID/GID in local copy */
+#endif
+ break;
+ case EF_TIME:
+ ef_fieldname = efTime;
+ break;
+ case EF_UNIPATH:
+ ef_fieldname = efU8Path;
+ break;
+ case EF_UNICOMNT:
+ ef_fieldname = efU8Commnt;
+ break;
+ case EF_MAC3:
+ ef_fieldname = efMac3;
+ break;
+ case EF_JLMAC:
+ ef_fieldname = efJLMac;
+ break;
+ case EF_ZIPIT:
+ ef_fieldname = efZipIt;
+ break;
+ case EF_ZIPIT2:
+ ef_fieldname = efZipIt2;
+ break;
+ case EF_VMCMS:
+ ef_fieldname = efVMCMS;
+ break;
+ case EF_MVS:
+ ef_fieldname = efMVS;
+ break;
+ case EF_ATHEOS:
+ ef_fieldname = efAtheOS;
+ break;
+ case EF_BEOS:
+ ef_fieldname = efBeOS;
+ break;
+ case EF_QDOS:
+ ef_fieldname = efQDOS;
+ break;
+ case EF_AOSVS:
+ ef_fieldname = efAOSVS;
+ break;
+ case EF_SPARK: /* from RISC OS */
+ ef_fieldname = efSpark;
+ break;
+ case EF_MD5:
+ ef_fieldname = efMD5;
+ break;
+ case EF_ASIUNIX:
+ ef_fieldname = efASiUnix;
+ break;
+ case EF_TANDEM:
+ ef_fieldname = efTandem;
+ break;
+ case EF_SMARTZIP:
+ ef_fieldname = efSmartZip;
+ break;
+ case EF_THEOS:
+#ifdef OLD_THEOS_EXTRA
+ case EF_THEOSO:
+#endif
+ ef_fieldname = efTheos;
+ break;
+ default:
+ ef_fieldname = efUnknown;
+ break;
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldType),
+ eb_id, LoadFarStringSmall(ef_fieldname), eb_datalen));
+
+ /* additional, field-specific information: */
+ switch (eb_id) {
+ case EF_OS2:
+ case EF_ACL:
+ if (eb_datalen >= EB_OS2_HLEN) {
+ if (eb_id == EF_OS2)
+ ef_fieldname = OS2EAs;
+ else
+ ef_fieldname = ACLdata;
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ef_fieldname), makelong(ef_ptr)));
+ *pEndprev = 0L; /* no clue about csize of local */
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_NTSD:
+ if (eb_datalen >= EB_NTSD_C_LEN) {
+ Info(slide, 0, ((char *)slide, LoadFarString(NTSDData),
+ makelong(ef_ptr)));
+ *pEndprev = 0L; /* no clue about csize of local */
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_IZVMS:
+ if (eb_datalen >= 8) {
+ char *p, q[8];
+ unsigned compr = makeword(ef_ptr+EB_IZVMS_FLGS)
+ & EB_IZVMS_BCMASK;
+
+ *q = '\0';
+ if (compr > 3)
+ compr = 3;
+ switch (makelong(ef_ptr)) {
+ case 0x42414656: /* "VFAB" */
+ p = "FAB"; break;
+ case 0x4C4C4156: /* "VALL" */
+ p = "XABALL"; break;
+ case 0x43484656: /* "VFHC" */
+ p = "XABFHC"; break;
+ case 0x54414456: /* "VDAT" */
+ p = "XABDAT"; break;
+ case 0x54445256: /* "VRDT" */
+ p = "XABRDT"; break;
+ case 0x4F525056: /* "VPRO" */
+ p = "XABPRO"; break;
+ case 0x59454B56: /* "VKEY" */
+ p = "XABKEY"; break;
+ case 0x56534D56: /* "VMSV" */
+ p = "version";
+ if (eb_datalen >= 16) {
+ /* put termitation first, for A_TO_N() */
+ q[7] = '\0';
+ q[0] = ' ';
+ q[1] = '(';
+ strncpy(q+2,
+ (char *)ef_ptr+EB_IZVMS_HLEN, 4);
+ A_TO_N(q+2);
+ q[6] = ')';
+ }
+ break;
+ default:
+ p = "unknown";
+ }
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(izVMSdata),
+ LoadFarStringSmall(izVMScomp[compr]),
+ makeword(ef_ptr+EB_IZVMS_UCSIZ), p, q));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_TIME:
+ if (eb_datalen > 0) {
+ char types[80];
+ int num = 0, len;
+
+ *types = '\0';
+ if (*ef_ptr & 1) {
+ strcpy(types, LoadFarString(UTmodification));
+ ++num;
+ }
+ if (*ef_ptr & 2) {
+ len = strlen(types);
+ if (num)
+ types[len++] = '/';
+ strcpy(types+len, LoadFarString(UTaccess));
+ ++num;
+ if (*pEndprev > 0L)
+ *pEndprev += 4L;
+ }
+ if (*ef_ptr & 4) {
+ len = strlen(types);
+ if (num)
+ types[len++] = '/';
+ strcpy(types+len, LoadFarString(UTcreation));
+ ++num;
+ if (*pEndprev > 0L)
+ *pEndprev += 4L;
+ }
+ if (num > 0)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(UTdata), types,
+ num == 1? nullStr : PlurSufx));
+ }
+ break;
+ case EF_UNIPATH:
+ case EF_UNICOMNT:
+ if (eb_datalen >= 5) {
+ unsigned i, n;
+ ulg name_crc = makelong(ef_ptr+1);
+
+ if (eb_datalen <= 29) {
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(U8PthCmnComplete),
+ (unsigned)ef_ptr[0], name_crc));
+ n = eb_datalen;
+ } else {
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(U8PthCmnF24),
+ (unsigned)ef_ptr[0], name_crc));
+ n = 29;
+ }
+ for (i = 5; i < n; ++i)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(efFormat), ef_ptr[i]));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_MAC3:
+ if (eb_datalen >= EB_MAC3_HLEN) {
+ ulg eb_uc = makelong(ef_ptr);
+ unsigned mac3_flgs = makeword(ef_ptr+EB_FLGS_OFFS);
+ unsigned eb_is_uc = mac3_flgs & EB_M3_FL_UNCMPR;
+
+ Info(slide, 0, ((char *)slide, LoadFarString(Mac3data),
+ eb_uc, eb_is_uc ? "un" : nullStr));
+ if (eb_is_uc) {
+ if (*pEndprev > 0L)
+ *pEndprev += makelong(ef_ptr);
+ } else {
+ *pEndprev = 0L; /* no clue about csize of local */
+ }
+
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(MacOSMAC3flags),
+ LoadFarStringSmall(mac3_flgs & EB_M3_FL_DATFRK ?
+ MacOS_DF : MacOS_RF),
+ (mac3_flgs & EB_M3_FL_TIME64 ? 64 : 32)));
+ zi_showMacTypeCreator(__G__ &ef_ptr[6]);
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_ZIPIT2:
+ if (eb_datalen >= 5 &&
+ makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
+
+ if (eb_datalen >= 12) {
+ zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+ }
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_ZIPIT:
+ if (eb_datalen >= 5 &&
+ makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) {
+ unsigned fnlen = ef_ptr[4];
+
+ if ((unsigned)eb_datalen >= fnlen + (5 + 8)) {
+ uch nullchar = ef_ptr[fnlen+5];
+
+ ef_ptr[fnlen+5] = '\0'; /* terminate filename */
+ A_TO_N(ef_ptr+5);
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ZipItFname), (char *)ef_ptr+5));
+ ef_ptr[fnlen+5] = nullchar;
+ zi_showMacTypeCreator(__G__ &ef_ptr[fnlen+5]);
+ }
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_JLMAC:
+ if (eb_datalen >= 40 &&
+ makelong(ef_ptr) == 0x45454C4A /* "JLEE" */)
+ {
+ zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(MacOSJLEEflags),
+ LoadFarStringSmall(ef_ptr[31] & 1 ?
+ MacOS_DF : MacOS_RF)));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_SMARTZIP:
+ if ((eb_datalen == EB_SMARTZIP_HLEN) &&
+ makelong(ef_ptr) == 0x70695A64 /* "dZip" */) {
+ char filenameBuf[32];
+ zi_showMacTypeCreator(__G__ &ef_ptr[4]);
+ memcpy(filenameBuf, &ef_ptr[33], 31);
+ filenameBuf[ef_ptr[32]] = '\0';
+ A_TO_N(filenameBuf);
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ZipItFname), filenameBuf));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+#ifdef CMS_MVS
+ case EF_VMCMS:
+ case EF_MVS:
+ {
+ char type[100];
+
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(VmMvsExtraField),
+ (getVMMVSexfield(type, ef_ptr-EB_HEADSIZE,
+ (unsigned)eb_datalen) > 0)?
+ type : LoadFarStringSmall(VmMvsInvalid)));
+ }
+ break;
+#endif /* CMS_MVS */
+ case EF_ATHEOS:
+ case EF_BEOS:
+ if (eb_datalen >= EB_BEOS_HLEN) {
+ ulg eb_uc = makelong(ef_ptr);
+ unsigned eb_is_uc =
+ *(ef_ptr+EB_FLGS_OFFS) & EB_BE_FL_UNCMPR;
+
+ if (eb_id == EF_ATHEOS)
+ ef_fieldname = AtheOSdata;
+ else
+ ef_fieldname = BeOSdata;
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ef_fieldname),
+ eb_uc, eb_is_uc ? "un" : nullStr));
+ if (eb_is_uc) {
+ if (*pEndprev > 0L)
+ *pEndprev += makelong(ef_ptr);
+ } else {
+ *pEndprev = 0L; /* no clue about csize of local */
+ }
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_QDOS:
+ if (eb_datalen >= 4) {
+ Info(slide, 0, ((char *)slide, LoadFarString(QDOSdata),
+ ef_ptr[0], ef_ptr[1], ef_ptr[2], ef_ptr[3]));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_AOSVS:
+ if (eb_datalen >= 5) {
+ Info(slide, 0, ((char *)slide, LoadFarString(AOSVSdata),
+ ((int)(uch)ef_ptr[4])/10, ((int)(uch)ef_ptr[4])%10));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_TANDEM:
+ if (eb_datalen == 20) {
+ unsigned type, code;
+
+ type = (ef_ptr[18] & 0x60) >> 5;
+ code = makeword(ef_ptr);
+ /* Arrg..., Tandem e.f. uses BigEndian byte-order */
+ code = ((code << 8) & 0xff00) | ((code >> 8) & 0x00ff);
+ if (type == NSK_UNSTRUCTURED) {
+ if (code == NSK_EDITFILECODE)
+ type = 4;
+ else if (code == NSK_OBJECTFILECODE)
+ type = 5;
+ }
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(Tandemdata),
+ LoadFarStringSmall(TandemFileformat[type]),
+ code));
+ } else {
+ goto ef_default_display;
+ }
+ break;
+ case EF_MD5:
+ if (eb_datalen >= 19) {
+ char md5[33];
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ sprintf(&md5[i<<1], "%02x", ef_ptr[15-i]);
+ md5[32] = '\0';
+ Info(slide, 0, ((char *)slide, LoadFarString(MD5data),
+ md5));
+ break;
+ } /* else: fall through !! */
+ default:
+ef_default_display:
+ if (eb_datalen > 0) {
+ unsigned i, n;
+
+ if (eb_datalen <= 24) {
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(ColonIndent)));
+ n = eb_datalen;
+ } else {
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(First20)));
+ n = 20;
+ }
+ for (i = 0; i < n; ++i)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(efFormat), ef_ptr[i]));
+ }
+ break;
+ }
+ (*G.message)((zvoid *)&G, (uch *)".", 1L, 0);
+
+ ef_ptr += eb_datalen;
+ ef_len -= eb_datalen;
+ }
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+ }
+
+ /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */
+ if ((xattr = (unsigned)((G.crec.external_file_attributes & 0xC000) >> 12))
+ & 8)
+ {
+ if (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)
+ {
+ Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
+ "is", EF_IZUNIX, LoadFarStringSmall(efIZUnix),
+ (unsigned)(xattr&12), (xattr&4)? efIZuid : efIZnouid));
+ if (*pEndprev > 0L)
+ *pEndprev += (ulg)(xattr&12);
+ }
+ else if (hostnum == FS_FAT_ && !(xattr&4))
+ Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType),
+ "may be", EF_IZUNIX, LoadFarStringSmall(efIZUnix), 8,
+ efIZnouid));
+ }
+
+ if (!G.crec.file_comment_length)
+ Info(slide, 0, ((char *)slide, LoadFarString(NoFileComment)));
+ else {
+ Info(slide, 0, ((char *)slide, LoadFarString(FileCommBegin)));
+ if ((error = do_string(__G__ G.crec.file_comment_length, DISPL_8)) !=
+ PK_COOL)
+ {
+ error_in_archive = error; /* might be warning */
+ if (error > PK_WARN) /* fatal */
+ return error;
+ }
+ Info(slide, 0, ((char *)slide, LoadFarString(FileCommEnd)));
+ }
+
+ return error_in_archive;
+
+} /* end function zi_long() */
+
+
+
+
+
+/*************************/
+/* Function zi_short() */
+/*************************/
+
+static int zi_short(__G) /* return PK-type error code */
+ __GDEF
+{
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+ time_t *z_modtim;
+#endif
+ int k, error, error_in_archive=PK_COOL;
+ unsigned hostnum, hostver, methid, methnum, xattr;
+ char *p, workspace[12], attribs[17];
+ char methbuf[5];
+ static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
+ static ZCONST char Far os[NUM_HOSTS+1][4] = {
+ "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
+ "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk",
+ "ths", "osx", "???", "???", "???", "???", "???", "???", "???",
+ "???", "???", "???", "ath", "???"
+ };
+#ifdef OLD_THEOS_EXTRA
+ static ZCONST char Far os_TheosOld[] = "tho";
+#endif
+ static ZCONST char Far method[NUM_METHODS+1][5] = {
+ "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn",
+ "def#", "d64#", "dcli", "bzp2", "lzma", "ters", "lz77", "wavp",
+ "ppmd", "u###"
+ };
+
+
+/*---------------------------------------------------------------------------
+ Print out various interesting things about the compressed file.
+ ---------------------------------------------------------------------------*/
+
+ methid = (unsigned)(G.crec.compression_method);
+ methnum = find_compr_idx(G.crec.compression_method);
+ hostnum = (unsigned)(G.pInfo->hostnum);
+ hostver = (unsigned)(G.pInfo->hostver);
+/*
+ extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
+ extver = (unsigned)G.crec.version_needed_to_extract[0];
+ */
+
+ zfstrcpy(methbuf, method[methnum]);
+ if (methid == IMPLODED) {
+ methbuf[1] = (char)((G.crec.general_purpose_bit_flag & 2)? '8' : '4');
+ methbuf[3] = (char)((G.crec.general_purpose_bit_flag & 4)? '3' : '2');
+ } else if (methid == DEFLATED || methid == ENHDEFLATED) {
+ ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+ methbuf[3] = dtype[dnum];
+ } else if (methnum >= NUM_METHODS) { /* unknown */
+ /* 2016-12-05 SMS.
+ * https://launchpad.net/bugs/1643750
+ * Unexpectedly large compression methods overflow
+ * &methbuf[]. Use the old, three-digit decimal format
+ * for values which fit. Otherwise, sacrifice the "u",
+ * and use four-digit hexadecimal.
+ */
+ if (G.crec.compression_method <= 999) {
+ sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
+ } else {
+ sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
+ }
+
+ }
+
+ for (k = 0; k < 15; ++k)
+ attribs[k] = ' ';
+ attribs[15] = 0;
+
+ xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
+ switch (hostnum) {
+ case VMS_:
+ { int i, j;
+
+ for (k = 0; k < 12; ++k)
+ workspace[k] = 0;
+ if (xattr & VMS_IRUSR)
+ workspace[0] = 'R';
+ if (xattr & VMS_IWUSR) {
+ workspace[1] = 'W';
+ workspace[3] = 'D';
+ }
+ if (xattr & VMS_IXUSR)
+ workspace[2] = 'E';
+ if (xattr & VMS_IRGRP)
+ workspace[4] = 'R';
+ if (xattr & VMS_IWGRP) {
+ workspace[5] = 'W';
+ workspace[7] = 'D';
+ }
+ if (xattr & VMS_IXGRP)
+ workspace[6] = 'E';
+ if (xattr & VMS_IROTH)
+ workspace[8] = 'R';
+ if (xattr & VMS_IWOTH) {
+ workspace[9] = 'W';
+ workspace[11] = 'D';
+ }
+ if (xattr & VMS_IXOTH)
+ workspace[10] = 'E';
+
+ p = attribs;
+ for (k = j = 0; j < 3; ++j) { /* groups of permissions */
+ for (i = 0; i < 4; ++i, ++k) /* perms within a group */
+ if (workspace[k])
+ *p++ = workspace[k];
+ *p++ = ','; /* group separator */
+ }
+ *--p = ' '; /* overwrite last comma */
+ if ((p - attribs) < 12)
+ sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+ }
+ break;
+
+ case AMIGA_:
+ switch (xattr & AMI_IFMT) {
+ case AMI_IFDIR: attribs[0] = 'd'; break;
+ case AMI_IFREG: attribs[0] = '-'; break;
+ default: attribs[0] = '?'; break;
+ }
+ attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-';
+ attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-';
+ attribs[3] = (xattr & AMI_IPURE)? 'p' : '-';
+ attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-';
+ attribs[5] = (xattr & AMI_IREAD)? 'r' : '-';
+ attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-';
+ attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-';
+ attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-';
+ sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+ break;
+
+ case THEOS_:
+ switch (xattr & THS_IFMT) {
+ case THS_IFLIB: *attribs = 'L'; break;
+ case THS_IFDIR: *attribs = 'D'; break;
+ case THS_IFCHR: *attribs = 'C'; break;
+ case THS_IFREG: *attribs = 'S'; break;
+ case THS_IFREL: *attribs = 'R'; break;
+ case THS_IFKEY: *attribs = 'K'; break;
+ case THS_IFIND: *attribs = 'I'; break;
+ case THS_IFR16: *attribs = 'P'; break;
+ case THS_IFP16: *attribs = '2'; break;
+ case THS_IFP32: *attribs = '3'; break;
+ default: *attribs = '?'; break;
+ }
+ attribs[1] = (xattr & THS_INHID) ? '.' : 'H';
+ attribs[2] = (xattr & THS_IMODF) ? '.' : 'M';
+ attribs[3] = (xattr & THS_IWOTH) ? '.' : 'W';
+ attribs[4] = (xattr & THS_IROTH) ? '.' : 'R';
+ attribs[5] = (xattr & THS_IEUSR) ? '.' : 'E';
+ attribs[6] = (xattr & THS_IXUSR) ? '.' : 'X';
+ attribs[7] = (xattr & THS_IWUSR) ? '.' : 'W';
+ attribs[8] = (xattr & THS_IRUSR) ? '.' : 'R';
+ sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+ break;
+
+ case FS_VFAT_:
+#ifdef OLD_THEOS_EXTRA
+ if (hostver == 20) {
+ switch (xattr & _THS_IFMT) {
+ case _THS_IFLIB: *attribs = 'L'; break;
+ case _THS_IFDIR: *attribs = 'd'; break;
+ case _THS_IFCHR: *attribs = 'c'; break;
+ case _THS_IFREG: *attribs = 'S'; break;
+ case _THS_IODRC: *attribs = 'D'; break;
+ case _THS_IOKEY: *attribs = 'K'; break;
+ case _THS_IOIND: *attribs = 'I'; break;
+ case _THS_IOPRG: *attribs = 'P'; break;
+ case _THS_IO286: *attribs = '2'; break;
+ case _THS_IO386: *attribs = '3'; break;
+ default: *attribs = '?'; break;
+ }
+ attribs[1] = (xattr & _THS_HIDDN) ? 'H' : '.';
+ attribs[2] = (xattr & _THS_IXOTH) ? '.' : 'X';
+ attribs[3] = (xattr & _THS_IWOTH) ? '.' : 'W';
+ attribs[4] = (xattr & _THS_IROTH) ? '.' : 'R';
+ attribs[5] = (xattr & _THS_IEUSR) ? '.' : 'E';
+ attribs[6] = (xattr & _THS_IXUSR) ? '.' : 'X';
+ attribs[7] = (xattr & _THS_IWUSR) ? '.' : 'W';
+ attribs[8] = (xattr & _THS_IRUSR) ? '.' : 'R';
+ sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+ break;
+ } /* else: fall through! */
+#endif /* OLD_THEOS_EXTRA */
+
+ case FS_FAT_:
+ case FS_HPFS_:
+ case FS_NTFS_:
+ case VM_CMS_:
+ case MVS_:
+ case ACORN_:
+ if (hostnum != FS_FAT_ ||
+ (unsigned)(xattr & 0700) !=
+ ((unsigned)0400 |
+ ((unsigned)!(G.crec.external_file_attributes & 1) << 7) |
+ ((unsigned)(G.crec.external_file_attributes & 0x10) << 2))
+ )
+ {
+ xattr = (unsigned)(G.crec.external_file_attributes & 0xFF);
+ sprintf(attribs, ".r.-... %u.%u", hostver/10, hostver%10);
+ attribs[2] = (xattr & 0x01)? '-' : 'w';
+ attribs[5] = (xattr & 0x02)? 'h' : '-';
+ attribs[6] = (xattr & 0x04)? 's' : '-';
+ attribs[4] = (xattr & 0x20)? 'a' : '-';
+ if (xattr & 0x10) {
+ attribs[0] = 'd';
+ attribs[3] = 'x';
+ } else
+ attribs[0] = '-';
+ if (IS_VOLID(xattr))
+ attribs[0] = 'V';
+ else if ((p = MBSRCHR(G.filename, '.')) != (char *)NULL) {
+ ++p;
+ if (STRNICMP(p, "com", 3) == 0 ||
+ STRNICMP(p, "exe", 3) == 0 ||
+ STRNICMP(p, "btm", 3) == 0 ||
+ STRNICMP(p, "cmd", 3) == 0 ||
+ STRNICMP(p, "bat", 3) == 0)
+ attribs[3] = 'x';
+ }
+ break;
+ } /* else: fall through! */
+
+ default: /* assume Unix-like */
+ switch ((unsigned)(xattr & UNX_IFMT)) {
+ case (unsigned)UNX_IFDIR: attribs[0] = 'd'; break;
+ case (unsigned)UNX_IFREG: attribs[0] = '-'; break;
+ case (unsigned)UNX_IFLNK: attribs[0] = 'l'; break;
+ case (unsigned)UNX_IFBLK: attribs[0] = 'b'; break;
+ case (unsigned)UNX_IFCHR: attribs[0] = 'c'; break;
+ case (unsigned)UNX_IFIFO: attribs[0] = 'p'; break;
+ case (unsigned)UNX_IFSOCK: attribs[0] = 's'; break;
+ default: attribs[0] = '?'; break;
+ }
+ attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
+ attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
+ attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
+ attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
+ attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
+ attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
+
+ if (xattr & UNX_IXUSR)
+ attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
+ else
+ attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S==undefined */
+ if (xattr & UNX_IXGRP)
+ attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
+ else
+ /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; real 4.3BSD */
+ attribs[6] = (xattr & UNX_ISGID)? 'S' : '-'; /* SunOS 4.1.x */
+ if (xattr & UNX_IXOTH)
+ attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */
+ else
+ attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */
+
+ sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+ break;
+
+ } /* end switch (hostnum: external attributes format) */
+
+#ifdef OLD_THEOS_EXTRA
+ Info(slide, 0, ((char *)slide, "%s %s %s ", attribs,
+ LoadFarStringSmall(((hostnum == FS_VFAT_ && hostver == 20) ?
+ os_TheosOld :
+ os[hostnum])),
+ FmZofft(G.crec.ucsize, "8", "u")));
+#else
+ Info(slide, 0, ((char *)slide, "%s %s %s ", attribs,
+ LoadFarStringSmall(os[hostnum]),
+ FmZofft(G.crec.ucsize, "8", "u")));
+#endif
+ Info(slide, 0, ((char *)slide, "%c",
+ (G.crec.general_purpose_bit_flag & 1)?
+ ((G.crec.internal_file_attributes & 1)? 'T' : 'B') : /* encrypted */
+ ((G.crec.internal_file_attributes & 1)? 't' : 'b'))); /* plaintext */
+ k = (G.crec.extra_field_length ||
+ /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */
+ ((G.crec.external_file_attributes & 0x8000) &&
+ (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_)));
+ Info(slide, 0, ((char *)slide, "%c", k?
+ ((G.crec.general_purpose_bit_flag & 8)? 'X' : 'x') : /* extra field */
+ ((G.crec.general_purpose_bit_flag & 8)? 'l' : '-'))); /* no extra field */
+ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */
+
+ if (uO.lflag == 4) {
+ zusz_t csiz = G.crec.csize;
+
+ if (G.crec.general_purpose_bit_flag & 1)
+ csiz -= 12; /* if encrypted, don't count encryption header */
+ Info(slide, 0, ((char *)slide, "%3d%%",
+ (ratio(G.crec.ucsize,csiz)+5)/10));
+ } else if (uO.lflag == 5)
+ Info(slide, 0, ((char *)slide, " %s",
+ FmZofft(G.crec.csize, "8", "u")));
+
+ /* For printing of date & time, a "char d_t_buf[16]" is required.
+ * To save stack space, we reuse the "char attribs[16]" buffer whose
+ * content is no longer needed.
+ */
+# define d_t_buf attribs
+#ifdef USE_EF_UT_TIME
+ z_modtim = G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
+ G.crec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME)
+ ? &z_utime.mtime : NULL;
+ TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0 or Macintosh */
+ d_t_buf[0] = (char)0; /* signal "show local time" */
+#else
+# define z_modtim NULL
+#endif
+ Info(slide, 0, ((char *)slide, " %s %s ", methbuf,
+ zi_time(__G__ &G.crec.last_mod_dos_datetime, z_modtim, d_t_buf)));
+ fnprint(__G);
+
+/*---------------------------------------------------------------------------
+ Skip the file comment, if any (the filename has already been printed,
+ above). That finishes up this file entry...
+ ---------------------------------------------------------------------------*/
+
+ SKIP_(G.crec.file_comment_length)
+
+ return error_in_archive;
+
+} /* end function zi_short() */
+
+
+
+
+
+/**************************************/
+/* Function zi_showMacTypeCreator() */
+/**************************************/
+
+static void zi_showMacTypeCreator(__G__ ebfield)
+ __GDEF
+ uch *ebfield;
+{
+ /* not every Type / Creator character is printable */
+ if (isprint(native(ebfield[0])) && isprint(native(ebfield[1])) &&
+ isprint(native(ebfield[2])) && isprint(native(ebfield[3])) &&
+ isprint(native(ebfield[4])) && isprint(native(ebfield[5])) &&
+ isprint(native(ebfield[6])) && isprint(native(ebfield[7]))) {
+ Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata),
+ native(ebfield[0]), native(ebfield[1]),
+ native(ebfield[2]), native(ebfield[3]),
+ native(ebfield[4]), native(ebfield[5]),
+ native(ebfield[6]), native(ebfield[7])));
+ } else {
+ Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata1),
+ (((ulg)ebfield[0]) << 24) +
+ (((ulg)ebfield[1]) << 16) +
+ (((ulg)ebfield[2]) << 8) +
+ ((ulg)ebfield[3]),
+ (((ulg)ebfield[4]) << 24) +
+ (((ulg)ebfield[5]) << 16) +
+ (((ulg)ebfield[6]) << 8) +
+ ((ulg)ebfield[7])));
+ }
+} /* end function zi_showMacTypeCreator() */
+
+
+
+
+
+/************************/
+/* Function zi_time() */
+/************************/
+
+static char *zi_time(__G__ datetimez, modtimez, d_t_str)
+ __GDEF
+ ZCONST ulg *datetimez;
+ ZCONST time_t *modtimez;
+ char *d_t_str;
+{
+ unsigned yr, mo, dy, hh, mm, ss;
+ char monthbuf[4];
+ ZCONST char *monthstr;
+ static ZCONST char Far month[12][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+#ifdef USE_EF_UT_TIME
+ struct tm *t;
+#endif
+
+
+
+/*---------------------------------------------------------------------------
+ Convert the file-modification date and time info to a string of the form
+ "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending
+ on values of lflag and T_flag. If using Unix-time extra fields, convert
+ to local time or not, depending on value of first character in d_t_str[].
+ ---------------------------------------------------------------------------*/
+
+#ifdef USE_EF_UT_TIME
+ if (modtimez != NULL) {
+#ifndef NO_GMTIME
+ /* check for our secret message from above... */
+ t = (d_t_str[0] == (char)1)? gmtime(modtimez) : localtime(modtimez);
+#else
+ t = localtime(modtimez);
+#endif
+ if (uO.lflag > 9 && t == (struct tm *)NULL)
+ /* time conversion error in verbose listing format,
+ * return string with '?' instead of data
+ */
+ return (strcpy(d_t_str, LoadFarString(lngYMDHMSTimeError)));
+ } else
+ t = (struct tm *)NULL;
+ if (t != (struct tm *)NULL) {
+ mo = (unsigned)(t->tm_mon + 1);
+ dy = (unsigned)(t->tm_mday);
+ yr = (unsigned)(t->tm_year);
+
+ hh = (unsigned)(t->tm_hour);
+ mm = (unsigned)(t->tm_min);
+ ss = (unsigned)(t->tm_sec);
+ } else
+#endif /* USE_EF_UT_TIME */
+ {
+ yr = ((unsigned)(*datetimez >> 25) & 0x7f) + 80;
+ mo = ((unsigned)(*datetimez >> 21) & 0x0f);
+ dy = ((unsigned)(*datetimez >> 16) & 0x1f);
+
+ hh = (((unsigned)*datetimez >> 11) & 0x1f);
+ mm = (((unsigned)*datetimez >> 5) & 0x3f);
+ ss = (((unsigned)*datetimez << 1) & 0x3e);
+ }
+
+ if (mo == 0 || mo > 12) {
+ sprintf(monthbuf, LoadFarString(BogusFmt), mo);
+ monthstr = monthbuf;
+ } else
+ monthstr = LoadFarStringSmall(month[mo-1]);
+
+ if (uO.lflag > 9) /* verbose listing format */
+ sprintf(d_t_str, LoadFarString(lngYMDHMSTime), yr+1900, monthstr, dy,
+ hh, mm, ss);
+ else if (uO.T_flag)
+ sprintf(d_t_str, LoadFarString(DecimalTime), yr+1900, mo, dy,
+ hh, mm, ss);
+ else /* was: if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
+ sprintf(d_t_str, LoadFarString(shtYMDHMTime), yr%100, monthstr, dy,
+ hh, mm);
+
+ return d_t_str;
+
+} /* end function zi_time() */
+
+#endif /* !NO_ZIPINFO */
Index: unzip/create-6.0-slackware-patch/unzip60-new
===================================================================
--- unzip/create-6.0-slackware-patch/unzip60-new (nonexistent)
+++ unzip/create-6.0-slackware-patch/unzip60-new (revision 5)
Property changes on: unzip/create-6.0-slackware-patch/unzip60-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/create-6.0-slackware-patch
===================================================================
--- unzip/create-6.0-slackware-patch (nonexistent)
+++ unzip/create-6.0-slackware-patch (revision 5)
Property changes on: unzip/create-6.0-slackware-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip/patches/README
===================================================================
--- unzip/patches/README (nonexistent)
+++ unzip/patches/README (revision 5)
@@ -0,0 +1,59 @@
+
+/* begin *
+
+ Patches from Slackware:
+ ======================
+
+ Various patches:
+ ---------------
+ unzip-6.0-bzip2-configure.patch.gz
+ unzip-6.0-exec-shield.patch.gz
+ unzip-6.0-close.patch.gz
+ unzip-6.0-attribs-overflow.patch.gz
+
+ RH specific:
+ -----------
+ unzip-6.0-manpage-fix.patch.gz
+ unzip-6.0-fix-recmatch.patch.gz
+ unzip-6.0-symlink.patch.gz
+ unzip-6.0-caseinsensitive.patch.gz
+ unzip-6.0-format-secure.patch.gz
+ unzip-6.0-valgrind.patch.gz
+ unzip-6.0-x-option.patch.gz
+ unzip-6.0-overflow.patch.gz
+ unzip-6.0-cve-2014-8139.patch.gz
+ unzip-6.0-cve-2014-8140.patch.gz
+ unzip-6.0-cve-2014-8141.patch.gz
+ unzip-6.0-overflow-long-fsize.patch.gz
+ unzip-6.0-heap-overflow-infloop.patch.gz
+ unzip-6.0-alt-iconv-utf8.patch.gz
+ unzip-6.0-alt-iconv-utf8-print.patch.gz
+ 0001-Fix-CVE-2016-9844-rhbz-1404283.patch.gz
+ unzip-6.0-timestamp.patch.gz
+ unzip-6.0-cve-2018-1000035-heap-based-overflow.patch.gz
+ unzip-6.0-cve-2018-18384.patch.gz
+ unzip-6.0-COVSCAN-fix-unterminated-string.patch.gz
+
+ Arch Linux:
+ -----------
+ unzip-6.0_CVE-2021-4217.patch
+ 28-cve-2022-0529-and-cve-2022-0530.patch
+
+ Changed files:
+ =============
+ unzip60/crc_i386.S
+ unzip60/crypt.c
+ unzip60/extract.c
+ unzip60/fileio.c
+ unzip60/list.c
+ unzip60/man/unzip.1
+ unzip60/match.c
+ unzip60/process.c
+ unzip60/unix/configure
+ unzip60/unix/unix.c
+ unzip60/unix/unxcfg.h
+ unzip60/unzip.c
+ unzip60/unzpriv.h
+ unzip60/zipinfo.c
+
+ * end */
Index: unzip/patches
===================================================================
--- unzip/patches (nonexistent)
+++ unzip/patches (revision 5)
Property changes on: unzip/patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: unzip
===================================================================
--- unzip (nonexistent)
+++ unzip (revision 5)
Property changes on: unzip
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/Makefile
===================================================================
--- zip/Makefile (nonexistent)
+++ zip/Makefile (revision 5)
@@ -0,0 +1,65 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url = $(DOWNLOAD_SERVER)/sources/packages/a/infozip/zip30
+
+versions = 30
+pkgname = zip
+suffix = tar.gz
+
+tarballs = $(addsuffix .$(suffix), $(addprefix $(pkgname), $(versions)))
+sha1s = $(addsuffix .sha1sum, $(tarballs))
+
+
+patches = $(CURDIR)/patches/zip-3.0-curdir.patch
+patches += $(CURDIR)/patches/zip-3.0-exec-shield.patch
+patches += $(CURDIR)/patches/zip-3.0-format-security.patch
+patches += $(CURDIR)/patches/zip-3.0-man-pages.patch
+patches += $(CURDIR)/patches/zip-3.0-zipnote.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+ @echo -e "\n======= Downloading source tarballs =======" ; \
+ for tarball in $(tarballs) ; do \
+ echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+ done ; wait
+
+$(sha1s): $(tarballs)
+ @for sha in $@ ; do \
+ echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+ echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+ touch $$sha ; \
+ echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+ sha1sum --check $$sha ; ret="$$?" ; \
+ if [ "$$ret" == "1" ]; then \
+ echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+ exit 1 ; \
+ fi ; \
+ done
+
+$(patches): $(sha1s)
+ @echo -e "\n======= Create Patches =======\n" ; \
+ ( cd create-3.0-curdir-patch ; ./create.patch.sh ) ; \
+ ( cd create-3.0-exec-shield-patch ; ./create.patch.sh ) ; \
+ ( cd create-3.0-format-security-patch ; ./create.patch.sh ) ; \
+ ( cd create-3.0-man-pages-patch ; ./create.patch.sh ) ; \
+ ( cd create-3.0-zipnote-patch ; ./create.patch.sh ) ; \
+ echo -e "\n"
+
+download_clean:
+ @rm -f $(tarballs) $(sha1s) $(patches)
Index: zip/create-3.0-curdir-patch/create.patch.sh
===================================================================
--- zip/create-3.0-curdir-patch/create.patch.sh (nonexistent)
+++ zip/create-3.0-curdir-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr zip${version}-orig zip${version} > zip-${VERSION}-curdir.patch
+
+mv zip-${VERSION}-curdir.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig
Property changes on: zip/create-3.0-curdir-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-curdir-patch/file.list
===================================================================
--- zip/create-3.0-curdir-patch/file.list (nonexistent)
+++ zip/create-3.0-curdir-patch/file.list (revision 5)
@@ -0,0 +1 @@
+zip30/util.c
Index: zip/create-3.0-curdir-patch/zip30-new/util.c
===================================================================
--- zip/create-3.0-curdir-patch/zip30-new/util.c (nonexistent)
+++ zip/create-3.0-curdir-patch/zip30-new/util.c (revision 5)
@@ -0,0 +1,1452 @@
+/*
+ util.c
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * util.c by Mark Adler.
+ */
+#define __UTIL_C
+
+#include "zip.h"
+#include "ebcdic.h"
+#include <ctype.h>
+
+#ifdef MSDOS16
+# include <dos.h>
+#endif
+
+#ifdef NO_MKTIME
+# ifndef IZ_MKTIME_ONLY
+# define IZ_MKTIME_ONLY /* only mktime() related code is pulled in */
+# endif
+# include "timezone.c"
+#endif
+
+uch upper[256], lower[256];
+/* Country-dependent case map table */
+
+
+#ifndef UTIL /* UTIL picks out namecmp code (all utils) */
+
+/* RISC OS uses # as its single-character wildcard */
+#ifdef RISCOS
+# define WILDCHR_SINGLE '#'
+# define WILDCHR_MULTI '*'
+# define DIRSEP_CHR '.'
+#endif
+
+#ifdef VMS
+# define WILDCHR_SINGLE '%'
+# define WILDCHR_MULTI '*'
+# define DIRSEP_CHR '.'
+#endif
+
+#ifndef WILDCHR_SINGLE
+# define WILDCHR_SINGLE '?'
+#endif
+#ifndef WILDCHR_MULTI
+# define WILDCHR_MULTI '*'
+#endif
+#ifndef DIRSEP_CHR
+# define DIRSEP_CHR '/'
+#endif
+
+/* Local functions */
+local int recmatch OF((ZCONST char *, ZCONST char *, int));
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ local long recmatchw OF((ZCONST wchar_t *, ZCONST wchar_t *, int));
+#endif
+local int count_args OF((char *s));
+
+#ifdef MSDOS16
+ local unsigned ident OF((unsigned chr));
+#endif
+
+#ifndef HAVE_FSEEKABLE
+
+/* 2004-11-12 SMS.
+ Changed to use z*o() functions, and ftell() test from >= 0 to != -1.
+ This solves problems with negative 32-bit offsets, even on small-file
+ products.
+*/
+int fseekable( fp)
+FILE *fp;
+{
+ zoff_t x;
+
+ return (fp == NULL ||
+ ((zfseeko( fp, ((zoff_t) -1), SEEK_CUR) == 0) && /* Seek ok. */
+ ((x = zftello( fp)) != ((zoff_t) -1)) && /* Tell ok. */
+ (zfseeko( fp, ((zoff_t) 1), SEEK_CUR) == 0) && /* Seek ok. */
+ (zftello( fp) == x+ 1))); /* Tells agree. */
+}
+#endif /* HAVE_FSEEKABLE */
+
+
+char *isshexp(p)
+char *p; /* candidate sh expression */
+/* If p is a sh expression, a pointer to the first special character is
+ returned. Otherwise, NULL is returned. */
+{
+ for (; *p; INCSTR(p))
+ if (*p == '\\' && *(p+1))
+ p++;
+#ifdef VMS
+ else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI)
+#else /* !VMS */
+ else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI || *p == '[')
+#endif /* ?VMS */
+ return p;
+ return NULL;
+}
+
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+wchar_t *isshexpw(pw)
+ wchar_t *pw; /* candidate sh expression */
+/* If pw is a sh expression, a pointer to the first special character is
+ returned. Otherwise, NULL is returned. */
+{
+ for (; *pw; pw++)
+ if (*pw == (wchar_t)'\\' && *(pw+1))
+ pw++;
+ else if (*pw == (wchar_t)WILDCHR_SINGLE || *pw == (wchar_t)WILDCHR_MULTI ||
+ *pw == (wchar_t)'[')
+ return pw;
+ return NULL;
+}
+
+# endif
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+local long recmatchw(pw, sw, cs)
+ZCONST wchar_t *pw; /* sh pattern to match */
+ZCONST wchar_t *sw; /* string to match it to */
+int cs; /* flag: force case-sensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+ they match, and 0 or 2 if they don't or if there is a syntax error in the
+ pattern. This routine recurses on itself no deeper than the number of
+ characters in the pattern. */
+{
+ long c; /* pattern char or start of range in [-] loop */
+ /* Get first character, the pattern for new recmatch calls follows */
+
+ c = (long)*(pw++);
+
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *sw == 0;
+
+ /* '?' matches any character (but not an empty string) */
+ if ((wchar_t)c == (wchar_t)WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*sw && *sw != (wchar_t)DIRSEP_CHR) ? recmatchw(pw, sw + 1, cs) : 0;
+ else
+ return *sw ? recmatchw(pw, sw + 1, cs) : 0;
+ }
+
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+ if (!no_wild && (wchar_t)c == (wchar_t)WILDCHR_MULTI)
+ {
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+ if (*pw != (wchar_t)WILDCHR_MULTI) {
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *sw && *sw != (wchar_t)DIRSEP_CHR; sw++)
+ if ((c = recmatchw(pw, sw, cs)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*pw == 0)
+ return (*sw == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*pw == (wchar_t)DIRSEP_CHR || (*pw == (wchar_t)'\\' &&
+ pw[1] == (wchar_t)DIRSEP_CHR))
+ ? recmatchw(pw, sw, cs) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ pw++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
+ if (*pw == 0)
+ return 1;
+ if (!isshexpw((wchar_t *)pw))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST wchar_t *swrest;
+
+ swrest = sw + (wcslen(sw) - wcslen(pw));
+ if (swrest - sw < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
+ return ((cs ? wcscmp(pw, swrest) : _wcsicmp(pw, swrest)) == 0);
+ }
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *sw; sw++)
+ if ((c = recmatchw(pw, sw, cs)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
+ }
+ }
+
+ /* Parse and process the list of characters and ranges in brackets */
+ if (!no_wild && allow_regex && (wchar_t)c == '[')
+ {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST wchar_t *qw; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*sw == 0) /* need a character to match */
+ return 0;
+ pw += (r = (*pw == (wchar_t)'!' || *pw == (wchar_t)'^')); /* see if reverse */
+ for (qw = pw, e = 0; *qw; qw++) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*qw == (wchar_t)'\\')
+ e = 1;
+ else if (*qw == (wchar_t)']')
+ break;
+ if (*qw != (wchar_t)']') /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = *pw == (wchar_t)'-'; pw < qw; pw++) /* go through the list */
+ {
+ if (e == 0 && *pw == (wchar_t)'\\') /* set escape flag if \ */
+ e = 1;
+ else if (e == 0 && *pw == (wchar_t)'-') /* set start of range if - */
+ c = *(pw-1);
+ else
+ {
+ wchar_t cc = (cs ? *sw : towupper(*sw));
+ wchar_t uc = (wchar_t) c;
+
+ if (*(pw+1) != (wchar_t)'-')
+ for (uc = uc ? uc : *pw; cc <= *pw; uc++)
+ /* compare range */
+ if ((cs ? uc : towupper(uc)) == cc)
+ return r ? 0 : recmatchw(qw + 1, sw + 1, cs);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatchw(qw + 1, sw + 1, cs) : 0;
+ /* bracket match failed */
+ }
+
+ /* If escape ('\'), just compare next character */
+ if (!no_wild && (wchar_t)c == (wchar_t)'\\')
+ if ((c = *pw++) == '\0') /* if \ at end, then syntax error */
+ return 0;
+
+ /* Just a character--compare it */
+ return (cs ? (wchar_t)c == *sw : towupper((wchar_t)c) == towupper(*sw)) ?
+ recmatchw(pw, sw + 1, cs) : 0;
+}
+
+# endif
+#endif
+
+
+local int recmatch(p, s, cs)
+ZCONST char *p; /* sh pattern to match */
+ZCONST char *s; /* string to match it to */
+int cs; /* flag: force case-sensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+ they match, and 0 or 2 if they don't or if there is a syntax error in the
+ pattern. This routine recurses on itself no deeper than the number of
+ characters in the pattern. */
+{
+ int c; /* pattern char or start of range in [-] loop */
+ /* Get first character, the pattern for new recmatch calls follows */
+
+ /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+ See 21 July 2006 mail.
+ It only applies when p is pointing to a doublebyte character and
+ things like / and wildcards are not doublebyte. This probably
+ should not be needed. */
+
+#ifdef _MBCS
+ if (CLEN(p) == 2) {
+ if (CLEN(s) == 2) {
+ return (*p == *s && *(p+1) == *(s+1)) ?
+ recmatch(p + 2, s + 2, cs) : 0;
+ } else {
+ return 0;
+ }
+ }
+#endif /* ?_MBCS */
+
+ c = *POSTINCSTR(p);
+
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *s == 0;
+
+ /* '?' (or '%' or '#') matches any character (but not an empty string) */
+ if (c == WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
+ else
+ return *s ? recmatch(p, s + CLEN(s), cs) : 0;
+ }
+
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+#ifdef AMIGA
+ if (!no_wild && c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+#endif /* AMIGA */
+ if (!no_wild && c == WILDCHR_MULTI)
+ {
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+ if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+ if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+ if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*p == 0)
+ return (*s == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+ ? recmatch(p, s, cs) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ p++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
+ if (*p == 0)
+ return 1;
+ if (!isshexp((char *)p))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST char *srest;
+
+ srest = s + (strlen(s) - strlen(p));
+ if (srest - s < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
+#ifdef _MBCS
+ {
+ ZCONST char *q = s;
+
+ /* MBCS-aware code must not scan backwards into a string from
+ * the end.
+ * So, we have to move forward by character from our well-known
+ * character position s in the test string until we have advanced
+ * to the srest position.
+ */
+ while (q < srest)
+ INCSTR(q);
+ /* In case the byte *srest is a trailing byte of a multibyte
+ * character, we have actually advanced past the position (srest).
+ * For this case, the match has failed!
+ */
+ if (q != srest)
+ return 0;
+ return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
+ }
+#else /* !_MBCS */
+ return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+#endif /* ?_MBCS */
+ }
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *s; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
+ }
+ }
+
+#ifndef VMS /* No bracket matching in VMS */
+ /* Parse and process the list of characters and ranges in brackets */
+ if (!no_wild && allow_regex && c == '[')
+ {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST char *q; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*s == 0) /* need a character to match */
+ return 0;
+ p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+ for (q = p, e = 0; *q; q++) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*q == '\\')
+ e = 1;
+ else if (*q == ']')
+ break;
+ if (*q != ']') /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = *p == '-'; p < q; p++) /* go through the list */
+ {
+ if (e == 0 && *p == '\\') /* set escape flag if \ */
+ e = 1;
+ else if (e == 0 && *p == '-') /* set start of range if - */
+ c = *(p-1);
+ else
+ {
+ uch cc = (cs ? (uch)*s : case_map((uch)*s));
+ uch uc = (uch) c;
+ if (*(p+1) != '-')
+ for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+ /* compare range */
+ if ((cs ? uc : case_map(uc)) == cc)
+ return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
+ /* bracket match failed */
+ }
+#endif /* !VMS */
+
+ /* If escape ('\'), just compare next character */
+ if (!no_wild && c == '\\')
+ if ((c = *p++) == '\0') /* if \ at end, then syntax error */
+ return 0;
+
+#ifdef VMS
+ /* 2005-11-06 SMS.
+ Handle "..." wildcard in p with "." or "]" in s.
+ */
+ if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+ ((*s == '.') || (*s == ']')))
+ {
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* Else, look for a reduced match in s, until "]" in or end of s. */
+ for (; *s && (*s != ']'); INCSTR(s))
+ if (*s == '.')
+ /* If reduced match, then continue after "..." in p, "." in s. */
+ if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
+ return (int)c;
+
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* No reduced match. Quit. */
+ return 2;
+ }
+
+#endif /* def VMS */
+
+ /* Just a character--compare it */
+ return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
+ recmatch(p, s + CLEN(s), cs) : 0;
+}
+
+
+int shmatch(p, s, cs)
+ZCONST char *p; /* sh pattern to match */
+ZCONST char *s; /* string to match it to */
+int cs; /* force case-sensitive match if TRUE */
+/* Compare the sh pattern p with the string s and return true if they match,
+ false if they don't or if there is a syntax error in the pattern. */
+{
+ while (s[0] == '.' && s[1] == '/')
+ s += 2; /* strip redundant leading "./" sections */
+ return recmatch(p, s, cs) == 1;
+}
+
+
+#if defined(DOS) || defined(WIN32)
+
+#ifdef UNICODE_SUPPORT
+
+int dosmatchw(pw, sw, cs)
+ZCONST wchar_t *pw; /* dos pattern to match */
+ZCONST wchar_t *sw; /* string to match it to */
+int cs; /* force case-sensitive match if TRUE */
+/* Treat filenames without periods as having an implicit trailing period */
+{
+ wchar_t *sw1; /* revised string to match */
+ int r; /* result */
+
+ if (wcschr(pw, (wchar_t)'.') && !wcschr(sw, (wchar_t)'.') &&
+ ((sw1 = (wchar_t *)malloc((wcslen(sw) + 2) * sizeof(wchar_t))) != NULL))
+ {
+ wcscpy(sw1, sw);
+ wcscat(sw1, L".");
+ }
+ else
+ {
+ /* will usually be OK */
+ sw1 = (wchar_t *)sw;
+ }
+
+ r = recmatchw(pw, sw1, cs) == 1;
+ if (sw != sw1)
+ free((zvoid *)sw1);
+ return r == 1;
+}
+
+#endif
+
+/* XXX also suitable for OS2? Atari? Human68K? TOPS-20?? */
+
+int dosmatch(p, s, cs)
+ZCONST char *p; /* dos pattern to match */
+ZCONST char *s; /* string to match it to */
+int cs; /* force case-sensitive match if TRUE */
+/* Treat filenames without periods as having an implicit trailing period */
+{
+ char *s1; /* revised string to match */
+ int r; /* result */
+
+ if (strchr(p, '.') && !strchr(s, '.') &&
+ ((s1 = malloc(strlen(s) + 2)) != NULL))
+ {
+ strcpy(s1, s);
+ strcat(s1, ".");
+ }
+ else
+ {
+ /* will usually be OK */
+ s1 = (char *)s;
+ }
+
+ r = recmatch(p, s1, cs) == 1;
+ if (s != s1)
+ free((zvoid *)s1);
+ return r == 1;
+}
+
+#endif /* DOS || WIN32 */
+
+zvoid far **search(b, a, n, cmp)
+ZCONST zvoid *b; /* pointer to value to search for */
+ZCONST zvoid far **a; /* table of pointers to values, sorted */
+extent n; /* number of pointers in a[] */
+int (*cmp) OF((ZCONST zvoid *, ZCONST zvoid far *)); /* comparison function */
+
+/* Search for b in the pointer list a[0..n-1] using the compare function
+ cmp(b, c) where c is an element of a[i] and cmp() returns negative if
+ *b < *c, zero if *b == *c, or positive if *b > *c. If *b is found,
+ search returns a pointer to the entry in a[], else search() returns
+ NULL. The nature and size of *b and *c (they can be different) are
+ left up to the cmp() function. A binary search is used, and it is
+ assumed that the list is sorted in ascending order. */
+{
+ ZCONST zvoid far **i; /* pointer to midpoint of current range */
+ ZCONST zvoid far **l; /* pointer to lower end of current range */
+ int r; /* result of (*cmp)() call */
+ ZCONST zvoid far **u; /* pointer to upper end of current range */
+
+ l = (ZCONST zvoid far **)a; u = l + (n-1);
+ while (u >= l) {
+ i = l + ((unsigned)(u - l) >> 1);
+ if ((r = (*cmp)(b, (ZCONST char far *)*(struct zlist far **)i)) < 0)
+ u = i - 1;
+ else if (r > 0)
+ l = i + 1;
+ else
+ return (zvoid far **)i;
+ }
+ return NULL; /* If b were in list, it would belong at l */
+}
+
+#endif /* !UTIL */
+
+#ifdef MSDOS16
+
+local unsigned ident(unsigned chr)
+{
+ return chr; /* in al */
+}
+
+void init_upper()
+{
+ static struct country {
+ uch ignore[18];
+ int (far *casemap)(int);
+ uch filler[16];
+ } country_info;
+
+ struct country far *info = &country_info;
+ union REGS regs;
+ struct SREGS sregs;
+ unsigned int c;
+
+ regs.x.ax = 0x3800; /* get country info */
+ regs.x.dx = FP_OFF(info);
+ sregs.ds = FP_SEG(info);
+ intdosx(®s, ®s, &sregs);
+ for (c = 0; c < 128; c++) {
+ upper[c] = (uch) toupper(c);
+ lower[c] = (uch) c;
+ }
+ for (; c < sizeof(upper); c++) {
+ upper[c] = (uch) (*country_info.casemap)(ident(c));
+ /* ident() required because casemap takes its parameter in al */
+ lower[c] = (uch) c;
+ }
+ for (c = 0; c < sizeof(upper); c++ ) {
+ unsigned int u = upper[c];
+ if (u != c && lower[u] == (uch) u) {
+ lower[u] = (uch)c;
+ }
+ }
+ for (c = 'A'; c <= 'Z'; c++) {
+ lower[c] = (uch) (c - 'A' + 'a');
+ }
+}
+#else /* !MSDOS16 */
+# ifndef OS2
+
+void init_upper()
+{
+ unsigned int c;
+#if defined(ATARI) || defined(CMS_MVS)
+#include <ctype.h>
+/* this should be valid for all other platforms too. (HD 11/11/95) */
+ for (c = 0; c< sizeof(upper); c++) {
+ upper[c] = islower(c) ? toupper(c) : c;
+ lower[c] = isupper(c) ? tolower(c) : c;
+ }
+#else
+ for (c = 0; c < sizeof(upper); c++) upper[c] = lower[c] = (uch)c;
+ for (c = 'a'; c <= 'z'; c++) upper[c] = (uch)(c - 'a' + 'A');
+ for (c = 'A'; c <= 'Z'; c++) lower[c] = (uch)(c - 'A' + 'a');
+#endif
+}
+# endif /* !OS2 */
+
+#endif /* ?MSDOS16 */
+
+int namecmp(string1, string2)
+ ZCONST char *string1, *string2;
+/* Compare the two strings ignoring case, and correctly taking into
+ * account national language characters. For operating systems with
+ * case sensitive file names, this function is equivalent to strcmp.
+ */
+{
+ int d;
+
+ for (;;)
+ {
+ d = (int) (uch) case_map(*string1)
+ - (int) (uch) case_map(*string2);
+
+ if (d || *string1 == 0 || *string2 == 0)
+ return d;
+
+ string1++;
+ string2++;
+ }
+}
+
+#ifdef EBCDIC
+char *strtoasc(char *str1, ZCONST char *str2)
+{
+ char *old;
+ old = str1;
+ while (*str1++ = (char)ascii[(uch)(*str2++)]);
+ return old;
+}
+
+char *strtoebc(char *str1, ZCONST char *str2)
+{
+ char *old;
+ old = str1;
+ while (*str1++ = (char)ebcdic[(uch)(*str2++)]);
+ return old;
+}
+
+char *memtoasc(char *mem1, ZCONST char *mem2, unsigned len)
+{
+ char *old;
+ old = mem1;
+ while (len--)
+ *mem1++ = (char)ascii[(uch)(*mem2++)];
+ return old;
+}
+
+char *memtoebc(char *mem1, ZCONST char *mem2, unsigned len)
+{
+ char *old;
+ old = mem1;
+ while (len--)
+ *mem1++ = (char)ebcdic[(uch)(*mem2++)];
+ return old;
+}
+#endif /* EBCDIC */
+
+#ifdef IZ_ISO2OEM_ARRAY
+char *str_iso_to_oem(dst, src)
+ ZCONST char *src;
+ char *dst;
+{
+ char *dest_start = dst;
+ while (*dst++ = (char)iso2oem[(uch)(*src++)]);
+ return dest_start;
+}
+#endif
+
+#ifdef IZ_OEM2ISO_ARRAY
+char *str_oem_to_iso(dst, src)
+ ZCONST char *src;
+ char *dst;
+{
+ char *dest_start = dst;
+ while (*dst++ = (char)oem2iso[(uch)(*src++)]);
+ return dest_start;
+}
+#endif
+
+
+
+/* DBCS support for Info-ZIP's zip (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
+ * This code is public domain! Date: 1998/12/20
+ */
+#ifdef _MBCS
+
+char *___tmp_ptr;
+
+int lastchar(ptr)
+ ZCONST char *ptr;
+{
+ ZCONST char *oldptr = ptr;
+ while(*ptr != '\0'){
+ oldptr = ptr;
+ INCSTR(ptr);
+ }
+ return (int)(unsigned)*oldptr;
+}
+
+unsigned char *zmbschr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ while(*str != '\0'){
+ if (*str == c) {return (unsigned char *)str;}
+ INCSTR(str);
+ }
+ return NULL;
+}
+
+unsigned char *zmbsrchr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ unsigned char *match = NULL;
+ while(*str != '\0'){
+ if (*str == c) {match = (unsigned char*)str;}
+ INCSTR(str);
+ }
+ return match;
+}
+#endif /* _MBCS */
+
+
+
+#ifndef UTIL
+
+/*****************************************************************
+ | envargs - add default options from environment to command line
+ |----------------------------------------------------------------
+ | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
+ | This program is in the public domain.
+ |----------------------------------------------------------------
+ | Minor program notes:
+ | 1. Yes, the indirection is a tad complex
+ | 2. Parenthesis were added where not needed in some cases
+ | to make the action of the code less obscure.
+ ****************************************************************/
+
+void envargs(Pargc, Pargv, envstr, envstr2)
+ int *Pargc;
+ char ***Pargv;
+ char *envstr;
+ char *envstr2;
+{
+ char *envptr; /* value returned by getenv */
+ char *bufptr; /* copy of env info */
+ int argc; /* internal arg count */
+ register int ch; /* spare temp value */
+ char **argv; /* internal arg vector */
+ char **argvect; /* copy of vector address */
+
+ /* see if anything in the environment */
+ envptr = getenv(envstr);
+ if (envptr != NULL) /* usual var */
+ while (isspace((uch)*envptr)) /* we must discard leading spaces */
+ envptr++;
+ if (envptr == NULL || *envptr == '\0')
+ if ((envptr = getenv(envstr2)) != NULL) /* alternate */
+ while (isspace((uch)*envptr))
+ envptr++;
+ if (envptr == NULL || *envptr == '\0')
+ return;
+
+ /* count the args so we can allocate room for them */
+ argc = count_args(envptr);
+ bufptr = malloc(1 + strlen(envptr));
+ if (bufptr == NULL)
+ ziperr(ZE_MEM, "Can't get memory for arguments");
+ strcpy(bufptr, envptr);
+
+ /* allocate a vector large enough for all args */
+ argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
+ if (argv == NULL) {
+ free(bufptr);
+ ziperr(ZE_MEM, "Can't get memory for arguments");
+ }
+ argvect = argv;
+
+ /* copy the program name first, that's always true */
+ *(argv++) = *((*Pargv)++);
+
+ /* copy the environment args first, may be changed */
+ do {
+#if defined(AMIGA) || defined(UNIX)
+ if (*bufptr == '"') {
+ char *argstart = ++bufptr;
+ *(argv++) = argstart;
+ for (ch = *bufptr; ch != '\0' && ch != '\"';
+ ch = *PREINCSTR(bufptr))
+ if (ch == '\\' && bufptr[1] != '\0')
+ ++bufptr; /* skip to char after backslash */
+ if (ch != '\0') /* overwrite trailing '"' */
+ *(bufptr++) = '\0';
+
+ /* remove escape characters */
+ while ((argstart = MBSCHR(argstart, '\\')) != NULL) {
+ strcpy(argstart, argstart + 1);
+ if (*argstart)
+ ++argstart;
+ }
+ } else {
+ *(argv++) = bufptr;
+ while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+ if (ch != '\0') *(bufptr++) = '\0';
+ }
+#else
+# ifdef WIN32
+ /* We do not support backslash-quoting of quotes in quoted */
+ /* strings under Win32, because backslashes are directory */
+ /* separators and double quotes are illegal in filenames. */
+ if (*bufptr == '"') {
+ *(argv++) = ++bufptr;
+ while ((ch = *bufptr) != '\0' && ch != '\"') INCSTR(bufptr);
+ if (ch != '\0') *(bufptr++) = '\0';
+ } else {
+ *(argv++) = bufptr;
+ while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+ if (ch != '\0') *(bufptr++) = '\0';
+ }
+# else
+ *(argv++) = bufptr;
+ while ((ch = *bufptr) != '\0' && !isspace((uch)ch)) INCSTR(bufptr);
+ if (ch != '\0') *(bufptr++) = '\0';
+# endif
+#endif /* ?(AMIGA || UNIX) */
+ while ((ch = *bufptr) != '\0' && isspace((uch)ch)) INCSTR(bufptr);
+ } while (ch);
+
+ /* now save old argc and copy in the old args */
+ argc += *Pargc;
+ while (--(*Pargc)) *(argv++) = *((*Pargv)++);
+
+ /* finally, add a NULL after the last arg, like UNIX */
+ *argv = NULL;
+
+ /* save the values and return */
+ *Pargv = argvect;
+ *Pargc = argc;
+}
+
+local int count_args(s)
+char *s;
+{
+ int count = 0;
+ char ch;
+
+ do {
+ /* count and skip args */
+ ++count;
+#if defined(AMIGA) || defined(UNIX)
+ if (*s == '\"') {
+ for (ch = *PREINCSTR(s); ch != '\0' && ch != '\"';
+ ch = *PREINCSTR(s))
+ if (ch == '\\' && s[1] != '\0')
+ INCSTR(s);
+ if (*s) INCSTR(s); /* trailing quote */
+ } else
+ while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+#else
+# ifdef WIN32
+ if (*s == '\"') {
+ ++s; /* leading quote */
+ while ((ch = *s) != '\0' && ch != '\"') INCSTR(s);
+ if (*s) INCSTR(s); /* trailing quote */
+ } else
+ while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+# else
+ while ((ch = *s) != '\0' && !isspace((uch)ch)) INCSTR(s);
+# endif
+#endif /* ?(AMIGA || UNIX) */
+ while ((ch = *s) != '\0' && isspace((uch)ch)) INCSTR(s);
+ } while (ch);
+
+ return(count);
+}
+
+
+
+/* Extended argument processing -- by Rich Wales
+ * This function currently deals only with the MKS shell, but could be
+ * extended later to understand other conventions.
+ *
+ * void expand_args(int *argcp, char ***argvp)
+ *
+ * Substitutes the extended command line argument list produced by
+ * the MKS Korn Shell in place of the command line info from DOS.
+ *
+ * The MKS shell gets around DOS's 128-byte limit on the length of
+ * a command line by passing the "real" command line in the envi-
+ * ronment. The "real" arguments are flagged by prepending a tilde
+ * (~) to each one.
+ *
+ * This "expand_args" routine creates a new argument list by scanning
+ * the environment from the beginning, looking for strings begin-
+ * ning with a tilde character. The new list replaces the original
+ * "argv" (pointed to by "argvp"), and the number of arguments
+ * in the new list replaces the original "argc" (pointed to by
+ * "argcp").
+ */
+void expand_args(argcp, argvp)
+ int *argcp;
+ char ***argvp;
+{
+#ifdef DOS
+
+/* Do NEVER include (re)definiton of `environ' variable with any version
+ of MSC or BORLAND/Turbo C. These compilers supply an incompatible
+ definition in <stdlib.h>. */
+#if defined(__GO32__) || defined(__EMX__)
+ extern char **environ; /* environment */
+#endif /* __GO32__ || __EMX__ */
+ char **envp; /* pointer into environment */
+ char **newargv; /* new argument list */
+ char **argp; /* pointer into new arg list */
+ int newargc; /* new argument count */
+
+ /* sanity check */
+ if (environ == NULL
+ || argcp == NULL
+ || argvp == NULL || *argvp == NULL)
+ return;
+ /* find out how many environment arguments there are */
+ for (envp = environ, newargc = 0;
+ *envp != NULL && (*envp)[0] == '~';
+ envp++, newargc++) ;
+ if (newargc == 0)
+ return; /* no environment arguments */
+ /* set up new argument list */
+ newargv = (char **) malloc(sizeof(char **) * (newargc+1));
+ if (newargv == NULL)
+ return; /* malloc failed */
+ for (argp = newargv, envp = environ;
+ *envp != NULL && (*envp)[0] == '~';
+ *argp++ = &(*envp++)[1]) ;
+ *argp = NULL; /* null-terminate the list */
+ /* substitute new argument list in place of old one */
+ *argcp = newargc;
+ *argvp = newargv;
+#else /* !DOS */
+ if (argcp || argvp) return;
+#endif /* ?DOS */
+}
+
+
+/* Fast routine for detection of plain text
+ * (ASCII or an ASCII-compatible extension such as ISO-8859, UTF-8, etc.)
+ * Author: Cosmin Truta.
+ * See "proginfo/txtvsbin.txt" for more information.
+ *
+ * This function returns the same result as set_file_type() in "trees.c".
+ * Unlike in set_file_type(), however, the speed depends on the buffer size,
+ * so the optimal implementation is different.
+ */
+int is_text_buf(buf_ptr, buf_size)
+ ZCONST char *buf_ptr;
+ unsigned buf_size;
+{
+ int result = 0;
+ unsigned i;
+ unsigned char c;
+
+ for (i = 0; i < buf_size; ++i)
+ {
+ c = (unsigned char)buf_ptr[i];
+ if (c >= 32) /* speed up the loop by checking this first */
+ result = 1; /* white-listed character found; keep looping */
+ else /* speed up the loop by inlining the following check */
+ if ((c <= 6) || (c >= 14 && c <= 25) || (c >= 28 && c <= 31))
+ return 0; /* black-listed character found; stop */
+ }
+
+ return result;
+}
+
+#endif /* UTIL */
+
+
+#ifdef DEBUGNAMES
+#undef free
+int Free(x)
+void *x;
+{
+ if (x == (void *) 0xdeadbeef)
+ exit(-1);
+ free(x);
+ return 0;
+}
+
+int printnames()
+{
+ struct zlist far *z;
+
+ for (z = zfiles; z != NULL; z = z->nxt)
+ fprintf(mesg, "%s %s %s %p %p %p %08x %08x %08x\n",
+ z->name, z->zname, z->iname,
+ z->name, z->zname, z->iname,
+ *((int *) z->name), *((int *) z->zname),
+ *((int *) z->iname));
+ return 0;
+}
+
+#endif /* DEBUGNAMES */
+
+
+/* Below is used to format zoff_t values, which can be either long or long long
+ depending on if LARGE FILES are supported. Function provided by SMS.
+ 10/17/04 EG */
+
+/* 2004-12-01 SMS.
+ * Brought in fancy fzofft() from UnZip.
+ */
+
+/* This implementation assumes that no more than FZOFF_NUM values will be
+ needed in any printf using it. */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set.
+ This version renamed from fzofft because of name conflict in unzip
+ when combined in WiZ. */
+
+/* 2004-12-19 SMS.
+ * I still claim than the smart move would have been to disable one or
+ * the other instance with #if for Wiz. But fine. We'll change the
+ * name.
+ */
+
+/* This is likely not thread safe. Needs to be done without static storage.
+ 12/29/04 EG */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set. */
+
+#define FZOFFT_NUM 4 /* Number of chambers. */
+#define FZOFFT_LEN 24 /* Number of characters/chamber. */
+
+
+/* Format a zoff_t value in a cylindrical buffer set. */
+
+char *zip_fzofft( val, pre, post)
+ zoff_t val;
+ char *pre;
+ char *post;
+{
+ /* Storage cylinder. */
+ static char fzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+ static int fzofft_index = 0;
+
+ /* Temporary format string storage. */
+ static char fmt[ 16] = "%";
+
+ /* Assemble the format string. */
+ fmt[ 1] = '\0'; /* Start after initial "%". */
+ if (pre == FZOFFT_HEX_WID) /* Special hex width. */
+ {
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+ {
+ strcat( fmt, ".");
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre != NULL) /* Caller's prefix (width). */
+ {
+ strcat( fmt, pre);
+ }
+
+ strcat( fmt, FZOFFT_FMT); /* Long or long-long or whatever. */
+
+ if (post == NULL)
+ strcat( fmt, "d"); /* Default radix = decimal. */
+ else
+ strcat( fmt, post); /* Caller's radix. */
+
+ /* Advance the cylinder. */
+ fzofft_index = (fzofft_index+ 1)% FZOFFT_NUM;
+
+ /* Write into the current chamber. */
+ sprintf( fzofft_buf[ fzofft_index], fmt, val);
+
+ /* Return a pointer to this chamber. */
+ return fzofft_buf[ fzofft_index];
+}
+
+
+/* Format a uzoff_t value in a cylindrical buffer set. */
+/* Added to support uzoff_t type. 12/29/04 */
+
+char *zip_fuzofft( val, pre, post)
+ uzoff_t val;
+ char *pre;
+ char *post;
+{
+ /* Storage cylinder. */
+ static char fuzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+ static int fuzofft_index = 0;
+
+ /* Temporary format string storage. */
+ static char fmt[ 16] = "%";
+
+ /* Assemble the format string. */
+ fmt[ 1] = '\0'; /* Start after initial "%". */
+ if (pre == FZOFFT_HEX_WID) /* Special hex width. */
+ {
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+ {
+ strcat( fmt, ".");
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre != NULL) /* Caller's prefix (width). */
+ {
+ strcat( fmt, pre);
+ }
+
+ strcat( fmt, FZOFFT_FMT); /* Long or long-long or whatever. */
+
+ if (post == NULL)
+ strcat( fmt, "u"); /* Default radix = decimal. */
+ else
+ strcat( fmt, post); /* Caller's radix. */
+
+ /* Advance the cylinder. */
+ fuzofft_index = (fuzofft_index+ 1)% FZOFFT_NUM;
+
+ /* Write into the current chamber. */
+ sprintf( fuzofft_buf[ fuzofft_index], fmt, val);
+
+ /* Return a pointer to this chamber. */
+ return fuzofft_buf[ fuzofft_index];
+}
+
+
+/* Display number to mesg stream
+ 5/15/05 EG */
+
+int DisplayNumString(file, i)
+ FILE *file;
+ uzoff_t i;
+{
+ char tempstrg[100];
+ int j;
+ char *s = tempstrg;
+
+ WriteNumString(i, tempstrg);
+ /* skip spaces */
+ for (j = 0; j < 3; j++) {
+ if (*s != ' ') break;
+ s++;
+ }
+ fprintf(file, "%s", s);
+
+ return 0;
+}
+
+/* Read numbers with trailing size multiplier (like 10M) and return number.
+ 10/30/04 EG */
+
+uzoff_t ReadNumString( numstring )
+ char *numstring;
+{
+ zoff_t num = 0;
+ char multchar = ' ';
+ int i;
+ uzoff_t mult = 1;
+
+ /* check if valid number (currently no negatives) */
+ if (numstring == NULL) {
+ zipwarn("Unable to read empty number in ReadNumString", "");
+ return (uzoff_t)-1;
+ }
+ if (numstring[0] < '0' || numstring[0] > '9') {
+ zipwarn("Unable to read number (must start with digit): ", numstring);
+ return (uzoff_t)-1;
+ }
+ if (strlen(numstring) > 8) {
+ zipwarn("Number too long to read (8 characters max): ", numstring);
+ return (uzoff_t)-1;
+ }
+
+ /* get the number part */
+ num = atoi(numstring);
+
+ /* find trailing multiplier */
+ for (i = 0; numstring[i] && isdigit(numstring[i]); i++) ;
+
+ /* return if no multiplier */
+ if (numstring[i] == '\0') {
+ return (uzoff_t)num;
+ }
+
+ /* nothing follows multiplier */
+ if (numstring[i + 1]) {
+ return (uzoff_t)-1;
+ }
+
+ /* get multiplier */
+ multchar = toupper(numstring[i]);
+
+ if (multchar == 'K') {
+ mult <<= 10;
+ } else if (multchar == 'M') {
+ mult <<= 20;
+ } else if (multchar == 'G') {
+ mult <<= 30;
+#ifdef LARGE_FILE_SUPPORT
+ } else if (multchar == 'T') {
+ mult <<= 40;
+#endif
+ } else {
+ return (uzoff_t)-1;
+ }
+
+ return (uzoff_t)num * mult;
+}
+
+
+/* Write the number as a string with a multiplier (like 10M) to outstring.
+ Always writes no more than 3 digits followed maybe by a multiplier and
+ returns the characters written or -1 if error.
+ 10/30/04 EG */
+
+int WriteNumString( num, outstring )
+ uzoff_t num;
+ char *outstring;
+{
+ int mult;
+ int written = 0;
+ int i;
+ int j;
+ char digits[4];
+ int dig;
+
+ *outstring = '\0';
+
+ /* shift number 1 K until less than 10000 */
+ for (mult = 0; num >= 10240; mult++) {
+ num >>= 10;
+ }
+
+ /* write digits as " 0" */
+ for (i = 1; i < 4; i++) {
+ digits[i] = ' ';
+ }
+ digits[0] = '0';
+
+ if (num >= 1000) {
+ i = 3;
+ num *= 10;
+ num >>= 10;
+ mult++;
+ digits[0] = (char) (num % 10) + '0';
+ digits[1] = '.';
+ digits[2] = (char) (num / 10) + '0';
+ } else {
+ for (i = 0; num; i++) {
+ dig = (int) (num % 10);
+ num /= 10;
+ digits[i] = dig + '0';
+ }
+ }
+ if (i == 0) i = 1;
+ for (j = i; j > 0; j--) {
+ *outstring = digits[j - 1];
+ outstring++;
+ written++;
+ }
+
+ /* output multiplier */
+ if (mult == 0) {
+ } else if (mult == 1) {
+ *outstring = 'K';
+ outstring++;
+ written++;
+ } else if (mult == 2) {
+ *outstring = 'M';
+ outstring++;
+ written++;
+ } else if (mult == 3) {
+ *outstring = 'G';
+ outstring++;
+ written++;
+ } else if (mult == 4) {
+ *outstring = 'T';
+ outstring++;
+ written++;
+ } else {
+ *outstring = '?';
+ outstring++;
+ written++;
+ }
+
+ *outstring = '\0';
+
+ return written;
+}
+
+
+#if 0 /* not used anywhere, should get removed by next release... */
+
+/* Apply the Adler-16 checksum to a set of bytes.
+ * Use this function as you would use crc32():
+ * - First call this function by passing a NULL pointer instead of buf
+ * OR initialize the checksum register with ADLERVAL_INITIAL.
+ * - Iteratively call this function for each buffer fragment.
+ * This function returns the updated checksum.
+ *
+ * IN assertion: chksum is a valid Adler-16 checksum:
+ * (chksum & 0xffU) < ADLER16_BASE && ((chksum >> 8) & 0xffU) < ADLER16_BASE
+ *
+ * Author: Cosmin Truta.
+ * See "proginfo/adler16.txt" for more information.
+ */
+
+#define ADLER16_BASE 251 /* The largest prime smaller than 256 */
+
+unsigned int adler16(chksum, buf, len)
+ unsigned int chksum;
+ ZCONST uch *buf;
+ extent len;
+{
+ unsigned int sum1 = chksum & 0xff;
+ unsigned int sum2 = (chksum >> 8) & 0xff;
+ extent i;
+
+ Assert((sum1 < ADLER16_BASE) && (sum2 < ADLER16_BASE),
+ "adler16: invalid checksum");
+
+ if (buf == NULL)
+ return 1;
+
+ for (i = 0; i < len; ++i)
+ {
+ sum1 += buf[i];
+ if (sum1 >= ADLER16_BASE) /* this is faster than modulo ADLER16_BASE */
+ sum1 -= ADLER16_BASE;
+ sum2 += sum1;
+ if (sum2 >= ADLER16_BASE) /* ditto */
+ sum2 -= ADLER16_BASE;
+ }
+
+ return (sum2 << 8) | sum1;
+}
+
+#endif /* 0, not used anywhere */
+
+
+/* returns true if abbrev is abbreviation for matchstring */
+int abbrevmatch (matchstring, abbrev, case_sensitive, minmatch)
+ char *matchstring;
+ char *abbrev;
+ int case_sensitive;
+ int minmatch;
+{
+ int cnt = 0;
+ char *m;
+ char *a;
+
+ m = matchstring;
+ a = abbrev;
+
+ for (; *m && *a; m++, a++) {
+ cnt++;
+ if (case_sensitive) {
+ if (*m != *a) {
+ /* mismatch */
+ return 0;
+ }
+ } else {
+ if (toupper(*m) != toupper(*a)) {
+ /* mismatch */
+ return 0;
+ }
+ }
+ }
+ if (cnt < minmatch) {
+ /* not big enough string */
+ return 0;
+ }
+ if (*a != '\0') {
+ /* abbreviation longer than match string */
+ return 0;
+ }
+ /* either abbreviation or match */
+ return 1;
+}
Index: zip/create-3.0-curdir-patch/zip30-new
===================================================================
--- zip/create-3.0-curdir-patch/zip30-new (nonexistent)
+++ zip/create-3.0-curdir-patch/zip30-new (revision 5)
Property changes on: zip/create-3.0-curdir-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-curdir-patch
===================================================================
--- zip/create-3.0-curdir-patch (nonexistent)
+++ zip/create-3.0-curdir-patch (revision 5)
Property changes on: zip/create-3.0-curdir-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-exec-shield-patch/create.patch.sh
===================================================================
--- zip/create-3.0-exec-shield-patch/create.patch.sh (nonexistent)
+++ zip/create-3.0-exec-shield-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr zip${version}-orig zip${version} > zip-${VERSION}-exec-shield.patch
+
+mv zip-${VERSION}-exec-shield.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig
Property changes on: zip/create-3.0-exec-shield-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-exec-shield-patch/file.list
===================================================================
--- zip/create-3.0-exec-shield-patch/file.list (nonexistent)
+++ zip/create-3.0-exec-shield-patch/file.list (revision 5)
@@ -0,0 +1,2 @@
+zip30/crc_i386.S
+zip30/match.S
Index: zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S (nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new/crc_i386.S (revision 5)
@@ -0,0 +1,307 @@
+/*
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * crc_i386.S, optimized CRC calculation function for Zip and UnZip,
+ * created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007.
+ *
+ * GRR 961110: incorporated Scott Field optimizations from win32/crc_i386.asm
+ * => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
+ *
+ * SPC 970402: revised for Rodney Brown's optimizations (32-bit-wide
+ * aligned reads for most of the data from buffer), can be
+ * disabled by defining the macro NO_32_BIT_LOADS
+ *
+ * SPC 971012: added Rodney Brown's additional tweaks for 32-bit-optimized
+ * CPUs (like the Pentium Pro, Pentium II, and probably some
+ * Pentium clones). This optimization is controlled by the
+ * preprocessor switch "__686" and is disabled by default.
+ * (This default is based on the assumption that most users
+ * do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * COS 050116: Enabled the 686 build by default, because there are hardly any
+ * pre-686 CPUs in serious use nowadays. (See SPC 970402 above.)
+ *
+ * SPC 060103: Updated code to incorporate newer optimizations found in zlib.
+ *
+ * SPC 070107: Added conditional switch to deactivate crc32() compilation.
+ *
+ * FLAT memory model assumed. Calling interface:
+ * - args are pushed onto the stack from right to left,
+ * - return value is given in the EAX register,
+ * - all other registers (with exception of EFLAGS) are preserved. (With
+ * GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
+ * them nevertheless adds only 4 single byte instructions.)
+ *
+ * This source generates the function
+ * ulg crc32(ulg crc, ZCONST uch *buf, extent len).
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ */
+
+/* This file is NOT used in conjunction with zlib, or when only creation of
+ * the basic CRC_32_Table (for other purpose) is requested.
+ */
+#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+# define _crc32 crc32
+# define _get_crc_table get_crc_table
+#endif
+/* Use 16-byte alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+# define ALIGNMENT .align 4,0x90
+#endif
+
+#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
+
+/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to use the C version,
+ * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
+ */
+
+ .file "crc_i386.S"
+
+#if !defined(PRE_686) && !defined(__686)
+ /* Optimize for Pentium Pro and compatible CPUs by default. */
+# define __686
+#endif
+
+#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
+# undef USE_STACKFRAME
+#else
+ /* The default is to use standard stack frame entry, because it
+ * results in smaller code!
+ */
+# ifndef USE_STD_STACKFRAME
+# define USE_STD_STACKFRAME
+# endif
+#endif
+
+#ifdef USE_STD_STACKFRAME
+# define _STD_ENTRY pushl %ebp ; movl %esp,%ebp
+# define arg1 8(%ebp)
+# define arg2 12(%ebp)
+# define arg3 16(%ebp)
+# define _STD_LEAVE popl %ebp
+#else /* !USE_STD_STACKFRAME */
+# define _STD_ENTRY
+# define arg1 24(%esp)
+# define arg2 28(%esp)
+# define arg3 32(%esp)
+# define _STD_LEAVE
+#endif /* ?USE_STD_STACKFRAME */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ * eax : crc value "c"
+ * esi : pointer to next data byte (or lword) "buf++"
+ * registers read:
+ * edi : pointer to base of crc_table array
+ * scratch registers:
+ * ebx : index into crc_table array
+ * (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686 /* optimize for 386, 486, Pentium */
+#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
+ movb %al, %bl ;/* tmp = c & 0xFF */\
+ shrl $8, %eax ;/* c = (c >> 8) */\
+ xorl (%edi, %ebx, 4), %eax ;/* c ^= table[tmp] */
+#else /* __686 : optimize for Pentium Pro and compatible CPUs */
+#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
+ movzbl %al, %ebx ;/* tmp = c & 0xFF */\
+ shrl $8, %eax ;/* c = (c >> 8) */\
+ xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */
+#endif /* ?__686 */
+
+#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+ xorb (%esi), %al ;/* c ^= *buf */\
+ incl %esi ;/* buf++ */\
+ Do_CRC
+
+#define Do_CRC_byteof(ofs) /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+ xorb ofs(%esi), %al ;/* c ^= *buf */\
+ incl %esi ;/* buf++ */\
+ Do_CRC
+
+#ifndef NO_32_BIT_LOADS
+# ifdef IZ_CRCOPTIM_UNFOLDTBL
+ /* the edx register is needed in crc calculation */
+# define SavLen arg3
+# define UpdCRC_lword \
+ movzbl %al, %ebx ; \
+ movl 3072(%edi,%ebx,4), %edx ; \
+ movzbl %ah, %ebx ; \
+ shrl $16, %eax ; \
+ xor 2048(%edi,%ebx,4), %edx ; \
+ movzbl %al, %ebx ; \
+ shrl $8,%eax ; \
+ xorl 1024(%edi,%ebx,4), %edx ; \
+ movl (%edi,%eax,4), %eax ; \
+ xorl %edx,%eax ;
+# define UpdCRC_lword_sh(dwPtrIncr) \
+ movzbl %al, %ebx ; \
+ movl 3072(%edi,%ebx,4), %edx ; \
+ movzbl %ah, %ebx ; \
+ shrl $16, %eax ; \
+ xor 2048(%edi,%ebx,4), %edx ; \
+ movzbl %al, %ebx ; \
+ addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)+=dwPtrIncr */\
+ shrl $8,%eax ; \
+ xorl 1024(%edi,%ebx,4), %edx ; \
+ movl (%edi,%eax,4),%eax ; \
+ xorl %edx,%eax ;
+# else /* !IZ_CRCOPTIM_UNFOLDTBL */
+ /* the edx register is not needed anywhere else */
+# define SavLen %edx
+# define UpdCRC_lword \
+ Do_CRC \
+ Do_CRC \
+ Do_CRC \
+ Do_CRC
+# define UpdCRC_lword_sh(dwPtrIncr) \
+ Do_CRC \
+ Do_CRC \
+ addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)++ */\
+ Do_CRC \
+ Do_CRC
+# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+#define Do_CRC_lword \
+ xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
+ UpdCRC_lword_sh(1) /* ... ((ulg *)buf)++ */
+#define Do_CRC_4lword \
+ xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
+ UpdCRC_lword \
+ xorl 4(%esi), %eax ;/* c ^= *((ulg *)buf+1) */\
+ UpdCRC_lword \
+ xorl 8(%esi), %eax ;/* c ^= *((ulg *)buf+2) */\
+ UpdCRC_lword \
+ xorl 12(%esi), %eax ;/* c ^= *((ulg *)buf]+3 */\
+ UpdCRC_lword_sh(4) /* ... ((ulg *)buf)+=4 */
+#endif /* !NO_32_BIT_LOADS */
+
+
+ .text
+
+ .globl _crc32
+
+_crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */
+ _STD_ENTRY
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %edx
+ pushl %ecx
+
+ movl arg2, %esi /* 2nd arg: uch *buf */
+ subl %eax, %eax /* > if (!buf) */
+ testl %esi, %esi /* > return 0; */
+ jz .L_fine /* > else { */
+ call _get_crc_table
+ movl %eax, %edi
+ movl arg1, %eax /* 1st arg: ulg crc */
+#ifndef __686
+ subl %ebx, %ebx /* ebx=0; bl usable as dword */
+#endif
+ movl arg3, %ecx /* 3rd arg: extent len */
+ notl %eax /* > c = ~crc; */
+
+ testl %ecx, %ecx
+#ifndef NO_UNROLLED_LOOPS
+ jz .L_bail
+# ifndef NO_32_BIT_LOADS
+ /* Assert now have positive length */
+.L_align_loop:
+ testl $3, %esi /* Align buf on lword boundary */
+ jz .L_aligned_now
+ Do_CRC_byte
+ decl %ecx
+ jnz .L_align_loop
+.L_aligned_now:
+# endif /* !NO_32_BIT_LOADS */
+ movl %ecx, SavLen /* save current value of len */
+ shrl $4, %ecx /* ecx = len / 16 */
+ jz .L_No_Sixteens
+/* align loop head at start of 486 internal cache line !! */
+ ALIGNMENT
+.L_Next_Sixteen:
+# ifndef NO_32_BIT_LOADS
+ Do_CRC_4lword
+# else /* NO_32_BIT_LOADS */
+ Do_CRC_byteof(0)
+ Do_CRC_byteof(1)
+ Do_CRC_byteof(2)
+ Do_CRC_byteof(3)
+ Do_CRC_byteof(4)
+ Do_CRC_byteof(5)
+ Do_CRC_byteof(6)
+ Do_CRC_byteof(7)
+ Do_CRC_byteof(8)
+ Do_CRC_byteof(9)
+ Do_CRC_byteof(10)
+ Do_CRC_byteof(11)
+ Do_CRC_byteof(12)
+ Do_CRC_byteof(13)
+ Do_CRC_byteof(14)
+ Do_CRC_byteof(15)
+ addl $16,%esi ;/* buf += 16 */
+# endif /* ?NO_32_BIT_LOADS */
+ decl %ecx
+ jnz .L_Next_Sixteen
+
+.L_No_Sixteens:
+ movl SavLen, %ecx
+ andl $15, %ecx /* ecx = len % 16 */
+# ifndef NO_32_BIT_LOADS
+ shrl $2,%ecx /* ecx = len / 4 */
+ jz .L_No_Fours
+.L_Next_Four:
+ Do_CRC_lword
+ decl %ecx
+ jnz .L_Next_Four
+.L_No_Fours:
+ movl SavLen,%ecx
+ andl $3,%ecx /* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
+#endif /* !NO_UNROLLED_LOOPS */
+ jz .L_bail /* > if (len) */
+/* align loop head at start of 486 internal cache line !! */
+ ALIGNMENT
+.L_loupe: /* > do { */
+ Do_CRC_byte /* c = CRC32(c,*buf++,crctab);*/
+ decl %ecx /* > } while (--len); */
+ jnz .L_loupe
+
+.L_bail: /* > } */
+ notl %eax /* > return ~c; */
+.L_fine:
+ popl %ecx
+ popl %edx
+ popl %ebx
+ popl %esi
+ popl %edi
+ _STD_LEAVE
+ ret
+
+#else
+ error: this asm version is for 386 only
+#endif /* i386 || _i386 || _I386 || __i386 */
+
+#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: zip/create-3.0-exec-shield-patch/zip30-new/match.S
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new/match.S (nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new/match.S (revision 5)
@@ -0,0 +1,410 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+
+/*
+ * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel.
+ * The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
+ * with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
+ * Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
+ * Kristoffer Eriksson <ske@pkmab.se>
+ */
+
+/* This file is NOT used in conjunction with zlib. */
+#ifndef USE_ZLIB
+
+/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
+ * external symbols with an underline character '_'.
+ */
+#if defined(NO_UNDERLINE) || defined(__ELF__)
+# define _prev prev
+# define _window window
+# define _match_start match_start
+# define _prev_length prev_length
+# define _good_match good_match
+# define _nice_match nice_match
+# define _strstart strstart
+# define _max_chain_length max_chain_length
+
+# define _match_init match_init
+# define _longest_match longest_match
+#endif
+
+#ifdef DYN_ALLOC
+ error: DYN_ALLOC not yet supported in match.s
+#endif
+
+/* Use 16-bytes alignment if your assembler supports it. Warning: gas
+ * uses a log(x) parameter (.align 4 means 16-bytes alignment). On SVR4
+ * the parameter is a number of bytes.
+ */
+#ifndef ALIGNMENT
+# define ALIGNMENT 4
+#endif
+
+
+#ifndef WSIZE
+# define WSIZE 32768
+#endif
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_DIST (WSIZE - MIN_LOOKAHEAD)
+
+#if defined(i386) || defined(_I386) || defined(_i386) || defined(__i386)
+
+/* This version is for 386 Unix or OS/2 in 32 bit mode.
+ * Warning: it uses the AT&T syntax: mov source,dest
+ * This file is only optional. If you want to force the C version,
+ * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
+ * If you have reduced WSIZE in (g)zip.h, then make sure this is
+ * assembled with an equivalent -DWSIZE=<whatever>.
+ * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
+ */
+
+ .file "match.S"
+
+ .globl _match_init
+ .globl _longest_match
+
+ .text
+
+_match_init:
+ ret
+
+/*-----------------------------------------------------------------------
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+
+ .align ALIGNMENT
+
+_longest_match: /* int longest_match(cur_match) */
+
+#define cur_match 20(%esp)
+ /* return address */ /* esp+16 */
+ push %ebp /* esp+12 */
+ push %edi /* esp+8 */
+ push %esi /* esp+4 */
+ push %ebx /* esp */
+
+/*
+ * match equ esi
+ * scan equ edi
+ * chain_length equ ebp
+ * best_len equ ebx
+ * limit equ edx
+ */
+ mov cur_match,%esi
+ mov _strstart,%edx
+ mov _max_chain_length,%ebp /* chain_length = max_chain_length */
+ mov %edx,%edi
+ sub $(MAX_DIST),%edx /* limit = strstart-MAX_DIST */
+ cld /* string ops increment si and di */
+ jae limit_ok
+ sub %edx,%edx /* limit = NIL */
+limit_ok:
+ add $2+_window,%edi /* edi = offset(window+strstart+2) */
+ mov _prev_length,%ebx /* best_len = prev_length */
+ movw -2(%edi),%cx /* cx = scan[0..1] */
+ movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
+ cmp _good_match,%ebx /* do we have a good match already? */
+ jb do_scan
+ shr $2,%ebp /* chain_length >>= 2 */
+ jmp do_scan
+
+ .align ALIGNMENT
+long_loop:
+/* at this point, edi == scan+2, esi == cur_match */
+ movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
+ movw -2(%edi),%cx /* cx = scan[0..1] */
+short_loop:
+/*
+ * at this point, di == scan+2, si == cur_match,
+ * ax = scan[best_len-1..best_len] and cx = scan[0..1]
+ */
+ and $(WSIZE-1), %esi
+ dec %ebp /* --chain_length */
+ movw _prev(,%esi,2),%si /* cur_match = prev[cur_match] */
+ /* top word of esi is still 0 */
+ jz the_end
+ cmp %edx,%esi /* cur_match <= limit ? */
+ jbe the_end
+do_scan:
+ cmpw _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
+ jne short_loop
+ cmpw _window(%esi),%cx /* check min_match_length match */
+ jne short_loop
+
+ add $2+_window,%esi /* si = match */
+ mov $((MAX_MATCH>>1)-1),%ecx/* scan for at most MAX_MATCH bytes */
+ mov %edi,%eax /* ax = scan+2 */
+ repe; cmpsw /* loop until mismatch */
+ je maxmatch /* match of length MAX_MATCH? */
+mismatch:
+ movb -2(%edi),%cl /* mismatch on first or second byte? */
+ xchg %edi,%eax /* edi = scan+2, eax = end of scan */
+ subb -2(%esi),%cl /* cl = 0 if first bytes equal */
+ sub %edi,%eax /* eax = len */
+ sub $2+_window,%esi /* esi = cur_match + len */
+ sub %eax,%esi /* esi = cur_match */
+ subb $1,%cl /* set carry if cl == 0 (cannot use DEC) */
+ adc $0,%eax /* eax = carry ? len+1 : len */
+ cmp %ebx,%eax /* len > best_len ? */
+ jle long_loop
+ mov %esi,_match_start /* match_start = cur_match */
+ mov %eax,%ebx /* ebx = best_len = len */
+#ifdef FULL_SEARCH
+ cmp $(MAX_MATCH),%eax /* len >= MAX_MATCH ? */
+#else
+ cmp _nice_match,%eax /* len >= nice_match ? */
+#endif
+ jl long_loop
+the_end:
+ mov %ebx,%eax /* result = eax = best_len */
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+ .align ALIGNMENT
+maxmatch:
+ cmpsb
+ jmp mismatch
+
+#else /* !(i386 || _I386 || _i386 || __i386) */
+
+/* ======================== 680x0 version ================================= */
+
+#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
+# ifndef mc68000
+# define mc68000
+# endif
+#endif
+
+#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
+# ifndef mc68020
+# define mc68020
+# endif
+#endif
+
+#if defined(mc68020) || defined(mc68000)
+
+#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
+# define UNALIGNED_OK
+#endif
+
+#ifdef sysV68 /* Try Motorola Delta style */
+
+# define GLOBAL(symbol) global symbol
+# define TEXT text
+# define FILE(filename) file filename
+# define invert_maybe(src,dst) dst,src
+# define imm(data) &data
+# define reg(register) %register
+
+# define addl add.l
+# define addql addq.l
+# define blos blo.b
+# define bhis bhi.b
+# define bras bra.b
+# define clrl clr.l
+# define cmpmb cmpm.b
+# define cmpw cmp.w
+# define cmpl cmp.l
+# define lslw lsl.w
+# define lsrl lsr.l
+# define movel move.l
+# define movew move.w
+# define moveb move.b
+# define moveml movem.l
+# define subl sub.l
+# define subw sub.w
+# define subql subq.l
+
+# define IndBase(bd,An) (bd,An)
+# define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
+# define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
+# define predec(An) -(An)
+# define postinc(An) (An)+
+
+#else /* default style (Sun 3, NeXT, Amiga, Atari) */
+
+# define GLOBAL(symbol) .globl symbol
+# define TEXT .text
+# define FILE(filename) .even
+# define invert_maybe(src,dst) src,dst
+# if defined(sun) || defined(mc68k)
+# define imm(data) #data
+# else
+# define imm(data) \#data
+# endif
+# define reg(register) register
+
+# define blos bcss
+# if defined(sun) || defined(mc68k)
+# define movel movl
+# define movew movw
+# define moveb movb
+# endif
+# define IndBase(bd,An) An@(bd)
+# define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l)
+# define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w)
+# define predec(An) An@-
+# define postinc(An) An@+
+
+#endif /* styles */
+
+#define Best_Len reg(d0) /* unsigned */
+#define Cur_Match reg(d1) /* Ipos */
+#define Loop_Counter reg(d2) /* int */
+#define Scan_Start reg(d3) /* unsigned short */
+#define Scan_End reg(d4) /* unsigned short */
+#define Limit reg(d5) /* IPos */
+#define Chain_Length reg(d6) /* unsigned */
+#define Scan_Test reg(d7)
+#define Scan reg(a0) /* *uch */
+#define Match reg(a1) /* *uch */
+#define Prev_Address reg(a2) /* *Pos */
+#define Scan_Ini reg(a3) /* *uch */
+#define Match_Ini reg(a4) /* *uch */
+#define Stack_Pointer reg(sp)
+
+ GLOBAL (_match_init)
+ GLOBAL (_longest_match)
+
+ TEXT
+
+ FILE ("match.S")
+
+_match_init:
+ rts
+
+/*-----------------------------------------------------------------------
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+
+/* int longest_match (cur_match) */
+
+#ifdef UNALIGNED_OK
+# define pushreg 15928 /* d2-d6/a2-a4 */
+# define popreg 7292
+#else
+# define pushreg 16184 /* d2-d7/a2-a4 */
+# define popreg 7420
+#endif
+
+_longest_match:
+ movel IndBase(4,Stack_Pointer),Cur_Match
+ moveml imm(pushreg),predec(Stack_Pointer)
+ movel _max_chain_length,Chain_Length
+ movel _prev_length,Best_Len
+ movel imm(_prev),Prev_Address
+ movel imm(_window+MIN_MATCH),Match_Ini
+ movel _strstart,Limit
+ movel Match_Ini,Scan_Ini
+ addl Limit,Scan_Ini
+ subw imm(MAX_DIST),Limit
+ bhis L__limit_ok
+ clrl Limit
+L__limit_ok:
+ cmpl invert_maybe(_good_match,Best_Len)
+ blos L__length_ok
+ lsrl imm(2),Chain_Length
+L__length_ok:
+ subql imm(1),Chain_Length
+#ifdef UNALIGNED_OK
+ movew IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+ movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+#else
+ moveb IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
+ lslw imm(8),Scan_Start
+ moveb IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start
+ moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+ lslw imm(8),Scan_End
+ moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+#endif
+ bras L__do_scan
+
+L__long_loop:
+#ifdef UNALIGNED_OK
+ movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+#else
+ moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
+ lslw imm(8),Scan_End
+ moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
+#endif
+
+L__short_loop:
+ lslw imm(1),Cur_Match
+ movew IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match
+ cmpw invert_maybe(Limit,Cur_Match)
+ dbls Chain_Length,L__do_scan
+ bras L__return
+
+L__do_scan:
+ movel Match_Ini,Match
+ addl Cur_Match,Match
+#ifdef UNALIGNED_OK
+ cmpw invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End)
+ bne L__short_loop
+ cmpw invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start)
+ bne L__short_loop
+#else
+ moveb IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test
+ lslw imm(8),Scan_Test
+ moveb IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test
+ cmpw invert_maybe(Scan_Test,Scan_End)
+ bne L__short_loop
+ moveb IndBase(-MIN_MATCH,Match),Scan_Test
+ lslw imm(8),Scan_Test
+ moveb IndBase(-MIN_MATCH+1,Match),Scan_Test
+ cmpw invert_maybe(Scan_Test,Scan_Start)
+ bne L__short_loop
+#endif
+
+ movew imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter
+ movel Scan_Ini,Scan
+L__scan_loop:
+ cmpmb postinc(Match),postinc(Scan)
+ dbne Loop_Counter,L__scan_loop
+
+ subl Scan_Ini,Scan
+ addql imm(MIN_MATCH-1),Scan
+ cmpl invert_maybe(Best_Len,Scan)
+ bls L__short_loop
+ movel Scan,Best_Len
+ movel Cur_Match,_match_start
+#ifdef FULL_SEARCH
+ cmpl invert_maybe(imm(MAX_MATCH),Best_Len)
+#else
+ cmpl invert_maybe(_nice_match,Best_Len)
+#endif
+ blos L__long_loop
+L__return:
+ moveml postinc(Stack_Pointer),imm(popreg)
+ rts
+
+#else
+ error: this asm version is for 386 or 680x0 only
+#endif /* mc68000 || mc68020 */
+#endif /* i386 || _I386 || _i386 || __i386 */
+
+#endif /* !USE_ZLIB */
+
+.section .note.GNU-stack, "", @progbits
+.previous
Index: zip/create-3.0-exec-shield-patch/zip30-new
===================================================================
--- zip/create-3.0-exec-shield-patch/zip30-new (nonexistent)
+++ zip/create-3.0-exec-shield-patch/zip30-new (revision 5)
Property changes on: zip/create-3.0-exec-shield-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-exec-shield-patch
===================================================================
--- zip/create-3.0-exec-shield-patch (nonexistent)
+++ zip/create-3.0-exec-shield-patch (revision 5)
Property changes on: zip/create-3.0-exec-shield-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-format-security-patch/create.patch.sh
===================================================================
--- zip/create-3.0-format-security-patch/create.patch.sh (nonexistent)
+++ zip/create-3.0-format-security-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr zip${version}-orig zip${version} > zip-${VERSION}-format-security.patch
+
+mv zip-${VERSION}-format-security.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig
Property changes on: zip/create-3.0-format-security-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-format-security-patch/file.list
===================================================================
--- zip/create-3.0-format-security-patch/file.list (nonexistent)
+++ zip/create-3.0-format-security-patch/file.list (revision 5)
@@ -0,0 +1 @@
+zip30/zip.c
Index: zip/create-3.0-format-security-patch/zip30-new/zip.c
===================================================================
--- zip/create-3.0-format-security-patch/zip30-new/zip.c (nonexistent)
+++ zip/create-3.0-format-security-patch/zip30-new/zip.c (revision 5)
@@ -0,0 +1,6018 @@
+/*
+ zip.c - Zip 3
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * zip.c by Mark Adler.
+ */
+#define __ZIP_C
+
+#include "zip.h"
+#include <time.h> /* for tzset() declaration */
+#if defined(WIN32) || defined(WINDLL)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+#ifdef WINDLL
+# include <setjmp.h>
+# include "windll/windll.h"
+#endif
+#define DEFCPYRT /* main module: enable copyright string defines! */
+#include "revision.h"
+#include "crc32.h"
+#include "crypt.h"
+#include "ttyio.h"
+#include <ctype.h>
+#include <errno.h>
+#ifdef VMS
+# include <stsdef.h>
+# include "vms/vmsmunch.h"
+# include "vms/vms.h"
+#endif
+
+#ifdef MACOS
+# include "macglob.h"
+ extern MacZipGlobals MacZip;
+ extern int error_level;
+#endif
+
+#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
+# include <process.h>
+# if (!defined(P_WAIT) && defined(_P_WAIT))
+# define P_WAIT _P_WAIT
+# endif
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef UNICODE_TEST
+# ifdef WIN32
+# include <direct.h>
+# endif
+#endif
+
+#ifdef BZIP2_SUPPORT
+ /* If IZ_BZIP2 is defined as the location of the bzip2 files then
+ assume the location has been added to include path. For Unix
+ this is done by the configure script. */
+ /* Also do not need path for bzip2 include if OS includes support
+ for bzip2 library. */
+# include "bzlib.h"
+#endif
+
+#define MAXCOM 256 /* Maximum one-line comment size */
+
+
+/* Local option flags */
+#ifndef DELETE
+#define DELETE 0
+#endif
+#define ADD 1
+#define UPDATE 2
+#define FRESHEN 3
+#define ARCHIVE 4
+local int action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
+local int comadd = 0; /* 1=add comments for new files */
+local int zipedit = 0; /* 1=edit zip comment and all file comments */
+local int latest = 0; /* 1=set zip file time to time of latest file */
+local int test = 0; /* 1=test zip file with unzip -t */
+local char *unzip_path = NULL; /* where to find unzip */
+local int tempdir = 0; /* 1=use temp directory (-b) */
+local int junk_sfx = 0; /* 1=junk the sfx prefix */
+#if defined(AMIGA) || defined(MACOS)
+local int filenotes = 0; /* 1=take comments from AmigaDOS/MACOS filenotes */
+#endif
+
+#ifdef EBCDIC
+int aflag = __EBCDIC; /* Convert EBCDIC to ASCII or stay EBCDIC ? */
+#endif
+#ifdef CMS_MVS
+int bflag = 0; /* Use text mode as default */
+#endif
+
+#ifdef QDOS
+char _version[] = VERSION;
+#endif
+
+#ifdef WINDLL
+jmp_buf zipdll_error_return;
+#ifdef ZIP64_SUPPORT
+ unsigned long low, high; /* returning 64 bit values for systems without an _int64 */
+ uzoff_t filesize64;
+#endif
+#endif
+
+#if CRYPT
+/* Pointer to crc_table, needed in crypt.c */
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ZCONST ulg near *crc_32_tab;
+# else
+ZCONST uLongf *crc_32_tab;
+# endif
+#endif /* CRYPT */
+
+/* Local functions */
+
+local void freeup OF((void));
+local int finish OF((int));
+#if (!defined(MACOS) && !defined(WINDLL))
+local void handler OF((int));
+local void license OF((void));
+#ifndef VMSCLI
+local void help OF((void));
+local void help_extended OF((void));
+#endif /* !VMSCLI */
+#endif /* !MACOS && !WINDLL */
+
+/* prereading of arguments is not supported in new command
+ line interpreter get_option() so read filters as arguments
+ are processed and convert to expected array later */
+local int add_filter OF((int flag, char *pattern));
+local int filterlist_to_patterns OF((void));
+/* not used
+ local int get_filters OF((int argc, char **argv));
+*/
+
+/* list to store file arguments */
+local long add_name OF((char *filearg));
+
+
+local int DisplayRunningStats OF((void));
+local int BlankRunningStats OF((void));
+
+#if !defined(WINDLL)
+local void version_info OF((void));
+# if !defined(MACOS)
+local void zipstdout OF((void));
+# endif /* !MACOS */
+local int check_unzip_version OF((char *unzippath));
+local void check_zipfile OF((char *zipname, char *zippath));
+#endif /* !WINDLL */
+
+/* structure used by add_filter to store filters */
+struct filterlist_struct {
+ char flag;
+ char *pattern;
+ struct filterlist_struct *next;
+};
+struct filterlist_struct *filterlist = NULL; /* start of list */
+struct filterlist_struct *lastfilter = NULL; /* last filter in list */
+
+/* structure used by add_filearg to store file arguments */
+struct filelist_struct {
+ char *name;
+ struct filelist_struct *next;
+};
+long filearg_count = 0;
+struct filelist_struct *filelist = NULL; /* start of list */
+struct filelist_struct *lastfile = NULL; /* last file in list */
+
+local void freeup()
+/* Free all allocations in the 'found' list, the 'zfiles' list and
+ the 'patterns' list. */
+{
+ struct flist far *f; /* steps through found list */
+ struct zlist far *z; /* pointer to next entry in zfiles list */
+
+ for (f = found; f != NULL; f = fexpel(f))
+ ;
+ while (zfiles != NULL)
+ {
+ z = zfiles->nxt;
+ if (zfiles->zname && zfiles->zname != zfiles->name)
+ free((zvoid *)(zfiles->zname));
+ if (zfiles->name)
+ free((zvoid *)(zfiles->name));
+ if (zfiles->iname)
+ free((zvoid *)(zfiles->iname));
+ if (zfiles->cext && zfiles->cextra && zfiles->cextra != zfiles->extra)
+ free((zvoid *)(zfiles->cextra));
+ if (zfiles->ext && zfiles->extra)
+ free((zvoid *)(zfiles->extra));
+ if (zfiles->com && zfiles->comment)
+ free((zvoid *)(zfiles->comment));
+ if (zfiles->oname)
+ free((zvoid *)(zfiles->oname));
+#ifdef UNICODE_SUPPORT
+ if (zfiles->uname)
+ free((zvoid *)(zfiles->uname));
+ if (zfiles->zuname)
+ free((zvoid *)(zfiles->zuname));
+ if (zfiles->ouname)
+ free((zvoid *)(zfiles->ouname));
+# ifdef WIN32
+ if (zfiles->namew)
+ free((zvoid *)(zfiles->namew));
+ if (zfiles->inamew)
+ free((zvoid *)(zfiles->inamew));
+ if (zfiles->znamew)
+ free((zvoid *)(zfiles->znamew));
+# endif
+#endif
+ farfree((zvoid far *)zfiles);
+ zfiles = z;
+ zcount--;
+ }
+
+ if (patterns != NULL) {
+ while (pcount-- > 0) {
+ if (patterns[pcount].zname != NULL)
+ free((zvoid *)(patterns[pcount].zname));
+ }
+ free((zvoid *)patterns);
+ patterns = NULL;
+ }
+
+ /* close logfile */
+ if (logfile) {
+ fclose(logfile);
+ }
+}
+
+local int finish(e)
+int e; /* exit code */
+/* Process -o and -m options (if specified), free up malloc'ed stuff, and
+ exit with the code e. */
+{
+ int r; /* return value from trash() */
+ ulg t; /* latest time in zip file */
+ struct zlist far *z; /* pointer into zfile list */
+
+ /* If latest, set time to zip file to latest file in zip file */
+ if (latest && zipfile && strcmp(zipfile, "-"))
+ {
+ diag("changing time of zip file to time of latest file in it");
+ /* find latest time in zip file */
+ if (zfiles == NULL)
+ zipwarn("zip file is empty, can't make it as old as latest entry", "");
+ else {
+ t = 0;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ /* Ignore directories in time comparisons */
+#ifdef USE_EF_UT_TIME
+ if (z->iname[z->nam-1] != (char)0x2f) /* ascii '/' */
+ {
+ iztimes z_utim;
+ ulg z_tim;
+
+ z_tim = ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ unix2dostime(&z_utim.mtime) : z->tim);
+ if (t < z_tim)
+ t = z_tim;
+ }
+#else /* !USE_EF_UT_TIME */
+ if (z->iname[z->nam-1] != (char)0x2f /* ascii '/' */
+ && t < z->tim)
+ t = z->tim;
+#endif /* ?USE_EF_UT_TIME */
+ /* set modified time of zip file to that time */
+ if (t != 0)
+ stamp(zipfile, t);
+ else
+ zipwarn(
+ "zip file has only directories, can't make it as old as latest entry",
+ "");
+ }
+ }
+ if (tempath != NULL)
+ {
+ free((zvoid *)tempath);
+ tempath = NULL;
+ }
+ if (zipfile != NULL)
+ {
+ free((zvoid *)zipfile);
+ zipfile = NULL;
+ }
+ if (in_file != NULL)
+ {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ if (in_path != NULL)
+ {
+ free((zvoid *)in_path);
+ in_path = NULL;
+ }
+ if (out_path != NULL)
+ {
+ free((zvoid *)out_path);
+ out_path = NULL;
+ }
+ if (zcomment != NULL)
+ {
+ free((zvoid *)zcomment);
+ zcomment = NULL;
+ }
+
+
+ /* If dispose, delete all files in the zfiles list that are marked */
+ if (dispose)
+ {
+ diag("deleting files that were added to zip file");
+ if ((r = trash()) != ZE_OK)
+ ZIPERR(r, "was deleting moved files and directories");
+ }
+
+
+ /* Done! */
+ freeup();
+ return e;
+}
+
+void ziperr(c, h)
+int c; /* error code from the ZE_ class */
+ZCONST char *h; /* message about how it happened */
+/* Issue a message for the error, clean up files and memory, and exit. */
+{
+#ifndef WINDLL
+#ifndef MACOS
+ static int error_level = 0;
+#endif
+
+ if (error_level++ > 0)
+ /* avoid recursive ziperr() printouts (his should never happen) */
+ EXIT(ZE_LOGIC); /* ziperr recursion is an internal logic error! */
+#endif /* !WINDLL */
+
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logfile && logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ if (h != NULL) {
+ if (PERR(c))
+ fprintf(mesg, "zip I/O error: %s", strerror(errno));
+ /* perror("zip I/O error"); */
+ fflush(mesg);
+ fprintf(mesg, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
+ if (logfile) {
+ if (PERR(c))
+ fprintf(logfile, "zip I/O error: %s\n", strerror(errno));
+ fprintf(logfile, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+ logfile_line_started = 0;
+ }
+ }
+ if (tempzip != NULL)
+ {
+ if (tempzip != zipfile) {
+ if (current_local_file)
+ fclose(current_local_file);
+ if (y != current_local_file && y != NULL)
+ fclose(y);
+#ifndef DEBUG
+ destroy(tempzip);
+#endif
+ free((zvoid *)tempzip);
+ } else {
+ /* -g option, attempt to restore the old file */
+
+ /* zip64 support 09/05/2003 R.Nausedat */
+ uzoff_t k = 0; /* keep count for end header */
+ uzoff_t cb = cenbeg; /* get start of central */
+
+ struct zlist far *z; /* steps through zfiles linked list */
+
+ fprintf(mesg, "attempting to restore %s to its previous state\n",
+ zipfile);
+ if (logfile)
+ fprintf(logfile, "attempting to restore %s to its previous state\n",
+ zipfile);
+
+ zfseeko(y, cenbeg, SEEK_SET);
+
+ tempzn = cenbeg;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+ putcentral(z);
+ tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+ k++;
+ }
+ putend(k, tempzn - cb, cb, zcomlen, zcomment);
+ fclose(y);
+ y = NULL;
+ }
+ }
+
+ if (key != NULL) {
+ free((zvoid *)key);
+ key = NULL;
+ }
+ if (tempath != NULL) {
+ free((zvoid *)tempath);
+ tempath = NULL;
+ }
+ if (zipfile != NULL) {
+ free((zvoid *)zipfile);
+ zipfile = NULL;
+ }
+ if (out_path != NULL) {
+ free((zvoid *)out_path);
+ out_path = NULL;
+ }
+ if (zcomment != NULL) {
+ free((zvoid *)zcomment);
+ zcomment = NULL;
+ }
+
+ freeup();
+#ifndef WINDLL
+ EXIT(c);
+#else
+ longjmp(zipdll_error_return, c);
+#endif
+}
+
+
+void error(h)
+ ZCONST char *h;
+/* Internal error, should never happen */
+{
+ ziperr(ZE_LOGIC, h);
+}
+
+#if (!defined(MACOS) && !defined(WINDLL))
+local void handler(s)
+int s; /* signal number (ignored) */
+/* Upon getting a user interrupt, turn echo back on for tty and abort
+ cleanly using ziperr(). */
+{
+#if defined(AMIGA) && defined(__SASC)
+ _abort();
+#else
+#if !defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS)
+ echon();
+ putc('\n', mesg);
+#endif /* !MSDOS */
+#endif /* AMIGA && __SASC */
+ ziperr(ZE_ABORT, "aborting");
+ s++; /* keep some compilers happy */
+}
+#endif /* !MACOS && !WINDLL */
+
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. If logfile is
+ open then also write message to log file. */
+{
+ if (noisy) {
+ if (a && strlen(a)) {
+ fprintf(mesg, "%s", a);
+ mesg_line_started = 1;
+ }
+ if (nl) {
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ } else if (a && strlen(a)) {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (a && strlen(a)) {
+ fprintf(logfile, "%s", a);
+ logfile_line_started = 1;
+ }
+ if (nl) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ } else if (a && strlen(a)) {
+ logfile_line_started = 1;
+ }
+ fflush(logfile);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Also write to log file if
+ open. Write new line first if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (logfile_line_started)
+ fprintf(logfile, "\n");
+ fprintf(logfile, "%s%s\n", a, b);
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+}
+
+void zipwarn(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a warning message to mesg (usually stderr) and return. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "\tzip warning: %s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (logfile_line_started)
+ fprintf(logfile, "\n");
+ fprintf(logfile, "\tzip warning: %s%s\n", a, b);
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+}
+
+#ifndef WINDLL
+local void license()
+/* Print license information to stdout. */
+{
+ extent i; /* counter for copyright array */
+
+ for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
+ puts(swlicense[i]);
+}
+
+#ifdef VMSCLI
+void help()
+#else
+local void help()
+#endif
+/* Print help (along with license info) to stdout. */
+{
+ extent i; /* counter for help array */
+
+ /* help array */
+ static ZCONST char *text[] = {
+#ifdef VMS
+"Zip %s (%s). Usage: zip == \"$ disk:[dir]zip.exe\"",
+#else
+"Zip %s (%s). Usage:",
+#endif
+#ifdef MACOS
+"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+" The default action is to add or replace zipfile entries from list.",
+" ",
+" -f freshen: only changed files -u update: only changed or new files",
+" -d delete entries in zipfile -m move into zipfile (delete OS files)",
+" -r recurse into directories -j junk (don't record) directory names",
+" -0 store only -l convert LF to CR LF (-ll CR LF to LF)",
+" -1 compress faster -9 compress better",
+" -q quiet operation -v verbose operation/print version info",
+" -c add one-line comments -z add zipfile comment",
+" -o make zipfile as old as latest entry",
+" -F fix zipfile (-FF try harder) -D do not add directory entries",
+" -T test zipfile integrity -X eXclude eXtra file attributes",
+# if CRYPT
+" -e encrypt -n don't compress these suffixes"
+# else
+" -h show this help -n don't compress these suffixes"
+# endif
+," -h2 show more help",
+" Macintosh specific:",
+" -jj record Fullpath (+ Volname) -N store finder-comments as comments",
+" -df zip only datafork of a file -S include finder invisible/system files"
+#else /* !MACOS */
+#ifdef VM_CMS
+"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+#else /* !VM_CMS */
+"zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",
+#endif /* ?VM_CMS */
+" The default action is to add or replace zipfile entries from list, which",
+" can include the special name - to compress standard input.",
+" If zipfile and list are omitted, zip compresses stdin to stdout.",
+" -f freshen: only changed files -u update: only changed or new files",
+" -d delete entries in zipfile -m move into zipfile (delete OS files)",
+" -r recurse into directories -j junk (don't record) directory names",
+#ifdef THEOS
+" -0 store only -l convert CR to CR LF (-ll CR LF to CR)",
+#else
+" -0 store only -l convert LF to CR LF (-ll CR LF to LF)",
+#endif
+" -1 compress faster -9 compress better",
+" -q quiet operation -v verbose operation/print version info",
+" -c add one-line comments -z add zipfile comment",
+" -@ read names from stdin -o make zipfile as old as latest entry",
+" -x exclude the following names -i include only the following names",
+#ifdef EBCDIC
+#ifdef CMS_MVS
+" -a translate to ASCII -B force binary read (text is default)",
+#else /* !CMS_MVS */
+" -a translate to ASCII",
+#endif /* ?CMS_MVS */
+#endif /* EBCDIC */
+#ifdef TANDEM
+" -Bn set Enscribe formatting options",
+#endif
+" -F fix zipfile (-FF try harder) -D do not add directory entries",
+" -A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)",
+" -T test zipfile integrity -X eXclude eXtra file attributes",
+#ifdef VMS
+" -C preserve case of file names -C- down-case all file names",
+" -C2 preserve case of ODS2 names -C2- down-case ODS2 file names* (*=default)",
+" -C5 preserve case of ODS5 names* -C5- down-case ODS5 file names",
+" -V save VMS file attributes (-VV also save allocated blocks past EOF)",
+" -w store file version numbers\
+ -ww store file version numbers as \".nnn\"",
+#endif /* def VMS */
+#ifdef NTSD_EAS
+" -! use privileges (if granted) to obtain all aspects of WinNT security",
+#endif /* NTSD_EAS */
+#ifdef OS2
+" -E use the .LONGNAME Extended attribute (if found) as filename",
+#endif /* OS2 */
+#ifdef S_IFLNK
+" -y store symbolic links as the link instead of the referenced file",
+#endif /* !S_IFLNK */
+/*
+" -R PKZIP recursion (see manual)",
+*/
+#if defined(MSDOS) || defined(OS2)
+" -$ include volume label -S include system and hidden files",
+#endif
+#ifdef AMIGA
+# if CRYPT
+" -N store filenotes as comments -e encrypt",
+" -h show this help -n don't compress these suffixes"
+# else
+" -N store filenotes as comments -n don't compress these suffixes"
+# endif
+#else /* !AMIGA */
+# if CRYPT
+" -e encrypt -n don't compress these suffixes"
+# else
+" -h show this help -n don't compress these suffixes"
+# endif
+#endif /* ?AMIGA */
+#ifdef RISCOS
+," -h2 show more help -I don't scan thru Image files"
+#else
+," -h2 show more help"
+#endif
+#endif /* ?MACOS */
+#ifdef VMS
+," (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND)"
+#endif /* def VMS */
+," "
+ };
+
+ for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+ {
+ printf(copyright[i], "zip");
+ putchar('\n');
+ }
+ for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+ {
+ printf(text[i], VERSION, REVDATE);
+ putchar('\n');
+ }
+}
+
+#ifdef VMSCLI
+void help_extended()
+#else
+local void help_extended()
+#endif
+/* Print extended help to stdout. */
+{
+ extent i; /* counter for help array */
+
+ /* help array */
+ static ZCONST char *text[] = {
+"",
+"Extended Help for Zip",
+"",
+"See the Zip Manual for more detailed help",
+"",
+"",
+"Zip stores files in zip archives. The default action is to add or replace",
+"zipfile entries.",
+"",
+"Basic command line:",
+" zip options archive_name file file ...",
+"",
+"Some examples:",
+" Add file.txt to z.zip (create z if needed): zip z file.txt",
+" Zip all files in current dir: zip z *",
+" Zip files in current dir and subdirs also: zip -r z .",
+"",
+"Basic modes:",
+" External modes (selects files from file system):",
+" add - add new files/update existing files in archive (default)",
+" -u update - add new files/update existing files only if later date",
+" -f freshen - update existing files only (no files added)",
+" -FS filesync - update if date or size changed, delete if no OS match",
+" Internal modes (selects entries in archive):",
+" -d delete - delete files from archive (see below)",
+" -U copy - select files in archive to copy (use with --out)",
+"",
+"Basic options:",
+" -r recurse into directories (see Recursion below)",
+" -m after archive created, delete original files (move into archive)",
+" -j junk directory names (store just file names)",
+" -q quiet operation",
+" -v verbose operation (just \"zip -v\" shows version information)",
+" -c prompt for one-line comment for each entry",
+" -z prompt for comment for archive (end with just \".\" line or EOF)",
+" -@ read names to zip from stdin (one path per line)",
+" -o make zipfile as old as latest entry",
+"",
+"",
+"Syntax:",
+" The full command line syntax is:",
+"",
+" zip [-shortopts ...] [--longopt ...] [zipfile [path path ...]] [-xi list]",
+"",
+" Any number of short option and long option arguments are allowed",
+" (within limits) as well as any number of path arguments for files",
+" to zip up. If zipfile exists, the archive is read in. If zipfile",
+" is \"-\", stream to stdout. If any path is \"-\", zip stdin.",
+"",
+"Options and Values:",
+" For short options that take values, use -ovalue or -o value or -o=value",
+" For long option values, use either --longoption=value or --longoption value",
+" For example:",
+" zip -ds 10 --temp-dir=path zipfile path1 path2 --exclude pattern pattern",
+" Avoid -ovalue (no space between) to avoid confusion",
+" In particular, be aware of 2-character options. For example:",
+" -d -s is (delete, split size) while -ds is (dot size)",
+" Usually better to break short options across multiple arguments by function",
+" zip -r -dbdcds 10m -lilalf logfile archive input_directory -ll",
+"",
+" All args after just \"--\" arg are read verbatim as paths and not options.",
+" zip zipfile path path ... -- verbatimpath verbatimpath ...",
+" Use -nw to also disable wildcards, so paths are read literally:",
+" zip zipfile -nw -- \"-leadingdashpath\" \"a[path].c\" \"path*withwildcard\"",
+" You may still have to escape or quote arguments to avoid shell expansion",
+"",
+"Wildcards:",
+" Internally zip supports the following wildcards:",
+" ? (or %% or #, depending on OS) matches any single character",
+" * matches any number of characters, including zero",
+" [list] matches char in list (regex), can do range [ac-f], all but [!bf]",
+" If port supports [], must escape [ as [[] or use -nw to turn off wildcards",
+" For shells that expand wildcards, escape (\\* or \"*\") so zip can recurse",
+" zip zipfile -r . -i \"*.h\"",
+"",
+" Normally * crosses dir bounds in path, e.g. 'a*b' can match 'ac/db'. If",
+" -ws option used, * does not cross dir bounds but ** does",
+"",
+" For DOS and Windows, [list] is now disabled unless the new option",
+" -RE enable [list] (regular expression) matching",
+" is used to avoid problems with file paths containing \"[\" and \"]\":",
+" zip files_ending_with_number -RE foo[0-9].c",
+"",
+"Include and Exclude:",
+" -i pattern pattern ... include files that match a pattern",
+" -x pattern pattern ... exclude files that match a pattern",
+" Patterns are paths with optional wildcards and match paths as stored in",
+" archive. Exclude and include lists end at next option, @, or end of line.",
+" zip -x pattern pattern @ zipfile path path ...",
+"",
+"Case matching:",
+" On most OS the case of patterns must match the case in the archive, unless",
+" the -ic option is used.",
+" -ic ignore case of archive entries",
+" This option not available on case-sensitive file systems. On others, case",
+" ignored when matching files on file system but matching against archive",
+" entries remains case sensitive for modes -f (freshen), -U (archive copy),",
+" and -d (delete) because archive paths are always case sensitive. With",
+" -ic, all matching ignores case, but it's then possible multiple archive",
+" entries that differ only in case will match.",
+"",
+"End Of Line Translation (text files only):",
+" -l change CR or LF (depending on OS) line end to CR LF (Unix->Win)",
+" -ll change CR LF to CR or LF (depending on OS) line end (Win->Unix)",
+" If first buffer read from file contains binary the translation is skipped",
+"",
+"Recursion:",
+" -r recurse paths, include files in subdirs: zip -r a path path ...",
+" -R recurse current dir and match patterns: zip -R a ptn ptn ...",
+" Use -i and -x with either to include or exclude paths",
+" Path root in archive starts at current dir, so if /a/b/c/file and",
+" current dir is /a/b, 'zip -r archive .' puts c/file in archive",
+"",
+"Date filtering:",
+" -t date exclude before (include files modified on this date and later)",
+" -tt date include before (include files modified before date)",
+" Can use both at same time to set a date range",
+" Dates are mmddyyyy or yyyy-mm-dd",
+"",
+"Deletion, File Sync:",
+" -d delete files",
+" Delete archive entries matching internal archive paths in list",
+" zip archive -d pattern pattern ...",
+" Can use -t and -tt to select files in archive, but NOT -x or -i, so",
+" zip archive -d \"*\" -t 2005-12-27",
+" deletes all files from archive.zip with date of 27 Dec 2005 and later",
+" Note the * (escape as \"*\" on Unix) to select all files in archive",
+"",
+" -FS file sync",
+" Similar to update, but files updated if date or size of entry does not",
+" match file on OS. Also deletes entry from archive if no matching file",
+" on OS.",
+" zip archive_to_update -FS -r dir_used_before",
+" Result generally same as creating new archive, but unchanged entries",
+" are copied instead of being read and compressed so can be faster.",
+" WARNING: -FS deletes entries so make backup copy of archive first",
+"",
+"Compression:",
+" -0 store files (no compression)",
+" -1 to -9 compress fastest to compress best (default is 6)",
+" -Z cm set compression method to cm:",
+" store - store without compression, same as option -0",
+" deflate - original zip deflate, same as -1 to -9 (default)",
+" if bzip2 is enabled:",
+" bzip2 - use bzip2 compression (need modern unzip)",
+"",
+"Encryption:",
+" -e use standard (weak) PKZip 2.0 encryption, prompt for password",
+" -P pswd use standard encryption, password is pswd",
+"",
+"Splits (archives created as a set of split files):",
+" -s ssize create split archive with splits of size ssize, where ssize nm",
+" n number and m multiplier (kmgt, default m), 100k -> 100 kB",
+" -sp pause after each split closed to allow changing disks",
+" WARNING: Archives created with -sp use data descriptors and should",
+" work with most unzips but may not work with some",
+" -sb ring bell when pause",
+" -sv be verbose about creating splits",
+" Split archives CANNOT be updated, but see --out and Copy Mode below",
+"",
+"Using --out (output to new archive):",
+" --out oa output to new archive oa",
+" Instead of updating input archive, create new output archive oa.",
+" Result is same as without --out but in new archive. Input archive",
+" unchanged.",
+" WARNING: --out ALWAYS overwrites any existing output file",
+" For example, to create new_archive like old_archive but add newfile1",
+" and newfile2:",
+" zip old_archive newfile1 newfile2 --out new_archive",
+" Cannot update split archive, so use --out to out new archive:",
+" zip in_split_archive newfile1 newfile2 --out out_split_archive",
+" If input is split, output will default to same split size",
+" Use -s=0 or -s- to turn off splitting to convert split to single file:",
+" zip in_split_archive -s 0 --out out_single_file_archive",
+" WARNING: If overwriting old split archive but need less splits,",
+" old splits not overwritten are not needed but remain",
+"",
+"Copy Mode (copying from archive to archive):",
+" -U (also --copy) select entries in archive to copy (reverse delete)",
+" Copy Mode copies entries from old to new archive with --out and is used by",
+" zip when either no input files on command line or -U (--copy) used.",
+" zip inarchive --copy pattern pattern ... --out outarchive",
+" To copy only files matching *.c into new archive, excluding foo.c:",
+" zip old_archive --copy \"*.c\" --out new_archive -x foo.c",
+" If no input files and --out, copy all entries in old archive:",
+" zip old_archive --out new_archive",
+"",
+"Streaming and FIFOs:",
+" prog1 | zip -ll z - zip output of prog1 to zipfile z, converting CR LF",
+" zip - -R \"*.c\" | prog2 zip *.c files in current dir and stream to prog2 ",
+" prog1 | zip | prog2 zip in pipe with no in or out acts like zip - -",
+" If Zip is Zip64 enabled, streaming stdin creates Zip64 archives by default",
+" that need PKZip 4.5 unzipper like UnZip 6.0",
+" WARNING: Some archives created with streaming use data descriptors and",
+" should work with most unzips but may not work with some",
+" Can use -fz- to turn off Zip64 if input not large (< 4 GB):",
+" prog_with_small_output | zip archive -fz-",
+"",
+" Zip now can read Unix FIFO (named pipes). Off by default to prevent zip",
+" from stopping unexpectedly on unfed pipe, use -FI to enable:",
+" zip -FI archive fifo",
+"",
+"Dots, counts:",
+" -db display running count of bytes processed and bytes to go",
+" (uncompressed size, except delete and copy show stored size)",
+" -dc display running count of entries done and entries to go",
+" -dd display dots every 10 MB (or dot size) while processing files",
+" -dg display dots globally for archive instead of for each file",
+" zip -qdgds 10m will turn off most output except dots every 10 MB",
+" -ds siz each dot is siz processed where siz is nm as splits (0 no dots)",
+" -du display original uncompressed size for each entry as added",
+" -dv display volume (disk) number in format in_disk>out_disk",
+" Dot size is approximate, especially for dot sizes less than 1 MB",
+" Dot options don't apply to Scanning files dots (dot/2sec) (-q turns off)",
+"",
+"Logging:",
+" -lf path open file at path as logfile (overwrite existing file)",
+" -la append to existing logfile",
+" -li include info messages (default just warnings and errors)",
+"",
+"Testing archives:",
+" -T test completed temp archive with unzip before updating archive",
+" -TT cmd use command cmd instead of 'unzip -tqq' to test archive",
+" On Unix, to use unzip in current directory, could use:",
+" zip archive file1 file2 -T -TT \"./unzip -tqq\"",
+" In cmd, {} replaced by temp archive path, else temp appended.",
+" The return code is checked for success (0 on Unix)",
+"",
+"Fixing archives:",
+" -F attempt to fix a mostly intact archive (try this first)",
+" -FF try to salvage what can (may get more but less reliable)",
+" Fix options copy entries from potentially bad archive to new archive.",
+" -F tries to read archive normally and copy only intact entries, while",
+" -FF tries to salvage what can and may result in incomplete entries.",
+" Must use --out option to specify output archive:",
+" zip -F bad.zip --out fixed.zip",
+" Use -v (verbose) with -FF to see details:",
+" zip reallybad.zip -FF -v --out fixed.zip",
+" Currently neither option fixes bad entries, as from text mode ftp get.",
+"",
+"Difference mode:",
+" -DF (also --dif) only include files that have changed or are",
+" new as compared to the input archive",
+" Difference mode can be used to create incremental backups. For example:",
+" zip --dif full_backup.zip -r somedir --out diff.zip",
+" will store all new files, as well as any files in full_backup.zip where",
+" either file time or size have changed from that in full_backup.zip,",
+" in new diff.zip. Output archive not excluded automatically if exists,",
+" so either use -x to exclude it or put outside what is being zipped.",
+"",
+"DOS Archive bit (Windows only):",
+" -AS include only files with the DOS Archive bit set",
+" -AC after archive created, clear archive bit of included files",
+" WARNING: Once the archive bits are cleared they are cleared",
+" Use -T to test the archive before the bits are cleared",
+" Can also use -sf to save file list before zipping files",
+"",
+"Show files:",
+" -sf show files to operate on and exit (-sf- logfile only)",
+" -su as -sf but show escaped UTF-8 Unicode names also if exist",
+" -sU as -sf but show escaped UTF-8 Unicode names instead",
+" Any character not in the current locale is escaped as #Uxxxx, where x",
+" is hex digit, if 16-bit code is sufficient, or #Lxxxxxx if 24-bits",
+" are needed. If add -UN=e, Zip escapes all non-ASCII characters.",
+"",
+"Unicode:",
+" If compiled with Unicode support, Zip stores UTF-8 path of entries.",
+" This is backward compatible. Unicode paths allow better conversion",
+" of entry names between different character sets.",
+"",
+" New Unicode extra field includes checksum to verify Unicode path",
+" goes with standard path for that entry (as utilities like ZipNote",
+" can rename entries). If these do not match, use below options to",
+" set what Zip does:",
+" -UN=Quit - if mismatch, exit with error",
+" -UN=Warn - if mismatch, warn, ignore UTF-8 (default)",
+" -UN=Ignore - if mismatch, quietly ignore UTF-8",
+" -UN=No - ignore any UTF-8 paths, use standard paths for all",
+" An exception to -UN=N are entries with new UTF-8 bit set (instead",
+" of using extra fields). These are always handled as Unicode.",
+"",
+" Normally Zip escapes all chars outside current char set, but leaves",
+" as is supported chars, which may not be OK in path names. -UN=Escape",
+" escapes any character not ASCII:",
+" zip -sU -UN=e archive",
+" Can use either normal path or escaped Unicode path on command line",
+" to match files in archive.",
+"",
+" Zip now stores UTF-8 in entry path and comment fields on systems",
+" where UTF-8 char set is default, such as most modern Unix, and",
+" and on other systems in new extra fields with escaped versions in",
+" entry path and comment fields for backward compatibility.",
+" Option -UN=UTF8 will force storing UTF-8 in entry path and comment",
+" fields:",
+" -UN=UTF8 - store UTF-8 in entry path and comment fields",
+" This option can be useful for multi-byte char sets on Windows where",
+" escaped paths and comments can be too long to be valid as the UTF-8",
+" versions tend to be shorter.",
+"",
+" Only UTF-8 comments on UTF-8 native systems supported. UTF-8 comments",
+" for other systems planned in next release.",
+"",
+"Self extractor:",
+" -A Adjust offsets - a self extractor is created by prepending",
+" the extractor executable to archive, but internal offsets",
+" are then off. Use -A to fix offsets.",
+" -J Junk sfx - removes prepended extractor executable from",
+" self extractor, leaving a plain zip archive.",
+"",
+"More option highlights (see manual for additional options and details):",
+" -b dir when creating or updating archive, create the temp archive in",
+" dir, which allows using seekable temp file when writing to a",
+" write once CD, such archives compatible with more unzips",
+" (could require additional file copy if on another device)",
+" -MM input patterns must match at least one file and matched files",
+" must be readable or exit with OPEN error and abort archive",
+" (without -MM, both are warnings only, and if unreadable files",
+" are skipped OPEN error (18) returned after archive created)",
+" -nw no wildcards (wildcards are like any other character)",
+" -sc show command line arguments as processed and exit",
+" -sd show debugging as Zip does each step",
+" -so show all available options on this system",
+" -X default=strip old extra fields, -X- keep old, -X strip most",
+" -ws wildcards don't span directory boundaries in paths",
+""
+ };
+
+ for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+ {
+ printf("%s", text[i]);
+ putchar('\n');
+ }
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
+}
+
+/*
+ * XXX version_info() in a separate file
+ */
+local void version_info()
+/* Print verbose info about program version and compile time options
+ to stdout. */
+{
+ extent i; /* counter in text arrays */
+ char *envptr;
+
+ /* Bzip2 option string storage (with version). */
+
+#ifdef BZIP2_SUPPORT
+ static char bz_opt_ver[81];
+ static char bz_opt_ver2[81];
+ static char bz_opt_ver3[81];
+#endif
+
+ /* Options info array */
+ static ZCONST char *comp_opts[] = {
+#ifdef ASM_CRC
+ "ASM_CRC",
+#endif
+#ifdef ASMV
+ "ASMV",
+#endif
+#ifdef DYN_ALLOC
+ "DYN_ALLOC",
+#endif
+#ifdef MMAP
+ "MMAP",
+#endif
+#ifdef BIG_MEM
+ "BIG_MEM",
+#endif
+#ifdef MEDIUM_MEM
+ "MEDIUM_MEM",
+#endif
+#ifdef SMALL_MEM
+ "SMALL_MEM",
+#endif
+#ifdef DEBUG
+ "DEBUG",
+#endif
+#ifdef USE_EF_UT_TIME
+ "USE_EF_UT_TIME (store Universal Time)",
+#endif
+#ifdef NTSD_EAS
+ "NTSD_EAS (store NT Security Descriptor)",
+#endif
+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+ "NO_W32TIMES_IZFIX",
+#endif
+#ifdef VMS
+#ifdef VMSCLI
+ "VMSCLI",
+#endif
+#ifdef VMS_IM_EXTRA
+ "VMS_IM_EXTRA",
+#endif
+#ifdef VMS_PK_EXTRA
+ "VMS_PK_EXTRA",
+#endif
+#endif /* VMS */
+#ifdef WILD_STOP_AT_DIR
+ "WILD_STOP_AT_DIR (wildcards do not cross directory boundaries)",
+#endif
+#ifdef WIN32_OEM
+ "WIN32_OEM (store file paths on Windows as OEM)",
+#endif
+#ifdef BZIP2_SUPPORT
+ bz_opt_ver,
+ bz_opt_ver2,
+ bz_opt_ver3,
+#endif
+#ifdef S_IFLNK
+# ifdef VMS
+ "SYMLINK_SUPPORT (symbolic links supported, if C RTL permits)",
+# else
+ "SYMLINK_SUPPORT (symbolic links supported)",
+# endif
+#endif
+#ifdef LARGE_FILE_SUPPORT
+# ifdef USING_DEFAULT_LARGE_FILE_SUPPORT
+ "LARGE_FILE_SUPPORT (default settings)",
+# else
+ "LARGE_FILE_SUPPORT (can read and write large files on file system)",
+# endif
+#endif
+#ifdef ZIP64_SUPPORT
+ "ZIP64_SUPPORT (use Zip64 to store large files in archives)",
+#endif
+#ifdef UNICODE_SUPPORT
+ "UNICODE_SUPPORT (store and read UTF-8 Unicode paths)",
+#endif
+
+#ifdef UNIX
+ "STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field)",
+# ifdef UIDGID_NOT_16BIT
+ "UIDGID_NOT_16BIT (old Unix 16-bit UID/GID extra field not used)",
+# else
+ "UIDGID_16BIT (old Unix 16-bit UID/GID extra field also used)",
+# endif
+#endif
+
+#if CRYPT && defined(PASSWD_FROM_STDIN)
+ "PASSWD_FROM_STDIN",
+#endif /* CRYPT & PASSWD_FROM_STDIN */
+ NULL
+ };
+
+ static ZCONST char *zipenv_names[] = {
+#ifndef VMS
+# ifndef RISCOS
+ "ZIP"
+# else /* RISCOS */
+ "Zip$Options"
+# endif /* ?RISCOS */
+#else /* VMS */
+ "ZIP_OPTS"
+#endif /* ?VMS */
+ ,"ZIPOPT"
+#ifdef AZTEC_C
+ , /* extremely lame compiler bug workaround */
+#endif
+#ifndef __RSXNT__
+# ifdef __EMX__
+ ,"EMX"
+ ,"EMXOPT"
+# endif
+# if (defined(__GO32__) && (!defined(__DJGPP__) || __DJGPP__ < 2))
+ ,"GO32"
+ ,"GO32TMP"
+# endif
+# if (defined(__DJGPP__) && __DJGPP__ >= 2)
+ ,"TMPDIR"
+# endif
+#endif /* !__RSXNT__ */
+#ifdef RISCOS
+ ,"Zip$Exts"
+#endif
+ };
+
+ for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+ {
+ printf(copyright[i], "zip");
+ putchar('\n');
+ }
+
+ for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
+ {
+ printf(versinfolines[i], "Zip", VERSION, REVDATE);
+ putchar('\n');
+ }
+
+ version_local();
+
+ puts("Zip special compilation options:");
+#if WSIZE != 0x8000
+ printf("\tWSIZE=%u\n", WSIZE);
+#endif
+
+ /* Fill in bzip2 version. (32-char limit valid as of bzip 1.0.3.) */
+#ifdef BZIP2_SUPPORT
+ sprintf( bz_opt_ver,
+ "BZIP2_SUPPORT (bzip2 library version %.32s)", BZ2_bzlibVersion());
+ sprintf( bz_opt_ver2,
+ " bzip2 code and library copyright (c) Julian R Seward");
+ sprintf( bz_opt_ver3,
+ " (See the bzip2 license for terms of use)");
+#endif
+
+ for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
+ {
+ printf("\t%s\n",comp_opts[i]);
+ }
+#ifdef USE_ZLIB
+ if (strcmp(ZLIB_VERSION, zlibVersion()) == 0)
+ printf("\tUSE_ZLIB [zlib version %s]\n", ZLIB_VERSION);
+ else
+ printf("\tUSE_ZLIB [compiled with version %s, using version %s]\n",
+ ZLIB_VERSION, zlibVersion());
+ i++; /* zlib use means there IS at least one compilation option */
+#endif
+#if CRYPT
+ printf("\t[encryption, version %d.%d%s of %s] (modified for Zip 3)\n\n",
+ CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
+ for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++)
+ {
+ printf("%s", cryptnote[i]);
+ putchar('\n');
+ }
+ ++i; /* crypt support means there IS at least one compilation option */
+#endif /* CRYPT */
+ if (i == 0)
+ puts("\t[none]");
+
+ puts("\nZip environment options:");
+ for (i = 0; i < sizeof(zipenv_names)/sizeof(char *); i++)
+ {
+ envptr = getenv(zipenv_names[i]);
+ printf("%16s: %s\n", zipenv_names[i],
+ ((envptr == (char *)NULL || *envptr == 0) ? "[none]" : envptr));
+ }
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
+}
+#endif /* !WINDLL */
+
+
+#ifndef PROCNAME
+/* Default to case-sensitive matching of archive entries for the modes
+ that specifically operate on archive entries, as this archive may
+ have come from a system that allows paths in the archive to differ
+ only by case. Except for adding ARCHIVE (copy mode), this is how it
+ was done before. Note that some case-insensitive ports (WIN32, VMS)
+ define their own PROCNAME() in their respective osdep.h that use the
+ filter_match_case flag set to FALSE by the -ic option to enable
+ case-insensitive archive entry mathing. */
+# define PROCNAME(n) procname(n, (action == ARCHIVE || action == DELETE \
+ || action == FRESHEN) \
+ && filter_match_case)
+#endif /* PROCNAME */
+
+#ifndef WINDLL
+#ifndef MACOS
+local void zipstdout()
+/* setup for writing zip file on stdout */
+{
+ mesg = stderr;
+ if (isatty(1))
+ ziperr(ZE_PARMS, "cannot write zip file to terminal");
+ if ((zipfile = malloc(4)) == NULL)
+ ziperr(ZE_MEM, "was processing arguments");
+ strcpy(zipfile, "-");
+ /*
+ if ((r = readzipfile()) != ZE_OK)
+ ziperr(r, zipfile);
+ */
+}
+#endif /* !MACOS */
+
+local int check_unzip_version(unzippath)
+ char *unzippath;
+{
+#ifdef ZIP64_SUPPORT
+ /* Here is where we need to check for the version of unzip the user
+ * has. If creating a Zip64 archive need UnZip 6 or may fail.
+ */
+ char cmd[4004];
+ FILE *unzip_out = NULL;
+ char buf[1001];
+ float UnZip_Version = 0.0;
+
+ cmd[0] = '\0';
+ strncat(cmd, unzippath, 4000);
+ strcat(cmd, " -v");
+
+ if ((unzip_out = popen(cmd, "r")) == NULL) {
+ perror("unzip pipe error");
+ } else {
+ if (fgets(buf, 1000, unzip_out) == NULL) {
+ zipwarn("failed to get information from UnZip", "");
+ } else {
+ /* the first line should start with the version */
+ if (sscanf(buf, "UnZip %f ", &UnZip_Version) < 1) {
+ zipwarn("unexpected output of UnZip -v", "");
+ } else {
+ /* printf("UnZip %f\n", UnZip_Version); */
+
+ while (fgets(buf, 1000, unzip_out)) {
+ }
+ }
+ }
+ pclose(unzip_out);
+ }
+ if (UnZip_Version < 6.0 && zip64_archive) {
+ sprintf(buf, "Found UnZip version %4.2f", UnZip_Version);
+ zipwarn(buf, "");
+ zipwarn("Need UnZip 6.00 or later to test this Zip64 archive", "");
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+local void check_zipfile(zipname, zippath)
+ char *zipname;
+ char *zippath;
+ /* Invoke unzip -t on the given zip file */
+{
+#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
+ int status, len;
+ char *path, *p;
+ char *zipnam;
+
+ if ((zipnam = (char *)malloc(strlen(zipname) + 3)) == NULL)
+ ziperr(ZE_MEM, "was creating unzip zipnam");
+
+# ifdef MSDOS
+ /* Add quotes for MSDOS. 8/11/04 */
+ strcpy(zipnam, "\""); /* accept spaces in name and path */
+ strcat(zipnam, zipname);
+ strcat(zipnam, "\"");
+# else
+ strcpy(zipnam, zipname);
+# endif
+
+ if (unzip_path) {
+ /* if user gave us the unzip to use go with it */
+ char *here;
+ int len;
+ char *cmd;
+
+ /* Replace first {} with archive name. If no {} append name to string. */
+ here = strstr(unzip_path, "{}");
+
+ if ((cmd = (char *)malloc(strlen(unzip_path) + strlen(zipnam) + 3)) == NULL)
+ ziperr(ZE_MEM, "was creating unzip cmd");
+
+ if (here) {
+ /* have {} so replace with temp name */
+ len = here - unzip_path;
+ strcpy(cmd, unzip_path);
+ cmd[len] = '\0';
+ strcat(cmd, " ");
+ strcat(cmd, zipnam);
+ strcat(cmd, " ");
+ strcat(cmd, here + 2);
+ } else {
+ /* No {} so append temp name to end */
+ strcpy(cmd, unzip_path);
+ strcat(cmd, " ");
+ strcat(cmd, zipnam);
+ }
+
+ status = system(cmd);
+
+ free(unzip_path);
+ unzip_path = NULL;
+ free(cmd);
+ } else {
+ /* Here is where we need to check for the version of unzip the user
+ * has. If creating a Zip64 archive need UnZip 6 or may fail.
+ */
+ if (check_unzip_version("unzip") == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+ status = spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
+ zipnam, NULL);
+# ifdef __human68k__
+ if (status == -1)
+ perror("unzip");
+# else
+/*
+ * unzip isn't in PATH range, assume an absolute path to zip in argv[0]
+ * and hope that unzip is in the same directory.
+ */
+ if (status == -1) {
+ p = MBSRCHR(zippath, '\\');
+ path = MBSRCHR((p == NULL ? zippath : p), '/');
+ if (path != NULL)
+ p = path;
+ if (p != NULL) {
+ len = (int)(p - zippath) + 1;
+ if ((path = malloc(len + sizeof("unzip.exe"))) == NULL)
+ ziperr(ZE_MEM, "was creating unzip path");
+ memcpy(path, zippath, len);
+ strcpy(&path[len], "unzip.exe");
+
+ if (check_unzip_version(path) == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+ status = spawnlp(P_WAIT, path, "unzip", verbose ? "-t" : "-tqq",
+ zipnam, NULL);
+ free(path);
+ }
+ if (status == -1)
+ perror("unzip");
+ }
+ }
+# endif /* ?__human68k__ */
+ free(zipnam);
+ if (status != 0) {
+
+#else /* (MSDOS && !__GO32__) || __human68k__ */
+ char *cmd;
+ int result;
+
+ /* Tell picky compilers to shut up about unused variables */
+ zippath = zippath;
+
+ if (unzip_path) {
+ /* user gave us a path to some unzip (may not be UnZip) */
+ char *here;
+ int len;
+
+ /* Replace first {} with archive name. If no {} append name to string. */
+ here = strstr(unzip_path, "{}");
+
+ if ((cmd = malloc(strlen(unzip_path) + strlen(zipname) + 3)) == NULL) {
+ ziperr(ZE_MEM, "building command string for testing archive");
+ }
+
+ if (here) {
+ /* have {} so replace with temp name */
+ len = here - unzip_path;
+ strcpy(cmd, unzip_path);
+ cmd[len] = '\0';
+ strcat(cmd, " ");
+# ifdef UNIX
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
+# else
+ strcat(cmd, zipname);
+# endif
+ strcat(cmd, " ");
+ strcat(cmd, here + 2);
+ } else {
+ /* No {} so append temp name to end */
+ strcpy(cmd, unzip_path);
+ strcat(cmd, " ");
+# ifdef UNIX
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
+# else
+ strcat(cmd, zipname);
+# endif
+ }
+ free(unzip_path);
+ unzip_path = NULL;
+
+ } else {
+ if ((cmd = malloc(20 + strlen(zipname))) == NULL) {
+ ziperr(ZE_MEM, "building command string for testing archive");
+ }
+
+ strcpy(cmd, "unzip -t ");
+# ifdef QDOS
+ strcat(cmd, "-Q4 ");
+# endif
+ if (!verbose) strcat(cmd, "-qq ");
+ if (check_unzip_version("unzip") == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+# ifdef UNIX
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
+# else
+ strcat(cmd, zipname);
+# endif
+ }
+
+ result = system(cmd);
+# ifdef VMS
+ /* Convert success severity to 0, others to non-zero. */
+ result = ((result & STS$M_SEVERITY) != STS$M_SUCCESS);
+# endif /* def VMS */
+ free(cmd);
+ cmd = NULL;
+ if (result) {
+#endif /* ?((MSDOS && !__GO32__) || __human68k__) */
+
+ fprintf(mesg, "test of %s FAILED\n", zipfile);
+ ziperr(ZE_TEST, "original files unmodified");
+ }
+ if (noisy) {
+ fprintf(mesg, "test of %s OK\n", zipfile);
+ fflush(mesg);
+ }
+ if (logfile) {
+ fprintf(logfile, "test of %s OK\n", zipfile);
+ fflush(logfile);
+ }
+}
+#endif /* !WINDLL */
+
+/* get_filters() is replaced by the following
+local int get_filters(argc, argv)
+*/
+
+/* The filter patterns for options -x, -i, and -R are
+ returned by get_option() one at a time, so use a linked
+ list to store until all args are processed. Then convert
+ to array for processing.
+ */
+
+/* add a filter to the linked list */
+local int add_filter(flag, pattern)
+ int flag;
+ char *pattern;
+{
+ char *iname, *p = NULL;
+ FILE *fp;
+ struct filterlist_struct *filter = NULL;
+
+ /* should never happen */
+ if (flag != 'R' && flag != 'x' && flag != 'i') {
+ ZIPERR(ZE_LOGIC, "bad flag to add_filter");
+ }
+ if (pattern == NULL) {
+ ZIPERR(ZE_LOGIC, "null pattern to add_filter");
+ }
+
+ if (pattern[0] == '@') {
+ /* read file with 1 pattern per line */
+ if (pattern[1] == '\0') {
+ ZIPERR(ZE_PARMS, "missing file after @");
+ }
+ fp = fopen(pattern + 1, "r");
+ if (fp == NULL) {
+ sprintf(errbuf, "%c pattern file '%s'", flag, pattern);
+ ZIPERR(ZE_OPEN, errbuf);
+ }
+ while ((p = getnam(fp)) != NULL) {
+ if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding filter");
+ }
+ if (filterlist == NULL) {
+ /* first filter */
+ filterlist = filter; /* start of list */
+ lastfilter = filter;
+ } else {
+ lastfilter->next = filter; /* link to last filter in list */
+ lastfilter = filter;
+ }
+ iname = ex2in(p, 0, (int *)NULL);
+ free(p);
+ if (iname != NULL) {
+ lastfilter->pattern = in2ex(iname);
+ free(iname);
+ } else {
+ lastfilter->pattern = NULL;
+ }
+ lastfilter->flag = flag;
+ pcount++;
+ lastfilter->next = NULL;
+ }
+ fclose(fp);
+ } else {
+ /* single pattern */
+ if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding filter");
+ }
+ if (filterlist == NULL) {
+ /* first pattern */
+ filterlist = filter; /* start of list */
+ lastfilter = filter;
+ } else {
+ lastfilter->next = filter; /* link to last filter in list */
+ lastfilter = filter;
+ }
+ iname = ex2in(pattern, 0, (int *)NULL);
+ if (iname != NULL) {
+ lastfilter->pattern = in2ex(iname);
+ free(iname);
+ } else {
+ lastfilter->pattern = NULL;
+ }
+ lastfilter->flag = flag;
+ pcount++;
+ lastfilter->next = NULL;
+ }
+
+ return pcount;
+}
+
+/* convert list to patterns array */
+local int filterlist_to_patterns()
+{
+ unsigned i;
+ struct filterlist_struct *next = NULL;
+
+ if (pcount == 0) {
+ patterns = NULL;
+ return 0;
+ }
+ if ((patterns = (struct plist *) malloc((pcount + 1) * sizeof(struct plist)))
+ == NULL) {
+ ZIPERR(ZE_MEM, "was creating pattern list");
+ }
+
+ for (i = 0; i < pcount && filterlist != NULL; i++) {
+ switch (filterlist->flag) {
+ case 'i':
+ icount++;
+ break;
+ case 'R':
+ Rcount++;
+ break;
+ }
+ patterns[i].select = filterlist->flag;
+ patterns[i].zname = filterlist->pattern;
+ next = filterlist->next;
+ free(filterlist);
+ filterlist = next;
+ }
+
+ return pcount;
+}
+
+
+/* add a file argument to linked list */
+local long add_name(filearg)
+ char *filearg;
+{
+ char *name = NULL;
+ struct filelist_struct *fileentry = NULL;
+
+ if ((fileentry = (struct filelist_struct *) malloc(sizeof(struct filelist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding file");
+ }
+ if ((name = malloc(strlen(filearg) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "adding file");
+ }
+ strcpy(name, filearg);
+ fileentry->next = NULL;
+ fileentry->name = name;
+ if (filelist == NULL) {
+ /* first file argument */
+ filelist = fileentry; /* start of list */
+ lastfile = fileentry;
+ } else {
+ lastfile->next = fileentry; /* link to last filter in list */
+ lastfile = fileentry;
+ }
+ filearg_count++;
+
+ return filearg_count;
+}
+
+
+/* Running Stats
+ 10/30/04 */
+
+local int DisplayRunningStats()
+{
+ char tempstrg[100];
+
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ if (display_volume) {
+ if (noisy) {
+ fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_counts) {
+ if (noisy) {
+ fprintf(mesg, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_bytes) {
+ /* since file sizes can change as we go, use bytes_so_far from
+ initial scan so all adds up */
+ WriteNumString(bytes_so_far, tempstrg);
+ if (noisy) {
+ fprintf(mesg, "[%4s", tempstrg);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "[%4s", tempstrg);
+ logfile_line_started = 1;
+ }
+ if (bytes_total >= bytes_so_far) {
+ WriteNumString(bytes_total - bytes_so_far, tempstrg);
+ if (noisy)
+ fprintf(mesg, "/%4s] ", tempstrg);
+ if (logall)
+ fprintf(logfile, "/%4s] ", tempstrg);
+ } else {
+ WriteNumString(bytes_so_far - bytes_total, tempstrg);
+ if (noisy)
+ fprintf(mesg, "-%4s] ", tempstrg);
+ if (logall)
+ fprintf(logfile, "-%4s] ", tempstrg);
+ }
+ }
+ if (noisy)
+ fflush(mesg);
+ if (logall)
+ fflush(logfile);
+
+ return 0;
+}
+
+local int BlankRunningStats()
+{
+ if (display_volume) {
+ if (noisy) {
+ fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_counts) {
+ if (noisy) {
+ fprintf(mesg, " / ");
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, " / ");
+ logfile_line_started = 1;
+ }
+ }
+ if (display_bytes) {
+ if (noisy) {
+ fprintf(mesg, " / ");
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, " / ");
+ logfile_line_started = 1;
+ }
+ }
+ if (noisy)
+ fflush(mesg);
+ if (logall)
+ fflush(logfile);
+
+ return 0;
+}
+
+#if CRYPT
+#ifndef WINDLL
+int encr_passwd(modeflag, pwbuf, size, zfn)
+int modeflag;
+char *pwbuf;
+int size;
+ZCONST char *zfn;
+{
+ char *prompt;
+
+ /* Tell picky compilers to shut up about unused variables */
+ zfn = zfn;
+
+ prompt = (modeflag == ZP_PW_VERIFY) ?
+ "Verify password: " : "Enter password: ";
+
+ if (getp(prompt, pwbuf, size) == NULL) {
+ ziperr(ZE_PARMS, "stderr is not a tty");
+ }
+ return IZ_PW_ENTERED;
+}
+#endif /* !WINDLL */
+#else /* !CRYPT */
+int encr_passwd(modeflag, pwbuf, size, zfn)
+int modeflag;
+char *pwbuf;
+int size;
+ZCONST char *zfn;
+{
+ /* Tell picky compilers to shut up about unused variables */
+ modeflag = modeflag; pwbuf = pwbuf; size = size; zfn = zfn;
+
+ return ZE_LOGIC; /* This function should never be called! */
+}
+#endif /* CRYPT */
+
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+
+/*
+ -------------------------------------------------------
+ Command Line Options
+ -------------------------------------------------------
+
+ Valid command line options.
+
+ The function get_option() uses this table to check if an
+ option is valid and if it takes a value (also called an
+ option argument). To add an option to zip just add it
+ to this table and add a case in the main switch to handle
+ it. If either shortopt or longopt not used set to "".
+
+ The fields:
+ shortopt - short option name (1 or 2 chars)
+ longopt - long option name
+ value_type - see zip.h for constants
+ negatable - option is negatable with trailing -
+ ID - unsigned long int returned for option
+ name - short description of option which is
+ returned on some errors and when options
+ are listed with -so option, can be NULL
+*/
+
+/* Most option IDs are set to the shortopt char. For
+ multichar short options set to arbitrary unused constant. */
+#define o_AC 0x101
+#define o_AS 0x102
+#define o_C2 0x103
+#define o_C5 0x104
+#define o_db 0x105
+#define o_dc 0x106
+#define o_dd 0x107
+#define o_des 0x108
+#define o_df 0x109
+#define o_DF 0x110
+#define o_dg 0x111
+#define o_ds 0x112
+#define o_du 0x113
+#define o_dv 0x114
+#define o_FF 0x115
+#define o_FI 0x116
+#define o_FS 0x117
+#define o_h2 0x118
+#define o_ic 0x119
+#define o_jj 0x120
+#define o_la 0x121
+#define o_lf 0x122
+#define o_li 0x123
+#define o_ll 0x124
+#define o_mm 0x125
+#define o_MM 0x126
+#define o_nw 0x127
+#define o_RE 0x128
+#define o_sb 0x129
+#define o_sc 0x130
+#define o_sd 0x131
+#define o_sf 0x132
+#define o_so 0x133
+#define o_sp 0x134
+#define o_su 0x135
+#define o_sU 0x136
+#define o_sv 0x137
+#define o_tt 0x138
+#define o_TT 0x139
+#define o_UN 0x140
+#define o_ve 0x141
+#define o_VV 0x142
+#define o_ws 0x143
+#define o_ww 0x144
+#define o_z64 0x145
+#ifdef UNICODE_TEST
+#define o_sC 0x146
+#endif
+
+
+/* the below is mainly from the old main command line
+ switch with a few changes */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+#ifdef EBCDIC
+ {"a", "ascii", o_NO_VALUE, o_NOT_NEGATABLE, 'a', "to ascii"},
+#endif /* EBCDIC */
+#ifdef CMS_MVS
+ {"B", "binary", o_NO_VALUE, o_NOT_NEGATABLE, 'B', "binary"},
+#endif /* CMS_MVS */
+#ifdef TANDEM
+ {"B", "", o_NUMBER_VALUE, o_NOT_NEGATABLE, 'B', "nsk"},
+#endif
+ {"0", "store", o_NO_VALUE, o_NOT_NEGATABLE, '0', "store"},
+ {"1", "compress-1", o_NO_VALUE, o_NOT_NEGATABLE, '1', "compress 1"},
+ {"2", "compress-2", o_NO_VALUE, o_NOT_NEGATABLE, '2', "compress 2"},
+ {"3", "compress-3", o_NO_VALUE, o_NOT_NEGATABLE, '3', "compress 3"},
+ {"4", "compress-4", o_NO_VALUE, o_NOT_NEGATABLE, '4', "compress 4"},
+ {"5", "compress-5", o_NO_VALUE, o_NOT_NEGATABLE, '5', "compress 5"},
+ {"6", "compress-6", o_NO_VALUE, o_NOT_NEGATABLE, '6', "compress 6"},
+ {"7", "compress-7", o_NO_VALUE, o_NOT_NEGATABLE, '7', "compress 7"},
+ {"8", "compress-8", o_NO_VALUE, o_NOT_NEGATABLE, '8', "compress 8"},
+ {"9", "compress-9", o_NO_VALUE, o_NOT_NEGATABLE, '9', "compress 9"},
+ {"A", "adjust-sfx", o_NO_VALUE, o_NOT_NEGATABLE, 'A', "adjust self extractor offsets"},
+#if defined(WIN32)
+ {"AC", "archive-clear", o_NO_VALUE, o_NOT_NEGATABLE, o_AC, "clear DOS archive bit of included files"},
+ {"AS", "archive-set", o_NO_VALUE, o_NOT_NEGATABLE, o_AS, "include only files with archive bit set"},
+#endif
+ {"b", "temp-path", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "dir to use for temp archive"},
+ {"c", "entry-comments", o_NO_VALUE, o_NOT_NEGATABLE, 'c', "add comments for each entry"},
+#ifdef VMS
+ {"C", "preserve-case", o_NO_VALUE, o_NEGATABLE, 'C', "Preserve (C-: down-) case all on VMS"},
+ {"C2", "preserve-case-2", o_NO_VALUE, o_NEGATABLE, o_C2, "Preserve (C2-: down-) case ODS2 on VMS"},
+ {"C5", "preserve-case-5", o_NO_VALUE, o_NEGATABLE, o_C5, "Preserve (C5-: down-) case ODS5 on VMS"},
+#endif /* VMS */
+ {"d", "delete", o_NO_VALUE, o_NOT_NEGATABLE, 'd', "delete entries from archive"},
+ {"db", "display-bytes", o_NO_VALUE, o_NEGATABLE, o_db, "display running bytes"},
+ {"dc", "display-counts", o_NO_VALUE, o_NEGATABLE, o_dc, "display running file count"},
+ {"dd", "display-dots", o_NO_VALUE, o_NEGATABLE, o_dd, "display dots as process each file"},
+ {"dg", "display-globaldots",o_NO_VALUE, o_NEGATABLE, o_dg, "display dots for archive instead of files"},
+ {"ds", "dot-size", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_ds, "set progress dot size - default 10M bytes"},
+ {"du", "display-usize", o_NO_VALUE, o_NEGATABLE, o_du, "display uncompressed size in bytes"},
+ {"dv", "display-volume", o_NO_VALUE, o_NEGATABLE, o_dv, "display volume (disk) number"},
+#ifdef MACOS
+ {"df", "datafork", o_NO_VALUE, o_NOT_NEGATABLE, o_df, "save datafork"},
+#endif /* MACOS */
+ {"D", "no-dir-entries", o_NO_VALUE, o_NOT_NEGATABLE, 'D', "no entries for dirs themselves (-x */)"},
+ {"DF", "difference-archive",o_NO_VALUE, o_NOT_NEGATABLE, o_DF, "create diff archive with changed/new files"},
+ {"e", "encrypt", o_NO_VALUE, o_NOT_NEGATABLE, 'e', "encrypt entries, ask for password"},
+#ifdef OS2
+ {"E", "longnames", o_NO_VALUE, o_NOT_NEGATABLE, 'E', "use OS2 longnames"},
+#endif
+ {"F", "fix", o_NO_VALUE, o_NOT_NEGATABLE, 'F', "fix mostly intact archive (try first)"},
+ {"FF", "fixfix", o_NO_VALUE, o_NOT_NEGATABLE, o_FF, "try harder to fix archive (not as reliable)"},
+ {"FI", "fifo", o_NO_VALUE, o_NEGATABLE, o_FI, "read Unix FIFO (zip will wait on open pipe)"},
+ {"FS", "filesync", o_NO_VALUE, o_NOT_NEGATABLE, o_FS, "add/delete entries to make archive match OS"},
+ {"f", "freshen", o_NO_VALUE, o_NOT_NEGATABLE, 'f', "freshen existing archive entries"},
+ {"fd", "force-descriptors", o_NO_VALUE, o_NOT_NEGATABLE, o_des,"force data descriptors as if streaming"},
+#ifdef ZIP64_SUPPORT
+ {"fz", "force-zip64", o_NO_VALUE, o_NEGATABLE, o_z64,"force use of Zip64 format, negate prevents"},
+#endif
+ {"g", "grow", o_NO_VALUE, o_NOT_NEGATABLE, 'g', "grow existing archive instead of replace"},
+#ifndef WINDLL
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"H", "", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"?", "", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"h2", "more-help", o_NO_VALUE, o_NOT_NEGATABLE, o_h2, "extended help"},
+#endif /* !WINDLL */
+ {"i", "include", o_VALUE_LIST, o_NOT_NEGATABLE, 'i', "include only files matching patterns"},
+#if defined(VMS) || defined(WIN32)
+ {"ic", "ignore-case", o_NO_VALUE, o_NEGATABLE, o_ic, "ignore case when matching archive entries"},
+#endif
+#ifdef RISCOS
+ {"I", "no-image", o_NO_VALUE, o_NOT_NEGATABLE, 'I', "no image"},
+#endif
+ {"j", "junk-paths", o_NO_VALUE, o_NOT_NEGATABLE, 'j', "strip paths and just store file names"},
+#ifdef MACOS
+ {"jj", "absolute-path", o_NO_VALUE, o_NOT_NEGATABLE, o_jj, "MAC absolute path"},
+#endif /* ?MACOS */
+ {"J", "junk-sfx", o_NO_VALUE, o_NOT_NEGATABLE, 'J', "strip self extractor from archive"},
+ {"k", "DOS-names", o_NO_VALUE, o_NOT_NEGATABLE, 'k', "force use of 8.3 DOS names"},
+ {"l", "to-crlf", o_NO_VALUE, o_NOT_NEGATABLE, 'l', "convert text file line ends - LF->CRLF"},
+ {"ll", "from-crlf", o_NO_VALUE, o_NOT_NEGATABLE, o_ll, "convert text file line ends - CRLF->LF"},
+ {"lf", "logfile-path",o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_lf, "log to log file at path (default overwrite)"},
+ {"la", "log-append", o_NO_VALUE, o_NEGATABLE, o_la, "append to existing log file"},
+ {"li", "log-info", o_NO_VALUE, o_NEGATABLE, o_li, "include informational messages in log"},
+#ifndef WINDLL
+ {"L", "license", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "display license"},
+#endif
+ {"m", "move", o_NO_VALUE, o_NOT_NEGATABLE, 'm', "add files to archive then delete files"},
+ {"mm", "", o_NO_VALUE, o_NOT_NEGATABLE, o_mm, "not used"},
+ {"MM", "must-match", o_NO_VALUE, o_NOT_NEGATABLE, o_MM, "error if in file not matched/not readable"},
+ {"n", "suffixes", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'n', "suffixes to not compress: .gz:.zip"},
+ {"nw", "no-wild", o_NO_VALUE, o_NOT_NEGATABLE, o_nw, "no wildcards during add or update"},
+#if defined(AMIGA) || defined(MACOS)
+ {"N", "notes", o_NO_VALUE, o_NOT_NEGATABLE, 'N', "add notes as entry comments"},
+#endif
+ {"o", "latest-time", o_NO_VALUE, o_NOT_NEGATABLE, 'o', "use latest entry time as archive time"},
+ {"O", "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O', "set out zipfile different than in zipfile"},
+ {"p", "paths", o_NO_VALUE, o_NOT_NEGATABLE, 'p', "store paths"},
+ {"P", "password", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'P', "encrypt entries, option value is password"},
+#if defined(QDOS) || defined(QLZIP)
+ {"Q", "Q-flag", o_NUMBER_VALUE, o_NOT_NEGATABLE, 'Q', "Q flag"},
+#endif
+ {"q", "quiet", o_NO_VALUE, o_NOT_NEGATABLE, 'q', "quiet"},
+ {"r", "recurse-paths", o_NO_VALUE, o_NOT_NEGATABLE, 'r', "recurse down listed paths"},
+ {"R", "recurse-patterns", o_NO_VALUE, o_NOT_NEGATABLE, 'R', "recurse current dir and match patterns"},
+ {"RE", "regex", o_NO_VALUE, o_NOT_NEGATABLE, o_RE, "allow [list] matching (regex)"},
+ {"s", "split-size", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 's', "do splits, set split size (-s=0 no splits)"},
+ {"sp", "split-pause", o_NO_VALUE, o_NOT_NEGATABLE, o_sp, "pause while splitting to select destination"},
+ {"sv", "split-verbose", o_NO_VALUE, o_NOT_NEGATABLE, o_sv, "be verbose about creating splits"},
+ {"sb", "split-bell", o_NO_VALUE, o_NOT_NEGATABLE, o_sb, "when pause for next split ring bell"},
+ {"sc", "show-command",o_NO_VALUE, o_NOT_NEGATABLE, o_sc, "show command line"},
+#ifdef UNICODE_TEST
+ {"sC", "create-files",o_NO_VALUE, o_NOT_NEGATABLE, o_sC, "create empty files using archive names"},
+#endif
+ {"sd", "show-debug", o_NO_VALUE, o_NOT_NEGATABLE, o_sd, "show debug"},
+ {"sf", "show-files", o_NO_VALUE, o_NEGATABLE, o_sf, "show files to operate on and exit"},
+ {"so", "show-options",o_NO_VALUE, o_NOT_NEGATABLE, o_so, "show options"},
+#ifdef UNICODE_SUPPORT
+ {"su", "show-unicode", o_NO_VALUE, o_NEGATABLE, o_su, "as -sf but also show escaped Unicode"},
+ {"sU", "show-just-unicode", o_NO_VALUE, o_NEGATABLE, o_sU, "as -sf but only show escaped Unicode"},
+#endif
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
+ {"S", "", o_NO_VALUE, o_NOT_NEGATABLE, 'S', "include system and hidden"},
+#endif /* MSDOS || OS2 || WIN32 || ATARI */
+ {"t", "from-date", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 't', "exclude before date"},
+ {"tt", "before-date", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_tt, "include before date"},
+ {"T", "test", o_NO_VALUE, o_NOT_NEGATABLE, 'T', "test updates before replacing archive"},
+ {"TT", "unzip-command", o_REQUIRED_VALUE,o_NOT_NEGATABLE,o_TT, "unzip command to use, name is added to end"},
+ {"u", "update", o_NO_VALUE, o_NOT_NEGATABLE, 'u', "update existing entries and add new"},
+ {"U", "copy-entries", o_NO_VALUE, o_NOT_NEGATABLE, 'U', "select from archive instead of file system"},
+#ifdef UNICODE_SUPPORT
+ {"UN", "unicode", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_UN, "UN=quit, warn, ignore, no, escape"},
+#endif
+ {"v", "verbose", o_NO_VALUE, o_NOT_NEGATABLE, 'v', "display additional information"},
+ {"", "version", o_NO_VALUE, o_NOT_NEGATABLE, o_ve, "(if no other args) show version information"},
+#ifdef VMS
+ {"V", "VMS-portable", o_NO_VALUE, o_NOT_NEGATABLE, 'V', "Store VMS attributes, portable file format"},
+ {"VV", "VMS-specific", o_NO_VALUE, o_NOT_NEGATABLE, o_VV, "Store VMS attributes, VMS specific format"},
+ {"w", "VMS-versions", o_NO_VALUE, o_NOT_NEGATABLE, 'w', "store VMS versions"},
+ {"ww", "VMS-dot-versions", o_NO_VALUE, o_NOT_NEGATABLE, o_ww, "store VMS versions as \".nnn\""},
+#endif /* VMS */
+ {"ws", "wild-stop-dirs", o_NO_VALUE, o_NOT_NEGATABLE, o_ws, "* stops at /, ** includes any /"},
+ {"x", "exclude", o_VALUE_LIST, o_NOT_NEGATABLE, 'x', "exclude files matching patterns"},
+/* {"X", "no-extra", o_NO_VALUE, o_NOT_NEGATABLE, 'X', "no extra"},
+*/
+ {"X", "strip-extra", o_NO_VALUE, o_NEGATABLE, 'X', "-X- keep all ef, -X strip but critical ef"},
+#ifdef S_IFLNK
+ {"y", "symlinks", o_NO_VALUE, o_NOT_NEGATABLE, 'y', "store symbolic links"},
+#endif /* S_IFLNK */
+ {"z", "archive-comment", o_NO_VALUE, o_NOT_NEGATABLE, 'z', "ask for archive comment"},
+ {"Z", "compression-method", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'Z', "compression method"},
+#if defined(MSDOS) || defined(OS2)
+ {"$", "volume-label", o_NO_VALUE, o_NOT_NEGATABLE, '$', "store volume label"},
+#endif
+#ifndef MACOS
+ {"@", "names-stdin", o_NO_VALUE, o_NOT_NEGATABLE, '@', "get file names from stdin, one per line"},
+#endif /* !MACOS */
+#ifdef NTSD_EAS
+ {"!", "use-privileges", o_NO_VALUE, o_NOT_NEGATABLE, '!', "use privileges"},
+#endif
+#ifdef RISCOS
+ {"/", "exts-to-swap", o_REQUIRED_VALUE, o_NOT_NEGATABLE, '/', "override Zip$Exts"},
+#endif
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
+
+
+#ifndef USE_ZIPMAIN
+int main(argc, argv)
+#else
+int zipmain(argc, argv)
+#endif
+int argc; /* number of tokens in command line */
+char **argv; /* command line tokens */
+/* Add, update, freshen, or delete zip entries in a zip file. See the
+ command help in help() above. */
+{
+ int d; /* true if just adding to a zip file */
+ char *e; /* malloc'd comment buffer */
+ struct flist far *f; /* steps through found linked list */
+ int i; /* arg counter, root directory flag */
+ int kk; /* next arg type (formerly another re-use of "k") */
+
+ /* zip64 support 09/05/2003 R.Nausedat */
+ uzoff_t c; /* start of central directory */
+ uzoff_t t; /* length of central directory */
+ zoff_t k; /* marked counter, comment size, entry count */
+ uzoff_t n; /* total of entry len's */
+
+ int o; /* true if there were any ZE_OPEN errors */
+ char *p; /* steps through option arguments */
+ char *pp; /* temporary pointer */
+ int r; /* temporary variable */
+ int s; /* flag to read names from stdin */
+ uzoff_t csize; /* compressed file size for stats */
+ uzoff_t usize; /* uncompressed file size for stats */
+ ulg tf; /* file time */
+ int first_listarg = 0;/* index of first arg of "process these files" list */
+ struct zlist far *v; /* temporary variable */
+ struct zlist far * far *w; /* pointer to last link in zfiles list */
+ FILE *x /*, *y */; /* input and output zip files (y global) */
+ struct zlist far *z; /* steps through zfiles linked list */
+ int bad_open_is_error = 0; /* if read fails, 0=warning, 1=error */
+#if 0
+ /* does not seem used */
+#ifdef WINDLL
+ int retcode; /* return code for dll */
+#endif /* WINDLL */
+#endif
+#if (!defined(VMS) && !defined(CMS_MVS))
+ char *zipbuf; /* stdio buffer for the zip file */
+#endif /* !VMS && !CMS_MVS */
+ FILE *comment_stream; /* set to stderr if anything is read from stdin */
+ int all_current; /* used by File Sync to determine if all entries are current */
+
+ struct filelist_struct *filearg;
+
+/* used by get_option */
+ unsigned long option; /* option ID returned by get_option */
+ int argcnt = 0; /* current argcnt in args */
+ int argnum = 0; /* arg number */
+ int optchar = 0; /* option state */
+ char *value = NULL; /* non-option arg, option value or NULL */
+ int negated = 0; /* 1 = option negated */
+ int fna = 0; /* current first non-opt arg */
+ int optnum = 0; /* index in table */
+
+ int show_options = 0; /* show options */
+ int show_what_doing = 0; /* show what doing */
+ int show_args = 0; /* show command line */
+ int seen_doubledash = 0; /* seen -- argument */
+ int key_needed = 0; /* prompt for encryption key */
+ int have_out = 0; /* if set in_path and out_path different archive */
+#ifdef UNICODE_TEST
+ int create_files = 0;
+#endif
+
+ char **args = NULL; /* could be wide argv */
+
+
+#ifdef THEOS
+ /* the argument expansion from the standard library is full of bugs */
+ /* use mine instead */
+ _setargv(&argc, &argv);
+ setlocale(LC_CTYPE, "I");
+#else
+ SETLOCALE(LC_CTYPE, "");
+#endif
+
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
+#endif
+
+#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
+ {
+ extern void DebugMalloc(void);
+ atexit(DebugMalloc);
+ }
+#endif
+
+#ifdef QDOS
+ {
+ extern void QDOSexit(void);
+ atexit(QDOSexit);
+ }
+#endif
+
+#ifdef NLM
+ {
+ extern void NLMexit(void);
+ atexit(NLMexit);
+ }
+#endif
+
+#ifdef RISCOS
+ set_prefix();
+#endif
+
+#ifdef __human68k__
+ fflush(stderr);
+ setbuf(stderr, NULL);
+#endif
+
+/* Re-initialize global variables to make the zip dll re-entrant. It is
+ * possible that we could get away with not re-initializing all of these
+ * but better safe than sorry.
+ */
+#if defined(MACOS) || defined(WINDLL) || defined(USE_ZIPMAIN)
+ action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
+ comadd = 0; /* 1=add comments for new files */
+ zipedit = 0; /* 1=edit zip comment and all file comments */
+ latest = 0; /* 1=set zip file time to time of latest file */
+ before = 0; /* 0=ignore, else exclude files before this time */
+ after = 0; /* 0=ignore, else exclude files newer than this time */
+ test = 0; /* 1=test zip file with unzip -t */
+ unzip_path = NULL; /* where to look for unzip command path */
+ tempdir = 0; /* 1=use temp directory (-b) */
+ junk_sfx = 0; /* 1=junk the sfx prefix */
+#if defined(AMIGA) || defined(MACOS)
+ filenotes = 0;/* 1=take comments from AmigaDOS/MACOS filenotes */
+#endif
+#ifndef USE_ZIPMAIN
+ zipstate = -1;
+#endif
+ tempzip = NULL;
+ fcount = 0;
+ recurse = 0; /* 1=recurse into directories; 2=match filenames */
+ dispose = 0; /* 1=remove files after put in zip file */
+ pathput = 1; /* 1=store path with name */
+ method = BEST; /* one of BEST, DEFLATE (only), or STORE (only) */
+ dosify = 0; /* 1=make new entries look like MSDOS */
+ verbose = 0; /* 1=report oddities in zip file structure */
+ fix = 0; /* 1=fix the zip file */
+ adjust = 0; /* 1=adjust offsets for sfx'd file (keep preamble) */
+ level = 6; /* 0=fastest compression, 9=best compression */
+ translate_eol = 0; /* Translate end-of-line LF -> CR LF */
+#if defined(OS2) || defined(WIN32)
+ use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
+#endif
+#ifdef NTSD_EAS
+ use_privileges = 0; /* 1=use security privileges overrides */
+#endif
+ no_wild = 0; /* 1 = wildcards are disabled */
+#ifdef WILD_STOP_AT_DIR
+ wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
+#else
+ wild_stop_at_dir = 0; /* default wildcards do include / in matches */
+#endif
+
+ skip_this_disk = 0;
+ des_good = 0; /* Good data descriptor found */
+ des_crc = 0; /* Data descriptor CRC */
+ des_csize = 0; /* Data descriptor csize */
+ des_usize = 0; /* Data descriptor usize */
+
+ dot_size = 0; /* buffers processed in deflate per dot, 0 = no dots */
+ dot_count = 0; /* buffers seen, recyles at dot_size */
+
+ display_counts = 0; /* display running file count */
+ display_bytes = 0; /* display running bytes remaining */
+ display_globaldots = 0; /* display dots for archive instead of each file */
+ display_volume = 0; /* display current input and output volume (disk) numbers */
+ display_usize = 0; /* display uncompressed bytes */
+
+ files_so_far = 0; /* files processed so far */
+ bad_files_so_far = 0; /* bad files skipped so far */
+ files_total = 0; /* files total to process */
+ bytes_so_far = 0; /* bytes processed so far (from initial scan) */
+ good_bytes_so_far = 0; /* good bytes read so far */
+ bad_bytes_so_far = 0; /* bad bytes skipped so far */
+ bytes_total = 0; /* total bytes to process (from initial scan) */
+
+ logall = 0; /* 0 = warnings/errors, 1 = all */
+ logfile = NULL; /* pointer to open logfile or NULL */
+ logfile_append = 0; /* append to existing logfile */
+ logfile_path = NULL; /* pointer to path of logfile */
+
+ hidden_files = 0; /* process hidden and system files */
+ volume_label = 0; /* add volume label */
+ dirnames = 1; /* include directory entries by default */
+#if defined(WIN32)
+ only_archive_set = 0; /* only include if DOS archive bit set */
+ clear_archive_bits = 0; /* clear DOS archive bit of included files */
+#endif
+ linkput = 0; /* 1=store symbolic links as such */
+ noisy = 1; /* 0=quiet operation */
+ extra_fields = 1; /* 0=create minimum, 1=don't copy old, 2=keep old */
+
+ use_descriptors = 0; /* 1=use data descriptors 12/29/04 */
+ zip_to_stdout = 0; /* output zipfile to stdout 12/30/04 */
+ allow_empty_archive = 0;/* if no files, create empty archive anyway 12/28/05 */
+ copy_only = 0; /* 1=copying archive entries only */
+
+ output_seekable = 1; /* 1 = output seekable 3/13/05 EG */
+
+#ifdef ZIP64_SUPPORT /* zip64 support 10/4/03 */
+ force_zip64 = -1; /* if 1 force entries to be zip64 */
+ /* mainly for streaming from stdin */
+ zip64_entry = 0; /* current entry needs Zip64 */
+ zip64_archive = 0; /* if 1 then at least 1 entry needs zip64 */
+#endif
+
+#ifdef UNICODE_SUPPORT
+ utf8_force = 0; /* 1=force storing UTF-8 as standard per AppNote bit 11 */
+#endif
+
+ unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */
+ unicode_mismatch = 1; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+
+ scan_delay = 5; /* seconds before display Scanning files message */
+ scan_dot_time = 2; /* time in seconds between Scanning files dots */
+ scan_start = 0; /* start of scan */
+ scan_last = 0; /* time of last message */
+ scan_started = 0; /* scan has started */
+ scan_count = 0; /* Used for Scanning files ... message */
+
+ before = 0; /* 0=ignore, else exclude files before this time */
+ after = 0; /* 0=ignore, else exclude files newer than this time */
+
+ special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
+ key = NULL; /* Scramble password if scrambling */
+ key_needed = 0; /* Need scramble password */
+ tempath = NULL; /* Path for temporary files */
+ patterns = NULL; /* List of patterns to be matched */
+ pcount = 0; /* number of patterns */
+ icount = 0; /* number of include only patterns */
+ Rcount = 0; /* number of -R include patterns */
+
+ found = NULL; /* List of names found, or new found entry */
+ fnxt = &found;
+
+ /* used by get_option */
+ argcnt = 0; /* size of args */
+ argnum = 0; /* current arg number */
+ optchar = 0; /* option state */
+ value = NULL; /* non-option arg, option value or NULL */
+ negated = 0; /* 1 = option negated */
+ fna = 0; /* current first nonopt arg */
+ optnum = 0; /* option index */
+
+ show_options = 0; /* 1 = show options */
+ show_what_doing = 0; /* 1 = show what zip doing */
+ show_args = 0; /* 1 = show command line */
+ seen_doubledash = 0; /* seen -- argument */
+
+ zipfile = NULL; /* path of usual in and out zipfile */
+ tempzip = NULL; /* name of temp file */
+ y = NULL; /* output file now global so can change in splits */
+ in_file = NULL; /* current input file for splits */
+ in_split_path = NULL; /* current in split path */
+ in_path = NULL; /* used by splits to track changing split locations */
+ out_path = NULL; /* if set, use -O out_path as output */
+ have_out = 0; /* if set, in_path and out_path not the same archive */
+
+ total_disks = 0; /* total disks in archive */
+ current_in_disk = 0; /* current read split disk */
+ current_in_offset = 0; /* current offset in current read disk */
+ skip_current_disk = 0; /* if != 0 and fix then skip entries on this disk */
+
+ zip64_eocd_disk = 0; /* disk with Zip64 End Of Central Directory Record */
+ zip64_eocd_offset = 0; /* offset for Zip64 EOCD Record */
+
+ current_local_disk = 0; /* disk with current local header */
+
+ current_disk = 0; /* current disk number */
+ cd_start_disk = (ulg)-1; /* central directory start disk */
+ cd_start_offset = 0; /* offset of start of cd on cd start disk */
+ cd_entries_this_disk = 0; /* cd entries this disk */
+ total_cd_entries = 0; /* total cd entries in new/updated archive */
+
+ /* for split method 1 (keep split with local header open and update) */
+ current_local_tempname = NULL; /* name of temp file */
+ current_local_file = NULL; /* file pointer for current local header */
+ current_local_offset = 0; /* offset to start of current local header */
+
+ /* global */
+ bytes_this_split = 0; /* bytes written to the current split */
+ read_split_archive = 0; /* 1=scanzipf_reg detected spanning signature */
+ split_method = 0; /* 0=no splits, 1=update LHs, 2=data descriptors */
+ split_size = 0; /* how big each split should be */
+ split_bell = 0; /* when pause for next split ring bell */
+ bytes_prev_splits = 0; /* total bytes written to all splits before this */
+ bytes_this_entry = 0; /* bytes written for this entry across all splits */
+ noisy_splits = 0; /* be verbose about creating splits */
+ mesg_line_started = 0; /* 1=started writing a line to mesg */
+ logfile_line_started = 0; /* 1=started writing a line to logfile */
+
+ filelist = NULL;
+ filearg_count = 0;
+ allow_empty_archive = 0; /* if no files, allow creation of empty archive anyway */
+ bad_open_is_error = 0; /* if read fails, 0=warning, 1=error */
+ unicode_mismatch = 0; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+ show_files = 0; /* show files to operate on and exit */
+ scan_delay = 5; /* seconds before display Scanning files message */
+ scan_dot_time = 2; /* time in seconds between Scanning files dots */
+ scan_started = 0; /* space at start of scan has been displayed */
+ scan_last = 0; /* Time last dot displayed for Scanning files message */
+ scan_start = 0; /* Time scanning started for Scanning files message */
+#ifdef UNICODE_SUPPORT
+ use_wide_to_mb_default = 0;
+#endif
+ filter_match_case = 1; /* default is to match case when matching archive entries */
+ allow_fifo = 0; /* 1=allow reading Unix FIFOs, waiting if pipe open */
+
+#if !defined(MACOS) && !defined(USE_ZIPMAIN)
+ retcode = setjmp(zipdll_error_return);
+ if (retcode) {
+ return retcode;
+ }
+#endif /* !MACOS */
+#endif /* MACOS || WINDLL */
+
+#if !defined(ALLOW_REGEX) && (defined(MSDOS) || defined(WIN32))
+ allow_regex = 0; /* 1 = allow [list] matching (regex) */
+#else
+ allow_regex = 1;
+#endif
+
+ mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
+ comment_stream = (FILE *)stdin;
+
+ init_upper(); /* build case map table */
+
+#ifdef LARGE_FILE_SUPPORT
+ /* test if we can support large files - 9/29/04 */
+ if (sizeof(zoff_t) < 8) {
+ ZIPERR(ZE_COMPERR, "LARGE_FILE_SUPPORT enabled but OS not supporting it");
+ }
+#endif
+ /* test if sizes are the same - 12/30/04 */
+ if (sizeof(uzoff_t) != sizeof(zoff_t)){
+ ZIPERR(ZE_COMPERR, "uzoff_t not same size as zoff_t");
+ }
+
+#if (defined(WIN32) && defined(USE_EF_UT_TIME))
+ /* For the Win32 environment, we may have to "prepare" the environment
+ prior to the tzset() call, to work around tzset() implementation bugs.
+ */
+ iz_w32_prepareTZenv();
+#endif
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+# ifndef VALID_TIMEZONE
+# define VALID_TIMEZONE(tmp) \
+ (((tmp = getenv("TZ")) != NULL) && (*tmp != '\0'))
+# endif
+ zp_tz_is_valid = VALID_TIMEZONE(p);
+#if (defined(AMIGA) || defined(DOS))
+ if (!zp_tz_is_valid)
+ extra_fields = 0; /* disable storing "UT" time stamps */
+#endif /* AMIGA || DOS */
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+/* For systems that do not have tzset() but supply this function using another
+ name (_tzset() or something similar), an appropiate "#define tzset ..."
+ should be added to the system specifc configuration section. */
+#if (!defined(TOPS20) && !defined(VMS))
+#if (!defined(RISCOS) && !defined(MACOS) && !defined(QDOS))
+#if (!defined(BSD) && !defined(MTS) && !defined(CMS_MVS) && !defined(TANDEM))
+ tzset();
+#endif
+#endif
+#endif
+
+#ifdef VMSCLI
+ {
+ ulg status = vms_zip_cmdline(&argc, &argv);
+ if (!(status & 1))
+ return status;
+ }
+#endif /* VMSCLI */
+
+ /* Substitutes the extended command line argument list produced by
+ * the MKS Korn Shell in place of the command line info from DOS.
+ */
+
+ /* extract extended argument list from environment */
+ expand_args(&argc, &argv);
+
+#ifndef WINDLL
+ /* Process arguments */
+ diag("processing arguments");
+ /* First, check if just the help or version screen should be displayed */
+ if (argc == 1 && isatty(1)) /* no arguments, and output screen available */
+ { /* show help screen */
+# ifdef VMSCLI
+ VMSCLI_help();
+# else
+ help();
+# endif
+ EXIT(ZE_OK);
+ }
+ /* Check -v here as env arg can change argc. Handle --version in main switch. */
+ else if (argc == 2 && strcmp(argv[1], "-v") == 0 &&
+ /* only "-v" as argument, and */
+ (isatty(1) || isatty(0)))
+ /* stdout or stdin is connected to console device */
+ { /* show diagnostic version info */
+ version_info();
+ EXIT(ZE_OK);
+ }
+# ifndef VMS
+# ifndef RISCOS
+ envargs(&argc, &argv, "ZIPOPT", "ZIP"); /* get options from environment */
+# else /* RISCOS */
+ envargs(&argc, &argv, "ZIPOPT", "Zip$Options"); /* get options from environment */
+ getRISCOSexts("Zip$Exts"); /* get the extensions to swap from environment */
+# endif /* ? RISCOS */
+# else /* VMS */
+ envargs(&argc, &argv, "ZIPOPT", "ZIP_OPTS"); /* 4th arg for unzip compat. */
+# endif /* ?VMS */
+#endif /* !WINDLL */
+
+ zipfile = tempzip = NULL;
+ y = NULL;
+ d = 0; /* disallow adding to a zip file */
+#if (!defined(MACOS) && !defined(WINDLL) && !defined(NLM))
+ signal(SIGINT, handler);
+#ifdef SIGTERM /* AMIGADOS and others have no SIGTERM */
+ signal(SIGTERM, handler);
+#endif
+# if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
+ signal(SIGABRT, handler);
+# endif
+# ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+# endif
+# ifdef SIGBUS
+ signal(SIGBUS, handler);
+# endif
+# ifdef SIGILL
+ signal(SIGILL, handler);
+# endif
+# ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+# endif
+#endif /* !MACOS && !WINDLL && !NLM */
+#ifdef NLM
+ NLMsignals();
+#endif
+
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ /* check if this Win32 OS has support for wide character calls */
+ has_win32_wide();
+#endif
+
+ /* make copy of args that can use with insert_arg() used by get_option() */
+ args = copy_args(argv, 0);
+
+ kk = 0; /* Next non-option argument type */
+ s = 0; /* set by -@ */
+
+ /*
+ -------------------------------------------
+ Process command line using get_option
+ -------------------------------------------
+
+ Each call to get_option() returns either a command
+ line option and possible value or a non-option argument.
+ Arguments are permuted so that all options (-r, -b temp)
+ are returned before non-option arguments (zipfile).
+ Returns 0 when nothing left to read.
+ */
+
+ /* set argnum = 0 on first call to init get_option */
+ argnum = 0;
+
+ /* get_option returns the option ID and updates parameters:
+ args - usually same as argv if no argument file support
+ argcnt - current argc for args
+ value - char* to value (free() when done with it) or NULL if no value
+ negated - option was negated with trailing -
+ */
+
+ while ((option = get_option(&args, &argcnt, &argnum,
+ &optchar, &value, &negated,
+ &fna, &optnum, 0)))
+ {
+ switch (option)
+ {
+#ifdef EBCDIC
+ case 'a':
+ aflag = ASCII;
+ printf("Translating to ASCII...\n");
+ break;
+#endif /* EBCDIC */
+#ifdef CMS_MVS
+ case 'B':
+ bflag = 1;
+ printf("Using binary mode...\n");
+ break;
+#endif /* CMS_MVS */
+#ifdef TANDEM
+ case 'B':
+ nskformatopt(value);
+ free(value);
+ break;
+#endif
+
+ case '0':
+ method = STORE; level = 0; break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* Set the compression efficacy */
+ level = (int)option - '0'; break;
+ case 'A': /* Adjust unzipsfx'd zipfile: adjust offsets only */
+ adjust = 1; break;
+#if defined(WIN32)
+ case o_AC:
+ clear_archive_bits = 1; break;
+ case o_AS:
+ /* Since some directories could be empty if no archive bits are
+ set for files in a directory, don't add directory entries (-D).
+ Just files with the archive bit set are added, including paths
+ (unless paths are excluded). All major unzips should create
+ directories for the paths as needed. */
+ dirnames = 0;
+ only_archive_set = 1; break;
+#endif /* MSDOS || OS2 || WIN32 */
+ case 'b': /* Specify path for temporary file */
+ tempdir = 1;
+ tempath = value;
+ break;
+ case 'c': /* Add comments for new files in zip file */
+ comadd = 1; break;
+
+ /* -C, -C2, and -C5 are with -V */
+
+ case 'd': /* Delete files from zip file */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = DELETE;
+ break;
+#ifdef MACOS
+ case o_df:
+ MacZip.DataForkOnly = true;
+ break;
+#endif /* MACOS */
+ case o_db:
+ if (negated)
+ display_bytes = 0;
+ else
+ display_bytes = 1;
+ break;
+ case o_dc:
+ if (negated)
+ display_counts = 0;
+ else
+ display_counts = 1;
+ break;
+ case o_dd:
+ /* display dots */
+ display_globaldots = 0;
+ if (negated) {
+ dot_count = 0;
+ } else {
+ /* set default dot size if dot_size not set (dot_count = 0) */
+ if (dot_count == 0)
+ /* default to 10 MB */
+ dot_size = 10 * 0x100000;
+ dot_count = -1;
+ }
+ break;
+ case o_dg:
+ /* display dots globally for archive instead of for each file */
+ if (negated) {
+ display_globaldots = 0;
+ } else {
+ display_globaldots = 1;
+ /* set default dot size if dot_size not set (dot_count = 0) */
+ if (dot_count == 0)
+ dot_size = 10 * 0x100000;
+ dot_count = -1;
+ }
+ break;
+ case o_ds:
+ /* input dot_size is now actual dot size to account for
+ different buffer sizes */
+ if (value == NULL)
+ dot_size = 10 * 0x100000;
+ else if (value[0] == '\0') {
+ /* default to 10 MB */
+ dot_size = 10 * 0x100000;
+ free(value);
+ } else {
+ dot_size = ReadNumString(value);
+ if (dot_size == (zoff_t)-1) {
+ sprintf(errbuf, "option -ds (--dot-size) has bad size: '%s'",
+ value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ if (dot_size < 0x400) {
+ /* < 1 KB so there is no multiplier, assume MB */
+ dot_size *= 0x100000;
+
+ } else if (dot_size < 0x400L * 32) {
+ /* 1K <= dot_size < 32K */
+ sprintf(errbuf, "dot size must be at least 32 KB: '%s'", value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+
+ } else {
+ /* 32K <= dot_size */
+ }
+ free(value);
+ }
+ dot_count = -1;
+ break;
+ case o_du:
+ if (negated)
+ display_usize = 0;
+ else
+ display_usize = 1;
+ break;
+ case o_dv:
+ if (negated)
+ display_volume = 0;
+ else
+ display_volume = 1;
+ break;
+ case 'D': /* Do not add directory entries */
+ dirnames = 0; break;
+ case o_DF: /* Create a difference archive */
+ diff_mode = 1;
+ allow_empty_archive = 1;
+ break;
+ case 'e': /* Encrypt */
+#if !CRYPT
+ ZIPERR(ZE_PARMS, "encryption not supported");
+#else /* CRYPT */
+ if (key)
+ free(key);
+ key_needed = 1;
+#endif /* !CRYPT */
+ break;
+ case 'F': /* fix the zip file */
+ fix = 1; break;
+ case o_FF: /* try harder to fix file */
+ fix = 2; break;
+ case o_FI:
+ if (negated)
+ allow_fifo = 0;
+ else
+ allow_fifo = 1;
+ break;
+ case o_FS: /* delete exiting entries in archive where there is
+ no matching file on file system */
+ filesync = 1; break;
+ case 'f': /* Freshen zip file--overwrite only */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = FRESHEN;
+ break;
+ case 'g': /* Allow appending to a zip file */
+ d = 1; break;
+#ifndef WINDLL
+ case 'h': case 'H': case '?': /* Help */
+#ifdef VMSCLI
+ VMSCLI_help();
+#else
+ help();
+#endif
+ RETURN(finish(ZE_OK));
+#endif /* !WINDLL */
+
+#ifndef WINDLL
+ case o_h2: /* Extended Help */
+ help_extended();
+ RETURN(finish(ZE_OK));
+#endif /* !WINDLL */
+
+ /* -i is with -x */
+#if defined(VMS) || defined(WIN32)
+ case o_ic: /* Ignore case (case-insensitive matching of archive entries) */
+ if (negated)
+ filter_match_case = 1;
+ else
+ filter_match_case = 0;
+ break;
+#endif
+#ifdef RISCOS
+ case 'I': /* Don't scan through Image files */
+ scanimage = 0;
+ break;
+#endif
+#ifdef MACOS
+ case o_jj: /* store absolute path including volname */
+ MacZip.StoreFullPath = true;
+ break;
+#endif /* ?MACOS */
+ case 'j': /* Junk directory names */
+ pathput = 0; break;
+ case 'J': /* Junk sfx prefix */
+ junk_sfx = 1; break;
+ case 'k': /* Make entries using DOS names (k for Katz) */
+ dosify = 1; break;
+ case 'l': /* Translate end-of-line */
+ translate_eol = 1; break;
+ case o_ll:
+ translate_eol = 2; break;
+ case o_lf:
+ /* open a logfile */
+ /* allow multiple use of option but only last used */
+ if (logfile_path) {
+ free(logfile_path);
+ }
+ logfile_path = value;
+ break;
+ case o_la:
+ /* append to existing logfile */
+ if (negated)
+ logfile_append = 0;
+ else
+ logfile_append = 1;
+ break;
+ case o_li:
+ /* log all including informational messages */
+ if (negated)
+ logall = 0;
+ else
+ logall = 1;
+ break;
+#ifndef WINDLL
+ case 'L': /* Show license */
+ license();
+ RETURN(finish(ZE_OK));
+#endif
+ case 'm': /* Delete files added or updated in zip file */
+ dispose = 1; break;
+ case o_mm: /* To prevent use of -mm for -MM */
+ ZIPERR(ZE_PARMS, "-mm not supported, Must_Match is -MM");
+ dispose = 1; break;
+ case o_MM: /* Exit with error if input file can't be read */
+ bad_open_is_error = 1; break;
+ case 'n': /* Don't compress files with a special suffix */
+ special = value;
+ /* special = NULL; */ /* will be set at next argument */
+ break;
+ case o_nw: /* no wildcards - wildcards are handled like other characters */
+ no_wild = 1;
+ break;
+#if defined(AMIGA) || defined(MACOS)
+ case 'N': /* Get zipfile comments from AmigaDOS/MACOS filenotes */
+ filenotes = 1; break;
+#endif
+ case 'o': /* Set zip file time to time of latest file in it */
+ latest = 1; break;
+ case 'O': /* Set output file different than input archive */
+ out_path = ziptyp(value);
+ free(value);
+ have_out = 1;
+ break;
+ case 'p': /* Store path with name */
+ break; /* (do nothing as annoyance avoidance) */
+ case 'P': /* password for encryption */
+ if (key != NULL) {
+ free(key);
+ }
+#if CRYPT
+ key = value;
+ key_needed = 0;
+#else
+ ZIPERR(ZE_PARMS, "encryption not supported");
+#endif /* CRYPT */
+ break;
+#if defined(QDOS) || defined(QLZIP)
+ case 'Q':
+ qlflag = strtol(value, NULL, 10);
+ /* qlflag = strtol((p+1), &p, 10); */
+ /* p--; */
+ if (qlflag == 0) qlflag = 4;
+ free(value);
+ break;
+#endif
+ case 'q': /* Quiet operation */
+ noisy = 0;
+#ifdef MACOS
+ MacZip.MacZip_Noisy = false;
+#endif /* MACOS */
+ if (verbose) verbose--;
+ break;
+ case 'r': /* Recurse into subdirectories, match full path */
+ if (recurse == 2) {
+ ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ }
+ recurse = 1; break;
+ case 'R': /* Recurse into subdirectories, match filename */
+ if (recurse == 1) {
+ ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ }
+ recurse = 2; break;
+
+ case o_RE: /* Allow [list] matching (regex) */
+ allow_regex = 1; break;
+
+ case o_sc: /* show command line args */
+ show_args = 1; break;
+#ifdef UNICODE_TEST
+ case o_sC: /* create empty files from archive names */
+ create_files = 1;
+ show_files = 1; break;
+#endif
+ case o_sd: /* show debugging */
+ show_what_doing = 1; break;
+ case o_sf: /* show files to operate on */
+ if (!negated)
+ show_files = 1;
+ else
+ show_files = 2;
+ break;
+ case o_so: /* show all options */
+ show_options = 1; break;
+#ifdef UNICODE_SUPPORT
+ case o_su: /* -sf but also show Unicode if exists */
+ if (!negated)
+ show_files = 3;
+ else
+ show_files = 4;
+ break;
+ case o_sU: /* -sf but only show Unicode if exists or normal if not */
+ if (!negated)
+ show_files = 5;
+ else
+ show_files = 6;
+ break;
+#endif
+
+ case 's': /* enable split archives */
+ /* get the split size from value */
+ if (strcmp(value, "-") == 0) {
+ /* -s- do not allow splits */
+ split_method = -1;
+ } else {
+ split_size = ReadNumString(value);
+ if (split_size == (uzoff_t)-1) {
+ sprintf(errbuf, "bad split size: '%s'", value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ if (split_size == 0) {
+ /* do not allow splits */
+ split_method = -1;
+ } else {
+ if (split_method == 0) {
+ split_method = 1;
+ }
+ if (split_size < 0x400) {
+ /* < 1 KB there is no multiplier, assume MB */
+ split_size *= 0x100000;
+ }
+ /* By setting the minimum split size to 64 KB we avoid
+ not having enough room to write a header unsplit
+ which is required */
+ if (split_size < 0x400L * 64) {
+ /* split_size < 64K */
+ sprintf(errbuf, "minimum split size is 64 KB: '%s'", value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ }
+ }
+ free(value);
+ break;
+ case o_sb: /* when pause for next split ring bell */
+ split_bell = 1;
+ break;
+ case o_sp: /* enable split select - pause splitting between splits */
+ use_descriptors = 1;
+ split_method = 2;
+ break;
+ case o_sv: /* be verbose about creating splits */
+ noisy_splits = 1;
+ break;
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
+ case 'S':
+ hidden_files = 1; break;
+#endif /* MSDOS || OS2 || WIN32 || ATARI */
+#ifdef MACOS
+ case 'S':
+ MacZip.IncludeInvisible = true; break;
+#endif /* MACOS */
+ case 't': /* Exclude files earlier than specified date */
+ {
+ int yyyy, mm, dd; /* results of sscanf() */
+
+ /* Support ISO 8601 & American dates */
+ if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+ sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+ mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+ ZIPERR(ZE_PARMS,
+ "invalid date entered for -t option - use mmddyyyy or yyyy-mm-dd");
+ }
+ before = dostime(yyyy, mm, dd, 0, 0, 0);
+ }
+ free(value);
+ break;
+ case o_tt: /* Exclude files at or after specified date */
+ {
+ int yyyy, mm, dd; /* results of sscanf() */
+
+ /* Support ISO 8601 & American dates */
+ if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+ sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+ mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+ ZIPERR(ZE_PARMS,
+ "invalid date entered for -tt option - use mmddyyyy or yyyy-mm-dd");
+ }
+ after = dostime(yyyy, mm, dd, 0, 0, 0);
+ }
+ free(value);
+ break;
+ case 'T': /* test zip file */
+ test = 1; break;
+ case o_TT: /* command path to use instead of 'unzip -t ' */
+ if (unzip_path)
+ free(unzip_path);
+ unzip_path = value;
+ break;
+ case 'U': /* Select archive entries to keep or operate on */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = ARCHIVE;
+ break;
+#ifdef UNICODE_SUPPORT
+ case o_UN: /* Unicode */
+ if (abbrevmatch("quit", value, 0, 1)) {
+ /* Unicode path mismatch is error */
+ unicode_mismatch = 0;
+ } else if (abbrevmatch("warn", value, 0, 1)) {
+ /* warn of mismatches and continue */
+ unicode_mismatch = 1;
+ } else if (abbrevmatch("ignore", value, 0, 1)) {
+ /* ignore mismatches and continue */
+ unicode_mismatch = 2;
+ } else if (abbrevmatch("no", value, 0, 1)) {
+ /* no use Unicode path */
+ unicode_mismatch = 3;
+ } else if (abbrevmatch("escape", value, 0, 1)) {
+ /* escape all non-ASCII characters */
+ unicode_escape_all = 1;
+
+ } else if (abbrevmatch("UTF8", value, 0, 1)) {
+ /* force storing UTF-8 as standard per AppNote bit 11 */
+ utf8_force = 1;
+
+ } else {
+ zipwarn("-UN must be Quit, Warn, Ignore, No, Escape, or UTF8: ", value);
+
+ free(value);
+ ZIPERR(ZE_PARMS, "-UN (unicode) bad value");
+ }
+ free(value);
+ break;
+#endif
+ case 'u': /* Update zip file--overwrite only if newer */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = UPDATE;
+ break;
+ case 'v': /* Either display version information or */
+ case o_ve: /* Mention oddities in zip file structure */
+ if (option == o_ve || /* --version */
+ (argcnt == 2 && strlen(args[1]) == 2)) { /* -v only */
+ /* display version */
+#ifndef WINDLL
+ version_info();
+#else
+ zipwarn("version information not supported for dll", "");
+#endif
+ RETURN(finish(ZE_OK));
+ } else {
+ noisy = 1;
+ verbose++;
+ }
+ break;
+#ifdef VMS
+ case 'C': /* Preserve case (- = down-case) all. */
+ if (negated)
+ { /* Down-case all. */
+ if ((vms_case_2 > 0) || (vms_case_5 > 0))
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C-)");
+ }
+ vms_case_2 = -1;
+ vms_case_5 = -1;
+ }
+ else
+ { /* Not negated. Preserve all. */
+ if ((vms_case_2 < 0) || (vms_case_5 < 0))
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C)");
+ }
+ vms_case_2 = 1;
+ vms_case_5 = 1;
+ }
+ break;
+ case o_C2: /* Preserve case (- = down-case) ODS2. */
+ if (negated)
+ { /* Down-case ODS2. */
+ if (vms_case_2 > 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C2-)");
+ }
+ vms_case_2 = -1;
+ }
+ else
+ { /* Not negated. Preserve ODS2. */
+ if (vms_case_2 < 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C2)");
+ }
+ vms_case_2 = 1;
+ }
+ break;
+ case o_C5: /* Preserve case (- = down-case) ODS5. */
+ if (negated)
+ { /* Down-case ODS5. */
+ if (vms_case_5 > 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C5-)");
+ }
+ vms_case_5 = -1;
+ }
+ else
+ { /* Not negated. Preserve ODS5. */
+ if (vms_case_5 < 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C5)");
+ }
+ vms_case_5 = 1;
+ }
+ break;
+ case 'V': /* Store in VMS format. (Record multiples.) */
+ vms_native = 1; break;
+ /* below does work with new parser but doesn't allow tracking
+ -VV separately, like adding a separate description */
+ /* vms_native++; break; */
+ case o_VV: /* Store in VMS specific format */
+ vms_native = 2; break;
+ case 'w': /* Append the VMS version number */
+ vmsver |= 1; break;
+ case o_ww: /* Append the VMS version number as ".nnn". */
+ vmsver |= 3; break;
+#endif /* VMS */
+ case o_ws: /* Wildcards do not include directory boundaries in matches */
+ wild_stop_at_dir = 1;
+ break;
+
+ case 'i': /* Include only the following files */
+ /* if nothing matches include list then still create an empty archive */
+ allow_empty_archive = 1;
+ case 'x': /* Exclude following files */
+ add_filter((int) option, value);
+ free(value);
+ break;
+#ifdef S_IFLNK
+ case 'y': /* Store symbolic links as such */
+ linkput = 1; break;
+#endif /* S_IFLNK */
+ case 'z': /* Edit zip file comment */
+ zipedit = 1; break;
+ case 'Z': /* Compression method */
+ if (abbrevmatch("deflate", value, 0, 1)) {
+ /* deflate */
+ method = DEFLATE;
+ } else if (abbrevmatch("store", value, 0, 1)) {
+ /* store */
+ method = STORE;
+ } else if (abbrevmatch("bzip2", value, 0, 1)) {
+ /* bzip2 */
+#ifdef BZIP2_SUPPORT
+ method = BZIP2;
+#else
+ ZIPERR(ZE_COMPERR, "Compression method bzip2 not enabled");
+#endif
+ } else {
+#ifdef BZIP2_SUPPORT
+ zipwarn("valid compression methods are: store, deflate, bzip2", "");
+#else
+ zipwarn("valid compression methods are: store, deflate)", "");
+#endif
+ zipwarn("unknown compression method found: ", value);
+ free(value);
+ ZIPERR(ZE_PARMS, "Option -Z (--compression-method): unknown method");
+ }
+ free(value);
+ break;
+#if defined(MSDOS) || defined(OS2)
+ case '$': /* Include volume label */
+ volume_label = 1; break;
+#endif
+#ifndef MACOS
+ case '@': /* read file names from stdin */
+ comment_stream = NULL;
+ s = 1; /* defer -@ until have zipfile name */
+ break;
+#endif /* !MACOS */
+ case 'X':
+ if (negated)
+ extra_fields = 2;
+ else
+ extra_fields = 0;
+ break;
+#ifdef OS2
+ case 'E':
+ /* use the .LONGNAME EA (if any) as the file's name. */
+ use_longname_ea = 1;
+ break;
+#endif
+#ifdef NTSD_EAS
+ case '!':
+ /* use security privilege overrides */
+ use_privileges = 1;
+ break;
+#endif
+#ifdef RISCOS
+ case '/':
+ exts2swap = value; /* override Zip$Exts */
+ break;
+#endif
+ case o_des:
+ use_descriptors = 1;
+ break;
+
+#ifdef ZIP64_SUPPORT
+ case o_z64: /* Force creation of Zip64 entries */
+ if (negated) {
+ force_zip64 = 0;
+ } else {
+ force_zip64 = 1;
+ }
+ break;
+#endif
+
+ case o_NON_OPTION_ARG:
+ /* not an option */
+ /* no more options as permuting */
+ /* just dash also ends up here */
+
+ if (recurse != 2 && kk == 0 && patterns == NULL) {
+ /* have all filters so convert filterlist to patterns array
+ as PROCNAME needs patterns array */
+ filterlist_to_patterns();
+ }
+
+ /* "--" stops arg processing for remaining args */
+ /* ignore only first -- */
+ if (strcmp(value, "--") == 0 && seen_doubledash == 0) {
+ /* -- */
+ seen_doubledash = 1;
+ if (kk == 0) {
+ ZIPERR(ZE_PARMS, "can't use -- before archive name");
+ }
+
+ /* just ignore as just marks what follows as non-option arguments */
+
+ } else if (kk == 6) {
+ /* value is R pattern */
+ add_filter((int)'R', value);
+ free(value);
+ if (first_listarg == 0) {
+ first_listarg = argnum;
+ }
+ } else switch (kk)
+ {
+ case 0:
+ /* first non-option arg is zipfile name */
+#if (!defined(MACOS) && !defined(WINDLL))
+ if (strcmp(value, "-") == 0) { /* output zipfile is dash */
+ /* just a dash */
+ zipstdout();
+ } else
+#endif /* !MACOS && !WINDLL */
+ {
+ /* name of zipfile */
+ if ((zipfile = ziptyp(value)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ /* read zipfile if exists */
+ /*
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+ */
+ free(value);
+ }
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipfile name '%s'\n", zipfile);
+ fflush(mesg);
+ }
+ /* if in_path not set, use zipfile path as usual for input */
+ /* in_path is used as the base path to find splits */
+ if (in_path == NULL) {
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ strcpy(in_path, zipfile);
+ }
+ /* if out_path not set, use zipfile path as usual for output */
+ /* out_path is where the output archive is written */
+ if (out_path == NULL) {
+ if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ strcpy(out_path, zipfile);
+ }
+ kk = 3;
+ if (s)
+ {
+ /* do -@ and get names from stdin */
+ /* should be able to read names from
+ stdin and output to stdout, but
+ this was not allowed in old code.
+ This check moved to kk = 3 case to fix. */
+ /* if (strcmp(zipfile, "-") == 0) {
+ ZIPERR(ZE_PARMS, "can't use - and -@ together");
+ }
+ */
+ while ((pp = getnam(stdin)) != NULL)
+ {
+ kk = 4;
+ if (recurse == 2) {
+ /* reading patterns from stdin */
+ add_filter((int)'R', pp);
+ } else {
+ /* file argument now processed later */
+ add_name(pp);
+ }
+ /*
+ if ((r = PROCNAME(pp)) != ZE_OK) {
+ if (r == ZE_MISS)
+ zipwarn("name not matched: ", pp);
+ else {
+ ZIPERR(r, pp);
+ }
+ }
+ */
+ free(pp);
+ }
+ s = 0;
+ }
+ if (recurse == 2) {
+ /* rest are -R patterns */
+ kk = 6;
+ }
+ break;
+
+ case 3: case 4:
+ /* no recurse and -r file names */
+ /* can't read filenames -@ and input - from stdin at
+ same time */
+ if (s == 1 && strcmp(value, "-") == 0) {
+ ZIPERR(ZE_PARMS, "can't read input (-) and filenames (-@) both from stdin");
+ }
+ /* add name to list for later processing */
+ add_name(value);
+ /*
+ if ((r = PROCNAME(value)) != ZE_OK) {
+ if (r == ZE_MISS)
+ zipwarn("name not matched: ", value);
+ else {
+ ZIPERR(r, value);
+ }
+ }
+ */
+ if (kk == 3) {
+ first_listarg = argnum;
+ kk = 4;
+ }
+ break;
+
+ } /* switch kk */
+ break;
+
+ default:
+ /* should never get here as get_option will exit if not in table */
+ sprintf(errbuf, "no such option ID: %ld", option);
+ ZIPERR(ZE_PARMS, errbuf);
+
+ } /* switch */
+ }
+
+
+ /* do processing of command line and one-time tasks */
+
+ /* Key not yet specified. If needed, get/verify it now. */
+ if (key_needed) {
+ if ((key = malloc(IZ_PWLEN+1)) == NULL) {
+ ZIPERR(ZE_MEM, "was getting encryption password");
+ }
+ r = encr_passwd(ZP_PW_ENTER, key, IZ_PWLEN+1, zipfile);
+ if (r != IZ_PW_ENTERED) {
+ if (r < IZ_PW_ENTERED)
+ r = ZE_PARMS;
+ ZIPERR(r, "was getting encryption password");
+ }
+ if (*key == '\0') {
+ ZIPERR(ZE_PARMS, "zero length password not allowed");
+ }
+ if ((e = malloc(IZ_PWLEN+1)) == NULL) {
+ ZIPERR(ZE_MEM, "was verifying encryption password");
+ }
+ r = encr_passwd(ZP_PW_VERIFY, e, IZ_PWLEN+1, zipfile);
+ if (r != IZ_PW_ENTERED && r != IZ_PW_SKIPVERIFY) {
+ free((zvoid *)e);
+ if (r < ZE_OK) r = ZE_PARMS;
+ ZIPERR(r, "was verifying encryption password");
+ }
+ r = ((r == IZ_PW_SKIPVERIFY) ? 0 : strcmp(key, e));
+ free((zvoid *)e);
+ if (r) {
+ ZIPERR(ZE_PARMS, "password verification failed");
+ }
+ }
+ if (key) {
+ /* if -P "" could get here */
+ if (*key == '\0') {
+ ZIPERR(ZE_PARMS, "zero length password not allowed");
+ }
+ }
+
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Command line read\n");
+ fflush(mesg);
+ }
+
+ /* show command line args */
+ if (show_args) {
+ fprintf(mesg, "command line:\n");
+ for (i = 0; args[i]; i++) {
+ fprintf(mesg, "'%s' ", args[i]);
+ }
+ fprintf(mesg, "\n");
+ ZIPERR(ZE_ABORT, "show command line");
+ }
+
+ /* show all options */
+ if (show_options) {
+ printf("available options:\n");
+ printf(" %-2s %-18s %-4s %-3s %-30s\n", "sh", "long", "val", "neg", "description");
+ printf(" %-2s %-18s %-4s %-3s %-30s\n", "--", "----", "---", "---", "-----------");
+ for (i = 0; options[i].option_ID; i++) {
+ printf(" %-2s %-18s ", options[i].shortopt, options[i].longopt);
+ switch (options[i].value_type) {
+ case o_NO_VALUE:
+ printf("%-4s ", "");
+ break;
+ case o_REQUIRED_VALUE:
+ printf("%-4s ", "req");
+ break;
+ case o_OPTIONAL_VALUE:
+ printf("%-4s ", "opt");
+ break;
+ case o_VALUE_LIST:
+ printf("%-4s ", "list");
+ break;
+ case o_ONE_CHAR_VALUE:
+ printf("%-4s ", "char");
+ break;
+ case o_NUMBER_VALUE:
+ printf("%-4s ", "num");
+ break;
+ default:
+ printf("%-4s ", "unk");
+ }
+ switch (options[i].negatable) {
+ case o_NEGATABLE:
+ printf("%-3s ", "neg");
+ break;
+ case o_NOT_NEGATABLE:
+ printf("%-3s ", "");
+ break;
+ default:
+ printf("%-3s ", "unk");
+ }
+ if (options[i].name)
+ printf("%-30s\n", options[i].name);
+ else
+ printf("\n");
+ }
+ RETURN(finish(ZE_OK));
+ }
+
+
+ /* open log file */
+ if (logfile_path) {
+ char mode[10];
+ char *p;
+ char *lastp;
+
+ /* if no extension add .log */
+ p = logfile_path;
+ /* find last / */
+ lastp = NULL;
+ for (p = logfile_path; (p = MBSRCHR(p, '/')) != NULL; p++) {
+ lastp = p;
+ }
+ if (lastp == NULL)
+ lastp = logfile_path;
+ if (MBSRCHR(lastp, '.') == NULL) {
+ /* add .log */
+ if ((p = malloc(strlen(logfile_path) + 5)) == NULL) {
+ ZIPERR(ZE_MEM, "logpath");
+ }
+ strcpy(p, logfile_path);
+ strcat(p, ".log");
+ free(logfile_path);
+ logfile_path = p;
+ }
+
+ if (logfile_append) {
+ sprintf(mode, "a");
+ } else {
+ sprintf(mode, "w");
+ }
+ if ((logfile = zfopen(logfile_path, mode)) == NULL) {
+ sprintf(errbuf, "could not open logfile '%s'", logfile_path);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ {
+ /* At top put start time and command line */
+
+ /* get current time */
+ struct tm *now;
+ time_t clocktime;
+
+ time(&clocktime);
+ now = localtime(&clocktime);
+
+ fprintf(logfile, "---------\n");
+ fprintf(logfile, "Zip log opened %s", asctime(now));
+ fprintf(logfile, "command line arguments:\n ");
+ for (i = 1; args[i]; i++) {
+ size_t j;
+ int has_space = 0;
+
+ for (j = 0; j < strlen(args[i]); j++) {
+ if (isspace(args[i][j])) {
+ has_space = 1;
+ break;
+ }
+ }
+ if (has_space)
+ fprintf(logfile, "\"%s\" ", args[i]);
+ else
+ fprintf(logfile, "%s ", args[i]);
+ }
+ fprintf(logfile, "\n\n");
+ fflush(logfile);
+ }
+ } else {
+ /* only set logall if logfile open */
+ logall = 0;
+ }
+
+
+ if (split_method && out_path) {
+ /* if splitting, the archive name must have .zip extension */
+ int plen = strlen(out_path);
+ char *out_path_ext;
+
+#ifdef VMS
+ /* On VMS, adjust plen (and out_path_ext) to avoid the file version. */
+ plen -= strlen( vms_file_version( out_path));
+#endif /* def VMS */
+ out_path_ext = out_path+ plen- 4;
+
+ if (plen < 4 ||
+ out_path_ext[0] != '.' ||
+ toupper(out_path_ext[1]) != 'Z' ||
+ toupper(out_path_ext[2]) != 'I' ||
+ toupper(out_path_ext[3]) != 'P') {
+ ZIPERR(ZE_PARMS, "archive name must end in .zip for splits");
+ }
+ }
+
+
+ if (verbose && (dot_size == 0) && (dot_count == 0)) {
+ /* now default to default 10 MB dot size */
+ dot_size = 10 * 0x100000;
+ /* show all dots as before if verbose set and dot_size not set (dot_count = 0) */
+ /* maybe should turn off dots in default verbose mode */
+ /* dot_size = -1; */
+ }
+
+ /* done getting -R filters so convert filterlist if not done */
+ if (pcount && patterns == NULL) {
+ filterlist_to_patterns();
+ }
+
+#if (defined(MSDOS) || defined(OS2)) && !defined(WIN32)
+ if ((kk == 3 || kk == 4) && volume_label == 1) {
+ /* read volume label */
+ PROCNAME(NULL);
+ kk = 4;
+ }
+#endif
+
+ if (have_out && kk == 3) {
+ copy_only = 1;
+ action = ARCHIVE;
+ }
+
+ if (have_out && namecmp(in_path, out_path) == 0) {
+ sprintf(errbuf, "--out path must be different than in path: %s", out_path);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+
+ if (fix && diff_mode) {
+ ZIPERR(ZE_PARMS, "can't use --diff (-DF) with fix (-F or -FF)");
+ }
+
+ if (action == ARCHIVE && !have_out && !show_files) {
+ ZIPERR(ZE_PARMS, "-U (--copy) requires -O (--out)");
+ }
+
+ if (fix && !have_out) {
+ zipwarn("fix options -F and -FF require --out:\n",
+ " zip -F indamagedarchive --out outfixedarchive");
+ ZIPERR(ZE_PARMS, "fix options require --out");
+ }
+
+ if (fix && !copy_only) {
+ ZIPERR(ZE_PARMS, "no other actions allowed when fixing archive (-F or -FF)");
+ }
+
+ if (!have_out && diff_mode) {
+ ZIPERR(ZE_PARMS, "-DF (--diff) requires -O (--out)");
+ }
+
+ if (diff_mode && (action == ARCHIVE || action == DELETE)) {
+ ZIPERR(ZE_PARMS, "can't use --diff (-DF) with -d or -U");
+ }
+
+ if (action != ARCHIVE && (recurse == 2 || pcount) && first_listarg == 0 &&
+ !filelist && (kk < 3 || (action != UPDATE && action != FRESHEN))) {
+ ZIPERR(ZE_PARMS, "nothing to select from");
+ }
+
+/*
+ -------------------------------------
+ end of new command line code
+ -------------------------------------
+*/
+
+#if (!defined(MACOS) && !defined(WINDLL))
+ if (kk < 3) { /* zip used as filter */
+ zipstdout();
+ comment_stream = NULL;
+ if ((r = procname("-", 0)) != ZE_OK) {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", "-");
+ ZIPERR(ZE_OPEN, "-");
+ } else {
+ zipwarn("name not matched: ", "-");
+ }
+ } else {
+ ZIPERR(r, "-");
+ }
+ }
+ kk = 4;
+ if (s) {
+ ZIPERR(ZE_PARMS, "can't use - and -@ together");
+ }
+ }
+#endif /* !MACOS && !WINDLL */
+
+ if (zipfile && !strcmp(zipfile, "-")) {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipping to stdout\n");
+ fflush(mesg);
+ }
+ zip_to_stdout = 1;
+ }
+
+ /* Check option combinations */
+ if (special == NULL) {
+ ZIPERR(ZE_PARMS, "missing suffix list");
+ }
+ if (level == 9 || !strcmp(special, ";") || !strcmp(special, ":"))
+ special = NULL; /* compress everything */
+
+ if (action == DELETE && (method != BEST || dispose || recurse ||
+ key != NULL || comadd || zipedit)) {
+ zipwarn("invalid option(s) used with -d; ignored.","");
+ /* reset flags - needed? */
+ method = BEST;
+ dispose = 0;
+ recurse = 0;
+ if (key != NULL) {
+ free((zvoid *)key);
+ key = NULL;
+ }
+ comadd = 0;
+ zipedit = 0;
+ }
+ if (action == ARCHIVE && (method != BEST || dispose || recurse ||
+ comadd || zipedit)) {
+ zipwarn("can't set method, move, recurse, or comments with copy mode.","");
+ /* reset flags - needed? */
+ method = BEST;
+ dispose = 0;
+ recurse = 0;
+ comadd = 0;
+ zipedit = 0;
+ }
+ if (linkput && dosify)
+ {
+ zipwarn("can't use -y with -k, -y ignored", "");
+ linkput = 0;
+ }
+ if (fix == 1 && adjust)
+ {
+ zipwarn("can't use -F with -A, -F ignored", "");
+ fix = 0;
+ }
+ if (fix == 2 && adjust)
+ {
+ zipwarn("can't use -FF with -A, -FF ignored", "");
+ fix = 0;
+ }
+ if (test && zip_to_stdout) {
+ test = 0;
+ zipwarn("can't use -T on stdout, -T ignored", "");
+ }
+ if (split_method && (fix || adjust)) {
+ ZIPERR(ZE_PARMS, "can't create split archive while fixing or adjusting\n");
+ }
+ if (split_method && (d || zip_to_stdout)) {
+ ZIPERR(ZE_PARMS, "can't create split archive with -d or -g or on stdout\n");
+ }
+ if ((action != ADD || d) && filesync) {
+ ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g with filesync -FS\n");
+ }
+ if ((action != ADD || d) && zip_to_stdout) {
+ ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g on stdout\n");
+ }
+#if defined(EBCDIC) && !defined(OS390)
+ if (aflag==ASCII && !translate_eol) {
+ /* Translation to ASCII implies EOL translation!
+ * (on OS390, consistent EOL translation is controlled separately)
+ * The default translation mode is "UNIX" mode (single LF terminators).
+ */
+ translate_eol = 2;
+ }
+#endif
+#ifdef CMS_MVS
+ if (aflag==ASCII && bflag)
+ ZIPERR(ZE_PARMS, "can't use -a with -B");
+#endif
+#ifdef VMS
+ if (!extra_fields && vms_native)
+ {
+ zipwarn("can't use -V with -X, -V ignored", "");
+ vms_native = 0;
+ }
+ if (vms_native && translate_eol)
+ ZIPERR(ZE_PARMS, "can't use -V with -l or -ll");
+#endif
+
+ if (noisy) {
+ if (fix == 1)
+ zipmessage("Fix archive (-F) - assume mostly intact archive", "");
+ else if (fix == 2)
+ zipmessage("Fix archive (-FF) - salvage what can", "");
+ }
+
+ /* Read old archive */
+
+ /* Now read the zip file here instead of when doing args above */
+ /* Only read the central directory and build zlist */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Reading archive\n");
+ fflush(mesg);
+ }
+
+
+
+
+ /* If -FF we do it all here */
+ if (fix == 2) {
+
+ /* Open zip file and temporary output file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Open zip file and create temp file (-FF)\n");
+ fflush(mesg);
+ }
+ diag("opening zip file and creating temporary zip file");
+ x = NULL;
+ tempzn = 0;
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Creating new zip file (-FF)\n");
+ fflush(mesg);
+ }
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+ {
+ int yd;
+ int i;
+
+ /* use mkstemp to avoid race condition and compiler warning */
+
+ if (tempath != NULL)
+ {
+ /* if -b used to set temp file dir use that for split temp */
+ if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, tempath);
+ if (lastchar(tempzip) != '/')
+ strcat(tempzip, "/");
+ }
+ else
+ {
+ /* create path by stripping name and appending template */
+ if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, zipfile);
+ for(i = strlen(tempzip); i > 0; i--) {
+ if (tempzip[i - 1] == '/')
+ break;
+ }
+ tempzip[i] = '\0';
+ }
+ strcat(tempzip, "ziXXXXXX");
+
+ if ((yd = mkstemp(tempzip)) == EOF) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ if ((y = fdopen(yd, FOPW_TMP)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ }
+#else
+ if ((tempzip = tempname(zipfile)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+#endif
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+ /* Use large buffer to speed up stdio: */
+#if (defined(_IOFBF) || !defined(BUFSIZ))
+ zipbuf = (char *)malloc(ZBSZ);
+#else
+ zipbuf = (char *)malloc(BUFSIZ);
+#endif
+ if (zipbuf == NULL) {
+ ZIPERR(ZE_MEM, tempzip);
+ }
+# ifdef _IOFBF
+ setvbuf(y, zipbuf, _IOFBF, ZBSZ);
+# else
+ setbuf(y, zipbuf);
+# endif /* _IOBUF */
+#endif /* !VMS && !CMS_MVS */
+
+
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+
+ /* Write central directory and end header to temporary zip */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing central directory (-FF)\n");
+ fflush(mesg);
+ }
+ diag("writing central directory");
+ k = 0; /* keep count for end header */
+ c = tempzn; /* get start of central */
+ n = t = 0;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+ if ((r = putcentral(z)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+ n += z->len;
+ t += z->siz;
+ k++;
+ }
+ if (zcount == 0)
+ zipwarn("zip file empty", "");
+ t = tempzn - c; /* compute length of central */
+ diag("writing end of central directory");
+ if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ if (fclose(y)) {
+ ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
+ }
+ if (in_file != NULL) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if (strcmp(zipfile, "-") && !d)
+ {
+ diag("replacing old zip file with new zip file");
+ if ((r = replace(out_path, tempzip)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", tempzip);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing the original zip file");
+ }
+ free((zvoid *)tempzip);
+ }
+ tempzip = NULL;
+ if (zip_attributes && strcmp(zipfile, "-")) {
+ setfileattr(out_path, zip_attributes);
+#ifdef VMS
+ /* If the zip file existed previously, restore its record format: */
+ if (x != NULL)
+ (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
+#endif
+ }
+
+ set_filetype(out_path);
+
+ /* finish logfile (it gets closed in freeup() called by finish()) */
+ if (logfile) {
+ struct tm *now;
+ time_t clocktime;
+
+ fprintf(logfile, "\nTotal %ld entries (", files_total);
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes)");
+
+ /* get current time */
+ time(&clocktime);
+ now = localtime(&clocktime);
+ fprintf(logfile, "\nDone %s", asctime(now));
+ fflush(logfile);
+ }
+
+ RETURN(finish(ZE_OK));
+ }
+
+
+
+ /* read zipfile if exists */
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+
+#ifndef UTIL
+ if (split_method == -1) {
+ split_method = 0;
+ } else if (!fix && split_method == 0 && total_disks > 1) {
+ /* if input archive is multi-disk and splitting has not been
+ enabled or disabled (split_method == -1), then automatically
+ set split size to same as first input split */
+ zoff_t size = 0;
+
+ in_split_path = get_in_split_path(in_path, 0);
+
+ if (filetime(in_split_path, NULL, &size, NULL) == 0) {
+ zipwarn("Could not get info for input split: ", in_split_path);
+ return ZE_OPEN;
+ }
+ split_method = 1;
+ split_size = (uzoff_t) size;
+
+ free(in_split_path);
+ in_split_path = NULL;
+ }
+
+ if (noisy_splits && split_size > 0)
+ zipmessage("splitsize = ", zip_fuzofft(split_size, NULL, NULL));
+#endif
+
+ /* so disk display starts at 1, will be updated when entries are read */
+ current_in_disk = 0;
+
+ /* no input zipfile and showing contents */
+ if (!zipfile_exists && show_files && (kk == 3 || action == ARCHIVE)) {
+ ZIPERR(ZE_OPEN, zipfile);
+ }
+
+ if (zcount == 0 && (action != ADD || d)) {
+ zipwarn(zipfile, " not found or empty");
+ }
+
+ if (have_out && kk == 3) {
+ /* no input paths so assume copy mode and match everything if --out */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+ }
+ }
+
+ /* Scan for new files */
+
+ /* Process file arguments from command line */
+ if (filelist) {
+ if (action == ARCHIVE) {
+ /* find in archive */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning archive entries\n");
+ fflush(mesg);
+ }
+ for (; filelist; ) {
+ if ((r = proc_archive_name(filelist->name, filter_match_case)) != ZE_OK) {
+ if (r == ZE_MISS) {
+ char *n = NULL;
+#ifdef WIN32
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ if ((n = malloc(strlen(filelist->name) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "name not matched error");
+ INTERN_TO_OEM(filelist->name, n);
+#else
+ n = filelist->name;
+#endif
+ zipwarn("not in archive: ", n);
+#ifdef WIN32
+ free(n);
+#endif
+ }
+ else {
+ ZIPERR(r, filelist->name);
+ }
+ }
+ free(filelist->name);
+ filearg = filelist;
+ filelist = filelist->next;
+ free(filearg);
+ }
+ } else {
+ /* try find matching files on OS first then try find entries in archive */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning files\n");
+ fflush(mesg);
+ }
+ for (; filelist; ) {
+ if ((r = PROCNAME(filelist->name)) != ZE_OK) {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", filelist->name);
+ ZIPERR(ZE_OPEN, filelist->name);
+ } else {
+ zipwarn("name not matched: ", filelist->name);
+ }
+ } else {
+ ZIPERR(r, filelist->name);
+ }
+ }
+ free(filelist->name);
+ filearg = filelist;
+ filelist = filelist->next;
+ free(filearg);
+ }
+ }
+ }
+
+ /* recurse from current directory for -R */
+ if (recurse == 2) {
+#ifdef AMIGA
+ if ((r = PROCNAME("")) != ZE_OK)
+#else
+ if ((r = PROCNAME(".")) != ZE_OK)
+#endif
+ {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", "current directory for -R");
+ ZIPERR(ZE_OPEN, "-R");
+ } else {
+ zipwarn("name not matched: ", "current directory for -R");
+ }
+ } else {
+ ZIPERR(r, "-R");
+ }
+ }
+ }
+
+
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Applying filters\n");
+ fflush(mesg);
+ }
+ /* Clean up selections ("3 <= kk <= 5" now) */
+ if (kk != 4 && first_listarg == 0 &&
+ (action == UPDATE || action == FRESHEN)) {
+ /* if -u or -f with no args, do all, but, when present, apply filters */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+#ifdef DOS
+ if (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */
+#endif
+ }
+ }
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Checking dups\n");
+ fflush(mesg);
+ }
+ if ((r = check_dup()) != ZE_OK) { /* remove duplicates in found list */
+ if (r == ZE_PARMS) {
+ ZIPERR(r, "cannot repeat names in zip file");
+ }
+ else {
+ ZIPERR(r, "was processing list of files");
+ }
+ }
+
+ if (zcount)
+ free((zvoid *)zsort);
+
+
+/*
+ * XXX make some kind of mktemppath() function for each OS.
+ */
+
+#ifndef VM_CMS
+/* For CMS, leave tempath NULL. A-disk will be used as default. */
+ /* If -b not specified, make temporary path the same as the zip file */
+#if defined(MSDOS) || defined(__human68k__) || defined(AMIGA)
+ if (tempath == NULL && ((p = MBSRCHR(zipfile, '/')) != NULL ||
+# ifdef MSDOS
+ (p = MBSRCHR(zipfile, '\\')) != NULL ||
+# endif /* MSDOS */
+ (p = MBSRCHR(zipfile, ':')) != NULL))
+ {
+ if (*p == ':')
+ p++;
+#else
+#ifdef RISCOS
+ if (tempath == NULL && (p = MBSRCHR(zipfile, '.')) != NULL)
+ {
+#else
+#ifdef QDOS
+ if (tempath == NULL && (p = LastDir(zipfile)) != NULL)
+ {
+#else
+ if (tempath == NULL && (p = MBSRCHR(zipfile, '/')) != NULL)
+ {
+#endif /* QDOS */
+#endif /* RISCOS */
+#endif /* MSDOS || __human68k__ || AMIGA */
+ if ((tempath = (char *)malloc((int)(p - zipfile) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ r = *p; *p = 0;
+ strcpy(tempath, zipfile);
+ *p = (char)r;
+ }
+#endif /* VM_CMS */
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+ if (!zp_tz_is_valid) {
+ zipwarn("TZ environment variable not found, cannot use UTC times!!","");
+ }
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+ /* For each marked entry, if not deleting, check if it exists, and if
+ updating or freshening, compare date with entry in old zip file.
+ Unmark if it doesn't exist or is too old, else update marked count. */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning files to update\n");
+ fflush(mesg);
+ }
+#ifdef MACOS
+ PrintStatProgress("Getting file information ...");
+#endif
+ diag("stating marked entries");
+ k = 0; /* Initialize marked count */
+ scan_started = 0;
+ scan_count = 0;
+ all_current = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ /* if already displayed Scanning files in newname() then continue dots */
+ if (noisy && scan_last) {
+ scan_count++;
+ if (scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_last > scan_dot_time) {
+ if (scan_started == 0) {
+ scan_started = 1;
+ fprintf(mesg, " ");
+ fflush(mesg);
+ }
+ scan_last = current;
+ fprintf(mesg, ".");
+ fflush(mesg);
+ }
+ }
+ }
+ z->current = 0;
+ if (!(z->mark)) {
+ /* if something excluded run through the list to catch deletions */
+ all_current = 0;
+ }
+ if (z->mark) {
+#ifdef USE_EF_UT_TIME
+ iztimes f_utim, z_utim;
+ ulg z_tim;
+#endif /* USE_EF_UT_TIME */
+ Trace((stderr, "zip diagnostics: marked file=%s\n", z->oname));
+
+ csize = z->siz;
+ usize = z->len;
+ if (action == DELETE) {
+ /* only delete files in date range */
+#ifdef USE_EF_UT_TIME
+ z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ unix2dostime(&z_utim.mtime) : z->tim;
+#else /* !USE_EF_UT_TIME */
+# define z_tim z->tim
+#endif /* ?USE_EF_UT_TIME */
+ if (z_tim < before || (after && z_tim >= after)) {
+ /* include in archive */
+ z->mark = 0;
+ } else {
+ /* delete file */
+ files_total++;
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+ bytes_total += csize;
+ k++;
+ }
+ } else if (action == ARCHIVE) {
+ /* only keep files in date range */
+#ifdef USE_EF_UT_TIME
+ z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ unix2dostime(&z_utim.mtime) : z->tim;
+#else /* !USE_EF_UT_TIME */
+# define z_tim z->tim
+#endif /* ?USE_EF_UT_TIME */
+ if (z_tim < before || (after && z_tim >= after)) {
+ /* exclude from archive */
+ z->mark = 0;
+ } else {
+ /* keep file */
+ files_total++;
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+ bytes_total += csize;
+ k++;
+ }
+ } else {
+ int isdirname = 0;
+
+ if (z->name && (z->name)[strlen(z->name) - 1] == '/') {
+ isdirname = 1;
+ }
+
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide) {
+ if (z->namew == NULL) {
+ if (z->uname != NULL)
+ z->namew = utf8_to_wchar_string(z->uname);
+ else
+ z->namew = local_to_wchar_string(z->name);
+ }
+ }
+# endif
+
+#ifdef USE_EF_UT_TIME
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+ else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# endif
+#else /* !USE_EF_UT_TIME */
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+ else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# endif
+#endif /* ?USE_EF_UT_TIME */
+ if (tf == 0)
+ /* entry that is not on OS */
+ all_current = 0;
+ if (tf == 0 ||
+ tf < before || (after && tf >= after) ||
+ ((action == UPDATE || action == FRESHEN) &&
+#ifdef USE_EF_UT_TIME
+ ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ f_utim.mtime <= ROUNDED_TIME(z_utim.mtime) : tf <= z->tim)
+#else /* !USE_EF_UT_TIME */
+ tf <= z->tim
+#endif /* ?USE_EF_UT_TIME */
+ ))
+ {
+ z->mark = comadd ? 2 : 0;
+ z->trash = tf && tf >= before &&
+ (after ==0 || tf < after); /* delete if -um or -fm */
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %s %s\n", z->oname,
+ z->trash ? "up to date" : "missing or early");
+ if (logfile)
+ fprintf(logfile, "zip diagnostic: %s %s\n", z->oname,
+ z->trash ? "up to date" : "missing or early");
+ }
+ else if (diff_mode && tf == z->tim &&
+ ((isdirname && (zoff_t)usize == -1) || (usize == z->len))) {
+ /* if in diff mode only include if file time or size changed */
+ /* usize is -1 for directories */
+ z->mark = 0;
+ }
+ else {
+ /* usize is -1 for directories and -2 for devices */
+ if (tf == z->tim &&
+ ((z->len == 0 && (zoff_t)usize == -1)
+ || usize == z->len)) {
+ /* FileSync uses the current flag */
+ /* Consider an entry current if file time is the same
+ and entry size is 0 and a directory on the OS
+ or the entry size matches the OS size */
+ z->current = 1;
+ } else {
+ all_current = 0;
+ }
+ files_total++;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ else
+ z->len = 0;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+ bytes_total += usize;
+ k++;
+ }
+ }
+ }
+ }
+
+ /* Remove entries from found list that do not exist or are too old */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: fcount = %u\n", (unsigned)fcount);
+ fflush(mesg);
+ }
+
+ diag("stating new entries");
+ scan_count = 0;
+ scan_started = 0;
+ Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
+ for (f = found; f != NULL;) {
+ Trace((stderr, "zip diagnostic: new file=%s\n", f->oname));
+
+ if (noisy) {
+ /* if updating archive and update was quick, scanning for new files
+ can still take a long time */
+ if (!zip_to_stdout && scan_last == 0 && scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_start > scan_delay) {
+ fprintf(mesg, "Scanning files ");
+ fflush(mesg);
+ mesg_line_started = 1;
+ scan_last = current;
+ }
+ }
+ /* if already displayed Scanning files in newname() or above then continue dots */
+ if (scan_last) {
+ scan_count++;
+ if (scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_last > scan_dot_time) {
+ if (scan_started == 0) {
+ scan_started = 1;
+ fprintf(mesg, " ");
+ fflush(mesg);
+ }
+ scan_last = current;
+ fprintf(mesg, ".");
+ fflush(mesg);
+ }
+ }
+ }
+ }
+ tf = 0;
+ if (action != DELETE && action != FRESHEN) {
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(f->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+ else
+ tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#else
+ tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#endif
+ }
+
+ if (action == DELETE || action == FRESHEN ||
+ tf == 0 ||
+ tf < before || (after && tf >= after) ||
+ (namecmp(f->zname, zipfile) == 0 && !zip_to_stdout)
+ )
+ f = fexpel(f);
+ else {
+ /* ??? */
+ files_total++;
+ f->usize = 0;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2) {
+ bytes_total += usize;
+ f->usize = usize;
+ }
+ f = f->nxt;
+ }
+ }
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+#ifdef MACOS
+ PrintStatProgress("done");
+#endif
+
+ if (show_files) {
+ uzoff_t count = 0;
+ uzoff_t bytes = 0;
+
+ if (noisy) {
+ fflush(mesg);
+ }
+
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5)) {
+ /* sf, su, sU */
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (kk == 3)
+ /* -sf alone */
+ fprintf(mesg, "Archive contains:\n");
+ else if (action == DELETE)
+ fprintf(mesg, "Would Delete:\n");
+ else if (action == FRESHEN)
+ fprintf(mesg, "Would Freshen:\n");
+ else if (action == ARCHIVE)
+ fprintf(mesg, "Would Copy:\n");
+ else
+ fprintf(mesg, "Would Add/Update:\n");
+ fflush(mesg);
+ }
+
+ if (logfile) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ if (kk == 3)
+ /* -sf alone */
+ fprintf(logfile, "Archive contains:\n");
+ else if (action == DELETE)
+ fprintf(logfile, "Would Delete:\n");
+ else if (action == FRESHEN)
+ fprintf(logfile, "Would Freshen:\n");
+ else if (action == ARCHIVE)
+ fprintf(logfile, "Would Copy:\n");
+ else
+ fprintf(logfile, "Would Add/Update:\n");
+ fflush(logfile);
+ }
+
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (z->mark || kk == 3) {
+ count++;
+ if ((zoff_t)z->len > 0)
+ bytes += z->len;
+ if (noisy && (show_files == 1 || show_files == 3))
+ /* sf, su */
+ fprintf(mesg, " %s\n", z->oname);
+ if (logfile && !(show_files == 5 || show_files == 6))
+ /* not sU or sU- show normal name in log */
+ fprintf(logfile, " %s\n", z->oname);
+
+#ifdef UNICODE_TEST
+ if (create_files) {
+ int r;
+ int dir = 0;
+ FILE *f;
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ char *fn = NULL;
+ wchar_t *fnw = NULL;
+
+ if (!no_win32_wide) {
+ if ((fnw = malloc((wcslen(z->znamew) + 120) * sizeof(wchar_t))) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ wcscpy(fnw, L"testdir/");
+ wcscat(fnw, z->znamew);
+ if (fnw[wcslen(fnw) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = _wmkdir(fnw);
+ else
+ f = _wfopen(fnw, L"w");
+ } else {
+ if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ strcpy(fn, "testdir/");
+ strcat(fn, z->zname);
+ if (fn[strlen(fn) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = mkdir(fn);
+ else
+ f = fopen(fn, "w");
+ }
+#else
+ char *fn = NULL;
+ if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ strcpy(fn, "testdir/");
+ if (z->uname)
+ strcat(fn, z->uname);
+ else
+ strcat(fn, z->zname);
+
+ if (fn[strlen(fn) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = mkdir(fn, 0777);
+ else
+ f = fopen(fn, "w");
+#endif
+ if (dir) {
+ if (r) {
+ if (errno != 17) {
+ printf(" - could not create directory testdir/%s\n", z->oname);
+ perror(" dir");
+ }
+ } else {
+ printf(" - created directory testdir/%s\n", z->oname);
+ }
+ } else {
+ if (f == NULL) {
+ printf(" - could not open testdir/%s\n", z->oname);
+ perror(" file");
+ } else {
+ fclose(f);
+ printf(" - created testdir/%s\n", z->oname);
+ if (z->uname)
+ printf(" u - created testdir/%s\n", z->uname);
+ }
+ }
+ }
+#endif
+#ifdef UNICODE_SUPPORT
+ if (show_files == 3 || show_files == 4) {
+ /* su, su- */
+ /* Include escaped Unicode name if exists under standard name */
+ if (z->ouname) {
+ if (noisy && show_files == 3)
+ fprintf(mesg, " Escaped Unicode: %s\n", z->ouname);
+ if (logfile)
+ fprintf(logfile, " Escaped Unicode: %s\n", z->ouname);
+ }
+ }
+ if (show_files == 5 || show_files == 6) {
+ /* sU, sU- */
+ /* Display only escaped Unicode name if exists or standard name */
+ if (z->ouname) {
+ /* Unicode name */
+ if (noisy && show_files == 5) {
+ fprintf(mesg, " %s\n", z->ouname);
+ }
+ if (logfile) {
+ fprintf(logfile, " %s\n", z->ouname);
+ }
+ } else {
+ /* No Unicode name so use standard name */
+ if (noisy && show_files == 5) {
+ fprintf(mesg, " %s\n", z->oname);
+ }
+ if (logfile) {
+ fprintf(logfile, " %s\n", z->oname);
+ }
+ }
+ }
+#endif
+ }
+ }
+ for (f = found; f != NULL; f = f->nxt) {
+ count++;
+ if ((zoff_t)f->usize > 0)
+ bytes += f->usize;
+#ifdef UNICODE_SUPPORT
+ if (unicode_escape_all) {
+ char *escaped_unicode;
+ escaped_unicode = local_to_escape_string(f->zname);
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+ /* sf, su, sU */
+ fprintf(mesg, " %s\n", escaped_unicode);
+ if (logfile)
+ fprintf(logfile, " %s\n", escaped_unicode);
+ free(escaped_unicode);
+ } else {
+#endif
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+ /* sf, su, sU */
+ fprintf(mesg, " %s\n", f->oname);
+ if (logfile)
+ fprintf(logfile, " %s\n", f->oname);
+#ifdef UNICODE_SUPPORT
+ }
+#endif
+ }
+ if (noisy || logfile == NULL)
+ fprintf(mesg, "Total %s entries (%s bytes)\n",
+ zip_fuzofft(count, NULL, NULL),
+ zip_fuzofft(bytes, NULL, NULL));
+ if (logfile)
+ fprintf(logfile, "Total %s entries (%s bytes)\n",
+ zip_fuzofft(count, NULL, NULL),
+ zip_fuzofft(bytes, NULL, NULL));
+ RETURN(finish(ZE_OK));
+ }
+
+ /* Make sure there's something left to do */
+ if (k == 0 && found == NULL && !diff_mode &&
+ !(zfiles == NULL && allow_empty_archive) &&
+ !(zfiles != NULL &&
+ (latest || fix || adjust || junk_sfx || comadd || zipedit))) {
+ if (test && (zfiles != NULL || zipbeg != 0)) {
+#ifndef WINDLL
+ check_zipfile(zipfile, argv[0]);
+#endif
+ RETURN(finish(ZE_OK));
+ }
+ if (action == UPDATE || action == FRESHEN) {
+ RETURN(finish(ZE_NONE));
+ }
+ else if (zfiles == NULL && (latest || fix || adjust || junk_sfx)) {
+ ZIPERR(ZE_NAME, zipfile);
+ }
+#ifndef WINDLL
+ else if (recurse && (pcount == 0) && (first_listarg > 0)) {
+#ifdef VMS
+ strcpy(errbuf, "try: zip \"");
+ for (i = 1; i < (first_listarg - 1); i++)
+ strcat(strcat(errbuf, args[i]), "\" ");
+ strcat(strcat(errbuf, args[i]), " *.* -i");
+#else /* !VMS */
+ strcpy(errbuf, "try: zip");
+ for (i = 1; i < first_listarg; i++)
+ strcat(strcat(errbuf, " "), args[i]);
+# ifdef AMIGA
+ strcat(errbuf, " \"\" -i");
+# else
+ strcat(errbuf, " . -i");
+# endif
+#endif /* ?VMS */
+ for (i = first_listarg; i < argc; i++)
+ strcat(strcat(errbuf, " "), args[i]);
+ ZIPERR(ZE_NONE, errbuf);
+ }
+ else {
+ ZIPERR(ZE_NONE, zipfile);
+ }
+#endif /* !WINDLL */
+ }
+
+ if (filesync && all_current && fcount == 0) {
+ zipmessage("Archive is current", "");
+ RETURN(finish(ZE_OK));
+ }
+
+ d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
+
+#if CRYPT
+ /* Initialize the crc_32_tab pointer, when encryption was requested. */
+ if (key != NULL) {
+ crc_32_tab = get_crc_table();
+#ifdef EBCDIC
+ /* convert encryption key to ASCII (ISO variant for 8-bit ASCII chars) */
+ strtoasc(key, key);
+#endif /* EBCDIC */
+ }
+#endif /* CRYPT */
+
+ /* Just ignore the spanning signature if a multi-disk archive */
+ if (zfiles && total_disks != 1 && zipbeg == 4) {
+ zipbeg = 0;
+ }
+
+ /* Before we get carried away, make sure zip file is writeable. This
+ * has the undesired side effect of leaving one empty junk file on a WORM,
+ * so when the zipfile does not exist already and when -b is specified,
+ * the writability check is made in replace().
+ */
+ if (strcmp(zipfile, "-"))
+ {
+ if (tempdir && zfiles == NULL && zipbeg == 0) {
+ zip_attributes = 0;
+ } else {
+ x = (have_out || (zfiles == NULL && zipbeg == 0)) ? zfopen(out_path, FOPW) :
+ zfopen(out_path, FOPM);
+ /* Note: FOPW and FOPM expand to several parameters for VMS */
+ if (x == NULL) {
+ ZIPERR(ZE_CREAT, out_path);
+ }
+ fclose(x);
+ zip_attributes = getfileattr(out_path);
+ if (zfiles == NULL && zipbeg == 0)
+ destroy(out_path);
+ }
+ }
+ else
+ zip_attributes = 0;
+
+ /* Throw away the garbage in front of the zip file for -J */
+ if (junk_sfx) zipbeg = 0;
+
+ /* Open zip file and temporary output file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Open zip file and create temp file\n");
+ fflush(mesg);
+ }
+ diag("opening zip file and creating temporary zip file");
+ x = NULL;
+ tempzn = 0;
+ if (strcmp(zipfile, "-") == 0)
+ {
+#ifdef MSDOS
+ /* It is nonsense to emit the binary data stream of a zipfile to
+ * the (text mode) console. This case should already have been caught
+ * in a call to zipstdout() far above. Therefore, if the following
+ * failsafe check detects a console attached to stdout, zip is stopped
+ * with an "internal logic error"! */
+ if (isatty(fileno(stdout)))
+ ZIPERR(ZE_LOGIC, "tried to write binary zipfile data to console!");
+ /* Set stdout mode to binary for MSDOS systems */
+# ifdef __HIGHC__
+ setmode(stdout, _BINARY);
+# else
+ setmode(fileno(stdout), O_BINARY);
+# endif
+ y = zfdopen(fileno(stdout), FOPW);
+#else
+ y = stdout;
+#endif
+ /* tempzip must be malloced so a later free won't barf */
+ tempzip = malloc(4);
+ if (tempzip == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, "-");
+ }
+ else if (d) /* d true if just appending (-g) */
+ {
+ if (total_disks > 1) {
+ ZIPERR(ZE_PARMS, "cannot grow split archive");
+ }
+ if ((y = zfopen(zipfile, FOPM)) == NULL) {
+ ZIPERR(ZE_NAME, zipfile);
+ }
+ tempzip = zipfile;
+ /*
+ tempzf = y;
+ */
+
+ if (zfseeko(y, cenbeg, SEEK_SET)) {
+ ZIPERR(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
+ }
+ bytes_this_split = cenbeg;
+ tempzn = cenbeg;
+ }
+ else
+ {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Creating new zip file\n");
+ fflush(mesg);
+ }
+ /* See if there is something at beginning of disk 1 to copy.
+ If not, do nothing as zipcopy() will open files to read
+ as needed. */
+ if (zipbeg) {
+ in_split_path = get_in_split_path(in_path, 0);
+
+ while ((in_file = zfopen(in_split_path, FOPR_EX)) == NULL) {
+ /* could not open split */
+
+ /* Ask for directory with split. Updates in_path */
+ if (ask_for_split_read_path(0) != ZE_OK) {
+ ZIPERR(ZE_ABORT, "could not open archive to read");
+ }
+ free(in_split_path);
+ in_split_path = get_in_split_path(in_path, 1);
+ }
+ }
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+ {
+ int yd;
+ int i;
+
+ /* use mkstemp to avoid race condition and compiler warning */
+
+ if (tempath != NULL)
+ {
+ /* if -b used to set temp file dir use that for split temp */
+ if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, tempath);
+ if (lastchar(tempzip) != '/')
+ strcat(tempzip, "/");
+ }
+ else
+ {
+ /* create path by stripping name and appending template */
+ if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, zipfile);
+ for(i = strlen(tempzip); i > 0; i--) {
+ if (tempzip[i - 1] == '/')
+ break;
+ }
+ tempzip[i] = '\0';
+ }
+ strcat(tempzip, "ziXXXXXX");
+
+ if ((yd = mkstemp(tempzip)) == EOF) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ if ((y = fdopen(yd, FOPW_TMP)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ }
+#else
+ if ((tempzip = tempname(zipfile)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+#endif
+ }
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+ /* Use large buffer to speed up stdio: */
+#if (defined(_IOFBF) || !defined(BUFSIZ))
+ zipbuf = (char *)malloc(ZBSZ);
+#else
+ zipbuf = (char *)malloc(BUFSIZ);
+#endif
+ if (zipbuf == NULL) {
+ ZIPERR(ZE_MEM, tempzip);
+ }
+# ifdef _IOFBF
+ setvbuf(y, zipbuf, _IOFBF, ZBSZ);
+# else
+ setbuf(y, zipbuf);
+# endif /* _IOBUF */
+#endif /* !VMS && !CMS_MVS */
+
+ /* If not seekable set some flags 3/14/05 EG */
+ output_seekable = 1;
+ if (!is_seekable(y)) {
+ output_seekable = 0;
+ use_descriptors = 1;
+ }
+
+ /* Not needed. Only need Zip64 when input file is larger than 2 GB or reading
+ stdin and writing stdout. This is set in putlocal() for each file. */
+#if 0
+ /* If using descriptors and Zip64 enabled force Zip64 3/13/05 EG */
+# ifdef ZIP64_SUPPORT
+ if (use_descriptors && force_zip64 != 0) {
+ force_zip64 = 1;
+ }
+# endif
+#endif
+
+ /* if archive exists, not streaming and not deleting or growing, copy
+ any bytes at beginning */
+ if (strcmp(zipfile, "-") != 0 && !d) /* this must go *after* set[v]buf */
+ {
+ /* copy anything before archive */
+ if (in_file && zipbeg && (r = bfcopy(zipbeg)) != ZE_OK) {
+ ZIPERR(r, r == ZE_TEMP ? tempzip : zipfile);
+ }
+ if (in_file) {
+ fclose(in_file);
+ in_file = NULL;
+ free(in_split_path);
+ }
+ tempzn = zipbeg;
+ if (split_method) {
+ /* add spanning signature */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Adding spanning/splitting signature at top of archive\n");
+ fflush(mesg);
+ }
+ /* write the spanning signature at the top of the archive */
+ errbuf[0] = 0x50 /*'P' except for EBCDIC*/;
+ errbuf[1] = 0x4b /*'K' except for EBCDIC*/;
+ errbuf[2] = 7;
+ errbuf[3] = 8;
+ bfwrite(errbuf, 1, 4, BFWRITE_DATA);
+ /* tempzn updated below */
+ tempzn += 4;
+ }
+ }
+
+ o = 0; /* no ZE_OPEN errors yet */
+
+
+ /* Process zip file, updating marked files */
+#ifdef DEBUG
+ if (zfiles != NULL)
+ diag("going through old zip file");
+#endif
+ if (zfiles != NULL && show_what_doing) {
+ fprintf(mesg, "sd: Going through old zip file\n");
+ fflush(mesg);
+ }
+ w = &zfiles;
+ while ((z = *w) != NULL) {
+ if (z->mark == 1)
+ {
+ uzoff_t len;
+ if ((zoff_t)z->len == -1)
+ /* device */
+ len = 0;
+ else
+ len = z->len;
+
+ /* if not deleting, zip it up */
+ if (action != ARCHIVE && action != DELETE)
+ {
+ struct zlist far *localz; /* local header */
+
+ if (verbose || !(filesync && z->current))
+ DisplayRunningStats();
+ if (noisy)
+ {
+ if (action == FRESHEN) {
+ fprintf(mesg, "freshening: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ } else if (filesync && z->current) {
+ if (verbose) {
+ fprintf(mesg, " ok: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ } else if (!(filesync && z->current)) {
+ fprintf(mesg, "updating: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ }
+ if (logall)
+ {
+ if (action == FRESHEN) {
+ fprintf(logfile, "freshening: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ } else if (filesync && z->current) {
+ if (verbose) {
+ fprintf(logfile, " current: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ } else {
+ fprintf(logfile, "updating: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ }
+
+ /* Get local header flags and extra fields */
+ if (readlocal(&localz, z) != ZE_OK) {
+ zipwarn("could not read local entry information: ", z->oname);
+ z->lflg = z->flg;
+ z->ext = 0;
+ } else {
+ z->lflg = localz->lflg;
+ z->ext = localz->ext;
+ z->extra = localz->extra;
+ if (localz->nam) free(localz->iname);
+ if (localz->nam) free(localz->name);
+#ifdef UNICODE_SUPPORT
+ if (localz->uname) free(localz->uname);
+#endif
+ free(localz);
+ }
+
+ if (!(filesync && z->current) &&
+ (r = zipup(z)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
+ {
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+ if (mesg_line_started) {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+ fflush(stdout);
+#endif
+ mesg_line_started = 0;
+ }
+ }
+ if (logall) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ }
+ */
+ sprintf(errbuf, "was zipping %s", z->name);
+ ZIPERR(r, errbuf);
+ }
+ if (filesync && z->current)
+ {
+ /* if filesync if entry matches OS just copy */
+ if ((r = zipcopy(z)) != ZE_OK)
+ {
+ sprintf(errbuf, "was copying %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+ if (mesg_line_started) {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+ fflush(stdout);
+#endif
+ mesg_line_started = 0;
+ }
+ }
+ if (logall) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ }
+ */
+ }
+ if (r == ZE_OPEN || r == ZE_MISS)
+ {
+ o = 1;
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+#endif
+ mesg_line_started = 0;
+ }
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ */
+ if (r == ZE_OPEN) {
+ perror(z->oname);
+ zipwarn("could not open for reading: ", z->oname);
+ if (bad_open_is_error) {
+ sprintf(errbuf, "was zipping %s", z->name);
+ ZIPERR(r, errbuf);
+ }
+ } else {
+ zipwarn("file and directory with the same name: ", z->oname);
+ }
+ zipwarn("will just copy entry over: ", z->oname);
+ if ((r = zipcopy(z)) != ZE_OK)
+ {
+ sprintf(errbuf, "was copying %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ z->mark = 0;
+ }
+ files_so_far++;
+ good_bytes_so_far += z->len;
+ bytes_so_far += len;
+ w = &z->nxt;
+ }
+ else if (action == ARCHIVE)
+ {
+#ifdef DEBUG
+ zoff_t here = zftello(y);
+#endif
+
+ DisplayRunningStats();
+ if (skip_this_disk - 1 != z->dsk)
+ /* moved to another disk so start copying again */
+ skip_this_disk = 0;
+ if (skip_this_disk - 1 == z->dsk) {
+ /* skipping this disk */
+ if (noisy) {
+ fprintf(mesg, " skipping: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, " skipping: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ } else {
+ /* copying this entry */
+ if (noisy) {
+ fprintf(mesg, " copying: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall)
+ {
+ fprintf(logfile, " copying: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ }
+
+ if (skip_this_disk - 1 == z->dsk)
+ /* skip entries on this disk */
+ z->mark = 0;
+ else if ((r = zipcopy(z)) != ZE_OK)
+ {
+ if (r == ZE_ABORT) {
+ ZIPERR(r, "user requested abort");
+ } else if (fix != 1) {
+ /* exit */
+ sprintf(errbuf, "was copying %s", z->oname);
+ zipwarn("(try -F to attempt to fix)", "");
+ ZIPERR(r, errbuf);
+ }
+ else /* if (r == ZE_FORM) */ {
+#ifdef DEBUG
+ zoff_t here = zftello(y);
+#endif
+
+ /* seek back in output to start of this entry so can overwrite */
+ if (zfseeko(y, current_local_offset, SEEK_SET) != 0){
+ ZIPERR(r, "could not seek in output file");
+ }
+ zipwarn("bad - skipping: ", z->oname);
+#ifdef DEBUG
+ here = zftello(y);
+#endif
+ tempzn = current_local_offset;
+ bytes_this_split = current_local_offset;
+ }
+ }
+ if (skip_this_disk || !(fix == 1 && r != ZE_OK))
+ {
+ if (noisy && mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logall && logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ }
+ /* input counts */
+ files_so_far++;
+ if (r != ZE_OK)
+ bad_bytes_so_far += z->siz;
+ else
+ good_bytes_so_far += z->siz;
+ bytes_so_far += z->siz;
+
+ if (r != ZE_OK && fix == 1) {
+ /* remove bad entry from list */
+ v = z->nxt; /* delete entry from list */
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+ if (z->ext)
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
+ if (z->cext && z->cextra != z->extra)
+ free((zvoid *)(z->cextra));
+ if (z->com)
+ free((zvoid *)(z->comment));
+ farfree((zvoid far *)z);
+ *w = v;
+ zcount--;
+ } else {
+ w = &z->nxt;
+ }
+
+#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+ /* int64 support in caller */
+ if (lpZipUserFunctions->ServiceApplication64 != NULL)
+ {
+ if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ else
+ {
+ /* no int64 support in caller */
+ filesize64 = z->siz;
+ low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+ high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+ if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+#else
+ if (lpZipUserFunctions->ServiceApplication != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+ each other, the Aztec Amiga compiler never sees the second endif! WTF?? PK */
+#endif /* WINDLL */
+ }
+ else
+ {
+ DisplayRunningStats();
+ if (noisy)
+ {
+ fprintf(mesg, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
+ fflush(mesg);
+ fprintf(mesg, "\n");
+ }
+ if (logall)
+ {
+ fprintf(logfile, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ fprintf(logfile, "\n");
+ fflush(logfile);
+ }
+ files_so_far++;
+ good_bytes_so_far += z->siz;
+ bytes_so_far += z->siz;
+#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+ /* int64 support in caller */
+ if (lpZipUserFunctions->ServiceApplication64 != NULL)
+ {
+ if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ else
+ {
+ /* no int64 support in caller */
+ filesize64 = z->siz;
+ low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+ high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+ if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+#else
+ if (lpZipUserFunctions->ServiceApplication != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+ each other, the Aztec Amiga compiler never sees the second endif! WTF?? PK */
+#endif /* WINDLL */
+
+ v = z->nxt; /* delete entry from list */
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+ if (z->ext)
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
+ if (z->cext && z->cextra != z->extra)
+ free((zvoid *)(z->cextra));
+ if (z->com)
+ free((zvoid *)(z->comment));
+ farfree((zvoid far *)z);
+ *w = v;
+ zcount--;
+ }
+ }
+ else
+ {
+ if (action == ARCHIVE) {
+ v = z->nxt; /* delete entry from list */
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+ if (z->ext)
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
+ if (z->cext && z->cextra != z->extra)
+ free((zvoid *)(z->cextra));
+ if (z->com)
+ free((zvoid *)(z->comment));
+ farfree((zvoid far *)z);
+ *w = v;
+ zcount--;
+ }
+ else
+ {
+ if (filesync) {
+ /* Delete entries if don't match a file on OS */
+ BlankRunningStats();
+ if (noisy)
+ {
+ fprintf(mesg, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
+ fflush(mesg);
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logall)
+ {
+ fprintf(logfile, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ fprintf(logfile, "\n");
+ fflush(logfile);
+ logfile_line_started = 0;
+ }
+ }
+ /* copy the original entry */
+ else if (!d && !diff_mode && (r = zipcopy(z)) != ZE_OK)
+ {
+ sprintf(errbuf, "was copying %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ w = &z->nxt;
+ }
+ }
+ }
+
+
+ /* Process the edited found list, adding them to the zip file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipping up new entries\n");
+ fflush(mesg);
+ }
+ diag("zipping up new entries, if any");
+ Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
+ for (f = found; f != NULL; f = fexpel(f))
+ {
+ uzoff_t len;
+ /* add a new zfiles entry and set the name */
+ if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ ZIPERR(ZE_MEM, "was adding files to zip file");
+ }
+ z->nxt = NULL;
+ z->name = f->name;
+ f->name = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = NULL; /* UTF-8 name for extra field */
+ z->zuname = NULL; /* externalized UTF-8 name for matching */
+ z->ouname = NULL; /* display version of UTF-8 name with OEM */
+
+#if 0
+ /* New AppNote bit 11 allowing storing UTF-8 in path */
+ if (utf8_force && f->uname) {
+ if (f->iname)
+ free(f->iname);
+ if ((f->iname = malloc(strlen(f->uname) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "Unicode bit 11");
+ strcpy(f->iname, f->uname);
+# ifdef WIN32
+ if (f->inamew)
+ free(f->inamew);
+ f->inamew = utf8_to_wchar_string(f->iname);
+# endif
+ }
+#endif
+
+ /* Only set z->uname if have a non-ASCII Unicode name */
+ /* The Unicode path extra field is created if z->uname is not NULL,
+ unless on a UTF-8 system, then instead of creating the extra field
+ set bit 11 in the General Purpose Bit Flag */
+ {
+ int is_ascii = 0;
+
+# ifdef WIN32
+ if (!no_win32_wide)
+ is_ascii = is_ascii_stringw(f->inamew);
+ else
+ is_ascii = is_ascii_string(f->uname);
+# else
+ is_ascii = is_ascii_string(f->uname);
+# endif
+
+ if (z->uname == NULL) {
+ if (!is_ascii)
+ z->uname = f->uname;
+ else
+ free(f->uname);
+ } else {
+ free(f->uname);
+ }
+ }
+ f->uname = NULL;
+
+#endif
+ z->iname = f->iname;
+ f->iname = NULL;
+ z->zname = f->zname;
+ f->zname = NULL;
+ z->oname = f->oname;
+ f->oname = NULL;
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ z->namew = f->namew;
+ f->namew = NULL;
+ z->inamew = f->inamew;
+ f->inamew = NULL;
+ z->znamew = f->znamew;
+ f->znamew = NULL;
+#endif
+ z->ext = z->cext = z->com = 0;
+ z->extra = z->cextra = NULL;
+ z->mark = 1;
+ z->dosflag = f->dosflag;
+ /* zip it up */
+ DisplayRunningStats();
+ if (noisy)
+ {
+ fprintf(mesg, " adding: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall)
+ {
+ fprintf(logfile, " adding: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ /* initial scan */
+ len = f->usize;
+ if ((r = zipup(z)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
+ {
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+#endif
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ */
+ sprintf(errbuf, "was zipping %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ if (r == ZE_OPEN || r == ZE_MISS)
+ {
+ o = 1;
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+#endif
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ */
+ if (r == ZE_OPEN) {
+ perror("zip warning");
+ if (logfile)
+ fprintf(logfile, "zip warning: %s\n", strerror(errno));
+ zipwarn("could not open for reading: ", z->oname);
+ if (bad_open_is_error) {
+ sprintf(errbuf, "was zipping %s", z->name);
+ ZIPERR(r, errbuf);
+ }
+ } else {
+ zipwarn("file and directory with the same name: ", z->oname);
+ }
+ files_so_far++;
+ bytes_so_far += len;
+ bad_files_so_far++;
+ bad_bytes_so_far += len;
+ free((zvoid *)(z->name));
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname)
+ free(z->uname);
+# ifdef WIN32
+ if (z->namew)
+ free((zvoid *)(z->namew));
+ if (z->inamew)
+ free((zvoid *)(z->inamew));
+ if (z->znamew)
+ free((zvoid *)(z->znamew));
+# endif
+#endif
+ farfree((zvoid far *)z);
+ }
+ else
+ {
+ files_so_far++;
+ /* current size of file (just before reading) */
+ good_bytes_so_far += z->len;
+ /* size of file on initial scan */
+ bytes_so_far += len;
+ *w = z;
+ w = &z->nxt;
+ zcount++;
+ }
+ }
+ if (key != NULL)
+ {
+ free((zvoid *)key);
+ key = NULL;
+ }
+
+ /* final status 3/17/05 EG */
+ if (noisy && bad_files_so_far)
+ {
+ char tempstrg[100];
+
+ fprintf(mesg, "\nzip warning: Not all files were readable\n");
+ fprintf(mesg, " files/entries read: %lu", files_total - bad_files_so_far);
+ WriteNumString(good_bytes_so_far, tempstrg);
+ fprintf(mesg, " (%s bytes)", tempstrg);
+ fprintf(mesg, " skipped: %lu", bad_files_so_far);
+ WriteNumString(bad_bytes_so_far, tempstrg);
+ fprintf(mesg, " (%s bytes)\n", tempstrg);
+ fflush(mesg);
+ }
+ if (logfile && bad_files_so_far)
+ {
+ char tempstrg[100];
+
+ fprintf(logfile, "\nzip warning: Not all files were readable\n");
+ fprintf(logfile, " files/entries read: %lu", files_total - bad_files_so_far);
+ WriteNumString(good_bytes_so_far, tempstrg);
+ fprintf(logfile, " (%s bytes)", tempstrg);
+ fprintf(logfile, " skipped: %lu", bad_files_so_far);
+ WriteNumString(bad_bytes_so_far, tempstrg);
+ fprintf(logfile, " (%s bytes)", tempstrg);
+ }
+
+ /* Get one line comment for each new entry */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Get comment if any\n");
+ fflush(mesg);
+ }
+#if defined(AMIGA) || defined(MACOS)
+ if (comadd || filenotes)
+ {
+ if (comadd)
+#else
+ if (comadd)
+ {
+#endif
+ {
+ if (comment_stream == NULL) {
+#ifndef RISCOS
+ comment_stream = (FILE*)fdopen(fileno(stderr), "r");
+#else
+ comment_stream = stderr;
+#endif
+ }
+ if ((e = malloc(MAXCOM + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was reading comment lines");
+ }
+ }
+#ifdef __human68k__
+ setmode(fileno(comment_stream), O_TEXT);
+#endif
+#ifdef MACOS
+ if (noisy) fprintf(mesg, "\nStart commenting files ...\n");
+#endif
+ for (z = zfiles; z != NULL; z = z->nxt)
+ if (z->mark)
+#if defined(AMIGA) || defined(MACOS)
+ if (filenotes && (p = GetComment(z->zname)))
+ {
+ if (z->comment = malloc(k = strlen(p)+1))
+ {
+ z->com = k;
+ strcpy(z->comment, p);
+ }
+ else
+ {
+ free((zvoid *)e);
+ ZIPERR(ZE_MEM, "was reading filenotes");
+ }
+ }
+ else if (comadd)
+#endif /* AMIGA || MACOS */
+ {
+ if (noisy)
+ fprintf(mesg, "Enter comment for %s:\n", z->oname);
+ if (fgets(e, MAXCOM+1, comment_stream) != NULL)
+ {
+ if ((p = malloc((extent)(k = strlen(e))+1)) == NULL)
+ {
+ free((zvoid *)e);
+ ZIPERR(ZE_MEM, "was reading comment lines");
+ }
+ strcpy(p, e);
+ if (p[k-1] == '\n')
+ p[--k] = 0;
+ z->comment = p;
+ /* zip64 support 09/05/2003 R.Nausedat */
+ z->com = (extent)k;
+ }
+ }
+#ifdef MACOS
+ if (noisy) fprintf(mesg, "\n...done");
+#endif
+#if defined(AMIGA) || defined(MACOS)
+ if (comadd)
+ free((zvoid *)e);
+ GetComment(NULL); /* makes it free its internal storage */
+#else
+ free((zvoid *)e);
+#endif
+ }
+
+ /* Get multi-line comment for the zip file */
+ if (zipedit)
+ {
+#ifndef WINDLL
+ if (comment_stream == NULL) {
+#ifndef RISCOS
+ comment_stream = (FILE*)fdopen(fileno(stderr), "r");
+#else
+ comment_stream = stderr;
+#endif
+ }
+ if ((e = malloc(MAXCOM + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was reading comment lines");
+ }
+ if (noisy && zcomlen)
+ {
+ fputs("current zip file comment is:\n", mesg);
+ fwrite(zcomment, 1, zcomlen, mesg);
+ if (zcomment[zcomlen-1] != '\n')
+ putc('\n', mesg);
+ free((zvoid *)zcomment);
+ }
+ if ((zcomment = malloc(1)) == NULL)
+ ZIPERR(ZE_MEM, "was setting comments to null");
+ zcomment[0] = '\0';
+ if (noisy)
+ fputs("enter new zip file comment (end with .):\n", mesg);
+#if (defined(AMIGA) && (defined(LATTICE)||defined(__SASC)))
+ flushall(); /* tty input/output is out of sync here */
+#endif
+#ifdef __human68k__
+ setmode(fileno(comment_stream), O_TEXT);
+#endif
+#ifdef MACOS
+ printf("\n enter new zip file comment \n");
+ if (fgets(e, MAXCOM+1, comment_stream) != NULL) {
+ if ((p = malloc((k = strlen(e))+1)) == NULL) {
+ free((zvoid *)e);
+ ZIPERR(ZE_MEM, "was reading comment lines");
+ }
+ strcpy(p, e);
+ if (p[k-1] == '\n') p[--k] = 0;
+ zcomment = p;
+ }
+#else /* !MACOS */
+ while (fgets(e, MAXCOM+1, comment_stream) != NULL && strcmp(e, ".\n"))
+ {
+ if (e[(r = strlen(e)) - 1] == '\n')
+ e[--r] = 0;
+ if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
+ {
+ free((zvoid *)e);
+ ZIPERR(ZE_MEM, "was reading comment lines");
+ }
+ if (*zcomment)
+ strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
+ else
+ strcpy(p, *e ? e : "\r\n");
+ free((zvoid *)zcomment);
+ zcomment = p;
+ }
+#endif /* ?MACOS */
+ free((zvoid *)e);
+#else /* WINDLL */
+ comment(zcomlen);
+ if ((p = malloc(strlen(szCommentBuf)+1)) == NULL) {
+ ZIPERR(ZE_MEM, "was setting comments to null");
+ }
+ if (szCommentBuf[0] != '\0')
+ lstrcpy(p, szCommentBuf);
+ else
+ p[0] = '\0';
+ free((zvoid *)zcomment);
+ GlobalUnlock(hStr);
+ GlobalFree(hStr);
+ zcomment = p;
+#endif /* WINDLL */
+ zcomlen = strlen(zcomment);
+ }
+
+ if (display_globaldots) {
+#ifndef WINDLL
+ putc('\n', mesg);
+#else
+ fprintf(stdout,"%c",'\n');
+#endif
+ mesg_line_started = 0;
+ }
+
+ /* Write central directory and end header to temporary zip */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing central directory\n");
+ fflush(mesg);
+ }
+ diag("writing central directory");
+ k = 0; /* keep count for end header */
+ c = tempzn; /* get start of central */
+ n = t = 0;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+ if (z->mark || !(diff_mode || filesync)) {
+ if ((r = putcentral(z)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+ n += z->len;
+ t += z->siz;
+ k++;
+ }
+ }
+
+ if (k == 0)
+ zipwarn("zip file empty", "");
+ if (verbose) {
+ fprintf(mesg, "total bytes=%s, compressed=%s -> %d%% savings\n",
+ zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, "total bytes=%s, compressed=%s -> %d%% savings\n",
+ zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+ fflush(logfile);
+ }
+ t = tempzn - c; /* compute length of central */
+ diag("writing end of central directory");
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing end of central directory\n");
+ fflush(mesg);
+ }
+
+ if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+
+ /*
+ tempzf = NULL;
+ */
+ if (fclose(y)) {
+ ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
+ }
+ y = NULL;
+ if (in_file != NULL) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ /*
+ if (x != NULL)
+ fclose(x);
+ */
+
+ /* Free some memory before spawning unzip */
+#ifdef USE_ZLIB
+ zl_deflate_free();
+#else
+ lm_free();
+#endif
+#ifdef BZIP2_SUPPORT
+ bz_compress_free();
+#endif
+
+#ifndef WINDLL
+ /* Test new zip file before overwriting old one or removing input files */
+ if (test)
+ check_zipfile(tempzip, argv[0]);
+#endif
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if (strcmp(zipfile, "-") && !d)
+ {
+ diag("replacing old zip file with new zip file");
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Replacing old zip file\n");
+ fflush(mesg);
+ }
+ if ((r = replace(out_path, tempzip)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", tempzip);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing the original zip file");
+ }
+ free((zvoid *)tempzip);
+ }
+ tempzip = NULL;
+ if (zip_attributes && strcmp(zipfile, "-")) {
+ setfileattr(out_path, zip_attributes);
+#ifdef VMS
+ /* If the zip file existed previously, restore its record format: */
+ if (x != NULL)
+ (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
+#endif
+ }
+ if (strcmp(zipfile, "-")) {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Setting file type\n");
+ fflush(mesg);
+ }
+
+ set_filetype(out_path);
+ }
+
+#if defined(WIN32)
+ /* All looks good so, if requested, clear the DOS archive bits */
+ if (clear_archive_bits) {
+ if (noisy)
+ zipmessage("Clearing archive bits...", "");
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+# ifdef UNICODE_SUPPORT
+ if (z->mark) {
+ if (!no_win32_wide) {
+ if (!ClearArchiveBitW(z->namew)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+ } else {
+ if (!ClearArchiveBit(z->name)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+ }
+ }
+# else
+ if (!ClearArchiveBit(z->name)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+# endif
+ }
+ }
+#endif
+
+ /* finish logfile (it gets closed in freeup() called by finish()) */
+ if (logfile) {
+ struct tm *now;
+ time_t clocktime;
+
+ fprintf(logfile, "\nTotal %ld entries (", files_total);
+ if (good_bytes_so_far != bytes_total) {
+ fprintf(logfile, "planned ");
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes, actual ");
+ DisplayNumString(logfile, good_bytes_so_far);
+ fprintf(logfile, " bytes)");
+ } else {
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes)");
+ }
+
+ /* get current time */
+
+ time(&clocktime);
+ now = localtime(&clocktime);
+ fprintf(logfile, "\nDone %s", asctime(now));
+ }
+
+ /* Finish up (process -o, -m, clean up). Exit code depends on o. */
+#if (!defined(VMS) && !defined(CMS_MVS))
+ free((zvoid *) zipbuf);
+#endif /* !VMS && !CMS_MVS */
+ RETURN(finish(o ? ZE_OPEN : ZE_OK));
+}
Index: zip/create-3.0-format-security-patch/zip30-new
===================================================================
--- zip/create-3.0-format-security-patch/zip30-new (nonexistent)
+++ zip/create-3.0-format-security-patch/zip30-new (revision 5)
Property changes on: zip/create-3.0-format-security-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-format-security-patch
===================================================================
--- zip/create-3.0-format-security-patch (nonexistent)
+++ zip/create-3.0-format-security-patch (revision 5)
Property changes on: zip/create-3.0-format-security-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch/create.patch.sh
===================================================================
--- zip/create-3.0-man-pages-patch/create.patch.sh (nonexistent)
+++ zip/create-3.0-man-pages-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr zip${version}-orig zip${version} > zip-${VERSION}-man-pages.patch
+
+mv zip-${VERSION}-man-pages.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig
Property changes on: zip/create-3.0-man-pages-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-man-pages-patch/file.list
===================================================================
--- zip/create-3.0-man-pages-patch/file.list (nonexistent)
+++ zip/create-3.0-man-pages-patch/file.list (revision 5)
@@ -0,0 +1,2 @@
+zip30/man/zipnote.1
+zip30/man/zipsplit.1
Index: zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1 (nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man/zipnote.1 (revision 5)
@@ -0,0 +1,89 @@
+.TH zipnote 1 "v3.0 of 8 May 2008"
+.SH NAME
+zipnote \- write the comments in zipfile to stdout, edit comments and rename files in zipfile
+
+.SH SYNOPSIS
+.I zipnote
+.RB [ \-w ]
+.RB [ \-b\ path ]
+.RB [ \-h ]
+.RB [ \-q ]
+.RB [ \-v ]
+.RB [ \-L ]
+zipfile
+
+.SH ARGUMENTS
+.in +13
+.ti -13
+zipfile Zipfile to read comments from or edit.
+
+.SH OPTIONS
+.TP
+.BI \-w
+Write comments to a zipfile from stdin (see below).
+.TP
+.BI \-b\ \fRpath
+Use path for the temporary zip file.
+.TP
+.BI \-h
+Show a short help.
+.TP
+.BI \-q
+Suppress some informational messages.
+.TP
+.BI \-v
+Show version information.
+.TP
+.BI \-L
+Show software license.
+
+.SH DESCRIPTION
+.I zipnote
+writes the comments in a zipfile to stdout. This is the default mode. A second mode
+allows updating the comments in a zipfile as well as allows changing the names
+of the files in the zipfile. These modes are described below.
+
+.SH EXAMPLES
+To write all comments in a zipfile to stdout use for example
+.LP
+.nf
+ zipnote foo.zip > foo.tmp
+.fi
+.LP
+This writes all comments in the zipfile
+.I foo.zip
+to the file
+.I foo.tmp
+in a specific format.
+
+.LP
+If desired, this file can then be edited to change the comments and then used
+to update the zipfile.
+.LP
+.nf
+ zipnote -w foo.zip < foo.tmp
+.fi
+.LP
+The names of the files in the zipfile can also be changed in this way. This is done by
+following lines like
+.nf
+ "@ name"
+.fi
+in the created temporary file (called
+.I foo.tmp
+here) with lines like
+.nf
+ "@=newname"
+.fi
+and then using the -w option as above.
+
+.SH BUGS
+The temporary file format is rather specific and zipnote is rather picky about it.
+It should be easier to change file names in a script.
+
+Does not yet support large (> 2 GB) or split archives.
+
+.SH SEE ALSO
+zip(1), unzip(1)
+.SH AUTHOR
+Info-ZIP
Index: zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1 (nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man/zipsplit.1 (revision 5)
@@ -0,0 +1,73 @@
+.TH zipnote 1 "v3.0 of 8 May 2008"
+.SH NAME
+zipsplit \- split a zipfile into smaller zipfiles
+
+.SH SYNOPSIS
+.I zipsplit
+.RB [ \-t ]
+.RB [ \-i ]
+.RB [ \-p ]
+.RB [ \-s ]
+.RB [ \-n\ size ]
+.RB [ \-r\ room ]
+.RB [ \-b\ path ]
+.RB [ \-h ]
+.RB [ \-q ]
+.RB [ \-v ]
+.RB [ \-L ]
+zipfile
+
+.SH ARGUMENTS
+.in +13
+.ti -13
+zipfile Zipfile to split.
+
+.SH OPTIONS
+.TP
+.BI \-t
+Report how many files it will take, but don't make them.
+.TP
+.BI \-i
+Make index (zipsplit.idx) and count its size against first zip file.
+.TP
+.BI \-n\ \fRsize
+Make zip files no larger than "size" (default = 36000).
+.TP
+.BI \-r\ \fRroom
+Leave room for "room" bytes on the first disk (default = 0).
+.TP
+.BI \-b\ \fRpath
+Use path for the output zip files.
+.TP
+.BI \-p
+Pause between output zip files.
+.TP
+.BI \-s
+Do a sequential split even if it takes more zip files.
+.TP
+.BI \-h
+Show a short help.
+.TP
+.BI \-q
+Suppress some informational messages.
+.TP
+.BI \-v
+Show version information.
+.TP
+.BI \-L
+Show software license.
+
+.SH DESCRIPTION
+.I zipsplit
+reads a zipfile and splits it into smaller zipfiles.
+
+.SH EXAMPLES
+To be filled in.
+
+.SH BUGS
+Does not yet support large (> 2 GB) or split archives.
+
+.SH SEE ALSO
+zip(1), unzip(1)
+.SH AUTHOR
+Info-ZIP
Index: zip/create-3.0-man-pages-patch/zip30-new/man
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new/man (nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new/man (revision 5)
Property changes on: zip/create-3.0-man-pages-patch/zip30-new/man
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch/zip30-new
===================================================================
--- zip/create-3.0-man-pages-patch/zip30-new (nonexistent)
+++ zip/create-3.0-man-pages-patch/zip30-new (revision 5)
Property changes on: zip/create-3.0-man-pages-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-man-pages-patch
===================================================================
--- zip/create-3.0-man-pages-patch (nonexistent)
+++ zip/create-3.0-man-pages-patch (revision 5)
Property changes on: zip/create-3.0-man-pages-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-zipnote-patch/create.patch.sh
===================================================================
--- zip/create-3.0-zipnote-patch/create.patch.sh (nonexistent)
+++ zip/create-3.0-zipnote-patch/create.patch.sh (revision 5)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+VERSION=3.0
+
+version=${VERSION/./}
+
+tar --files-from=file.list -xzvf ../zip${version}.tar.gz
+mv zip${version} zip${version}-orig
+
+cp -rf ./zip${version}-new ./zip${version}
+
+diff --unified -Nr zip${version}-orig zip${version} > zip-${VERSION}-zipnote.patch
+
+mv zip-${VERSION}-zipnote.patch ../patches
+
+rm -rf ./zip${version}
+rm -rf ./zip${version}-orig
Property changes on: zip/create-3.0-zipnote-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: zip/create-3.0-zipnote-patch/file.list
===================================================================
--- zip/create-3.0-zipnote-patch/file.list (nonexistent)
+++ zip/create-3.0-zipnote-patch/file.list (revision 5)
@@ -0,0 +1 @@
+zip30/zipnote.c
Index: zip/create-3.0-zipnote-patch/zip30-new/zipnote.c
===================================================================
--- zip/create-3.0-zipnote-patch/zip30-new/zipnote.c (nonexistent)
+++ zip/create-3.0-zipnote-patch/zip30-new/zipnote.c (revision 5)
@@ -0,0 +1,699 @@
+/*
+ zipnote.c - Zip 3
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * zipnote.c by Mark Adler.
+ */
+#define __ZIPNOTE_C
+
+#ifndef UTIL
+#define UTIL
+#endif
+#include "zip.h"
+#define DEFCPYRT /* main module: enable copyright string defines! */
+#include "revision.h"
+#include <signal.h>
+
+/* Calculate size of static line buffer used in write (-w) mode. */
+#define WRBUFSIZ 2047
+/* The line buffer size should be at least as large as FNMAX. */
+#if FNMAX > WRBUFSIZ
+# undef WRBUFSIZ
+# define WRBUFSIZ FNMAX
+#endif
+
+/* Character to mark zip entry names in the comment file */
+#define MARK '@'
+#define MARKE " (comment above this line)"
+#define MARKZ " (zip file comment below this line)"
+
+/* Temporary zip file pointer */
+local FILE *tempzf;
+
+
+/* Local functions */
+local void handler OF((int));
+local void license OF((void));
+local void help OF((void));
+local void version_info OF((void));
+local void putclean OF((char *, extent));
+/* getline name conflicts with GNU getline() function */
+local char *zgetline OF((char *, extent));
+local int catalloc OF((char * far *, char *));
+int main OF((int, char **));
+
+/* keep compiler happy until implement long options - 11/4/2003 EG */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
+#ifdef MACOS
+#define ziperr(c, h) zipnoteerr(c, h)
+#define zipwarn(a, b) zipnotewarn(a, b)
+
+void zipnoteerr(int c, ZCONST char *h);
+void zipnotewarn(ZCONST char *a, ZCONST char *b);
+#endif
+
+#ifdef QDOS
+#define exit(p1) QDOSexit()
+#endif
+
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. If logfile is
+ open then also write message to log file. */
+{
+ if (noisy) {
+ fprintf(mesg, "%s", a);
+ if (nl) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ } else {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Also write to log file if
+ open. Write new line first if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+}
+
+void ziperr(c, h)
+int c; /* error code from the ZE_ class */
+ZCONST char *h; /* message about how it happened */
+/* Issue a message for the error, clean up files and memory, and exit. */
+{
+ if (PERR(c))
+ perror("zipnote error");
+ fprintf(mesg, "zipnote error: %s (%s)\n", ZIPERRORS(c), h);
+ if (tempzf != NULL)
+ fclose(tempzf);
+ if (tempzip != NULL)
+ {
+ destroy(tempzip);
+ free((zvoid *)tempzip);
+ }
+ if (zipfile != NULL)
+ free((zvoid *)zipfile);
+ EXIT(c);
+}
+
+
+local void handler(s)
+int s; /* signal number (ignored) */
+/* Upon getting a user interrupt, abort cleanly using ziperr(). */
+{
+#ifndef MSDOS
+ putc('\n', mesg);
+#endif /* !MSDOS */
+ ziperr(ZE_ABORT, "aborting");
+ s++; /* keep some compilers happy */
+}
+
+
+void zipwarn(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a warning message to mesg (usually stderr) and return. */
+{
+ fprintf(mesg, "zipnote warning: %s%s\n", a, b);
+}
+
+
+local void license()
+/* Print license information to stdout. */
+{
+ extent i; /* counter for copyright array */
+
+ for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
+ puts(swlicense[i]);
+}
+
+
+local void help()
+/* Print help (along with license info) to stdout. */
+{
+ extent i; /* counter for help array */
+
+ /* help array */
+ static ZCONST char *text[] = {
+"",
+"ZipNote %s (%s)",
+#ifdef VM_CMS
+"Usage: zipnote [-w] [-q] [-b fm] zipfile",
+#else
+"Usage: zipnote [-w] [-q] [-b path] zipfile",
+#endif
+" the default action is to write the comments in zipfile to stdout",
+" -w write the zipfile comments from stdin",
+#ifdef VM_CMS
+" -b use \"fm\" as the filemode for the temporary zip file",
+#else
+" -b use \"path\" for the temporary zip file",
+#endif
+" -q quieter operation, suppress some informational messages",
+" -h show this help -v show version info -L show software license",
+"",
+"Example:",
+#ifdef VMS
+" define/user sys$output foo.tmp",
+" zipnote foo.zip",
+" edit foo.tmp",
+" ... then you edit the comments, save, and exit ...",
+" define/user sys$input foo.tmp",
+" zipnote -w foo.zip",
+#else
+#ifdef RISCOS
+" zipnote foo/zip > foo/tmp",
+" <!Edit> foo/tmp",
+" ... then you edit the comments, save, and exit ...",
+" zipnote -w foo/zip < foo/tmp",
+#else
+#ifdef VM_CMS
+" zipnote foo.zip > foo.tmp",
+" xedit foo tmp",
+" ... then you edit the comments, save, and exit ...",
+" zipnote -w foo.zip < foo.tmp",
+#else
+" zipnote foo.zip > foo.tmp",
+" ed foo.tmp",
+" ... then you edit the comments, save, and exit ...",
+" zipnote -w foo.zip < foo.tmp",
+#endif /* VM_CMS */
+#endif /* RISCOS */
+#endif /* VMS */
+"",
+" \"@ name\" can be followed by an \"@=newname\" line to change the name"
+ };
+
+ for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
+ printf(copyright[i], "zipnote");
+ putchar('\n');
+ }
+ for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+ {
+ printf(text[i], VERSION, REVDATE);
+ putchar('\n');
+ }
+}
+
+/*
+ * XXX put this in version.c
+ */
+
+local void version_info()
+/* Print verbose info about program version and compile time options
+ to stdout. */
+{
+ extent i; /* counter in text arrays */
+
+ /* Options info array */
+ static ZCONST char *comp_opts[] = {
+#ifdef DEBUG
+ "DEBUG",
+#endif
+ NULL
+ };
+
+ for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
+ {
+ printf(copyright[i], "zipnote");
+ putchar('\n');
+ }
+
+ for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
+ {
+ printf(versinfolines[i], "ZipNote", VERSION, REVDATE);
+ putchar('\n');
+ }
+
+ version_local();
+
+ puts("ZipNote special compilation options:");
+ for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
+ {
+ printf("\t%s\n",comp_opts[i]);
+ }
+ if (i == 0)
+ puts("\t[none]");
+}
+
+
+local void putclean(s, n)
+char *s; /* string to write to stdout */
+extent n; /* length of string */
+/* Write the string s to stdout, filtering out control characters that are
+ not tab or newline (mainly to remove carriage returns), and prefix MARK's
+ and backslashes with a backslash. Also, terminate with a newline if
+ needed. */
+{
+ int c; /* next character in string */
+ int e; /* last character written */
+
+ e = '\n'; /* if empty, write nothing */
+ while (n--)
+ {
+ c = *(uch *)s++;
+ if (c == MARK || c == '\\')
+ putchar('\\');
+ if (c >= ' ' || c == '\t' || c == '\n')
+ { e=c; putchar(e); }
+ }
+ if (e != '\n')
+ putchar('\n');
+}
+
+
+local char *zgetline(buf, size)
+char *buf;
+extent size;
+/* Read a line of text from stdin into string buffer 'buf' of size 'size'.
+ In case of buffer overflow or EOF, a NULL pointer is returned. */
+{
+ char *line;
+ unsigned len;
+
+ line = fgets(buf, size, stdin);
+ if (line != NULL && (len = strlen(line)) > 0) {
+ if (len == size-1 && line[len-1] != '\n') {
+ /* buffer is full and record delimiter not seen -> overflow */
+ line = NULL;
+ } else {
+ /* delete trailing record delimiter */
+ if (line[len-1] == '\n') line[len-1] = '\0';
+ }
+ }
+ return line;
+}
+
+
+local int catalloc(a, s)
+char * far *a; /* pointer to a pointer to a malloc'ed string */
+char *s; /* string to concatenate on a */
+/* Concatentate the string s to the malloc'ed string pointed to by a.
+ Preprocess s by removing backslash escape characters. */
+{
+ char *p; /* temporary pointer */
+ char *q; /* temporary pointer */
+
+ for (p = q = s; *q; *p++ = *q++)
+ if (*q == '\\' && *(q+1))
+ q++;
+ *p = 0;
+ if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL)
+ return ZE_MEM;
+ strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s);
+ free((zvoid *)*a);
+ *a = p;
+ return ZE_OK;
+}
+
+
+#ifndef USE_ZIPNOTEMAIN
+int main(argc, argv)
+#else
+int zipnotemain(argc, argv)
+#endif
+int argc; /* number of tokens in command line */
+char **argv; /* command line tokens */
+/* Write the comments in the zipfile to stdout, or read them from stdin. */
+{
+ char abf[WRBUFSIZ+1]; /* input line buffer */
+ char *a; /* pointer to line buffer or NULL */
+ zoff_t c; /* start of central directory */
+ int k; /* next argument type */
+ char *q; /* steps through option arguments */
+ int r; /* arg counter, temporary variable */
+ zoff_t s; /* length of central directory */
+ int t; /* attributes of zip file */
+ int w; /* true if updating zip file from stdin */
+ FILE *x; /* input file for testing if can write it */
+ struct zlist far *z; /* steps through zfiles linked list */
+
+#ifdef THEOS
+ setlocale(LC_CTYPE, "I");
+#endif
+
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
+#endif
+
+ /* If no args, show help */
+ if (argc == 1)
+ {
+ help();
+ EXIT(ZE_OK);
+ }
+
+ /* Direct info messages to stderr; stdout is used for data output. */
+ mesg = stderr;
+
+ init_upper(); /* build case map table */
+
+ /* Go through args */
+ zipfile = tempzip = NULL;
+ tempzf = NULL;
+ signal(SIGINT, handler);
+#ifdef SIGTERM /* AMIGA has no SIGTERM */
+ signal(SIGTERM, handler);
+#endif
+#ifdef SIGABRT
+ signal(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+ signal(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+#endif
+ k = w = 0;
+ for (r = 1; r < argc; r++)
+ if (*argv[r] == '-') {
+ if (argv[r][1])
+ for (q = argv[r]+1; *q; q++)
+ switch (*q)
+ {
+ case 'b': /* Specify path for temporary file */
+ if (k)
+ ziperr(ZE_PARMS, "use -b before zip file name");
+ else
+ k = 1; /* Next non-option is path */
+ break;
+ case 'h': /* Show help */
+ help(); EXIT(ZE_OK);
+ case 'l': case 'L': /* Show copyright and disclaimer */
+ license(); EXIT(ZE_OK);
+ case 'q': /* Quiet operation, suppress info messages */
+ noisy = 0; break;
+ case 'v': /* Show version info */
+ version_info(); EXIT(ZE_OK);
+ case 'w':
+ w = 1; break;
+ default:
+ ziperr(ZE_PARMS, "unknown option");
+ }
+ else
+ ziperr(ZE_PARMS, "zip file cannot be stdin");
+ } else
+ if (k == 0)
+ {
+ if (zipfile == NULL)
+ {
+ if ((zipfile = ziptyp(argv[r])) == NULL)
+ ziperr(ZE_MEM, "was processing arguments");
+ }
+ else
+ ziperr(ZE_PARMS, "can only specify one zip file");
+ }
+ else
+ {
+ tempath = argv[r];
+ k = 0;
+ }
+ if (zipfile == NULL)
+ ziperr(ZE_PARMS, "need to specify zip file");
+
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ziperr(ZE_MEM, "input");
+ }
+ strcpy(in_path, zipfile);
+
+ /* Read zip file */
+ if ((r = readzipfile()) != ZE_OK)
+ ziperr(r, zipfile);
+ if (zfiles == NULL)
+ ziperr(ZE_NAME, zipfile);
+
+ /* Put comments to stdout, if not -w */
+ if (!w)
+ {
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+ printf("%c %s\n", MARK, z->zname);
+ putclean(z->comment, z->com);
+ printf("%c%s\n", MARK, MARKE);
+ }
+ printf("%c%s\n", MARK, MARKZ);
+ putclean(zcomment, zcomlen);
+ EXIT(ZE_OK);
+ }
+
+ /* If updating comments, make sure zip file is writeable */
+ if ((x = fopen(zipfile, "a")) == NULL)
+ ziperr(ZE_CREAT, zipfile);
+ fclose(x);
+ t = getfileattr(zipfile);
+
+ /* Process stdin, replacing comments */
+ z = zfiles;
+ while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL &&
+ (a[0] != MARK || strcmp(a + 1, MARKZ)))
+ { /* while input and not file comment */
+ if (a[0] != MARK || a[1] != ' ') /* better be "@ name" */
+ ziperr(ZE_NOTE, "unexpected input");
+ while (z != NULL && strcmp(a + 2, z->zname))
+ z = z->nxt; /* allow missing entries in order */
+ if (z == NULL)
+ ziperr(ZE_NOTE, "unknown entry name");
+ if ((a = zgetline(abf, WRBUFSIZ+1)) != NULL && a[0] == MARK && a[1] == '=')
+ {
+ if (z->name != z->iname)
+ free((zvoid *)z->iname);
+ if ((z->iname = malloc(strlen(a+1))) == NULL)
+ ziperr(ZE_MEM, "was changing name");
+#ifdef EBCDIC
+ strtoasc(z->iname, a+2);
+#else
+ strcpy(z->iname, a+2);
+#endif
+
+/*
+ * Don't update z->nam here, we need the old value a little later.....
+ * The update is handled in zipcopy().
+ */
+ a = zgetline(abf, WRBUFSIZ+1);
+ }
+ if (z->com) /* change zip entry comment */
+ free((zvoid *)z->comment);
+ z->comment = malloc(1); *(z->comment) = 0;
+ while (a != NULL && *a != MARK)
+ {
+ if ((r = catalloc(&(z->comment), a)) != ZE_OK)
+ ziperr(r, "was building new zipentry comments");
+ a = zgetline(abf, WRBUFSIZ+1);
+ }
+ z->com = strlen(z->comment);
+ z = z->nxt; /* point to next entry */
+ }
+ if (a != NULL) /* change zip file comment */
+ {
+ zcomment = malloc(1); *zcomment = 0;
+ while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL)
+ if ((r = catalloc(&zcomment, a)) != ZE_OK)
+ ziperr(r, "was building new zipfile comment");
+ zcomlen = strlen(zcomment);
+ }
+
+ /* Open output zip file for writing */
+#if defined(UNIX) && !defined(NO_MKSTEMP)
+ {
+ int yd;
+ int i;
+
+ /* use mkstemp to avoid race condition and compiler warning */
+
+ if (tempath != NULL)
+ {
+ /* if -b used to set temp file dir use that for split temp */
+ if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, tempath);
+ if (lastchar(tempzip) != '/')
+ strcat(tempzip, "/");
+ }
+ else
+ {
+ /* create path by stripping name and appending template */
+ if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
+ ZIPERR(ZE_MEM, "allocating temp filename");
+ }
+ strcpy(tempzip, zipfile);
+ for(i = strlen(tempzip); i > 0; i--) {
+ if (tempzip[i - 1] == '/')
+ break;
+ }
+ tempzip[i] = '\0';
+ }
+ strcat(tempzip, "ziXXXXXX");
+
+ if ((yd = mkstemp(tempzip)) == EOF) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ if ((tempzf = y = fdopen(yd, FOPW)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ }
+#else
+ if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
+ ziperr(ZE_TEMP, tempzip);
+#endif
+
+ /* Open input zip file again, copy preamble if any */
+ if ((in_file = fopen(zipfile, FOPR)) == NULL)
+ ziperr(ZE_NAME, zipfile);
+
+ if (zipbeg && (r = bfcopy(zipbeg)) != ZE_OK)
+ ziperr(r, r == ZE_TEMP ? tempzip : zipfile);
+ tempzn = zipbeg;
+
+ /* Go through local entries, copying them over as is */
+ fix = 3; /* needed for zipcopy if name changed */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if ((r = zipcopy(z)) != ZE_OK)
+ ziperr(r, "was copying an entry");
+ }
+ fclose(in_file);
+
+ /* Write central directory and end of central directory with new comments */
+ if ((c = zftello(y)) == (zoff_t)-1) /* get start of central */
+ ziperr(ZE_TEMP, tempzip);
+ for (z = zfiles; z != NULL; z = z->nxt)
+ if ((r = putcentral(z)) != ZE_OK)
+ ziperr(r, tempzip);
+ if ((s = zftello(y)) == (zoff_t)-1) /* get end of central */
+ ziperr(ZE_TEMP, tempzip);
+ s -= c; /* compute length of central */
+ if ((r = putend((zoff_t)zcount, s, c, zcomlen, zcomment)) != ZE_OK)
+ ziperr(r, tempzip);
+ tempzf = NULL;
+ if (fclose(y))
+ ziperr(ZE_TEMP, tempzip);
+ if ((r = replace(zipfile, tempzip)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", tempzip);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ziperr(r, "was replacing the original zip file");
+ }
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ setfileattr(zipfile, t);
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(zipfile,0xDDC);
+#endif
+ free((zvoid *)zipfile);
+ zipfile = NULL;
+
+ /* Done! */
+ RETURN(0);
+}
Index: zip/create-3.0-zipnote-patch/zip30-new
===================================================================
--- zip/create-3.0-zipnote-patch/zip30-new (nonexistent)
+++ zip/create-3.0-zipnote-patch/zip30-new (revision 5)
Property changes on: zip/create-3.0-zipnote-patch/zip30-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/create-3.0-zipnote-patch
===================================================================
--- zip/create-3.0-zipnote-patch (nonexistent)
+++ zip/create-3.0-zipnote-patch (revision 5)
Property changes on: zip/create-3.0-zipnote-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip/patches/README
===================================================================
--- zip/patches/README (nonexistent)
+++ zip/patches/README (revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+ TODO: Leave some comment here.
+
+ * end */
Index: zip/patches
===================================================================
--- zip/patches (nonexistent)
+++ zip/patches (revision 5)
Property changes on: zip/patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: zip
===================================================================
--- zip (nonexistent)
+++ zip (revision 5)
Property changes on: zip
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 5)
Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~