home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-02 | 53.5 KB | 1,341 lines |
- Newsgroups: comp.sources.misc
- From: info-zip@cs.ucla.edu (Info-Zip)
- Subject: v29i033: unzip - Info-ZIP's portable UnZip v4.2, Part03/12
- Message-ID: <1992Apr3.063046.28673@sparky.imd.sterling.com>
- X-Md4-Signature: fa7345297a70ab7437f748c167203b96
- Date: Fri, 3 Apr 1992 06:30:46 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: info-zip@cs.ucla.edu (Info-Zip)
- Posting-number: Volume 29, Issue 33
- Archive-name: unzip/part03
- Environment: Unix, VMS, OS/2, MS-DOS, Amiga, Macintosh
- Supersedes: unzip, Volume 19, Issues 96-101
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: Contents unzip.c
- # Wrapped by kent@sparky on Mon Mar 30 01:45:51 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 3 (of 12)."'
- if test -f 'Contents' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Contents'\"
- else
- echo shar: Extracting \"'Contents'\" \(4533 characters\)
- sed "s/^X//" >'Contents' <<'END_OF_FILE'
- XContents of the UnZip 4.2 main archive (the "sub-archives" may be .arc
- Xor .tar.Z instead of .zip, or even sub-directories):
- X
- X Contents this file
- X README what UnZip is; general information (was unzip##.descr)
- X History.420 new features and fixes in this release
- X ZipRules Info-ZIP guidelines on (code) contributions to the cause
- X BUGS known bugs, problems, and (possible) features to be added
- X unzip.1 UnZip manual page, nroff format
- X unzip.man UnZip manual page, human-readable format
- X zipinfo.1 ZipInfo manual page, nroff format
- X zipinfo.man ZipInfo manual page, human-readable format
- X CONTRIBS list of contributors to UnZip
- X COPYING copyrights and distribution policy
- X crypt.c NOT INCLUDED: see notes below
- X extract.c high-level extraction and decryption code (required)
- X file_io.c file manipulation and password code (required)
- X mapname.c code to map filenames between different OS's (required)
- X match.c pattern-matching code for filename wildcards (required*)
- X misc.c various support routines (required*)
- X ship.c utility to encode/split/e-mail binary files (useful/optional)
- X unimplod.c code for unImploding (required)
- X unreduce.c code for unReducing (required)
- X unshrink.c code for unShrinking (required)
- X unzip.c main UnZip driver code (required)
- X unzip.h main UnZip header file (required*)
- X zip.h header for using crypt.c with UnZip (required for decryption)
- X zipinfo.c zipfile information utility (useful, but optional)
- X Makefile main Unix and OS/2 makefile for export version (required)
- X Makefile.cr main Unix and OS/2 makefile for decryption version (see below)
- X AMIGA.zip support files for compiling on Amiga (LF)
- X ATARI.zip support files for compiling v4.1 on Atari ST (CR LF)
- X MAC.zip support files for compiling on Macintosh (LF)
- X MSDOS.zip support files for compiling under MS-DOS (CR LF)
- X OS2.zip support files for compiling under OS/2 (CR LF)
- X VMS.zip support files for compiling under VMS (LF)
- X cray.dif patch to crypt.c 1.0 (8 Nov 91) to fix bug on 64-bit/Cray
- X
- XFiles marked "required*" are also needed to compile ZipInfo. There are
- XUnix, OS/2 and MS-DOS targets to make ZipInfo near the bottom of Makefile
- X(zipinfo, zi_dos, zi_os2, zi_gcc, zi_icc). The sub-archives are marked
- Xeither "CR LF" or "LF" to indicate the line-endings format of the contained
- Xtext files.
- X
- XThe file ship.c is the stand-alone source file for the ship utility, a
- Xprogram for ASCII-encoding, splitting, e-mailing, and decoding binaries
- X(similar to uuencode/uudecode but far more useful). This is the preferred
- Xformat for sending/receiving zipfiles to and from zip-bugs and Info-ZIP.
- XInstructions on how to use it are included in the comments near the top
- Xof ship.c, and there are Unix, OS/2 and DOS makefile targets in Makefile
- X(sorry, we haven't got this fully integrated into all the other sub-
- Xarchives). Ship is more fully supported in the Zip distribution; if
- Xyou've already got it from there, you don't need to make it again.
- X
- XThe Atari ST support is in the form of patches against UnZip 4.1; there
- Xare more details in the ATARI sub-archive Contents file. Amiga support
- Xhas not been tested since version 4.1 or earlier (the makefiles, however,
- Xhave been updated to reflect the new code structure, and any changes
- Xrequired shouldn't be TOO extensive; maybe--dare we say it?--none...).
- X
- XEncryption and decryption code for both Zip and UnZip (the only file
- Xrequired for UnZip is crypt.c) is available from the following sites
- X(the filenames may differ slightly, if later versions become available):
- X
- X From the US:
- X pit-manager.mit.edu:/pub/zip/crypt/zipcrypt.shar
- X (mail server at mail-server@pit-manager.mit.edu)
- X wuarchive.wustl.edu:/mirrors3/garbo.uwasa.fi/arcutil/zcrypt10.zip
- X Outside the US:
- X garbo.uwasa.fi:/pc/arcutil/zcrypt10.zip
- X ftp.win.tue.nl:/pub/compression/zip/zcrypt10.zip
- X ftp.inria.fr:/system/arch-compr/zcrypt10.zip
- X ftp.informatik.tu-muenchen.de:/pub/utils/archiver/zcrypt10.zip
- X (mail server at ftp-mailer@ftp.informatik.tu-muenchen.de)
- X
- XNon-US users, please do NOT ftp from the US site (US regulations and
- Xall that). Likewise, US users, please do not ftp from the European
- Xsites (it's not illegal, but it sure is a waste of expensive bandwidth).
- XIf someone repackages zipcrypt.shar or zcrypt10.zip as a VMS .share
- Xfile and places it on a VMS archive site somewhere, please let us know
- X(send e-mail to zip-bugs at the address listed in README). Likewise
- Xfor Mac- or Atari-specific formats (or any others).
- END_OF_FILE
- if test 4533 -ne `wc -c <'Contents'`; then
- echo shar: \"'Contents'\" unpacked with wrong size!
- fi
- # end of 'Contents'
- fi
- if test -f 'unzip.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unzip.c'\"
- else
- echo shar: Extracting \"'unzip.c'\" \(46692 characters\)
- sed "s/^X//" >'unzip.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X unzip.c
- X
- X UnZip - a zipfile extraction utility. See below for make instructions, or
- X read the comments in Makefile for a more detailed explanation. To join
- X Info-ZIP, send a message to info-zip-request@cs.ucla.edu.
- X
- X UnZip 4.x is nearly a complete rewrite of version 3.x, mainly to allow
- X access to zipfiles via the central directory (and hence to the OS bytes,
- X so we can make intelligent decisions about what to do with the extracted
- X files). Based on unzip.c 3.15+ and zipinfo.c 0.90. For a complete revi-
- X sion history, see UnzpHist.zip at Info-ZIP headquarters (below). For a
- X (partial) list of the many (near infinite) contributors, see "CONTRIBS" in
- X the UnZip source distribution.
- X
- X ---------------------------------------------------------------------------
- X
- X To compile (partial instructions):
- X
- X under Unix (cc): make <system name>
- X (type "make list" for a list of valid names, or read Makefile for
- X details. "make unzip" works for most systems. If you have a NEW
- X system, not covered by any of the existing targets, send FULL infor-
- X mation--hardware, OS, versions, etc.--to zip-bugs@cs.ucla.edu)
- X
- X under MS-DOS (TurboC): make -fMAKEFILE.DOS for command line compiles
- X (or use the integrated environment and the included files TCCONFIG.TC
- X and UNZIP.PRJ. Tweak for your environment.)
- X
- X under MS-DOS (MSC): make MAKEFILE.DOS
- X (or use Makefile if you have MSC 6.0: "nmake msc_dos")
- X
- X under OS/2 (MSC): make MAKEFILE.DOS (edit appropriately)
- X (or use Makefile if you have MSC 6.0: "nmake msc_os2")
- X
- X under Atari OS: needs a little work yet...
- X
- X under VMS: DEFINE LNK$LIBRARY SYS$LIBRARY:VAXCRTL.OLB (see VMSNOTES)
- X CC UNZIP,FILE_IO,MAPNAME,MATCH,...,UNSHRINK
- X LINK UNZIP,FILE_IO,MAPNAME,MATCH,...,UNSHRINK
- X UNZIP :== $DISKNAME:[DIRECTORY]UNZIP.EXE
- X
- X under Macintosh OS: Double click on unzip.make. Press <Command>-M.
- X
- X ---------------------------------------------------------------------------
- X
- X Version: unzip42.{arc | tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS,
- X Mac & Amiga.
- X Source: valeria.cs.ucla.edu (131.179.64.36) in /pub
- X wuarchive.wustl.edu (128.252.135.4) in /mirrors/misc/unix
- X wsmr-simtel20.army.mil (192.88.110.20) in pd1:[misc.unix]
- X Copyrights: see accompanying file "COPYING" in UnZip source distribution.
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X
- X
- X
- X#include "unzip.h" /* includes, defines, and macros */
- X
- X/* #define VERSION "v4.20x BETA of 3-20-92" internal beta level */
- X#define VERSION "v4.2 of 20 March 1992"
- X#define PAKFIX /* temporary solution to PAK-created zipfiles */
- X
- X
- X
- X
- X
- X/**********************/
- X/* Global Variables */
- X/**********************/
- X
- Xint aflag; /* -a: do ASCII to EBCDIC translation, or CR-LF */
- X/* int bflag; RESERVED for -b: extract as binary */
- Xint cflag; /* -c: output to stdout */
- Xint fflag; /* -f: "freshen" (extract only newer files) */
- Xint jflag; /* -j: junk pathnames */
- Xint overwrite_none; /* -n: never overwrite files (no prompting) */
- Xint overwrite_all; /* -o: OK to overwrite files without prompting */
- Xint force_flag; /* (shares -o for now): force to override errors, etc. */
- Xint quietflg; /* -q: produce a lot less output */
- X#ifdef DOS_OS2 /* to CR or LF conversion of extracted files */
- X int sflag; /* -s: allow spaces (blanks) in filenames */
- X#endif /* DOS_OS2 */
- Xint tflag; /* -t: test */
- Xint uflag; /* -u: "update" (extract only newer & brand-new files) */
- Xstatic int U_flag; /* -U: leave filenames in upper or mixed case */
- Xstatic int vflag; /* -v: view directory (only used in unzip.c) */
- Xint V_flag; /* -V: don't strip VMS version numbers */
- X#ifdef VMS
- X int secinf; /* -X: keep owner/protection */
- X#endif /* VMS */
- Xint zflag; /* -z: display only the archive comment */
- Xint process_all_files;
- X
- Xlongint csize; /* used by list_files(), ReadByte(): must be signed */
- Xlongint ucsize; /* used by list_files(), unReduce(), unImplode() */
- X
- Xchar *fnames[2] = {"*", NULL}; /* default filenames vector */
- Xchar **fnv = fnames;
- Xchar sig[5];
- Xchar answerbuf[10];
- X
- Xmin_info info[DIR_BLKSIZ], *pInfo=info;
- X
- X#ifdef OS2
- X int longname; /* used only in mapname.c and file_io.c */
- X char longfilename[FILNAMSIZ];
- X#endif /* OS2 */
- X
- X#ifdef CRYPT
- X char *key = NULL; /* password with which to decrypt data, or NULL */
- X#endif /* CRYPT */
- X
- X/*---------------------------------------------------------------------------
- X unShrink/unReduce/unImplode working storage:
- X ---------------------------------------------------------------------------*/
- X
- X/* prefix_of (for unShrink) is biggest storage area, esp. on Crays...space */
- X/* is shared by lit_nodes (unImplode) and followers (unReduce) */
- X
- Xshort prefix_of[HSIZE + 1]; /* (8193 * sizeof(short)) */
- X#ifdef MACOS
- X byte *suffix_of;
- X byte *stack;
- X#else
- X byte suffix_of[HSIZE + 1]; /* also s-f length_nodes (smaller) */
- X byte stack[HSIZE + 1]; /* also s-f distance_nodes (smaller) */
- X#endif
- X
- XULONG crc32val;
- X
- XULONG mask_bits[] =
- X{0x00000000L,
- X 0x00000001L, 0x00000003L, 0x00000007L, 0x0000000fL,
- X 0x0000001fL, 0x0000003fL, 0x0000007fL, 0x000000ffL,
- X 0x000001ffL, 0x000003ffL, 0x000007ffL, 0x00000fffL,
- X 0x00001fffL, 0x00003fffL, 0x00007fffL, 0x0000ffffL,
- X 0x0001ffffL, 0x0003ffffL, 0x0007ffffL, 0x000fffffL,
- X 0x001fffffL, 0x003fffffL, 0x007fffffL, 0x00ffffffL,
- X 0x01ffffffL, 0x03ffffffL, 0x07ffffffL, 0x0fffffffL,
- X 0x1fffffffL, 0x3fffffffL, 0x7fffffffL, 0xffffffffL};
- X
- X/*---------------------------------------------------------------------------
- X Input file variables:
- X ---------------------------------------------------------------------------*/
- X
- Xbyte *inbuf, *inptr; /* input buffer (any size is legal) and pointer */
- Xint incnt;
- X
- XULONG bitbuf;
- Xint bits_left;
- Xboolean zipeof;
- X
- Xint zipfd; /* zipfile file handle */
- Xchar zipfn[FILNAMSIZ];
- X
- Xchar local_hdr_sig[5] = "\120"; /* remaining signature bytes come later */
- Xchar central_hdr_sig[5] = "\120"; /* (must initialize at runtime so unzip */
- Xchar end_central_sig[5] = "\120"; /* executable won't look like a zipfile) */
- X
- Xcdir_file_hdr crec; /* used in unzip.c, extract.c, misc.c */
- Xlocal_file_hdr lrec; /* used in unzip.c, extract.c */
- Xecdir_rec ecrec; /* used in unzip.c, extract.c */
- Xstruct stat statbuf; /* used by main(), mapped_name(), check_for_newer() */
- X
- Xlongint extra_bytes = 0; /* used in unzip.c, misc.c */
- Xlongint cur_zipfile_bufstart; /* extract_or_test_files, readbuf, ReadByte */
- X
- Xbyte *extra_field = NULL; /* currently used by VMS version only */
- X
- X/*---------------------------------------------------------------------------
- X Output stream variables:
- X ---------------------------------------------------------------------------*/
- X
- Xbyte *outbuf; /* buffer for rle look-back */
- Xbyte *outptr;
- Xbyte *outout; /* scratch pad for ASCII-native trans */
- Xlongint outpos; /* absolute position in outfile */
- Xint outcnt; /* current position in outbuf */
- Xint outfd;
- Xint disk_full;
- Xchar filename[FILNAMSIZ];
- X
- X/*---------------------------------------------------------------------------
- X unzip.c static global variables (visible only within this file):
- X ---------------------------------------------------------------------------*/
- X
- Xstatic byte *hold;
- Xstatic char unkn[10];
- Xstatic longint ziplen;
- Xstatic UWORD methnum;
- X
- X/*---------------------------------------------------------------------------
- X unzip.c repeated error messages (we use all of these at least twice)
- X ---------------------------------------------------------------------------*/
- X
- Xchar *EndSigMsg = "\nwarning:\
- X didn't find end-of-central-dir signature at end of central dir.\n";
- Xchar *CentSigMsg =
- X "error: expected central file header signature not found (file #%u).\n";
- Xchar *SeekMsg =
- X "error: attempt to seek before beginning of zipfile\n%s";
- X
- X#ifdef VMS
- Xchar *ReportMsg = "\
- X (please check that you have transferred or created the zipfile in the\n\
- X appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
- X#else /* !VMS */
- Xchar *ReportMsg = "\
- X (please check that you have transferred or created the zipfile in the\n\
- X appropriate BINARY mode and that you have compiled unzip properly)\n";
- X#endif /* ?VMS */
- X
- X
- X
- X
- X/******************/
- X/* Main program */
- X/******************/
- X
- Xmain(argc, argv) /* return PK-type error code (except under VMS) */
- Xint argc;
- Xchar *argv[];
- X{
- X char *s;
- X int c, error=FALSE;
- X
- X
- X/*---------------------------------------------------------------------------
- X Macintosh initialization code.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef MACOS
- X#ifdef THINK_C
- X #include <console.h>
- X static char *argstr[30], args[30*64];
- X
- X Point p;
- X SFTypeList sfT;
- X int a;
- X EventRecord theEvent;
- X short eMask;
- X SFReply fileRep;
- X#endif /* THINK_C */
- X
- X typedef struct sf_node { /* node in a true shannon-fano tree */
- X UWORD left; /* 0 means leaf node */
- X UWORD right; /* or value if leaf node */
- X } sf_node;
- X
- X extern sf_node *lit_nodes, *length_nodes, *distance_nodes;
- X
- X#ifdef MCH_MACINTOSH
- X defSpin(0x20);
- X#endif
- X
- X suffix_of = (byte *)calloc(HSIZE+1, sizeof(byte));
- X stack = (byte *)calloc(HSIZE+1, sizeof(byte));
- X length_nodes = (sf_node *) suffix_of; /* 2*LENVALS nodes */
- X distance_nodes = (sf_node *) stack; /* 2*DISTVALS nodes */
- X
- X#ifdef THINK_C
- X for (a=0; a<30; a+=1)
- X argstr[a] = &args[a*64];
- Xstart:
- X tflag=vflag=cflag=aflag=jflag=U_flag=quietflg=fflag=uflag=zflag = 0;
- X local_hdr_sig[1]=central_hdr_sig[1]=end_central_sig[1]='\0';
- X
- X argc = ccommand(&argv);
- X SetPt(&p, 40,40);
- X
- X SFGetFile(p, "\pSpecify ZIP file:", 0L, -1, sfT, 0L, &fileRep);
- X if (!fileRep.good)
- X exit(1);
- X macfstest(fileRep.vRefNum);
- X SetMacVol(NULL, fileRep.vRefNum);
- X for (a=1; a<argc; a+=1)
- X if (argv[a][0] == '-')
- X BlockMove(argv[a], argstr[a], (strlen(argv[a])>63) ? 64 : strlen(argv[a])+1);
- X else
- X break;
- X PtoCstr((char *)fileRep.fName);
- X strcpy(argstr[a], (char *)fileRep.fName);
- X for (;a<argc; a+=1)
- X BlockMove(argv[a], argstr[a+1], (strlen(argv[a])>63) ? 64 : strlen(argv[a])+1);
- X argc+=1;
- X argv = argstr;
- X
- X if (hfsflag == FALSE) /* can't support directories: junk pathnames */
- X jflag = 1;
- X#endif /* THINK_C */
- X#endif /* MACOS */
- X
- X/*---------------------------------------------------------------------------
- X Debugging info for checking on structure padding:
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef DEBUG_STRUC
- X printf("local_file_hdr size: %X\n",
- X sizeof(local_file_hdr));
- X printf("local_byte_hdr size: %X\n",
- X sizeof(local_byte_hdr));
- X printf("actual size of local headers: %X\n", LREC_SIZE);
- X
- X printf("central directory header size: %X\n",
- X sizeof(cdir_file_hdr));
- X printf("central directory byte header size: %X\n",
- X sizeof(cdir_byte_hdr));
- X printf("actual size of central dir headers: %X\n", CREC_SIZE);
- X
- X printf("end central dir record size: %X\n",
- X sizeof(ecdir_rec));
- X printf("end central dir byte record size: %X\n",
- X sizeof(ec_byte_rec));
- X printf("actual size of end-central-dir record: %X\n", ECREC_SIZE);
- X#endif /* DEBUG_STRUC */
- X
- X/*---------------------------------------------------------------------------
- X Rip through any command-line options lurking about...
- X ---------------------------------------------------------------------------*/
- X
- X while (--argc > 0 && (*++argv)[0] == '-') {
- X s = argv[0] + 1;
- X while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
- X switch (c) {
- X case ('a'):
- X ++aflag;
- X break;
- X#if 0
- X case ('s'):
- X ++sflag;
- X break;
- X#endif
- X case ('c'):
- X ++cflag;
- X#ifdef NATIVE
- X ++aflag; /* this is so you can read it on the screen */
- X#endif
- X break;
- X case ('d'): /* re-create directory structure (now by default) */
- X break;
- X case ('e'): /* just ignore -e, -x options (extract) */
- X break;
- X case ('f'): /* "freshen" (extract only newer files) */
- X ++fflag;
- X ++uflag;
- X break;
- X case ('j'): /* junk pathnames/directory structure */
- X ++jflag;
- X break;
- X /* case ('l') is below, after fall-through for 'v' */
- X case ('n'): /* don't overwrite any files */
- X overwrite_none = TRUE;
- X break;
- X case ('o'): /* OK to overwrite files without prompting */
- X overwrite_all = TRUE;
- X force_flag = TRUE; /* (share -o for now): force to continue */
- X break;
- X case ('p'):
- X ++cflag;
- X#if defined(NATIVE) && !defined(DOS_OS2)
- X ++aflag;
- X#endif
- X quietflg += 99;
- X break;
- X case ('q'):
- X ++quietflg;
- X break;
- X#ifdef DOS_OS2
- X case ('s'):
- X ++sflag;
- X break;
- X#endif
- X case ('t'):
- X ++tflag;
- X break;
- X case ('U'): /* Uppercase flag (i.e., don't convert to lower) */
- X ++U_flag;
- X break;
- X case ('u'): /* "update" (extract only new and newer files) */
- X ++uflag;
- X break;
- X case ('V'): /* Version flag: retain VMS/DEC-20 file versions */
- X ++V_flag;
- X break;
- X case ('v'):
- X ++vflag;
- X /* fall thru */
- X case ('l'):
- X ++vflag;
- X break;
- X#ifdef VMS
- X case ('X'): /* restore owner/protection info (may need privs) */
- X secinf = TRUE;
- X break;
- X#endif /* VMS */
- X case ('x'): /* extract: default */
- X break;
- X case ('z'): /* display only the archive comment */
- X ++zflag;
- X break;
- X default:
- X error = TRUE;
- X break;
- X }
- X }
- X }
- X
- X/*---------------------------------------------------------------------------
- X Make sure we aren't trying to do too many things here. [This seems like
- X kind of a brute-force way to do things; but aside from that, isn't the
- X -a option useful when listing the directory (i.e., for reading zipfile
- X comments)? It's a modifier, not an action in and of itself, so perhaps
- X it should not be included in the test--certainly, in the case of zipfile
- X testing, it can just be ignored.]
- X ---------------------------------------------------------------------------*/
- X
- X if ((aflag && tflag) || (aflag && vflag) || (cflag && tflag) ||
- X (cflag && uflag) || (cflag && vflag) || (tflag && uflag) ||
- X (tflag && vflag) || (uflag && vflag) || (fflag && overwrite_none)) {
- X fprintf(stderr, "error:\
- X -at, -av, -ct, -cu, -cv, -fn, -tu, -tv, -uv combinations not allowed\n");
- X error = TRUE;
- X }
- X if (quietflg && zflag)
- X quietflg = 0;
- X if (overwrite_all && overwrite_none) {
- X fprintf(stderr, "caution: both -n and -o specified; ignoring -o\n");
- X overwrite_all = FALSE;
- X }
- X if ((argc-- == 0) || error)
- X RETURN(usage(error));
- X
- X/*---------------------------------------------------------------------------
- X Now get the zipfile name from the command line and see if it exists as a
- X regular (non-directory) file. If not, append the ".zip" suffix. We don't
- X immediately check to see if this results in a good name, but we will do so
- X later. In the meantime, see if there are any member filespecs on the com-
- X mand line, and if so, set the filename pointer to point at them.
- X ---------------------------------------------------------------------------*/
- X
- X strcpy(zipfn, *argv++);
- X if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR)
- X strcat(zipfn, ZSUFX);
- X#if defined(UNIX) && !defined(VMS) /* Unix executables have no extension-- */
- X else if (statbuf.st_mode & S_IEXEC) /* might find zip, not zip.zip; etc */
- X fprintf(stderr, "\nnote: file [ %s ] may be an executable\n\n", zipfn);
- X#endif /* UNIX && !VMS */
- X
- X if (stat(zipfn, &statbuf)) {/* try again */
- X fprintf(stderr, "error: can't find zipfile [ %s ]\n", zipfn);
- X RETURN(9); /* 9: file not found */
- X } else
- X ziplen = statbuf.st_size;
- X
- X if (argc != 0) {
- X fnv = argv;
- X process_all_files = FALSE;
- X } else
- X process_all_files = TRUE; /* for speed */
- X
- X/*---------------------------------------------------------------------------
- X Okey dokey, we have everything we need to get started. Let's roll.
- X ---------------------------------------------------------------------------*/
- X
- X inbuf = (byte *) malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */
- X outbuf = (byte *) malloc(OUTBUFSIZ + 1); /* 1 extra for string termin. */
- X#ifndef DOS_OS2
- X if (aflag) /* if need an ascebc scratch, */
- X outout = (byte *) malloc(OUTBUFSIZ);
- X else /* allocate it... */
- X#endif /* !DOS_OS2 */
- X outout = outbuf; /* else just point to outbuf */
- X
- X if ((inbuf == NULL) || (outbuf == NULL) || (outout == NULL)) {
- X fprintf(stderr, "error: can't allocate unzip buffers\n");
- X RETURN(4); /* 4-8: insufficient memory */
- X }
- X hold = &inbuf[INBUFSIZ]; /* to check for boundary-spanning signatures */
- X
- X#ifdef THINK_C
- X if (!process_zipfile())
- X goto start;
- X#else
- X RETURN(process_zipfile()); /* keep passing errors back... */
- X#endif
- X
- X} /* end main() */
- X
- X
- X
- X
- X
- X/**********************/
- X/* Function usage() */
- X/**********************/
- X
- Xint usage(error) /* return PK-type error code */
- X int error;
- X{
- X#ifdef NATIVE
- X#ifdef EBCDIC
- X char *astring = "-a convert ASCII to EBCDIC";
- X#else /* !EBCDIC */
- X char *astring = "-a convert ASCII to native chars";
- X#endif /* ?EBCDIC *?
- X/* char *astring = "-a convert ASCII to " NATIVE; (ANSI C concatenation) */
- X char *loc_str = "";
- X#else /* !NATIVE */
- X#ifdef DOS_OS2
- X char *astring = "-a convert text (LF => CR LF)";
- X char *loc_str = "-s allow spaces in filenames";
- X#else /* !DOS_OS2 */
- X#ifdef MACOS
- X char *astring = "-a convert text (CR LF => CR)";
- X char *loc_str = "";
- X#else /* !MACOS: UNIX, VMS */
- X char *astring = "-a convert text (CR LF => LF)";
- X#ifdef VMS
- X char *loc_str = "-X restore owner/protection info";
- X#else /* !VMS */
- X char *loc_str = "";
- X#endif /* ?VMS */
- X#endif /* ?MACOS */
- X#endif /* ?DOS_OS2 */
- X#endif /* ?NATIVE */
- X FILE *usagefp;
- X
- X
- X/*---------------------------------------------------------------------------
- X If user requested usage, send it to stdout; else send to stderr.
- X ---------------------------------------------------------------------------*/
- X
- X if (error)
- X usagefp = (FILE *) stderr;
- X else
- X usagefp = (FILE *) stdout;
- X
- X fprintf(usagefp, "\
- XUnZip: Zipfile Extract %s; (c) 1989 S.H.Smith and others\n\
- XVersions 3.0 and later by Info-ZIP. Bug reports ONLY to zip-bugs@cs.ucla.edu\
- X\n\n", VERSION);
- X
- X fprintf(usagefp, "\
- XUsage: unzip [ -options[modifiers] ] file[.zip] [filespec...]\n\
- X -x extract files (default) -l list files (short format)\n\
- X -c extract files to stdout/screen (CRT) -v list files (verbose format)\n\
- X -f freshen existing files, create none -p extract to pipe, no messages\n\
- X -u update files, create if necessary -t test archive integrity\n\
- X -z display archive comment\n\
- Xmodifiers:\n\
- X -n never overwrite existing files %s\n", loc_str);
- X fprintf(usagefp, "\
- X -o overwrite files WITHOUT prompting %s\n\
- X -j junk paths (don't make directories) -U don't make names lowercase\n\
- X -q quiet mode (-qq => quieter) -V retain VMS version numbers\
- X\n\n\
- XExamples: (See manual for more information)\n\
- X unzip data1 Readme => extracts file Readme from zipfile data1.zip\n\
- X unzip -p foo | more => send contents of foo.zip via pipe into program more\n\
- X unzip -fo foo => quietly replace existing files if archive files newer\
- X\n", astring);
- X
- X#ifdef VMS
- X fprintf(usagefp, "\
- X unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\
- X\n");
- X#endif
- X
- X if (error)
- X return 10; /* 10: bad or illegal parameters specified */
- X else
- X return 0; /* just wanted usage screen: no error */
- X
- X} /* end function usage() */
- X
- X
- X
- X
- X
- X/********************************/
- X/* Function process_zipfile() */
- X/********************************/
- X
- Xint process_zipfile() /* return PK-type error code */
- X{
- X int error=0, error_in_archive;
- X longint real_ecrec_offset, expect_ecrec_offset;
- X
- X
- X/*---------------------------------------------------------------------------
- X Open the zipfile for reading and in BINARY mode to prevent CR/LF trans-
- X lation, which would corrupt the bitstreams.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef VMS
- X {
- X int rtype;
- X
- X VMSmunch(zipfn, GET_RTYPE, (char *)&rtype);
- X if (rtype == FAT$C_VARIABLE) {
- X fprintf(stderr,
- X "\n Error: zipfile is in variable-length record format. Please\n\
- X run \"bilf l %s\" to convert the zipfile to stream-LF\n\
- X record format. (Bilf.exe, bilf.c and make_bilf.com are included\n\
- X in the VMS unzip distribution.)\n\n", zipfn);
- X return 2; /* 2: error in zipfile */
- X }
- X rtype = FAT$C_STREAMLF; /* Unix I/O loves it */
- X VMSmunch(zipfn, CHANGE_RTYPE, (char *)&rtype);
- X }
- X#endif
- X if (open_input_file()) /* this should never happen, given the */
- X return (9); /* stat() test in main(), but... */
- X
- X/*---------------------------------------------------------------------------
- X Reconstruct the various PK signature strings; find and process the cen-
- X tral directory; list, extract or test member files as instructed; and
- X close the zipfile.
- X ---------------------------------------------------------------------------*/
- X
- X strcat(local_hdr_sig, LOCAL_HDR_SIG);
- X strcat(central_hdr_sig, CENTRAL_HDR_SIG);
- X strcat(end_central_sig, END_CENTRAL_SIG);
- X
- X if (find_end_central_dir()) /* not found; nothing to do */
- X return (2); /* 2: error in zipfile */
- X
- X real_ecrec_offset = cur_zipfile_bufstart+(inptr-inbuf);
- X#ifdef TEST
- X printf("\n found end-of-central-dir signature at offset %ld (%.8lXh)\n",
- X real_ecrec_offset, real_ecrec_offset);
- X printf(" from beginning of file; offset %d (%.4Xh) within block\n",
- X inptr-inbuf, inptr-inbuf);
- X#endif
- X
- X if ((error_in_archive = process_end_central_dir()) > 1)
- X return (error_in_archive);
- X
- X if (zflag)
- X return (0);
- X
- X#ifndef PAKFIX
- X if (ecrec.number_this_disk == 0) {
- X#else /* PAKFIX */
- X if ((ecrec.number_this_disk == 0) ||
- X (error = ((ecrec.number_this_disk == 1) &&
- X (ecrec.num_disk_with_start_central_dir == 1)) )) {
- X
- X if (error) {
- X fprintf(stderr,
- X "\n Warning: zipfile claims to be disk 2 of a two-part archive;\n\
- X attempting to process anyway. If no further errors occur, this\n\
- X archive was probably created by PAK v2.5 or earlier. This bug\n\
- X was reported to NoGate and should have been fixed by mid-1991.\n\n");
- X error_in_archive = 1; /* 1: warning */
- X }
- X#endif /* ?PAKFIX */
- X expect_ecrec_offset = ecrec.offset_start_central_directory +
- X ecrec.size_central_directory;
- X if ((extra_bytes = real_ecrec_offset - expect_ecrec_offset) < 0) {
- X fprintf(stderr, "\nerror: missing %ld bytes in zipfile (\
- Xattempting to process anyway)\n\n", -extra_bytes);
- X error_in_archive = 2; /* 2: (weak) error in zipfile */
- X } else if (extra_bytes > 0) {
- X if ((ecrec.offset_start_central_directory == 0) &&
- X (ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */
- X {
- X fprintf(stderr, "\nerror: NULL central directory offset (\
- Xattempting to process anyway)\n\n");
- X ecrec.offset_start_central_directory = extra_bytes;
- X extra_bytes = 0;
- X error_in_archive = 2; /* 2: (weak) error in zipfile */
- X } else {
- X fprintf(stderr, "\nwarning: extra %ld bytes at beginning or\
- X within zipfile\n (attempting to process anyway)\n\n", extra_bytes);
- X error_in_archive = 1; /* 1: warning error */
- X }
- X }
- X LSEEK( ecrec.offset_start_central_directory )
- X if (vflag)
- X error = list_files(); /* LIST 'EM */
- X else
- X error = extract_or_test_files(); /* EXTRACT OR TEST 'EM */
- X if (error > error_in_archive) /* don't overwrite stronger error */
- X error_in_archive = error; /* with (for example) a warning */
- X } else {
- X fprintf(stderr, "\nerror: zipfile is part of multi-disk archive \
- X(sorry, not supported).\n");
- X fprintf(stderr, "Please report to zip-bugs@cs.ucla.edu\n");
- X error_in_archive = 11; /* 11: no files found */
- X }
- X
- X close(zipfd);
- X#ifdef VMS
- X VMSmunch(zipfn, RESTORE_RTYPE, NULL);
- X#endif
- X return (error_in_archive);
- X
- X} /* end function process_zipfile() */
- X
- X
- X
- X
- X
- X/************************************/
- X/* Function find_end_central_dir() */
- X/************************************/
- X
- Xint find_end_central_dir()
- X/* return 0 if found, 1 otherwise */
- X{
- X int i, numblks;
- X longint tail_len;
- X
- X
- X
- X/*---------------------------------------------------------------------------
- X Treat case of short zipfile separately.
- X ---------------------------------------------------------------------------*/
- X
- X if (ziplen <= INBUFSIZ) {
- X lseek(zipfd, 0L, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)ziplen)) == ziplen)
- X
- X /* 'P' must be at least 22 bytes from end of zipfile */
- X for ( inptr = inbuf+ziplen-22 ; inptr >= inbuf ; --inptr )
- X if ( (ascii_to_native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4) ) {
- X incnt -= inptr - inbuf;
- X return(0); /* found it! */
- X } /* ...otherwise fall through & fail */
- X
- X/*---------------------------------------------------------------------------
- X Zipfile is longer than INBUFSIZ: may need to loop. Start with short
- X block at end of zipfile (if not TOO short).
- X ---------------------------------------------------------------------------*/
- X
- X } else {
- X if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) {
- X cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) != tail_len)
- X goto fail; /* shut up, it's expedient. */
- X
- X /* 'P' must be at least 22 bytes from end of zipfile */
- X for ( inptr = inbuf+tail_len-22 ; inptr >= inbuf ; --inptr )
- X if ( (ascii_to_native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4) ) {
- X incnt -= inptr - inbuf;
- X return(0); /* found it! */
- X } /* ...otherwise search next block */
- X strncpy((char *)hold, (char *)inbuf, 3); /* sig may span block
- X boundary */
- X
- X } else {
- X cur_zipfile_bufstart = ziplen - tail_len;
- X }
- X
- X /*
- X * Loop through blocks of zipfile data, starting at the end and going
- X * toward the beginning. Need only check last 65557 bytes of zipfile:
- X * comment may be up to 65535 bytes long, end-of-central-directory rec-
- X * ord is 18 bytes (shouldn't hardcode this number, but what the hell:
- X * already did so above (22=18+4)), and sig itself is 4 bytes.
- X */
- X
- X /* ==amt to search== ==done== ==rounding== =blksiz= */
- X numblks = ( min(ziplen,65557) - tail_len + (INBUFSIZ-1) ) / INBUFSIZ;
- X
- X for ( i = 1 ; i <= numblks ; ++i ) {
- X cur_zipfile_bufstart -= INBUFSIZ;
- X lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
- X break; /* fall through and fail */
- X
- X for ( inptr = inbuf+INBUFSIZ-1 ; inptr >= inbuf ; --inptr )
- X if ( (ascii_to_native(*inptr) == 'P') &&
- X !strncmp((char *)inptr, end_central_sig, 4) ) {
- X incnt -= inptr - inbuf;
- X return(0); /* found it! */
- X }
- X strncpy((char *)hold, (char *)inbuf, 3); /* sig may span block
- X boundary */
- X }
- X
- X } /* end if (ziplen > INBUFSIZ) */
- X
- X/*---------------------------------------------------------------------------
- X Searched through whole region where signature should be without finding
- X it. Print informational message and die a horrible death.
- X ---------------------------------------------------------------------------*/
- X
- Xfail:
- X
- X fprintf(stderr, "\nFile: %s\n\n\
- X End-of-central-directory signature not found. Either this file is not\n\
- X a zipfile, or it constitutes one disk of a multi-part archive. In the\n\
- X latter case the central directory and zipfile comment will be found on\n\
- X the last disk(s) of this archive.\n", zipfn);
- X return(1);
- X
- X} /* end function find_end_central_dir() */
- X
- X
- X
- X
- X
- X/***************************************/
- X/* Function process_end_central_dir() */
- X/***************************************/
- X
- Xint process_end_central_dir() /* return PK-type error code */
- X{
- X ec_byte_rec byterec;
- X int error=0;
- X
- X
- X/*---------------------------------------------------------------------------
- X Read the end-of-central-directory record and do any necessary machine-
- X type conversions (byte ordering, structure padding compensation) by
- X reading data into character array, then copying to struct.
- X ---------------------------------------------------------------------------*/
- X
- X if (readbuf((char *) byterec, ECREC_SIZE+4) <= 0)
- X return (51);
- X
- X ecrec.number_this_disk =
- X makeword(&byterec[NUMBER_THIS_DISK]);
- X ecrec.num_disk_with_start_central_dir =
- X makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
- X ecrec.num_entries_centrl_dir_ths_disk =
- X makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);
- X ecrec.total_entries_central_dir =
- X makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
- X ecrec.size_central_directory =
- X makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
- X ecrec.offset_start_central_directory =
- X makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
- X ecrec.zipfile_comment_length =
- X makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
- X
- X/*---------------------------------------------------------------------------
- X Get the zipfile comment, if any, and print it out. (Comment may be up
- X to 64KB long. May the fleas of a thousand camels infest the armpits of
- X anyone who actually takes advantage of this fact.) Then position the
- X file pointer to the beginning of the central directory and fill buffer.
- X ---------------------------------------------------------------------------*/
- X
- X if (ecrec.zipfile_comment_length && !quietflg) {
- X if (!zflag)
- X printf("[%s] comment:\n", zipfn);
- X if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
- X fprintf(stderr, "\ncaution: zipfile comment truncated\n");
- X error = 1; /* 1: warning error */
- X }
- X#if 0
- X if (!zflag)
- X printf("\n\n"); /* what the heck is this doing here?! */
- X#endif
- X }
- X
- X return (error);
- X
- X} /* end function process_end_central_dir() */
- X
- X
- X
- X
- X
- X/**************************/
- X/* Function list_files() */
- X/**************************/
- X
- Xint list_files() /* return PK-type error code */
- X{
- X char **fnamev;
- X int do_this_file=FALSE, ratio, error, error_in_archive=0;
- X int which_hdr=(vflag>1);
- X UWORD j, yr, mo, dy, hh, mm, members=0;
- X ULONG tot_csize=0L, tot_ucsize=0L;
- X min_info info;
- X static char *method[NUM_METHODS+1] =
- X {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
- X "Implode", "Token", "Deflate", unkn};
- X static char *Headers[][2] = {
- X {" Length Date Time Name",
- X " ------ ---- ---- ----"},
- X {" Length Method Size Ratio Date Time CRC-32 Name",
- X " ------ ------ ---- ----- ---- ---- ------ ----"}
- X };
- X
- X
- X
- X/*---------------------------------------------------------------------------
- X Unlike extract_or_test_files(), this routine confines itself to the cen-
- X tral directory. Thus its structure is somewhat simpler, since we can do
- X just a single loop through the entire directory, listing files as we go.
- X
- X So to start off, print the heading line and then begin main loop through
- X the central directory. The results will look vaguely like the following:
- X
- X Length Method Size Ratio Date Time CRC-32 Name ("^" ==> case
- X ------ ------ ---- ----- ---- ---- ------ ---- conversion)
- X 44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
- X 3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 ^dos-file.ext
- X ---------------------------------------------------------------------------*/
- X
- X pInfo = &info;
- X
- X if (quietflg < 2)
- X if (U_flag)
- X printf("%s\n%s\n", Headers[which_hdr][0], Headers[which_hdr][1]);
- X else
- X printf("%s (\"^\" ==> case\n%s conversion)\n",
- X Headers[which_hdr][0], Headers[which_hdr][1]);
- X
- X for (j = 0; j < ecrec.total_entries_central_dir; ++j) {
- X
- X if (readbuf(sig, 4) <= 0)
- X return (51); /* 51: unexpected EOF */
- X if (strncmp(sig, central_hdr_sig, 4)) { /* just to make sure */
- X fprintf(stderr, CentSigMsg, j); /* sig not found */
- X fprintf(stderr, ReportMsg); /* check binary transfers */
- X return (3); /* 3: error in zipfile */
- X }
- X if ((error = process_cdir_file_hdr()) != 0) /* (sets pInfo->lcflag) */
- X return (error); /* only 51 (EOF) defined */
- X
- X /*
- X * We could DISPLAY the filename instead of storing (and possibly trun-
- X * cating, in the case of a very long name) and printing it, but that
- X * has the disadvantage of not allowing case conversion--and it's nice
- X * to be able to see in the listing precisely how you have to type each
- X * filename in order for unzip to consider it a match. Speaking of
- X * which, if member names were specified on the command line, check in
- X * with match() to see if the current file is one of them, and make a
- X * note of it if it is.
- X */
- X
- X if ((error = do_string(crec.filename_length, FILENAME)) != 0) {
- X error_in_archive = error; /* ^--(uses pInfo->lcflag) */
- X if (error > 1) /* fatal: can't continue */
- X return (error);
- X }
- X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
- X error_in_archive = error;
- X if (error > 1) /* fatal: can't continue */
- X return (error);
- X }
- X if (!process_all_files) { /* check if specified on command line */
- X do_this_file = FALSE;
- X fnamev = fnv; /* don't destroy permanent filename ptr */
- X for (--fnamev; *++fnamev;)
- X if (match(filename, *fnamev)) {
- X do_this_file = TRUE;
- X break; /* found match, so stop looping */
- X }
- X }
- X /*
- X * If current file was specified on command line, or if no names were
- X * specified, do the listing for this file. Otherwise, get rid of the
- X * file comment and go back for the next file.
- X */
- X
- X if (process_all_files || do_this_file) {
- X
- X yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)100;
- X mo = (crec.last_mod_file_date >> 5) & 0x0f;
- X dy = crec.last_mod_file_date & 0x1f;
- X
- X /* twist date so it displays according to national convention */
- X switch (dateformat()) {
- X case DF_YMD:
- X hh = mo; mo = yr; yr = dy; dy = hh; break;
- X case DF_DMY:
- X hh = mo; mo = dy; dy = hh;
- X }
- X hh = (crec.last_mod_file_time >> 11) & 0x1f;
- X mm = (crec.last_mod_file_time >> 5) & 0x3f;
- X
- X csize = (longint) crec.compressed_size;
- X ucsize = (longint) crec.uncompressed_size;
- X if (crec.general_purpose_bit_flag & 1)
- X csize -= 12; /* if encrypted, don't count encrypt hdr */
- X
- X ratio = (ucsize == 0) ? 0 : /* .zip can have 0-length members */
- X ((ucsize > 2000000) ? /* risk signed overflow if mult. */
- X (int) ((ucsize-csize) / (ucsize/1000L)) + 5 : /* big */
- X (int) ((1000L*(ucsize-csize)) / ucsize) + 5); /* small */
- X
- X switch (which_hdr) {
- X case 0: /* short form */
- X printf("%7ld %02u-%02u-%02u %02u:%02u %c%s\n",
- X ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '),
- X filename);
- X break;
- X case 1: /* verbose */
- X printf(
- X "%7ld %-7s%7ld %3d%% %02u-%02u-%02u %02u:%02u %08lx %c%s\n",
- X ucsize, method[methnum], csize, ratio/10, mo, dy, yr,
- X hh, mm, crec.crc32, (pInfo->lcflag?'^':' '), filename);
- X }
- X
- X error = do_string(crec.file_comment_length, (QCOND2? DISPLAY:SKIP));
- X if (error) {
- X error_in_archive = error; /* might be just warning */
- X if (error > 1) /* fatal */
- X return (error);
- X }
- X tot_ucsize += (ULONG) ucsize;
- X tot_csize += (ULONG) csize;
- X ++members;
- X
- X } else { /* not listing this file */
- X SKIP_(crec.file_comment_length)
- X }
- X } /* end for-loop (j: files in central directory) */
- X
- X/*---------------------------------------------------------------------------
- X Print footer line and totals (compressed size, uncompressed size, number
- X of members in zipfile).
- X ---------------------------------------------------------------------------*/
- X
- X ratio = (tot_ucsize == 0) ?
- X 0 : ((tot_ucsize > 4000000) ? /* risk unsigned overflow if mult. */
- X (int) ((tot_ucsize - tot_csize) / (tot_ucsize/1000L)) + 5 :
- X (int) ((tot_ucsize - tot_csize) * 1000L / tot_ucsize) + 5);
- X
- X if (quietflg < 2) {
- X switch (which_hdr) {
- X case 0: /* short */
- X printf("%s\n%7lu %-7u\n",
- X " ------ -------",
- X tot_ucsize, members);
- X break;
- X case 1: /* verbose */
- X printf(
- X "%s\n%7lu %7lu %3d%% %-7u\n",
- X " ------ ------ --- -------",
- X tot_ucsize, tot_csize, ratio / 10, members);
- X }
- X }
- X/*---------------------------------------------------------------------------
- X Double check that we're back at the end-of-central-directory record.
- X ---------------------------------------------------------------------------*/
- X
- X readbuf(sig, 4);
- X if (strncmp(sig, end_central_sig, 4)) { /* just to make sure again */
- X fprintf(stderr, EndSigMsg); /* didn't find end-of-central-dir sig */
- X/* fprintf(stderr, ReportMsg); */
- X error_in_archive = 1; /* 1: warning error */
- X }
- X return (error_in_archive);
- X
- X} /* end function list_files() */
- X
- X
- X
- X
- X
- X/**************************************/
- X/* Function process_cdir_file_hdr() */
- X/**************************************/
- X
- Xint process_cdir_file_hdr() /* return PK-type error code */
- X{
- X cdir_byte_hdr byterec;
- X
- X
- X/*---------------------------------------------------------------------------
- X Read the next central directory entry and do any necessary machine-type
- X conversions (byte ordering, structure padding compensation--do so by
- X copying the data from the array into which it was read (byterec) to the
- X usable struct (crec)).
- X ---------------------------------------------------------------------------*/
- X
- X if (readbuf((char *) byterec, CREC_SIZE) <= 0)
- X return (51); /* 51: unexpected EOF */
- X
- X crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
- X crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
- X crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
- X crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
- X
- X crec.general_purpose_bit_flag =
- X makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
- X crec.compression_method =
- X makeword(&byterec[C_COMPRESSION_METHOD]);
- X crec.last_mod_file_time =
- X makeword(&byterec[C_LAST_MOD_FILE_TIME]);
- X crec.last_mod_file_date =
- X makeword(&byterec[C_LAST_MOD_FILE_DATE]);
- X crec.crc32 =
- X makelong(&byterec[C_CRC32]);
- X crec.compressed_size =
- X makelong(&byterec[C_COMPRESSED_SIZE]);
- X crec.uncompressed_size =
- X makelong(&byterec[C_UNCOMPRESSED_SIZE]);
- X crec.filename_length =
- X makeword(&byterec[C_FILENAME_LENGTH]);
- X crec.extra_field_length =
- X makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
- X crec.file_comment_length =
- X makeword(&byterec[C_FILE_COMMENT_LENGTH]);
- X crec.disk_number_start =
- X makeword(&byterec[C_DISK_NUMBER_START]);
- X crec.internal_file_attributes =
- X makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
- X crec.external_file_attributes =
- X makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
- X crec.relative_offset_local_header =
- X makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
- X
- X pInfo->hostnum = min(crec.version_made_by[1], NUM_HOSTS);
- X/* extnum = min( crec.version_needed_to_extract[1], NUM_HOSTS ); */
- X methnum = min(crec.compression_method, NUM_METHODS);
- X if (methnum == NUM_METHODS)
- X sprintf(unkn, "Unk:%03d", crec.compression_method);
- X
- X/*---------------------------------------------------------------------------
- X Set flag for lowercase conversion of filename, depending on which OS the
- X file is coming from. This section could be ifdef'd if some people have
- X come to love DOS uppercase filenames under Unix...but really, guys, get
- X a life. :) NOTE THAT ALL SYSTEM NAMES NOW HAVE TRAILING UNDERSCORES!!!
- X This is to prevent interference with compiler command-line defines such
- X as -DUNIX, for example, which are then used in "#ifdef UNIX" constructs.
- X ---------------------------------------------------------------------------*/
- X
- X pInfo->lcflag = 0;
- X if (!U_flag) /* as long as user hasn't specified case-preservation */
- X switch (pInfo->hostnum) {
- X case DOS_OS2_FAT_:
- X case VMS_:
- X case VM_CMS_: /* all caps? */
- X case CPM_: /* like DOS, right? */
- X /* case ATARI_: ? */
- X /* case Z_SYSTEM_: ? */
- X /* case TOPS20_: (if we had such a thing...) */
- X pInfo->lcflag = 1; /* convert filename to lowercase */
- X break;
- X
- X default: /* AMIGA_, UNIX_, (ATARI_), OS2_HPFS_, */
- X break; /* MAC_, (Z_SYSTEM_): no conversion */
- X }
- X
- X return 0;
- X
- X} /* end function process_cdir_file_hdr() */
- X
- X
- X
- X
- X
- X/***************************************/
- X/* Function process_local_file_hdr() */
- X/***************************************/
- X
- Xint process_local_file_hdr() /* return PK-type error code */
- X{
- X local_byte_hdr byterec;
- X
- X
- X/*---------------------------------------------------------------------------
- X Read the next local file header and do any necessary machine-type con-
- X versions (byte ordering, structure padding compensation--do so by copy-
- X ing the data from the array into which it was read (byterec) to the
- X usable struct (lrec)).
- X ---------------------------------------------------------------------------*/
- X
- X if (readbuf((char *) byterec, LREC_SIZE) <= 0)
- X return (51); /* 51: unexpected EOF */
- X
- X lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
- X lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
- X
- X lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
- X lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
- X lrec.last_mod_file_time = makeword(&byterec[L_LAST_MOD_FILE_TIME]);
- X lrec.last_mod_file_date = makeword(&byterec[L_LAST_MOD_FILE_DATE]);
- X lrec.crc32 = makelong(&byterec[L_CRC32]);
- X lrec.compressed_size = makelong(&byterec[L_COMPRESSED_SIZE]);
- X lrec.uncompressed_size = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
- X lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
- X lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
- X
- X csize = (longint) lrec.compressed_size;
- X ucsize = (longint) lrec.uncompressed_size;
- X
- X return (0); /* 0: no error */
- X
- X} /* end function process_local_file_hdr() */
- END_OF_FILE
- if test 46692 -ne `wc -c <'unzip.c'`; then
- echo shar: \"'unzip.c'\" unpacked with wrong size!
- fi
- # end of 'unzip.c'
- fi
- echo shar: End of archive 3 \(of 12\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-