diff -u unzip-5.52/unix/unix.c unzip-5.52/unix/unix.c --- unzip-5.52/unix/unix.c +++ unzip-5.52/unix/unix.c @@ -30,6 +30,9 @@ #define UNZIP_INTERNAL #include "unzip.h" +#include +#include + #ifdef SCO_XENIX # define SYSNDIR #else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */ @@ -1687,0 +1691,87 @@ + + +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, + sizeof(OEM_CP)); + 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; + dlen = buflen = 2*slen; + d = buf = malloc(buflen + 1); + if(!d) + goto cleanup; + bzero(buf,buflen); + 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); +} diff -u unzip-5.52/unix/unxcfg.h unzip-5.52/unix/unxcfg.h --- unzip-5.52/unix/unxcfg.h +++ unzip-5.52/unix/unxcfg.h @@ -144,2 +144,28 @@ + +#define MAX_CP_NAME 25 + +#ifdef SETLOCALE +# undef SETLOCALE +#endif +#define SETLOCALE(category, locale) setlocale(category, locale) +#include + +#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 */ diff -u unzip-5.52/debian/control unzip-5.52/debian/control --- unzip-5.52/debian/control +++ unzip-5.52/debian/control @@ -1,7 +1,8 @@ Source: unzip Section: utils Priority: optional -Maintainer: Santiago Vila +Maintainer: Ubuntu Core Developers +XSBC-Original-Maintainer: Santiago Vila Standards-Version: 3.7.2 Package: unzip diff -u unzip-5.52/debian/changelog unzip-5.52/debian/changelog --- unzip-5.52/debian/changelog +++ unzip-5.52/debian/changelog @@ -1,3 +1,11 @@ +unzip (5.52-11ubuntu1) intrepid; urgency=low + + * Merge from debian unstable (LP: #239686), remaining changes: + - unzip.c: Change banner to indicate Ubuntu modification. + - support UTF-8 file names. + + -- Thierry Carrez Fri, 13 Jun 2008 16:20:20 +0200 + unzip (5.52-11) unstable; urgency=high * Apply patch from Tavis Ormandy to address invalid free() calls in @@ -5,12 +13,50 @@ -- Santiago Vila Thu, 20 Mar 2008 17:53:00 +0100 +unzip (5.52-10ubuntu2) hardy; urgency=low + + * SECURITY UPDATE: arbitrary code execution via heap corruption. + * inflate.c: fix invalid free() calls, patch from Tavis Ormandy. + * References + CVE-2008-0888 + + -- Kees Cook Wed, 19 Mar 2008 12:08:30 -0700 + +unzip (5.52-10ubuntu1) gutsy; urgency=low + + * Merge with Debian; remaining changes: + - debian/rules: Configure with large file support. + - unzip.c: Change banner to indicate Ubuntu modification. + - support UTF-8 file names. + + -- Matthias Klose Tue, 17 Jul 2007 10:03:01 +0000 + unzip (5.52-10) unstable; urgency=low * Fixed typo in unzipsfx(1). Thanks to Kevin Ryde. Closes: #419479. -- Santiago Vila Mon, 2 Jul 2007 18:08:44 +0200 +unzip (5.52-9ubuntu3) feisty; urgency=low + + * Apply patch from https://bugzilla.altlinux.org/long_list.cgi?buglist=4871 + to support UTF-8 file names. Ubuntu #10979. + + -- Matthias Klose Sat, 31 Mar 2007 13:10:40 +0200 + +unzip (5.52-9ubuntu2) feisty; urgency=low + + * Rebuild for changes in the amd64 toolchain. + * Set Ubuntu maintainer address. + + -- Matthias Klose Mon, 5 Mar 2007 01:27:17 +0000 + +unzip (5.52-9ubuntu1) feisty; urgency=low + + * Merge from debian unstable. + + -- Michael Vogt Wed, 22 Nov 2006 12:10:13 +0100 + unzip (5.52-9) unstable; urgency=low * Added appropriate compiler flags for Large File Support (Closes: #192253). @@ -20,6 +66,14 @@ -- Santiago Vila Wed, 30 Aug 2006 10:34:24 +0200 +unzip (5.52-8ubuntu1) edgy; urgency=low + + * Merge from debian unstable; only Ubuntu changes left: + - debian/rules: Configure with large file support. + - unzip.c: Change banner to indicate Ubuntu modification. + + -- Martin Pitt Fri, 30 Jun 2006 11:28:40 +0200 + unzip (5.52-8) unstable; urgency=low * Modified unix/unxcfg.h to always #include . @@ -37,6 +91,43 @@ -- Santiago Vila Thu, 16 Mar 2006 10:31:20 +0100 +unzip (5.52-6ubuntu4) dapper; urgency=low + + * const.h, process.c: Limit the maximum length of displayed file names to + 512 bytes, to avoid spewage with excessively long file names (which caused + buffer overflows until the recent security fix for CVE-2005-4667). + * Thanks to Santiago Vila for pointing this out. + + -- Martin Pitt Thu, 23 Mar 2006 13:00:08 +0100 + +unzip (5.52-6ubuntu3) dapper; urgency=low + + * Previous security update scrambled the output fields in the contents + listing, fix that regression. + + -- Martin Pitt Wed, 15 Feb 2006 12:11:47 +0100 + +unzip (5.52-6ubuntu2) dapper; urgency=low + + * SECURITY UPDATE: Arbitrary code execution on specially crafted long file + names (which should not happen in many scenarios, though). + * unzpriv.h, Info macro: + - Use snprintf() instead of sprintf() as inner formatting function. + - Use fputs() instead of fprintf() as outer function to ignore leftover + format strings which might not have been substituted in the inner + snprintf(). + - Throw away the three different implementations of that macro and use + just one safe one. + - CVE-2005-4667 + + -- Martin Pitt Fri, 10 Feb 2006 20:14:01 +0100 + +unzip (5.52-6ubuntu1) dapper; urgency=low + + * Resynchronise with Debian. + + -- Michael Vogt Wed, 28 Dec 2005 11:02:39 +0100 + unzip (5.52-6) unstable; urgency=medium * Symlinks should work again (Closes: #343680). Fix provided by @@ -44,6 +135,15 @@ -- Santiago Vila Tue, 20 Dec 2005 19:18:32 +0100 +unzip (5.52-5ubuntu1) dapper; urgency=low + + * Resynchronise with Debian. + * Repaired totally scrambled changelog. + * unzip.c: Change Debian banner to 'Ubuntu', as advised by the Debian + maintainer. + + -- Martin Pitt Mon, 21 Nov 2005 20:38:41 +0100 + unzip (5.52-5) unstable; urgency=low * Fixed CAN-2005-2475 the same way it will be fixed in unzip 5.53. @@ -54,6 +154,12 @@ -- Santiago Vila Thu, 17 Nov 2005 16:34:24 +0100 +unzip (5.52-4ubuntu1) dapper; urgency=low + + * Resynchronise with Debian. + + -- Michael Vogt Fri, 11 Nov 2005 13:16:29 +0100 + unzip (5.52-4) unstable; urgency=medium * Fixed toctou vulnerability (Closes: #321927). Modified unix/unix.c @@ -63,6 +169,22 @@ -- Santiago Vila Wed, 9 Nov 2005 18:05:02 +0100 +unzip (5.52-3ubuntu2) breezy; urgency=low + + * SECURITY UPDATE: Fix file permission modification race. + * unix/unix.c: Use fchmod() instead of chmod() to change permissions on the + files unzip actually created, not the files another attacker might have + hardlinked to in the meantime. + * CAN-2005-2475 + + -- Martin Pitt Thu, 29 Sep 2005 17:02:50 +0200 + +unzip (5.52-3ubuntu1) breezy; urgency=low + + * Resynchronise with Debian. + + -- Michael Vogt Tue, 28 Jun 2005 15:46:02 +0200 + unzip (5.52-3) unstable; urgency=low * Put manpages in section 1, not 1L. @@ -84,6 +206,12 @@ -- Santiago Vila Tue, 1 Mar 2005 15:33:54 +0100 +unzip (5.51-2ubuntu1) hoary; urgency=low + + * Fixed unzip of >2GB files, thanks to patch from ard at kwaak.net + + -- Thom May Mon, 28 Feb 2005 15:25:52 +0000 + unzip (5.51-2) unstable; urgency=low * Added unshrinking support (Closes: #252563). @@ -256,0 +385 @@ + diff -u unzip-5.52/unzpriv.h unzip-5.52/unzpriv.h --- unzip-5.52/unzpriv.h +++ unzip-5.52/unzpriv.h @@ -1200,7 +1200,9 @@ # define lastchar(ptr, len) (ptr[(len)-1]) # define MBSCHR(str, c) strchr(str, c) # define MBSRCHR(str, c) strrchr(str, c) -# define SETLOCALE(category, locale) +# ifndef SETLOCALE +# define SETLOCALE(category, locale) +# endif #endif /* ?_MBCS */ #define INCSTR(ptr) PREINCSTR(ptr) @@ -2570,7 +2572,7 @@ !(((islochdr) || (isuxatt)) && \ ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \ (hostnum) == FS_HPFS_ || \ - ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \ + ((hostnum) == FS_NTFS_/* && (hostver) == 50*/)) { \ _OEM_INTERN((string)); \ } else { \ _ISO_INTERN((string)); \ diff -u unzip-5.52/unzip.c unzip-5.52/unzip.c --- unzip-5.52/unzip.c +++ unzip-5.52/unzip.c @@ -309,11 +309,21 @@ -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 %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"; +#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 #ifdef VMS static ZCONST char Far ZipInfoUsageLine4[] = @@ -518,7 +528,7 @@ #else /* !VMS */ # ifdef COPYRIGHT_CLEAN static ZCONST char Far UnzipUsageLine1[] = "\ -UnZip %d.%d%d%s of %s, by Debian. Original by Info-ZIP.\ +UnZip %d.%d%d%s of %s, by Ubuntu. Original by Info-ZIP.\ \n\n"; # else static ZCONST char Far UnzipUsageLine1[] = "\ @@ -598,6 +608,7 @@ #endif /* ?VM_CMS */ #endif /* ?MACOS */ +#ifndef UNIX static ZCONST char Far UnzipUsageLine4[] = "\ modifiers: -q quiet mode (-qq => quieter)\n\ -n never overwrite existing files -a auto-convert any text files\n\ @@ -605,6 +616,17 @@ -j junk paths (do not make directories) -v be verbose/print version info\n\ %c-C%c match filenames case-insensitively %c-L%c make (some) names \ lowercase\n %-42s %c-V%c retain VMS version numbers\n%s"; +#else /* UNIX */ +static ZCONST char Far UnzipUsageLine4[] = "\ +modifiers: -q quiet mode (-qq => quieter)\n\ + -n never overwrite existing files -a auto-convert any text files\n\ + -o overwrite files WITHOUT prompting -aa treat ALL files as text\n \ + -j junk paths (do not make directories) -v be verbose/print version info\n\ + %c-C%c match filenames case-insensitively %c-L%c make (some) names \ +lowercase\n %-42s %c-V%c retain VMS version numbers\n%s\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\n"; +#endif /* !UNIX */ static ZCONST char Far UnzipUsageLine5[] = "\ Examples (see unzip.txt for more info):\n\ @@ -667,6 +689,10 @@ SETLOCALE(LC_CTYPE,""); +#ifdef UNIX + init_conversion_charsets(); +#endif + #if (defined(__IBMC__) && defined(__DEBUG_ALLOC__)) extern void DebugMalloc(void); @@ -1088,6 +1114,11 @@ 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 */ @@ -1251,6 +1282,35 @@ } 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, sizeof(ISO_CP)); + } 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, sizeof(ISO_CP)); + } + while(*(++s)); /* No params straight after charset name */ + } + break; +#endif /* ?UNIX */ case ('j'): /* junk pathnames/directory structure */ if (negative) uO.jflag = FALSE, negative = 0; @@ -1326,6 +1386,35 @@ } 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, sizeof(OEM_CP)); + } 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, sizeof(OEM_CP)); + } + while(*(++s)); /* No params straight after charset name */ + } + break; +#endif /* ?UNIX */ case ('p'): /* pipes: extract to stdout, no messages */ if (negative) { uO.cflag = FALSE; only in patch2: unchanged: --- unzip-5.52.orig/unzip.c.orig +++ unzip-5.52/unzip.c.orig @@ -0,0 +1,2041 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + 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. + + --------------------------------------------------------------------------- + + [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 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 NoMemArguments[] = + "envargs: cannot get memory for arguments"; +#endif /* !_WIN32_WCE */ +#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 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(DLL) && defined(API_DOC)) + static ZCONST char Far local1[] = + " -A print extended help for API functions"; +#else /* !(DLL && API_DOC) */ + static ZCONST char Far local1[] = ""; +#endif /* ?(DLL && API_DOC) */ + +/* 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/protection info"; +#ifdef MORE + static ZCONST char Far local3[] = " \ + \"-M\" pipe through \"more\" pager\n"; +#else + static ZCONST char Far local3[] = "\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"; + +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"; +#ifdef MORE +#ifdef VMS + static ZCONST char Far ZipInfoUsageLine4[] = + " \"-M\" page output through built-in \"more\"\n"; +#else + static ZCONST char Far ZipInfoUsageLine4[] = + " -M page output through built-in \"more\"\n"; +#endif +#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 ; 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[] = "\t%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: %s\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 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 MULT_VOLUME + static ZCONST char Far Use_MultiVol[] = + "MULT_VOLUME (multi-volume archives 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 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[] = + "\t[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 Ubuntu. Original by Info-ZIP.\ +\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] " +# ifdef VMS + static ZCONST char Far ZipInfoMode[] = + "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage)."; +# else + static ZCONST char Far ZipInfoMode[] = + "-Z => ZipInfo mode (\"unzip -Z\" for usage)."; +# endif +#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\n\ +%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\n\ + -x exclude files that follow (in xlist) -d extract files onto disk fm\n\ +%s\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\n\ + -x exclude files that follow (in xlist) -d extract files into exdir\n\ +%s\n"; +#endif /* ?VM_CMS */ +#endif /* ?MACOS */ + +static ZCONST char Far UnzipUsageLine4[] = "\ +modifiers: -q quiet mode (-qq => quieter)\n\ + -n never overwrite existing files -a auto-convert any text files\n\ + -o overwrite files WITHOUT prompting -aa treat ALL files as text\n \ + -j junk paths (do not make directories) -v be verbose/print version info\n\ + %c-C%c match filenames case-insensitively %c-L%c make (some) names \ +lowercase\n %-42s %c-V%c retain VMS version numbers\n%s"; + +static ZCONST char Far UnzipUsageLine5[] = "\ +Examples (see unzip.txt for more info):\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 +#ifdef DOS_FLX_H68_NLM_OS2_W32 + 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 */ + + SETLOCALE(LC_CTYPE,""); + +#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 +#ifdef SIGBUS + SET_SIGHANDLER(SIGBUS, 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. Explicitely 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 + +/*--------------------------------------------------------------------------- + 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(NoMemArguments)); + else +#endif + error = zi_opts(__G__ &argc, &argv); + } 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(NoMemArguments)); + else +#endif + 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); + } + ++G.pfnames; +#endif /* ?__human68k__ */ + } +#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) */ + +/*--------------------------------------------------------------------------- + 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 + 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; + + + argc = *pargc; + argv = *pargv; + + 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 */ + 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 */ + *pargc = -1; + return USAGE(PK_OK); +#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 */ + 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; + 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 */ + 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; +#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 */ +#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 */ + 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 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 (':'): + if (negative) { + uO.ddotflag = MAX(uO.ddotflag-negative,0); + negative = 0; + } else + ++uO.ddotflag; + break; +#endif /* !RISCOS && !CMS_MVS && !TANDEM */ + 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 ((uO.cflag && uO.tflag) || (uO.cflag && 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; +#endif + 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 = PK_PARAM; /* 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 + +# ifdef MORE +# define SFXOPT1 "M" +# else +# define SFXOPT1 "" +# 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), + QUOT,QUOT, QUOT,QUOT, 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), + QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(local2), QUOT,QUOT, + 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 + +#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 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 MULT_VOLUME + Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat), + LoadFarStringSmall(Use_MultiVol))); + ++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 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 */ only in patch2: unchanged: --- unzip-5.52.orig/zipinfo.c +++ unzip-5.52/zipinfo.c @@ -447,6 +447,10 @@ 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 */ @@ -491,6 +495,35 @@ 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, sizeof(ISO_CP)); + } 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, sizeof(ISO_CP)); + } + 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; @@ -511,6 +544,35 @@ 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, sizeof(OEM_CP)); + } 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, sizeof(OEM_CP)); + } + 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; only in patch2: unchanged: --- unzip-5.52.orig/unix/unxcfg.h.orig +++ unzip-5.52/unix/unxcfg.h.orig @@ -0,0 +1,145 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + Unix specific configuration section: + ---------------------------------------------------------------------------*/ + +#ifndef __unxcfg_h +#define __unxcfg_h + +#include /* off_t, time_t, dev_t, ... */ +#include +#include + +#ifndef COHERENT +# include /* O_BINARY for open() w/o CR/LF translation */ +#else /* COHERENT */ +# ifdef _I386 +# include /* Coherent 4.0.x, Mark Williams C */ +# else +# include /* 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 */ +# endif +# ifdef BSD +# define TEMP_BSD /* may be defined again in */ +# undef BSD +# endif +# include /* conflict with , 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 +# define DIRENT +# define HAVE_TERMIOS_H +# ifndef timezone +# define timezone _timezone +# endif +#endif + +#ifdef BSD +# include +# include +# if (defined(_AIX) || defined(__GLIBC__) || defined(__GNU__)) +# include +# endif +#else +# include + struct tm *gmtime(), *localtime(); +#endif + +#if (defined(BSD4_4) || (defined(SYSV) && defined(MODERN))) +# include /* this includes utime.h on SGIs */ +# if (defined(BSD4_4) || defined(linux) || defined(__GLIBC__)) +# include +# define GOT_UTIMBUF +# endif +# if (!defined(GOT_UTIMBUF) && defined(__GNU__)) +# include +# define GOT_UTIMBUF +# endif +#endif +#if (defined(__DGUX__) && !defined(GOT_UTIMBUF)) + /* DG/UX requires this because of a non-standard struct utimebuf */ +# include +# 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 + +#ifdef MINIX +# include +#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 +#define SET_DIR_ATTRIB +#if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP)) /* GRR 970513 */ +# define TIMESTAMP +#endif +#define RESTORE_UIDGID + +/* 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(). */ + +#endif /* !__unxcfg_h */ only in patch2: unchanged: --- unzip-5.52.orig/unix/unix.c.orig +++ unzip-5.52/unix/unix.c.orig @@ -0,0 +1,1687 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + 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" + +#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 +#else +# ifdef SYSV +# ifdef SYSNDIR +# include +# else +# include +# endif +# else /* !SYSV */ +# ifndef NO_SYSDIR +# include +# 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 */ + ush 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)); + + +#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 GID 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 +{ + 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_: + G.pInfo->file_attr = (unsigned)(tmp >> 16); + if (G.pInfo->file_attr != 0 || !G.extra_field) { + return 0; + } else { + /* 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; + int r = FALSE; + + 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) + 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! + */ + 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: + /* allow European characters in filenames: */ + if (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 + /* set approx. dir perms (make sure can still read/write in dir) */ + if (chmod(G.filename, filtattr(__G__ 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'; + } + +#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\ + unable to process %s.\n", + FnFilter2(G.buildpath), 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", + FnFilter1(tmproot))); + 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, ush z_uidgid[2])); + +static int get_extattribs(__G__ pzt, z_uidgid) + __GDEF + iztimes *pzt; + ush 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 close_outfile() */ +/****************************/ + +void close_outfile(__G) /* GRR: change to return PK-style warning level */ + __GDEF +{ + union { + iztimes t3; /* mtime, atime, ctime */ + ztimbuf t2; /* modtime, actime */ + } zt; + ush z_uidgid[2]; + int have_uidgid_flg; + +/*--------------------------------------------------------------------------- + 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) { + unsigned ucsize = (unsigned)G.lrec.ucsize; + extent slnk_entrysize = sizeof(slinkentry) + ucsize + + strlen(G.filename); + slinkentry *slnk_entry; + + if ((unsigned)slnk_entrysize < ucsize) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: mem alloc overflow\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + + if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: no mem\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + slnk_entry->next = NULL; + slnk_entry->targetlen = ucsize; + slnk_entry->attriblen = 0; /* don't set attributes for symlinks */ + slnk_entry->target = slnk_entry->buf; + 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) != (int)ucsize) + { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed\n", + FnFilter1(G.filename))); + free(slnk_entry); + fclose(G.outfile); + return; + } + fclose(G.outfile); /* 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; + } +#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) || defined(NO_FCHMOD)) + fclose(G.outfile); +#endif + + have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid); + + /* if -X option was specified and we have UID/GID info, restore it */ + if (have_uidgid_flg) { + TTrace((stderr, "close_outfile: restoring Unix UID/GID info\n")); +#if (defined(NO_FCHOWN) || defined(NO_FCHMOD)) + 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, + "warning: cannot set UID %d and/or GID %d for %s\n", + z_uidgid[0], z_uidgid[1], FnFilter1(G.filename))); + else + Info(slide, 0x201, ((char *)slide, + " (warning) cannot set UID %d and/or GID %d", + z_uidgid[0], z_uidgid[1])); + } + } + +#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("chmod (file attributes) error"); + + fclose(G.outfile); +#endif /* !NO_FCHOWN && !NO_FCHMOD */ + + /* set the file's access and modification times */ + if (utime(G.filename, &(zt.t2))) { +#ifdef AOS_VS + if (uO.qflag) + Info(slide, 0x201, ((char *)slide, "... cannot set time for %s\n", + FnFilter1(G.filename))); + else + Info(slide, 0x201, ((char *)slide, "... cannot set time")); +#else + if (uO.qflag) + Info(slide, 0x201, ((char *)slide, + "warning: cannot set times for %s\n", FnFilter1(G.filename))); + else + Info(slide, 0x201, ((char *)slide, + " (warning) cannot set times")); +#endif /* ?AOS_VS */ + } + +#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 */ + +} /* end function close_outfile() */ + +#endif /* !MTS */ + + +#ifdef SET_DIR_ATTRIB +/* messages of code for setting directory attributes */ +static ZCONST char Far DirlistUidGidFailed[] = + "warning: cannot set UID %d and/or GID %d for %s\n"; +static ZCONST char Far DirlistUtimeFailed[] = + "warning: cannot set modification, access times for %s\n"; +# ifndef NO_CHMOD + static ZCONST char Far DirlistChmodFailed[] = + "warning: cannot set permissions for %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 && + chown(UxAtt(d)->fn, (uid_t)UxAtt(d)->uidgid[0], + (gid_t)UxAtt(d)->uidgid[1])) + { + Info(slide, 0x201, ((char *)slide, + LoadFarString(DirlistUidGidFailed), + UxAtt(d)->uidgid[0], UxAtt(d)->uidgid[1], FnFilter1(d->fn))); + if (!errval) + errval = PK_WARN; + } + if (utime(d->fn, &UxAtt(d)->u.t2)) { + Info(slide, 0x201, ((char *)slide, + LoadFarString(DirlistUtimeFailed), FnFilter1(d->fn))); + if (!errval) + errval = PK_WARN; + } +#ifndef NO_CHMOD + if (chmod(d->fn, filtattr(__G__ UxAtt(d)->perms))) { + Info(slide, 0x201, ((char *)slide, + LoadFarString(DirlistChmodFailed), FnFilter1(d->fn))); + /* perror("chmod (file attributes) error"); */ + 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(CRAY) && defined(_RELEASE)) + char cc_versbuf[40]; +#endif +#endif +#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(CRAY) && defined(_RELEASE) + "cc ", (sprintf(cc_versbuf, "version %d", _RELEASE), 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 +# endif +#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 + "", +#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 + * dependant 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) + { + fseek(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 */ only in patch2: unchanged: --- unzip-5.52.orig/unzpriv.h.orig +++ unzip-5.52/unzpriv.h.orig @@ -0,0 +1,2625 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + 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 +#endif + +#if (defined(USE_ZLIB) && !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 + +#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 + +#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 explicitely 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 + ---------------------------------------------------------------------------*/ + +#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 + +#ifdef MODERN +# ifndef NO_STDDEF_H +# include +# endif +# ifndef NO_STDLIB_H +# include /* 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 +# else + char *malloc(); +# endif /* ?VAXC */ +# endif /* !AOS_VS */ + typedef unsigned int extent; +#endif /* ?MODERN */ + + +#ifndef MINIX /* Minix needs it after all the other includes (?) */ +# include +#endif +#include /* skip for VMS, to use tolower() function? */ +#include /* used in mapname() */ +#ifdef USE_STRINGS_H +# include /* strcpy, strcmp, memcpy, index/rindex, etc. */ +#else +# include /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */ +#endif +#if (defined(MODERN) && !defined(NO_LIMITS_H)) +# include /* GRR: EXPERIMENTAL! (can be deleted) */ +#endif + +/* this include must be down here for SysV.4, for some reason... */ +#include /* used in unzip.c, fileio.c */ + + +/*--------------------------------------------------------------------------- + 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 +# include +# include +# include +# 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. */ +# ifndef _MBCS +# define _MBCS +# endif +# include +# include +# include +# include +# include +# ifdef HAVE_MBSTRING_H +# include +# endif +# ifdef HAVE_MBCTYPE_H +# include +# 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 /* off_t, time_t, dev_t, ... */ +# include +# include /* lseek(), open(), setftime(), dup(), creat() */ +# include /* localtime() */ +# include /* 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 /* off_t, time_t, dev_t, ... */ +# include +# include /* MTS uses this instead of fcntl.h */ +# include +# include +# include /* 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 NLM section + ---------------------------------------------------------------------------*/ + +#ifdef NLM +# include "novell/nlmcfg.h" +#endif + + /*--------------------------------------------------------------------------- + QDOS section + ---------------------------------------------------------------------------*/ + +#ifdef QDOS +# define DIRENT +# include +# include +# include +# include +# 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 +# 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 /* off_t, time_t, dev_t, ... */ +# include +# include +# include +# include +# include +# include +# include /* 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 /* GRR: experimenting... */ +# include +# include /* the usual non-BSD time functions */ +# include /* same things as fcntl.h has */ +# include +# include +# define _MAX_PATH (NAM$C_MAXRSS+1) /* to define FILNAMSIZ below */ +# ifndef HAVE_STRNICMP /* use our private zstrnicmp() */ +# define NO_STRNICMP /* unless explicitely overridden */ +# endif +# ifdef RETURN_CODES /* VMS interprets standard PK return codes incorrectly */ +# define RETURN(ret) return_VMS(__G__ (ret)) /* verbose version */ +# define EXIT(ret) return_VMS(__G__ (ret)) +# else +# define RETURN return_VMS /* quiet version */ +# define EXIT return_VMS +# endif +# ifdef VMSCLI +# define USAGE(ret) VMSCLI_usage(__G__ (ret)) +# endif +# define DIR_BEG '[' +# define DIR_END ']' +# define DIR_EXT ".dir" +# ifndef DATE_FORMAT +# define DATE_FORMAT DF_MDY +# endif +# define lenEOL 1 +# define PutNativeEOL *q++ = native(LF); +# define SCREENSIZE(ttrows, ttcols) screensize(ttrows, ttcols) +# define SCREENWIDTH 80 +# define SCREENLWRAP screenlinewrap() +# if (defined(__VMS_VERSION) && !defined(VMS_VERSION)) +# define VMS_VERSION __VMS_VERSION +# endif +# if (defined(__VMS_VER) && !defined(__CRTL_VER)) +# define __CRTL_VER __VMS_VER +# endif +# if ((!defined(__CRTL_VER)) || (__CRTL_VER < 70000000)) +# define NO_GMTIME /* gmtime() of earlier VMS C RTLs is broken */ +# else +# if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +# endif +# endif +# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP)) +# define TIMESTAMP +# endif +# define RESTORE_UIDGID +# ifdef __DECC + /* File open callback ID values. */ +# define OPENR_ID 1 + /* File open callback ID storage. */ + extern int openr_id; + /* File open callback function. */ + extern int acc_cb(); + /* Option macros for open(). + * General: Stream access + * + * Callback function (DEC C only) sets deq, mbc, mbf, rah, wbh, ... + */ +# define OPNZIP_RMS_ARGS "ctx=stm", "acc", acc_cb, &openr_id +# else /* !__DECC */ /* (So, GNU C, VAX C, ...)*/ +# define OPNZIP_RMS_ARGS "ctx=stm" +# endif /* ?__DECC */ +#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 (when not using POCKET_UNZIP) + ---------------------------------------------------------------------------*/ + +#if (defined(_WIN32_WCE) || defined(POCKET_UNZIP)) +# include "wince/wcecfg.h" +#endif + + + + + +/*************/ +/* Defines */ +/*************/ + +#ifdef USE_DEFLATE64 +# define UNZIP_VERSION 21 /* compatible with PKUNZIP 4.0 */ +#else +# define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */ +#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 +# define DATE_FORMAT DF_MDY /* defaults to US convention */ +#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 SSTAT +# ifdef WILD_STAT_BUG +# define SSTAT(path,pbuf) (iswild(path) || stat(path,pbuf)) +# else +# define SSTAT stat +# endif +#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 + +#define DIR_BLKSIZ 64 /* number of directory entries per block + * (should fit in 4096 bytes, usually) */ +#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 + +#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 consist 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 +# 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 +# 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+b" +# endif +#endif /* ?MODERN */ + +/* + * If 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 +#endif + +#ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN /* in 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 */ + +#define FILNAMSIZ PATH_MAX + +/* 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 + /* Multi Byte Character Set */ +# define ___MBS_TMP_DEF char *___tmp_ptr; +# define ___TMP_PTR ___tmp_ptr +# define CLEN(ptr) mblen((ZCONST char *)(ptr), MB_CUR_MAX) +# 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 +# define SETLOCALE(category, locale) setlocale(category, locale) +#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) +# define SETLOCALE(category, locale) +#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 */ + +#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */ +# define stat(p,s) zstat((p),(s)) +#endif + +#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 + + +#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) + +#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 PKRESMOD11 11 +#define BZIP2ED 12 +#define NUM_METHODS 13 /* index of last method + 1 */ +/* don't forget to update 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_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_IZVMS 0x4d49 /* Info-ZIP's VMS ("IM") */ +#define EF_IZUNIX 0x5855 /* Info-ZIP's old Unix[1] ("UX") */ +#define EF_IZUNIX2 0x7855 /* Info-ZIP's new Unix[2] ("Ux") */ +#define EF_TIME 0x5455 /* universal timestamp ("UT") */ +#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_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_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, 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. + ---------------------------------------------------------------------------*/ +#define LREC_SIZE 26 /* lengths of local file headers, central */ +#define CREC_SIZE 42 /* directory headers, and the end-of- */ +#define ECREC_SIZE 18 /* central-dir record, 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 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[2]; /* name of link, allocs space for 2 '\0's */ + } slinkentry; +#endif /* SYMLINKS */ + +typedef struct min_info { + Z_OFF_T offset; + ulg compr_size; /* compressed size (needed if extended header) */ + ulg uncompr_size; /* uncompressed size (needed if extended header) */ + ulg crc; /* crc (needed if extended header) */ + ush 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 */ + unsigned HasUxAtt : 1; /* crec ext_file_attr has Unix style mode bits */ +#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_CENTRAL_DIR 6 +# define NUM_ENTRIES_CENTRL_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 + + +/* 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 */ + ulg csize; + ulg 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; + +#if 0 + typedef struct central_directory_file_header { /* CENTRAL */ + uch version_made_by[2]; + uch version_needed_to_extract[2]; + ush general_purpose_bit_flag; + ush compression_method; + ulg last_mod_dos_datetime; + ulg crc32; + ulg csize; + ulg ucsize; + ush filename_length; + ush extra_field_length; + ush file_comment_length; + ush disk_number_start; + ush internal_file_attributes; + ulg external_file_attributes; + ulg relative_offset_local_header; + } cdir_file_hdr; +#endif /* 0 */ + + typedef struct end_central_dir_record { /* END CENTRAL */ + ush number_this_disk; + ush num_disk_start_cdir; + ush num_entries_centrl_dir_ths_disk; + ush total_entries_central_dir; + ulg size_central_directory; + ulg offset_start_central_directory; + 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)); */ +int uz_end_central OF((__GPRO)); +int process_cdir_file_hdr OF((__GPRO)); +int get_cdir_ent OF((__GPRO)); +int process_local_file_hdr OF((__GPRO)); +unsigned ef_scan_for_izux OF((ZCONST uch *ef_buf, unsigned ef_len, + int ef_is_c, ulg dos_mdatetime, + iztimes *z_utim, ush *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 +int zi_end_central OF((__GPRO)); +int zipinfo OF((__GPRO)); +/* static int zi_long OF((__GPRO__ ulg *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((ulg uc, ulg 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__ Z_OFF_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)); +#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_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)); */ +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)); + +/*--------------------------------------------------------------------------- + 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 */ + +/*--------------------------------------------------------------------------- + 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: + ---------------------------------------------------------------------------*/ + +#if (defined(MSDOS) && (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 + +/*--------------------------------------------------------------------------- + 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 */ +#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, struct 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 */ + +#ifdef DYNALLOC_CRCTAB + void free_crc_table OF((void)); /* crctab.c */ +#endif +#ifndef USE_ZLIB + ZCONST ulg near *get_crc_table OF((void)); /* funzip.c, crctab.c */ + ulg crc32 OF((ulg crc, ZCONST uch *buf, extent len)); +#endif /* !USE_ZLIB */ /* assembler source or 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, ulg filesize)); /* local */ +#endif +#ifndef MTS /* macro in MTS */ + void 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 +#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 . + */ +# define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd)) +# define lseek(fd,o,w) fseek((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) \ + * (fprintf((flag)&1? stderr : stdout, \ + * (char *)(sprintf sprf_arg, (buf))) == EOF) + */ +#ifndef Info /* may already have been defined for redirection */ +# ifdef FUNZIP +# define Info(buf,flag,sprf_arg) \ + fprintf((flag)&1? stderr : stdout, (char *)(sprintf sprf_arg, (buf))) +# 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 */ + +/* 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 + (WSIZE>>1)) +#define FnFilter2(fname) fnfilter((fname), slide + ((WSIZE>>1) + (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 + +#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<>=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) {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) {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[(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[(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[]; +#endif +#ifdef IZ_OEM2ISO_ARRAY + extern ZCONST uch Far oem2iso[]; +#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 + + +#endif /* !__unzpriv_h */ only in patch2: unchanged: --- unzip-5.52.orig/zipinfo.c.orig +++ unzip-5.52/zipinfo.c.orig @@ -0,0 +1,2235 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + 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__ ulg *pEndprev)); +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 LongHeader[] = "Archive: %s %ld bytes %u file%s\n"; +static ZCONST char Far ShortHeader[] = "Archive: %s %ld %u\n"; +static ZCONST char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n"; +static ZCONST char Far LineSeparators[] = "-------------------------------\n\n"; +static ZCONST char Far ActOffsetCentDir[] = "\ + Actual offset of end-of-central-dir record: %9ld (%.8lXh)\n\ + Expected offset of end-of-central-dir record: %9ld (%.8lXh)\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 %u %s. The central directory is %lu\n\ + (%.8lXh) bytes long, and its (expected) offset in bytes from the\n"; +static ZCONST char Far SinglePartArchive2[] = "\ + beginning of the zipfile is %lu (%.8lXh).\n\n"; +static ZCONST char Far MultiPartArchive1[] = "\ + This zipfile constitutes disk %u of a multi-part archive. The central\n\ + directory starts on disk %u; %u of its entries %s contained within\n"; +static ZCONST char Far MultiPartArchive2[] = "\ + this zipfile, out of a total of %u %s. The entire central\n\ + directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n"; +static ZCONST char Far MultiPartArchive3[] = "\ + the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n"; +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\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"; +static ZCONST char Far ZipfileCommTruncMsg[] = + "\ncaution: zipfile comment truncated\n"; + +static ZCONST char Far CentralDirEntry[] = + "\nCentral directory entry #%lu:\n---------------------------\n\n"; +static ZCONST char Far ZipfileStats[] = + "%lu file%s, %lu bytes uncompressed, %lu 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 MthdPKRes11[] = "unkn. #11 (PK reserved)"; +static ZCONST char Far MthdBZip2[] = "bzipped"; + +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 %ld bytes preceding this file.\n\n"; + +static ZCONST char Far UnknownNo[] = "unknown (%d)"; + +static ZCONST char Far LocalHeaderOffset[] = + "\n offset of local header from start of archive: %lu (%.8lXh) bytes\n"; +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: %lu bytes\n"; +static ZCONST char Far UncompressedFileSize[] = + " uncompressed size: %lu 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 %u\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"; +static ZCONST char Far efTime[] = "universal time"; +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 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 DMYHMTime[] = "%2u-%s-%02u %02u:%02u"; +static ZCONST char Far YMDHMSTime[] = "%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 YMDHMSTimeError[] = "???? ??? ?? ??:??:??"; +#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 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; + 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 + 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; + 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() */ +/*******************************/ + +int zi_end_central(__G) /* return PK-type error code */ + __GDEF +{ + int error = PK_COOL; + + +/*--------------------------------------------------------------------------- + Print out various interesting things about the zipfile. + ---------------------------------------------------------------------------*/ + + /* header fits on one line, for anything up to 10GB and 10000 files: */ + if (uO.hflag) + Info(slide, 0, ((char *)slide, ((int)strlen(G.zipfn) < 39)? + LoadFarString(LongHeader) : LoadFarString(ShortHeader), G.zipfn, + (long)G.ziplen, G.ecrec.total_entries_central_dir, + (G.ecrec.total_entries_central_dir==1)? + nullStr : PlurSufx)); + + /* verbose format */ + if (uO.lflag > 9) { + Info(slide, 0, ((char *)slide, LoadFarString(EndCentDirRec))); + Info(slide, 0, ((char *)slide, LoadFarString(LineSeparators))); + + Info(slide, 0, ((char *)slide, LoadFarString(ActOffsetCentDir), + (long)G.real_ecrec_offset, (long)G.real_ecrec_offset, + (long)G.expect_ecrec_offset, (long)G.expect_ecrec_offset)); + + if (G.ecrec.number_this_disk == 0) { + Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive1), + G.ecrec.total_entries_central_dir, + (G.ecrec.total_entries_central_dir == 1)? "entry" : "entries", + G.ecrec.size_central_directory, + G.ecrec.size_central_directory)); + Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive2), + G.ecrec.offset_start_central_directory, + G.ecrec.offset_start_central_directory)); + } else { + Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive1), + G.ecrec.number_this_disk + 1, + G.ecrec.num_disk_start_cdir + 1, + G.ecrec.num_entries_centrl_dir_ths_disk, + (G.ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are")); + Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive2), + G.ecrec.total_entries_central_dir, + (G.ecrec.total_entries_central_dir == 1) ? "entry" : "entries", + G.ecrec.size_central_directory, + G.ecrec.size_central_directory)); + Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive3), + G.ecrec.offset_start_central_directory, + G.ecrec.offset_start_central_directory)); + } + + /*----------------------------------------------------------------------- + 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) */ + + /* non-verbose mode: print zipfile comment only if requested */ + } else if (uO.zflag && G.ecrec.zipfile_comment_length) { + if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) { + Info(slide, 0x401, ((char *)slide, + LoadFarString(ZipfileCommTruncMsg))); + error = PK_WARN; + } + } /* endif (verbose) */ + + return error; + +} /* 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; + ulg tot_csize=0L, tot_ucsize=0L; + ulg 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) + return PK_EOF; + if (strncmp(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, 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 */ + + if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != + PK_COOL) + { + error_in_archive = error; /* might be warning */ + 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; + 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) { + + switch (uO.lflag) { + case 1: + case 2: + fnprint(__G); + SKIP_(G.crec.extra_field_length) + 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 */ + if (error > PK_WARN) /* fatal */ + return error; + } + break; + + case 10: + Info(slide, 0, ((char *)slide, + LoadFarString(CentralDirEntry), j)); + if ((error = zi_long(__G__ &endprev)) != PK_COOL) { + error_in_archive = error; /* might be warning */ + if (error > PK_WARN) /* fatal */ + return error; + } + break; + + default: + SKIP_(G.crec.extra_field_length) + SKIP_(G.crec.file_comment_length) + break; + + } /* end switch (lflag) */ + + 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)) { + if (fn_matched) + free((zvoid *)fn_matched); + if (xn_matched) + free((zvoid *)xn_matched); + return IZ_CTRLC; /* cancel operation by user request */ + } +#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) + + } /* end if (list member?) */ + + } /* end for-loop (j: member files) */ + +/*--------------------------------------------------------------------------- + Check that we actually found requested files; if so, print totals. + ---------------------------------------------------------------------------*/ + + if (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, tot_ucsize, + tot_csize, sgn, cfactor/10, cfactor%10)); + } + +/*--------------------------------------------------------------------------- + Check for unmatched filespecs on command line and print warning if any + found. + ---------------------------------------------------------------------------*/ + + if (fn_matched) { + 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) { + 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); + } + +/*--------------------------------------------------------------------------- + Double check that we're back at the end-of-central-directory record. + ---------------------------------------------------------------------------*/ + + if (strncmp(G.sig, end_central_sig, 4)) { /* just to make sure again */ + Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); + error_in_archive = PK_WARN; /* didn't find sig */ + } + if (members == 0 && 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) /* return PK-type error code */ + __GDEF + ulg *pEndprev; /* for zi_long() check of extra bytes */ +{ +#ifdef USE_EF_UT_TIME + iztimes z_utime; +#endif + int error, error_in_archive=PK_COOL; + unsigned hostnum, hostver, extnum, extver, 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, + MthdPKRes11, MthdBZip2 + }; + 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), + (long)G.crec.relative_offset_local_header - (long)(*pEndprev))); + } + + /* 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; + +/*--------------------------------------------------------------------------- + Read the extra field, if any. It may be used to get UNIX style modtime. + ---------------------------------------------------------------------------*/ + + 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. + */ + } + +/*--------------------------------------------------------------------------- + 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]; + methnum = (unsigned)MIN(G.crec.compression_method, NUM_METHODS); + + (*G.message)((zvoid *)&G, (uch *)" ", 2L, 0); fnprint(__G); + + Info(slide, 0, ((char *)slide, LoadFarString(LocalHeaderOffset), + G.crec.relative_offset_local_header, + G.crec.relative_offset_local_header)); + + 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 (methnum == 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 (methnum == DEFLATED || methnum == 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), + G.crec.csize)); + Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize), + G.crec.ucsize)); + 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), + 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; + 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; + 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_TIME: + ef_fieldname = efTime; + 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 */ + } + 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 */ + } + 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)); + } + break; + case EF_TIME: + if (eb_datalen >= 1) { + 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_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]); + } + break; + case EF_ZIPIT2: + if (eb_datalen >= 5 && + makelong(ef_ptr) == 0x5449505A /* "ZPIT" */) { + + if (eb_datalen >= 12) { + zi_showMacTypeCreator(__G__ &ef_ptr[4]); + } + } + 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]); + } + } + 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))); + } + 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)); + } + 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 */ + } + } + 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])); + } + 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)); + } + 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)); + } + 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: + if (eb_datalen > 0) { + ush 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, methnum, xattr; + char *p, workspace[12], attribs[16]; + 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", "u011", "bzp2", "u###" + }; + + +/*--------------------------------------------------------------------------- + Print out various interesting things about the compressed file. + ---------------------------------------------------------------------------*/ + + methnum = (unsigned)MIN(G.crec.compression_method, NUM_METHODS); + 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 (methnum == 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 (methnum == DEFLATED || methnum == ENHDEFLATED) { + ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3); + methbuf[3] = dtype[dnum]; + } else if (methnum >= NUM_METHODS) { /* unknown */ + sprintf(&methbuf[1], "%03u", G.crec.compression_method); + } + + 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 %8lu ", attribs, + LoadFarStringSmall(((hostnum == FS_VFAT_ && hostver == 20) ? + os_TheosOld : + os[hostnum])), + G.crec.ucsize)); +#else + Info(slide, 0, ((char *)slide, "%s %s %8lu ", attribs, + LoadFarStringSmall(os[hostnum]), + G.crec.ucsize)); +#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) { + ulg 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, " %8lu", G.crec.csize)); + + /* Read the extra field, if any. The extra field info may be used + * in the file modification time section, 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; + /* We do not return prematurely in case of a "fatal" error (PK_EOF). + * This does not hurt here, because we do not need to read from the + * zipfile again before the end of this function. + */ + } + + /* 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(YMDHMSTimeError))); + } 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(YMDHMSTime), 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(DMYHMTime), dy, monthstr, yr%100, hh, + mm); + + return d_t_str; + +} /* end function zi_time() */ + +#endif /* !NO_ZIPINFO */