📄 unzip.c
字号:
/*---------------------------------------------------------------------------
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.
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 -> ... 1994
---------------------------------------------------------------------------
Version: unzip512.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Windows,
Windows NT, Macintosh, Amiga, Atari, Human68K and TOPS-20. De-
cryption requires sources in zcrypt23.zip, and Windows (not NT)
support requires sources in wunz20sr.zip (not up to date). 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, prototypes, etc. */
#include "crypt.h"
#include "version.h"
#ifdef MSWIN
# include "wizunzip.h"
#endif
/**********************/
/* Global Variables */
/**********************/
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 C_flag=0; /* -C: match filenames case-insensitively */
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 L_flag=0; /* -L: convert filenames from some OSes to lowercase */
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 T_flag=0; /* -T: decimal time format (zipinfo) */
int uflag=0; /* -u: "update" (extract only newer & brand-new files) */
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;
#if (defined(CRYPT) || !defined(NO_ZIPINFO))
int newzip; /* used in extract.c, crypt.c, zipinfo.c */
#endif
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;
#ifdef SFX
char *argv0; /* used for NT and EXE_EXTENSION */
#else
char *wildzipfn;
#endif
char *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 = (uch *)NULL; /* malloc'd ONLY if unshrink and -a */
#endif
#ifdef MSWIN
char *filename;
#else
char near filename[FILNAMSIZ]; /* also used by NT for temporary SFX path */
#endif
/********************/
/* Global strings */
/********************/
char Far UnzipVersion[] = UZ_VERSION; /* now defined in version.h */
#ifndef NO_ZIPINFO
char Far ZipinfoVersion[] = ZI_VERSION;
#endif
char Far EndSigMsg[] = "\nnote:\
didn't find end-of-central-dir signature at end of central dir.\n";
char Far CentSigMsg[] =
"error: expected central file header signature not found (file #%u).\n";
char Far SeekMsg[] =
"error [%s]: attempt to seek before beginning of zipfile\n%s";
char Far FilenameNotMatched[] = "caution: filename not matched: %s\n";
char Far ExclFilenameNotMatched[] =
"caution: excluded filename not matched: %s\n";
#ifndef SFX
char Far CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
#endif
#ifdef VMS
char Far 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 Far 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
/*******************/
/* Local strings */
/*******************/
#ifndef SFX
static char Far EnvUnZip[] = ENV_UNZIP;
static char Far EnvUnZip2[] = ENV_UNZIP2;
static char Far EnvZipInfo[] = ENV_ZIPINFO;
static char Far EnvZipInfo2[] = ENV_ZIPINFO2;
#endif
#if (!defined(SFX) || defined(SFX_EXDIR))
static char Far NotExtracting[] = "caution: not extracting; -d ignored\n";
static char Far MustGiveExdir[] =
"error: must specify directory to which to extract with -d option\n";
#endif
static char Far CentDirTooLong[] =
"error [%s]: reported length of central directory is\n\
%d bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1\n\
zipfile?). Compensating...\n";
static char Far InvalidOptionsMsg[] = "error:\
-fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
static char Far IgnoreOOptionMsg[] =
"caution: both -n and -o specified; ignoring -o\n";
static char Far CantAllocateBuffers[] =
"error: can't allocate unzip buffers\n";
/* usage() strings */
#ifndef VMSCLI
#ifndef SFX
#ifdef VMS
static char Far Example2[] = "vms.c";
static char Far Example1[] =
"unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS";
#else
static char Far Example2[] = "ReadMe";
static char Far Example1[] =
"unzip -p foo | more => send contents of foo.zip via pipe into program more";
#endif /* ?VMS */
#ifdef DOS_NT_OS2
static char Far loc_str[] = " -$ label removables (-$$ => fixed disks)";
static char Far loc2str[] = "\
-s spaces in filenames => '_'\n";
#else /* !DOS_NT_OS2 */
#ifdef VMS
static char Far loc_str[] = "\"-X\" restore owner/protection info";
static char Far loc2str[] = "\n";
#else
static char Far loc_str[] = ""; /* Unix, Amiga, Mac, etc. */
/* char Far loc_str[] = " -X restore UID/GID info"; Unix version, in 5.2 */
static char Far loc2str[] = "";
#endif /* ?VMS */
#endif /* ?DOS_NT_OS2 */
#endif /* !SFX */
#ifndef NO_ZIPINFO
#ifdef VMSWILD
static char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
#else
static char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
#endif
static char Far ZipInfoUsageLine1[] = "\
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 %s.\n\n\
usage: zipinfo [-12smlvhtTz] file[.zip] [list...] [-x xlist...]\n\
or: unzip %s-Z%s [-12smlvhtTz] file[.zip] [list...] [-x xlist...]\n";
static char Far ZipInfoUsageLine2[] = "\nmain\
listing-format options: -s short Unix \"ls -l\" format (def.)\n\
-1 filenames ONLY, one per line -m medium Unix \"ls -l\" format\n\
-2 just filenames but allow -h/-t/-z -l long Unix \"ls -l\" format\n\
-v verbose, multi-page format\n";
static char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
-h print header line -t print totals for listed files or for all\n\
-z print zipfile comment %c-T%c print file times in sortable decimal format\
\n -x exclude filenames that follow from listing\n";
/*" -p disable automatic \"more\" function (for pipes) [not implemented]\n";*/
#endif /* !NO_ZIPINFO */
#endif /* !VMSCLI */
#ifdef BETA
static char Far BetaVersion[] = "%s\
THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
#endif
#ifdef SFX
# if (defined(SFX_EXDIR) && !defined(VMS))
static char Far UnzipSFXUsage[] = "\
UnZipSFX %s, by Info-ZIP (zip-bugs@wkuvx1.wku.edu).\n\
Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCLV%s.\n";
# else
static char Far UnzipSFXUsage[] = "\
UnZipSFX %s, by Info-ZIP (zip-bugs@wkuvx1.wku.edu).\n\
Valid options are -tfupcz; modifiers are -abjnoqCLV%s.\n";
# endif
static char Far CantFindMyself[] =
"unzipsfx: can't find myself! [%s]\n";
#else /* !SFX */
static char Far CompileOptions[] = "UnZip special compilation options:\n";
static char Far CompileOptFormat[] = "\t%s\n";
static char Far EnvOptions[] = "\nUnZip and ZipInfo environment options:\n";
static char Far EnvOptFormat[] = "%16s: %s\n";
static char Far None[] = "[none]";
# ifdef NO_ZIPINFO
static char Far No_ZipInfo[] = "NO_ZIPINFO";
# endif
# ifdef CHECK_EOF
static char Far Check_EOF[] = "CHECK_EOF";
# endif
# ifdef DOSWILD
static char Far DosWild[] = "DOSWILD";
# endif
# ifdef VMSWILD
static char Far VmsWild[] = "VMSWILD";
# endif
# ifdef VMSCLI
static char Far VmsCLI[] = "VMSCLI";
# endif
# ifdef ASM_INFLATECODES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -