home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------
-
- 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, send a *complete* description to
- zip-bugs@wkuvx1.wku.edu; include machine type, operating system and ver-
- sion, compiler and version, and reasonably detailed error messages or prob-
- lem 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.
-
- The author finds it convenient to define an alias "ii" (under Unix and VMS)
- or to rename the executable to "ii.exe" (OS/2 and DOS). This nicely comple-
- ments the common Unix "ll" long-listing alias (ls -lF), since zipinfo's de-
- fault action is to produce a Unix-like listing of the archive's contents.
- "ii zipfile" is easier to type than "zipinfo zipfile"...
-
- 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@uchicago.edu, 23 August 1990 -> ...
- SizeOfEAs() by Kai Uwe Rommel.
-
- ---------------------------------------------------------------------------
-
- Quick compile instructions (see INSTALL file): copy and/or rename appro-
- priate makefile to main unzip directory, then:
-
- under Unix (cc): make <system name>
- (type "make list" for a list of valid names, or read Makefile for
- details. "make unzip" works for most systems. If you have a NEW
- system, not covered by any of the existing targets, send FULL in-
- formation--hardware, OS, versions, etc.--to zip-bugs)
-
- under VMS (VAX or Alpha C, or GNU C): @make_vaxc or @make_gcc
- (can also use MMS or MAKE/VMS; see [.vms]README.)
-
- under OS/2: nmake -f makefile.os2 <compiler>
- (type "nmake -f makefile.os2" for list of targets; Watcom, Borland,
- IBM, Microsoft, emx+gcc compilers and nmake and dmake supported)
-
- under MS-DOS (MS or Quick C, Turbo or Borland C[++]): make
- (project files no longer supported; for Microsoft, use nmake; for
- djgpp or cross-compiling, use appropriate targets in unix/Makefile)
-
- under MS Windows 3.1: get wunz20sr.{zip | zoo | whatever} and use
- the included makefile
-
- under Windows NT (MS Visual C++): nmake
-
- under Macintosh OS (Think C): un-BinHex the Think C project file and
- UnZip resource file, then click on something or other :-) )
-
- under AmigaDOS (SAS/Lattice C or Aztec C):
- with SAS C 6.x: lmk -f amiga/SMakeFile all
- with Aztec C: make -f amiga/Makefile.AZT all
-
- under Atari TOS (MiNT libraries and gcc 2.4.5): make
- (see atari/README and atari/Makefile for info about other compilers)
-
- under TOPS-20: use make.mic and "do make" [no longer fully ported]
-
- ---------------------------------------------------------------------------
-
- Version: unzip51.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Windows,
- Windows NT, Macintosh, Amiga, Atari and TOPS-20. Decryption
- requires sources in zcrypt20.zip, and Windows (not NT) support
- requires sources in wunz20sr.zip. See accompanying file "Where"
- in the main source distribution for ftp, uucp and mail-server
- sites.
- Copyrights: see accompanying file "COPYING" in UnZip source distribution.
-
- ---------------------------------------------------------------------------*/
-
-
-
- #include "unzip.h" /* includes, typedefs, macros, etc. */
- #ifdef MSWIN
- # include "wizunzip.h"
- #endif
-
-
- #define RELEASE
- #ifdef RELEASE
- # define UZ_VERSION "5.1 of 7 February 1994" /* official release version */
- # define ZI_VERSION "2.0 of 7 February 1994"
- #else
- # define UZ_VERSION "5.1p BETA of 6 Feb 94" /* internal beta level */
- # define ZI_VERSION "1.99 BETA of 6 Feb 94"
- #endif
-
-
-
- /**********************/
- /* Global Variables */
- /**********************/
-
- #ifdef MACOS
- extern char *unzip_version = UZ_VERSION;
- extern char *zipinfo_version = ZI_VERSION;
- #endif
-
- int zipinfo_mode; /* behave like ZipInfo or like normal UnZip? */
-
- int aflag=0; /* -a: do ASCII-EBCDIC and/or end-of-line translation */
- int cflag=0; /* -c: output to stdout */
- int dflag=0; /* -d: all args are files/dirs to be extracted */
- int fflag=0; /* -f: "freshen" (extract only newer files) */
- int hflag=0; /* -h: header line (zipinfo) */
- int jflag=0; /* -j: junk pathnames (unzip) */
- int lflag=(-1); /* -12slmv: listing format (zipinfo) */
- int overwrite_none=0; /* -n: never overwrite files (no prompting) */
- int overwrite_all=0; /* -o: OK to overwrite files without prompting */
- int force_flag=0; /* (shares -o for now): force to override errors, etc. */
- int qflag=0; /* -q: produce a lot less output */
- #ifdef DOS_NT_OS2
- int sflag=0; /* -s: convert filename spaces (blanks) to underscores */
- int volflag=0; /* -$: extract volume labels */
- #endif
- int tflag=0; /* -t: test (unzip) or totals line (zipinfo) */
- int uflag=0; /* -u: "update" (extract only newer & brand-new files) */
- int U_flag=0; /* -U: preserve uppercase characters in filenames */
- int vflag=0; /* -v: (verbosely) list directory */
- int V_flag=0; /* -V: don't strip VMS version numbers */
- #ifdef VMS
- int secinf=0; /* -X: keep owner/protection */
- #endif
- int zflag=0; /* -z: display the zipfile comment (only, for unzip) */
-
- int filespecs; /* number of real file specifications to be matched */
- int xfilespecs; /* number of excluded filespecs to be matched */
- int process_all_files = 0;
- int create_dirs; /* used by main(), mapname(), checkdir() */
- int extract_flag;
-
- LONGINT real_ecrec_offset, expect_ecrec_offset;
-
- long csize; /* used by list_files(), ReadByte(): must be signed */
- long ucsize; /* used by list_files(), unReduce(), explode() */
- long used_csize; /* used by extract_or_test_member(), explode() */
-
- static char *fnames[2] = {"*", NULL}; /* default filenames vector */
- char **pfnames = fnames, **pxnames = &fnames[1];
- char near sig[5];
- char near answerbuf[10];
-
- min_info info[DIR_BLKSIZ], *pInfo=info;
-
- /*---------------------------------------------------------------------------
- unreduce/unshrink/explode/inflate working storage and globals:
- ---------------------------------------------------------------------------*/
-
- union work area; /* see unzip.h for the definition of work */
- ulg crc32val;
-
- ush near mask_bits[] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
- };
-
- /*---------------------------------------------------------------------------
- Input file variables:
- ---------------------------------------------------------------------------*/
-
- uch *inbuf, *inptr; /* input buffer (any size is OK) and pointer */
- int incnt;
-
- ulg bitbuf;
- int bits_left;
- boolean zipeof;
-
- char *wildzipfn, *zipfn; /* GRR: MSWIN: must nuke any malloc'd zipfn... */
-
- int zipfd; /* zipfile file handle */
- LONGINT ziplen;
-
- uch *hold;
- char near local_hdr_sig[5]; /* initialize signatures at runtime so unzip */
- char near central_hdr_sig[5]; /* executable won't look like a zipfile */
- char near end_central_sig[5];
- /* char extd_local_sig[5]; NOT USED YET */
-
- cdir_file_hdr crec; /* used in unzip.c, extract.c, misc.c */
- local_file_hdr lrec; /* used in unzip.c, extract.c */
- ecdir_rec ecrec; /* used in unzip.c, extract.c */
- struct stat statbuf; /* used by main, mapname, check_for_newer */
-
- LONGINT cur_zipfile_bufstart; /* extract_or_test_files, readbuf, ReadByte */
- LONGINT extra_bytes = 0; /* used in unzip.c, misc.c */
-
- uch *extra_field = (uch *)NULL; /* used by VMS, Mac and OS/2 versions */
-
- #ifdef MACOS
- short gnVRefNum;
- long glDirID;
- OSType gostCreator;
- OSType gostType;
- boolean fMacZipped;
- boolean macflag;
- CursHandle rghCursor[4]; /* status cursors */
- short giCursor = 0;
- #endif
-
- /*---------------------------------------------------------------------------
- Output stream variables:
- ---------------------------------------------------------------------------*/
-
- int mem_mode = 0;
- int disk_full;
- #ifdef SYMLINKS
- int symlnk;
- #endif
- FILE *outfile;
- uch *outbuf;
- uch *outptr;
- ulg outcnt; /* number of chars stored in outbuf */
- #ifdef SMALL_MEM
- uch *outbuf2; /* initialized in main() (never changes) */
- #else
- uch *outbuf2 = NULL; /* malloc'd ONLY if unshrink and -a */
- #endif
- #ifdef MSWIN
- char *filename;
- #else
- char near filename[FILNAMSIZ];
- #endif
-
- /*---------------------------------------------------------------------------
- unzip.c repeated error messages (we use all of these at least twice)
- ---------------------------------------------------------------------------*/
-
- char *EndSigMsg = "\nnote:\
- didn't find end-of-central-dir signature at end of central dir.\n";
- char *CentSigMsg =
- "error: expected central file header signature not found (file #%u).\n";
- char *SeekMsg =
- "error [%s]: attempt to seek before beginning of zipfile\n%s";
-
- #ifdef VMS
- char *ReportMsg = "\
- (please check that you have transferred or created the zipfile in the\n\
- appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
- #else
- char *ReportMsg = "\
- (please check that you have transferred or created the zipfile in the\n\
- appropriate BINARY mode and that you have compiled unzip properly)\n";
- #endif
-
-
-
-
-
- #ifdef MSWIN
- # include "winsetup.c" /* duplicates some code in main() */
- #else /* !MSWIN */
-
- /******************/
- /* Main program */
- /******************/
-
- #ifdef THINK_C
- int unzip(argc, argv)
- #else
- int main(argc, argv) /* return PK-type error code (except under VMS) */
- #endif
- int argc;
- char *argv[];
- {
- char *p;
- int error=FALSE;
- #if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
- extern void DebugMalloc(void);
-
-
- atexit(DebugMalloc);
- #endif
-
- /*---------------------------------------------------------------------------
- Macintosh initialization code.
- ---------------------------------------------------------------------------*/
-
- #ifdef MACOS
- int a;
-
- for (a = 0; a < 4; ++a)
- rghCursor[a] = GetCursor(a+128);
- giCursor = 0;
-
- aflag=cflag=dflag=fflag=jflag=qflag=tflag=U_flag=uflag=vflag=zflag = 0;
- local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
- /* extd_local_sig[1] = '\0'; */
- error = FALSE;
-
- overwrite_none = overwrite_all = force_flag = 0;
- #endif /* MACOS */
-
- #ifdef MALLOC_WORK
- area.Slide = (uch *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
- area.shrink.Prefix_of = (short *)area.Slide;
- area.shrink.Suffix_of = area.Slide + (sizeof(short)*(HSIZE+1));
- area.shrink.Stack = area.Slide + (sizeof(short) + sizeof(char))*(HSIZE+1);
- #endif
-
- /*---------------------------------------------------------------------------
- Human68K initialization code.
- ---------------------------------------------------------------------------*/
-
- #ifdef __human68k__
- InitTwentyOne();
- #endif
-
- /*---------------------------------------------------------------------------
- Set signal handler for restoring echo, warn of zipfile corruption, etc.
- ---------------------------------------------------------------------------*/
-
- signal(SIGINT, handler);
- #ifdef SIGTERM /* some systems really have no SIGTERM */
- signal(SIGTERM, handler);
- #endif
- #ifdef SIGBUS
- signal(SIGBUS, handler);
- #endif
- #ifdef SIGSEGV
- signal(SIGSEGV, handler);
- #endif
-
- /*---------------------------------------------------------------------------
- Debugging info for checking on structure padding:
- ---------------------------------------------------------------------------*/
-
- #ifdef DEBUG_STRUC
- printf("local_file_hdr size: %X\n",
- sizeof(local_file_hdr));
- printf("local_byte_hdr size: %X\n",
- sizeof(local_byte_hdr));
- printf("actual size of local headers: %X\n", LREC_SIZE);
-
- printf("central directory header size: %X\n",
- sizeof(cdir_file_hdr));
- printf("central directory byte header size: %X\n",
- sizeof(cdir_byte_hdr));
- printf("actual size of central dir headers: %X\n", CREC_SIZE);
-
- printf("end central dir record size: %X\n",
- sizeof(ecdir_rec));
- printf("end central dir byte record size: %X\n",
- sizeof(ec_byte_rec));
- printf("actual size of end-central-dir record: %X\n", ECREC_SIZE);
- #endif /* DEBUG_STRUC */
-
- /*---------------------------------------------------------------------------
- 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
- zipfn = argv[0];
- #endif
-
- #ifndef NO_ZIPINFO
- if ((p = strrchr(argv[0], DIR_END)) == NULL)
- p = argv[0];
- else
- ++p;
-
- if (STRNICMP(p, "zipinfo", 7) == 0 || STRNICMP(p, "ii", 2) == 0 ||
- (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
- {
- zipinfo_mode = TRUE;
- envargs(&argc, &argv, ENV_ZIPINFO);
- error = zi_opts(&argc, &argv);
- } else
- #endif
- {
- zipinfo_mode = FALSE;
- envargs(&argc, &argv, ENV_UNZIP);
- error = uz_opts(&argc, &argv);
- }
-
- #ifdef MSDOS
- /* extract MKS extended argument list from environment */
- mksargs(&argc, &argv);
- #endif
-
- #ifdef SFX
- if (error)
- #else
- if ((argc < 0) || error)
- #endif
- RETURN(error);
-
- /*---------------------------------------------------------------------------
- Now get the zipfile name from the command line and see if it exists as a
- regular (non-directory) file. If not, append the ".zip" suffix. We don't
- immediately check to see if this results in a good name, but we will do so
- later. In the meantime, see if there are any member filespecs on the com-
- mand line, and if so, set the filename pointer to point at them.
- ---------------------------------------------------------------------------*/
-
- #ifdef DOS_NT_OS2
- /* convert MSDOS-style directory separators to Unix-style ones for
- * user's convenience (include zipfile name itself)
- */
- pfnames = argv;
- while (*pfnames != NULL) {
- char *q;
-
- for (q = *pfnames; *q; ++q)
- if (*q == '\\')
- *q = '/';
- ++pfnames;
- }
- #endif
-
- wildzipfn = *argv++;
-
- #ifdef OLD_EXDIR
-
- if (argc > 0) {
- /* -d: "name/" immediately after zipfile name is a stored directory to
- * be extracted--do NOT treat as directory to which to extract files
- */
- if (extract_flag && !dflag) {
- create_dirs = !fflag;
- if ((error = checkdir(*argv, ROOT)) > 2) /* mem, or file in way */
- RETURN(error);
- else if (!error) { /* it IS extract-to dir, so adjust pointers */
- ++argv;
- --argc;
- }
- }
- }
-
- filespecs = argc;
- xfilespecs = 0;
-
- if (argc > 0) {
- char **pp = argv-1;
-
- pfnames = argv;
- while (*++pp)
- if (strcmp(*pp, "-x") == 0) {
- if (pp > argv) {
- *pp = 0; /* terminate pfnames */
- filespecs = pp - pfnames;
- } else {
- pfnames = fnames; /* defaults */
- filespecs = 0;
- }
- pxnames = pp + 1; /* excluded-names ptr starts after -x */
- xfilespecs = argc - filespecs - 1;
- break; /* skip rest of args */
- }
- process_all_files = FALSE;
- } else
- process_all_files = TRUE; /* for speed */
-
- #else /* !OLD_EXDIR */
-
- filespecs = argc;
- xfilespecs = 0;
-
- if (argc > 0) {
- int in_files=FALSE, in_xfiles=FALSE;
- char **pp = argv-1;
-
- process_all_files = FALSE;
- pfnames = argv;
- while (*++pp) {
- Trace((stderr, "pp - argv = %d\n", pp-argv));
- if (!dflag && strcmp(*pp, "-d") == 0) {
- dflag = TRUE;
- if (in_files) { /* ... zipfile ... -d exdir ... */
- *pp = 0; /* terminate pfnames */
- filespecs = pp - pfnames;
- in_files = FALSE;
- } else if (in_xfiles) {
- *pp = 0; /* terminate pxnames */
- xfilespecs = pp - pxnames;
- /* "... -x xlist -d exdir": nothing left */
- }
- if (*++pp) {
- if (extract_flag) {
- create_dirs = !fflag;
- if ((error = checkdir(*pp, ROOT)) > 2)
- RETURN(error); /* out of memory, or file in way */
- } else
- fprintf(stderr,
- "caution: not extracting; -d ignored\n");
- } else {
- fprintf(stderr, "error: must specify directory to which to\
- extract with -d option\n");
- break; /* no arguments left */
- }
- if (pp == argv+1) /* ... zipfile -d exdir ... */
- if (pp[1]) {
- pfnames = pp + 1; /* argv+2 */
- filespecs = argc - (pfnames-argv); /* for now... */
- } else {
- process_all_files = TRUE;
- pfnames = fnames; /* GRR: necessary? */
- filespecs = 0; /* GRR: necessary? */
- break;
- }
- } else if (!in_xfiles) {
- if (strcmp(*pp, "-x") == 0) {
- in_xfiles = TRUE;
- if (pp == argv || (pp == argv+2 && dflag)) {
- pfnames = fnames; /* defaults */
- filespecs = 0;
- } else if (in_files) {
- *pp = 0; /* terminate pfnames */
- filespecs = pp - pfnames; /* adjust count */
- in_files = FALSE;
- }
- pxnames = pp + 1; /* excluded-names ptr starts after -x */
- xfilespecs = argc - (pxnames-argv); /* anything left... */
- } else
- in_files = TRUE;
- }
- }
- } else
- process_all_files = TRUE; /* for speed */
-
- #endif /* ?OLD_EXDIR */
-
- /*---------------------------------------------------------------------------
- Okey dokey, we have everything we need to get started. Let's roll.
- ---------------------------------------------------------------------------*/
-
- inbuf = (uch *)malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */
- outbuf = (uch *)malloc(OUTBUFSIZ + 1); /* 1 extra for string termin. */
-
- if ((inbuf == (uch *)NULL) || (outbuf == (uch *)NULL)) {
- fprintf(stderr, "error: can't allocate unzip buffers\n");
- RETURN(PK_MEM);
- }
- hold = inbuf + INBUFSIZ; /* to check for boundary-spanning signatures */
- #ifdef SMALL_MEM
- outbuf2 = outbuf+RAWBUFSIZ; /* never changes */
- #endif
-
- RETURN(process_zipfiles()); /* keep passing errors back... */
-
- } /* end main() */
-
-
-
-
-
- /************************/
- /* Function uz_opts() */
- /************************/
-
- int uz_opts(pargc, pargv)
- int *pargc;
- char ***pargv;
- {
- char **argv, *s;
- int argc, c, error=FALSE, negative=0;
-
-
- 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 ('a'):
- if (negative) {
- aflag = MAX(aflag-negative,0);
- negative = 0;
- } else
- ++aflag;
- break;
- case ('b'):
- if (negative)
- negative = 0; /* do nothing: "-b" is default */
- else
- aflag = 0;
- break;
- case ('c'):
- if (negative) {
- cflag = FALSE, negative = 0;
- #ifdef NATIVE
- aflag = 0;
- #endif
- } else {
- cflag = TRUE;
- #ifdef NATIVE
- aflag = 2; /* so you can read it on the screen */
- #endif
- }
- break;
- case ('d'): /* arg after zipfn is stored dir, not extract-to */
- #ifdef OLD_EXDIR
- if (negative)
- dflag = FALSE, negative = 0;
- else
- dflag = TRUE;
- #endif
- break;
- case ('e'): /* just ignore -e, -x options (extract) */
- break;
- case ('f'): /* "freshen" (extract only newer files) */
- if (negative)
- fflag = uflag = FALSE, negative = 0;
- else
- fflag = uflag = TRUE;
- break;
- case ('j'): /* junk pathnames/directory structure */
- if (negative)
- jflag = FALSE, negative = 0;
- else
- jflag = TRUE;
- break;
- case ('l'):
- if (negative) {
- vflag = MAX(vflag-negative,0);
- negative = 0;
- } else
- ++vflag;
- break;
- case ('n'): /* don't overwrite any files */
- if (negative)
- overwrite_none = FALSE, negative = 0;
- else
- overwrite_none = TRUE;
- break;
- case ('o'): /* OK to overwrite files without prompting */
- if (negative) {
- overwrite_all = MAX(overwrite_all-negative,0);
- force_flag = MAX(force_flag-negative,0);
- negative = 0;
- } else {
- ++overwrite_all;
- ++force_flag; /* (share -o for now) force to cont. */
- }
- break;
- case ('p'): /* pipes: stdout, no translation, no messages */
- if (negative) {
- cflag = FALSE;
- qflag = MAX(qflag-999,0);
- negative = 0;
- } else {
- aflag = 0;
- cflag = TRUE;
- qflag += 999;
- }
- break;
- case ('q'): /* quiet: fewer comments/messages */
- if (negative) {
- qflag = MAX(qflag-negative,0);
- negative = 0;
- } else
- ++qflag;
- break;
- #ifdef DOS_NT_OS2
- case ('s'): /* spaces in filenames: allow by default */
- if (negative)
- sflag = FALSE, negative = 0;
- else
- sflag = TRUE;
- break;
- #endif
- case ('t'):
- if (negative)
- tflag = FALSE, negative = 0;
- else
- tflag = TRUE;
- break;
- case ('U'): /* allow Uppercase (don't make all lowercase) */
- if (negative)
- U_flag = FALSE, negative = 0;
- else
- U_flag = TRUE;
- break;
- case ('u'): /* update (extract only new and newer files) */
- if (negative)
- uflag = FALSE, negative = 0;
- else
- uflag = TRUE;
- break;
- case ('V'): /* Version (retain VMS/DEC-20 file versions) */
- if (negative)
- V_flag = FALSE, negative = 0;
- else
- V_flag = TRUE;
- break;
- case ('v'): /* verbose */
- if (negative) {
- vflag = MAX(vflag-negative,0);
- negative = 0;
- } else if (vflag)
- ++vflag;
- else
- vflag = 2;
- break;
- #ifdef VMS
- case ('X'): /* restore owner/protection info (need privs?) */
- if (negative)
- secinf = FALSE, negative = 0;
- else
- secinf = TRUE;
- break;
- #endif /* VMS */
- case ('x'): /* extract: default */
- break;
- case ('z'): /* display only the archive comment */
- if (negative) {
- zflag -= negative;
- negative = 0;
- } else
- ++zflag;
- break;
- #ifdef DOS_NT_OS2
- case ('$'):
- if (negative) {
- volflag = MAX(volflag-negative,0);
- negative = 0;
- } else
- ++volflag;
- break;
- #endif
- 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. [Isn't the -a option use-
- ful when listing the directory (i.e., for reading zipfile comments)? It
- is only a modifier, so perhaps it should not be included in the test.]
- ---------------------------------------------------------------------------*/
-
- if ((cflag && tflag) || (cflag && uflag) || (cflag && vflag) ||
- (tflag && uflag) || (tflag && vflag) || (uflag && vflag) ||
- (fflag && overwrite_none)) {
- fprintf(stderr, "error:\
- -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n");
- error = TRUE;
- }
- if (aflag > 2)
- aflag = 2;
- #if 0
- if ((aflag && tflag) || (aflag && vflag)) /* -a makes no sense */
- aflag = 0;
- #endif
- if (overwrite_all && overwrite_none) {
- fprintf(stderr, "caution: both -n and -o specified; ignoring -o\n");
- overwrite_all = FALSE;
- }
-
- #ifdef SFX
- if (error)
- #else
- if ((argc-- == 0) || error)
- #endif
- {
- *pargc = argc;
- *pargv = argv;
- return usage(error);
- }
-
- if (cflag || tflag || vflag)
- extract_flag = FALSE;
- else
- extract_flag = TRUE;
-
- *pargc = argc;
- *pargv = argv;
- return 0;
-
- } /* end function uz_opts() */
-
-
-
-
-
- /**********************/
- /* Function usage() */
- /**********************/
-
- #ifdef SFX
-
- int usage(error) /* return PK-type error code */
- int error;
- {
- FILE *usagefp;
-
- if (error)
- usagefp = (FILE *)stderr;
- else
- usagefp = (FILE *)stdout;
-
- fprintf(usagefp, "\
- UnZipSFX %s, by Info-ZIP (zip-bugs@wkuvx1.wku.edu).\n\n",
- UZ_VERSION);
- #ifndef RELEASE
- fprintf(usagefp, "\
- THIS IS STILL A BETA VERSION OF UNZIPSFX -- DO NOT DISTRIBUTE.\n\n");
- #endif
-
- if (error)
- return PK_PARAM;
- else
- return PK_COOL; /* just wanted usage screen: no error */
-
- } /* end function usage() */
-
-
-
-
-
- #else /* !SFX */
-
- int usage(error) /* return PK-type error code */
- int error;
- {
- #ifdef VMS
- # define QUOT '\"'
- # define QUOTS "\""
- # define EXAMPLE2 "vms.c"
- # define EXAMPLE1 \
- "unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS"
- #else
- # define QUOT ' '
- # define QUOTS ""
- # define EXAMPLE2 "ReadMe"
- # define EXAMPLE1 \
- "unzip -p foo | more => send contents of foo.zip via pipe into program more"
- #endif
-
- #ifdef DOS_NT_OS2
- char *loc_str = " -$ label removables (-$$ => fixed disks)";
- char *loc2str = "\
- -s spaces in filenames => '_'\n";
- #else /* !DOS_NT_OS2 */
- #ifdef VMS
- char *loc_str = "\"-X\" restore owner/protection info";
- char *loc2str = "\n";
- #else
- char *loc_str = ""; /* Unix, Amiga, Mac, etc. */
- /* char *loc_str = " -X restore UID/GID info"; Unix version, in 5.2 */
- char *loc2str = "";
- #endif
- #endif /* ?DOS_NT_OS2 */
-
- FILE *usagefp;
-
-
- /*---------------------------------------------------------------------------
- If user requested usage, send it to stdout; else send to stderr.
- ---------------------------------------------------------------------------*/
-
- if (error)
- usagefp = (FILE *)stderr;
- else
- usagefp = (FILE *)stdout;
-
- /*---------------------------------------------------------------------------
- Print either ZipInfo usage or UnZip usage, depending on incantation.
- (Strings must be no longer than 512 bytes for Turbo C, apparently.)
- ---------------------------------------------------------------------------*/
-
- if (zipinfo_mode) {
-
- #ifndef NO_ZIPINFO
-
- fprintf(usagefp, "\
- ZipInfo %s, by Newtware and the fine folks at Info-ZIP.\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 *, ?, [] (e.g., \"[a-j]*\
- .zip\").\n\n\
- usage: zipinfo [-12smlvhtz] file[.zip] [list...] [-x xlist...]\n\
- or: unzip %s-Z%s [-12smlvhtz] file[.zip] [list...] [-x xlist...]\n",
- ZI_VERSION, QUOTS,QUOTS);
- fprintf(usagefp, "\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\
- miscellaneous options:\n \
- -h print header line -t print totals for files listed or for all files\n\
- -z print zipfile comment -x exclude filenames that follow from listing\n");
- /* -p disable automatic \"more\" function (for pipes) [not implemented]\n"); */
- #ifdef VMS
- fprintf(usagefp, "\nRemember that non-lowercase filespecs must be\
- quoted in VMS (e.g., \"Makefile\").\n");
- #endif
-
- #endif /* !NO_ZIPINFO */
-
- } else { /* UnZip mode */
-
- fprintf(usagefp, "\
- UnZip %s, by Info-ZIP. Portions (c) 1989 by S. H. Smith.\n\
- Send bug reports to authors at zip-bugs@wkuvx1.wku.edu; see README for details.\
- \n\n", UZ_VERSION);
- #ifndef RELEASE
- fprintf(usagefp, "\
- THIS IS STILL A BETA VERSION OF UNZIP -- DO NOT DISTRIBUTE.\n\n");
- #endif
- fprintf(usagefp, "\
- 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\n",
- #ifdef NO_ZIPINFO
- "", "(ZipInfo mode is disabled in this version.)");
- #else
- #ifdef VMS
- "[-Z] ", "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).");
- #else
- "[-Z] ", "-Z => ZipInfo mode (\"unzip -Z\" for usage).");
- #endif
- #endif /* ?NO_ZIPINFO */
-
- fprintf(usagefp, "\
- -c extract files to stdout/screen (CRT) -l list files (short format)\n\
- -p extract files to pipe, no messages -v list files (verbose 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 which follow (in xlist) -d extract files into exdir\n\n");
-
- fprintf(usagefp, "\
- 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 (don't make directories) %c-U%c don't make names lowercase\n\
- %-42s %c-V%c retain VMS version numbers\n%s",
- QUOT,QUOT, loc_str, QUOT,QUOT, loc2str);
-
- fprintf(usagefp, "\
- Examples (see unzip.doc for more info):\n\
- unzip data1 -x joe => extract all files except joe from zipfile data1.zip\n\
- %s\n\
- unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n",
- EXAMPLE1, EXAMPLE2,EXAMPLE2);
-
- }
-
- if (error)
- return PK_PARAM;
- else
- return PK_COOL; /* just wanted usage screen: no error */
-
- } /* end function usage() */
-
- #endif /* ?SFX */
- #endif /* ?MSWIN */
-
-
-
-
- /*********************************/
- /* Function process_zipfiles() */
- /*********************************/
-
- int process_zipfiles() /* return PK-type error code */
- {
- char *lastzipfn = NULL;
- int error=0, error_in_archive=0;
- int num_win_files, num_lose_files, num_warn_files;
- int num_miss_dirs, num_miss_files;
-
-
- /*---------------------------------------------------------------------------
- Start by constructing the various PK signature strings.
- ---------------------------------------------------------------------------*/
-
- local_hdr_sig[0] /* = extd_local_sig[0] */ = '\120'; /* ASCII 'P', */
- central_hdr_sig[0] = end_central_sig[0] = '\120'; /* not EBCDIC */
-
- strcpy(local_hdr_sig+1, LOCAL_HDR_SIG);
- strcpy(central_hdr_sig+1, CENTRAL_HDR_SIG);
- strcpy(end_central_sig+1, END_CENTRAL_SIG);
- /* strcpy(extd_local_sig+1, EXTD_LOCAL_SIG); still to be used in multi? */
-
- /*---------------------------------------------------------------------------
- Match (possible) wildcard zipfile specification with existing files and
- attempt to process each. If no hits, try again after appending ".zip"
- suffix. If still no luck, give up.
- ---------------------------------------------------------------------------*/
-
- #ifdef SFX
- if ((error = do_seekable(0)) != IZ_DIR && error > error_in_archive)
- error_in_archive = error;
-
- #else /* !SFX */
- num_win_files = num_lose_files = num_warn_files = 0;
- num_miss_dirs = num_miss_files = 0;
-
- while ((zipfn = do_wild(wildzipfn)) != NULL) {
- Trace((stderr, "do_wild( %s ) returns %s\n", wildzipfn, zipfn));
-
- lastzipfn = zipfn;
-
- if (!qflag && error != PK_NOZIP &&
- (num_win_files+num_lose_files+num_warn_files+num_miss_files) > 0)
- printf("\n");
- FFLUSH(stdout);
-
- if ((error = do_seekable(0)) == PK_WARN)
- ++num_warn_files;
- else if (error == IZ_DIR)
- ++num_miss_dirs;
- else if (error == PK_NOZIP)
- ++num_miss_files;
- else if (error)
- ++num_lose_files;
- else
- ++num_win_files;
-
- if (error != IZ_DIR && error > error_in_archive)
- error_in_archive = error;
- Trace((stderr, "do_seekable(0) returns %d\n", error));
-
- } /* end while-loop (wildcard zipfiles) */
-
- if ((num_win_files + num_warn_files + num_lose_files) == 0 &&
- (num_miss_dirs + num_miss_files) == 1 && lastzipfn != NULL)
- {
- num_miss_dirs = num_miss_files = 0;
- if (error_in_archive == PK_NOZIP)
- error_in_archive = PK_COOL;
- strcat((zipfn = lastzipfn), ZSUFX);
-
- if ((error = do_seekable(1)) == PK_WARN)
- ++num_warn_files;
- else if (error == IZ_DIR)
- ++num_miss_dirs;
- else if (error == PK_NOZIP)
- /* if increment again => bug: "1 file had no zipfile directory." */
- /* ++num_miss_files */ ;
- else if (error)
- ++num_lose_files;
- else
- ++num_win_files;
-
- if (error > error_in_archive)
- error_in_archive = error;
- Trace((stderr, "do_seekable(1) returns %d\n", error));
- }
- #endif /* ?SFX */
-
- FFLUSH(stdout);
- FFLUSH(stderr);
-
- #ifndef SFX
- if (num_miss_dirs + num_miss_files + num_lose_files + num_warn_files > 0
- || num_win_files != 1)
- fprintf(stderr, "\n");
- if ((num_win_files > 1) || (num_win_files == 1 &&
- num_miss_dirs + num_miss_files + num_lose_files + num_warn_files > 0))
- fprintf(stderr, "%d archive%s successfully processed.\n",
- num_win_files, (num_win_files == 1)? " was" : "s were");
- if (num_warn_files > 0)
- fprintf(stderr, "%d archive%s had warnings but no fatal errors.\n",
- num_warn_files, (num_warn_files == 1)? "" : "s");
- if (num_lose_files > 0)
- fprintf(stderr, "%d archive%s had fatal errors.\n",
- num_lose_files, (num_lose_files == 1)? "" : "s");
- if (num_miss_files > 0)
- fprintf(stderr, "%d file%s had no zipfile directory.\n",
- num_miss_files, (num_miss_files == 1)? "" : "s");
- if (num_miss_dirs == 1)
- fprintf(stderr, "1 \"zipfile\" was a directory.\n");
- else if (num_miss_dirs > 0)
- fprintf(stderr, "%d \"zipfiles\" were directories.\n", num_miss_dirs);
- if (num_win_files + num_lose_files + num_warn_files == 0)
- fprintf(stderr, "No zipfiles found.\n");
- #endif /* !SFX */
-
- /* free allocated memory */
- inflate_free();
- checkdir((char *)NULL, END);
- #ifndef SMALL_MEM
- if (outbuf2)
- free(outbuf2); /* malloc'd ONLY if unshrink and -a */
- #endif
- free(outbuf);
- free(inbuf);
-
- return error_in_archive;
-
- } /* end function process_zipfiles() */
-
-
-
-
-
- /****************************/
- /* Function do_seekable() */
- /****************************/
-
- int do_seekable(lastchance) /* return PK-type error code */
- int lastchance;
- {
- int error=0, error_in_archive, maybe_exe=FALSE;
- static int no_ecrec = FALSE;
-
-
- /*---------------------------------------------------------------------------
- Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
- which would corrupt the bit streams.
- ---------------------------------------------------------------------------*/
-
- if (SSTAT(zipfn, &statbuf) || (error = S_ISDIR(statbuf.st_mode)) != 0) {
- if (lastchance)
- if (no_ecrec)
- fprintf(stderr, "%s: can't find zipfile directory in %s,\n\
- %sand can't find %s, period.\n", zipinfo_mode? "zipinfo" : "unzip",
- wildzipfn, zipinfo_mode? " " : "", zipfn);
- else
- fprintf(stderr,
- "%s: can't find either %s or %s, so there.\n",
- zipinfo_mode? "zipinfo" : "unzip", wildzipfn, zipfn);
- return error? IZ_DIR : PK_NOZIP;
- }
- ziplen = statbuf.st_size;
-
- #if defined(UNIX) || defined(DOS_NT_OS2) /* no extension on Unix exec's: */
- if (statbuf.st_mode & S_IEXEC) /* might find zip, not zip.zip; etc. */
- maybe_exe = TRUE; /* (for other OS's, some executables */
- #endif /* can be self-extracting archives) */
-
- #ifdef VMS
- if (check_format()) /* check for variable-length format */
- return PK_ERR;
- #endif
-
- if (open_input_file()) /* this should never happen, given */
- return PK_NOZIP; /* the stat() test above, but... */
-
- /*---------------------------------------------------------------------------
- Find and process the end-of-central-directory header. UnZip need only
- check last 65557 bytes of zipfile: comment may be up to 65535, end-of-
- central-directory record is 18 bytes, and signature itself is 4 bytes;
- add some to allow for appended garbage. Since ZipInfo is often used as
- a debugging tool, search the whole zipfile if zipinfo_mode is true.
- ---------------------------------------------------------------------------*/
-
- cur_zipfile_bufstart = 0;
- inptr = inbuf;
-
- if (!qflag && !zipinfo_mode)
- printf("Archive: %s\n", zipfn);
-
- if ((
- #ifndef NO_ZIPINFO
- zipinfo_mode &&
- ((error_in_archive = find_end_central_dir(ziplen)) != 0 ||
- (error_in_archive = zi_end_central()) > PK_WARN))
- || (!zipinfo_mode &&
- #endif
- ((error_in_archive = find_end_central_dir(MIN(ziplen,66000L))) != 0 ||
- (error_in_archive = uz_end_central()) > PK_WARN)))
- {
- close(zipfd);
- #ifdef SFX
- return error_in_archive;
- #else
- if (maybe_exe)
- fprintf(stderr, "note: %s may be an executable, not an archive\n",
- zipfn);
- if (lastchance)
- return error_in_archive;
- else {
- no_ecrec = TRUE; /* assume we found wrong file: e.g., */
- return PK_NOZIP; /* unzip instead of unzip.zip */
- }
- #endif /* ?SFX */
- }
-
- if ((zflag > 0) && !zipinfo_mode) { /* in unzip, zflag = comment ONLY */
- close(zipfd);
- return error_in_archive;
- }
-
- /*---------------------------------------------------------------------------
- Test the end-of-central-directory info for incompatibilities (multi-disk
- archives) or inconsistencies (missing or extra bytes in zipfile).
- ---------------------------------------------------------------------------*/
-
- error = !zipinfo_mode && (ecrec.number_this_disk == 1) &&
- (ecrec.num_disk_with_start_central_dir == 1);
-
- if (zipinfo_mode &&
- ecrec.number_this_disk != ecrec.num_disk_with_start_central_dir)
- {
- fprintf(stderr, "\n\
- Zipfile is part of a multi-disk archive, and this is not the disk on\n\
- which the central zipfile directory begins.\n");
- error_in_archive = PK_FIND;
-
- } else if (!zipinfo_mode && !error && ecrec.number_this_disk != 0) {
-
- fprintf(stderr, "\nerror [%s]: zipfile is part of multi-disk archive\n\
- (sorry, not yet supported).\n", zipfn);
- error_in_archive = PK_FIND;
-
- } else { /* this is a (relatively) normal zipfile: process normally */
-
- if (error) {
- fprintf(stderr, "\n\
- Warning: zipfile claims to be second disk of a two-part archive;\n\
- attempting to process anyway. If no further errors occur, this\n\
- archive was probably created by PAK v2.51 or earlier. This bug\n\
- was reported to NoGate in March 1991 and was supposed to have been\n\
- fixed by mid-1991; as of mid-1992 it still hadn't been. (If fur-\n\
- ther errors do occur, archive was probably created by PKZIP 2.04c\n\
- or later; UnZip does not yet support multi-part archives.)\n\n");
- error_in_archive = PK_WARN;
- }
- if ((extra_bytes = real_ecrec_offset - expect_ecrec_offset) < (LONGINT)0) {
- fprintf(stderr, "error [%s]: missing %ld bytes in zipfile\n\
- (attempting to process anyway)\n", zipfn, (long)(-extra_bytes));
- error_in_archive = PK_ERR;
- } else if (extra_bytes > 0) {
- if ((ecrec.offset_start_central_directory == 0) &&
- (ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */
- {
- fprintf(stderr, "error [%s]: NULL central directory offset\n\
- (attempting to process anyway)\n", zipfn);
- ecrec.offset_start_central_directory = extra_bytes;
- extra_bytes = 0;
- error_in_archive = PK_ERR;
- } else {
- #ifndef SFX
- fprintf(stderr, "warning [%s]: extra %ld bytes at beginning\
- or within zipfile\n (attempting to process anyway)\n", zipfn,
- (long)extra_bytes);
- error_in_archive = PK_WARN;
- #endif
- }
- }
-
- /*-----------------------------------------------------------------------
- Check for empty zipfile and exit now if so.
- -----------------------------------------------------------------------*/
-
- if (expect_ecrec_offset == 0L && ecrec.size_central_directory == 0) {
- if (zipinfo_mode)
- printf("%sEmpty zipfile.\n", lflag>9 ? "\n " : "");
- else
- fprintf(stderr, "warning [%s]: zipfile is empty\n", zipfn);
- close(zipfd);
- return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
- }
-
- /*-----------------------------------------------------------------------
- Compensate for missing or extra bytes, and seek to where the start
- of central directory should be. If header not found, uncompensate
- and try again (necessary for at least some Atari archives created
- with STZIP, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
- -----------------------------------------------------------------------*/
-
- LSEEK( ecrec.offset_start_central_directory )
- if ((error = readbuf(sig, 4)) < 0) {
- close(zipfd);
- return PK_ERR; /* file may be locked, or possibly disk error(?) */
- }
- if ((error == 0) || strncmp(sig, central_hdr_sig, 4)) {
- long tmp = extra_bytes;
-
- extra_bytes = 0;
- LSEEK( ecrec.offset_start_central_directory )
- if ((readbuf(sig, 4) <= 0) || strncmp(sig, central_hdr_sig, 4)) {
- fprintf(stderr,
- "error [%s]: start of central directory not found;\n\
- zipfile corrupt.\n%s", zipfn, ReportMsg);
- close(zipfd);
- return PK_BADERR;
- }
- fprintf(stderr,
- "error [%s]: reported length of central directory is\n\
- %ld bytes too long (Atari STZIP zipfile? J.H.Holm ZIPSPLIT 1.1\n\
- zipfile?). Compensating...\n", zipfn, -tmp);
- error_in_archive = PK_ERR;
- }
-
- /*-----------------------------------------------------------------------
- Seek to the start of the central directory one last time, since we
- have just read the first entry's signature bytes; then list, extract
- or test member files as instructed, and close the zipfile.
- -----------------------------------------------------------------------*/
-
- Trace((stderr, "about to extract/list files (error = %d)\n",
- error_in_archive));
-
- LSEEK( ecrec.offset_start_central_directory )
-
- #ifndef NO_ZIPINFO
- if (zipinfo_mode) {
- error = zipinfo(); /* ZIPINFO 'EM */
- if (lflag > 9)
- printf("\n");
- } else
- #endif
- if (vflag)
- error = list_files(); /* LIST 'EM */
- else
- error = extract_or_test_files(); /* EXTRACT OR TEST 'EM */
-
- Trace((stderr, "done with extract/list files (error = %d)\n", error));
-
- if (error > error_in_archive) /* don't overwrite stronger error */
- error_in_archive = error; /* with (for example) a warning */
- }
-
- close(zipfd);
- return error_in_archive;
-
- } /* end function do_seekable() */
-
-
-
-
-
- /*****************************/
- /* Function uz_end_central() */
- /*****************************/
-
- int uz_end_central() /* return PK-type error code */
- {
- int error = PK_COOL;
-
-
- /*---------------------------------------------------------------------------
- Get the zipfile comment (up to 64KB long), if any, and print it out.
- Then position the file pointer to the beginning of the central directory
- and fill buffer.
- ---------------------------------------------------------------------------*/
-
- #ifdef MSWIN
- cchComment = ecrec.zipfile_comment_length; /* save for comment button */
- if (ecrec.zipfile_comment_length && (zflag > 0))
- #else /* !MSWIN */
- if (ecrec.zipfile_comment_length && (zflag > 0 || (zflag == 0 && !qflag)))
- #endif /* ?MSWIN */
- {
- #if 0
- #ifndef MSWIN
- if (zflag == 0) (add "&& single_zipfile" perhaps; unnecessary with
- printf("[%s] comment:\n", zipfn); multiple zipfiles: "Archive:...")
- #endif /* !MSWIN */
- #endif /* 0 */
- if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
- fprintf(stderr, "\ncaution: zipfile comment truncated\n");
- error = PK_WARN;
- }
- }
- return error;
-
- } /* end function uz_end_central() */
-
-
-
-
-
- /**************************************/
- /* Function process_cdir_file_hdr() */
- /**************************************/
-
- int process_cdir_file_hdr() /* return PK-type error code */
- {
- int error;
-
-
- /*---------------------------------------------------------------------------
- Get central directory info, save host and method numbers, and set flag
- for lowercase conversion of filename, depending on the OS from which the
- file is coming.
- ---------------------------------------------------------------------------*/
-
- if ((error = get_cdir_file_hdr()) != 0)
- return error;
-
- pInfo->hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
- /* extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
-
- pInfo->lcflag = 0;
- if (!U_flag) /* as long as user hasn't specified case-preservation */
- switch (pInfo->hostnum) {
- case FS_FAT_: /* PKZIP and zip -k store in uppercase */
- case ATARI_: /* MS-DOS filesystem */
- case CPM_: /* like MS-DOS, right? */
- case VM_CMS_: /* all caps? */
- case TOPS20_:
- /* case Z_SYSTEM_: ? */
- /* case QDOS_: ? */
- pInfo->lcflag = 1; /* convert filename to lowercase */
- break;
-
- /* case VMS_: Info-ZIP's VMS Zip converts filenames to lowercase */
- default: /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, */
- break; /* (Z_SYSTEM_): no conversion */
- }
-
- /* do Amigas (AMIGA_) also have volume labels? */
- if (IS_VOLID(crec.external_file_attributes) &&
- (pInfo->hostnum == FS_FAT_ || pInfo->hostnum == FS_HPFS_ ||
- pInfo->hostnum == FS_NTFS_ || pInfo->hostnum == ATARI_))
- {
- pInfo->vollabel = TRUE;
- pInfo->lcflag = 0; /* preserve case of volume labels */
- } else
- pInfo->vollabel = FALSE;
-
- return PK_COOL;
-
- } /* end function process_cdir_file_hdr() */
-
-
-
-
-
- /***************************************/
- /* Function process_local_file_hdr() */
- /***************************************/
-
- int process_local_file_hdr() /* return PK-type error code */
- {
- local_byte_hdr byterec;
-
-
- /*---------------------------------------------------------------------------
- Read the next local file header and do any necessary machine-type con-
- versions (byte ordering, structure padding compensation--do so by copy-
- ing the data from the array into which it was read (byterec) to the
- usable struct (lrec)).
- ---------------------------------------------------------------------------*/
-
- if (readbuf((char *)byterec, LREC_SIZE) <= 0)
- return PK_EOF;
-
- lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
- lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
-
- lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
- lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
- lrec.last_mod_file_time = makeword(&byterec[L_LAST_MOD_FILE_TIME]);
- lrec.last_mod_file_date = makeword(&byterec[L_LAST_MOD_FILE_DATE]);
- lrec.crc32 = makelong(&byterec[L_CRC32]);
- lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]);
- lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
- lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
- lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
-
- csize = (long) lrec.csize;
- ucsize = (long) lrec.ucsize;
-
- if ((lrec.general_purpose_bit_flag & 8) != 0) {
- /* can't trust local header, use central directory: */
- lrec.crc32 = pInfo->crc;
- csize = (long)(lrec.csize = pInfo->compr_size);
- }
-
- return PK_COOL;
-
- } /* end function process_local_file_hdr() */
-