📄 zip.c
字号:
/* Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. Permission is granted to any individual or institution to use, copy, or redistribute this software so long as all of the original files are included, that it is not sold for profit, and that this copyright notice is retained.*//* * zip.c by Mark Adler. */#include "zip.h"#ifdef WINDLL#include <windows.h>#include "windll/windll.h"#endif#include "revision.h"#include "crypt.h"#include "ttyio.h"#ifdef VMS# include "vms/vmsmunch.h"#endif#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k)# include <process.h>#endif#include <signal.h>#define MAXCOM 256 /* Maximum one-line comment size *//* Local option flags */#ifndef DELETE#define DELETE 0#endif#define ADD 1#define UPDATE 2#define FRESHEN 3local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */local int comadd = 0; /* 1=add comments for new files */local int zipedit = 0; /* 1=edit zip comment and all file comments */local int latest = 0; /* 1=set zip file time to time of latest file */local ulg before = 0; /* 0=ignore, else exclude files before this time */local ulg after = 0; /* 0=ignore, else exclude files newer than this time */local int test = 0; /* 1=test zip file with unzip -t */local int tempdir = 0; /* 1=use temp directory (-b) */local int junk_sfx = 0; /* 1=junk the sfx prefix */#ifdef AMIGAlocal int filenotes = 0; /* 1=take comments from AmigaDOS filenotes */#endif#ifdef EBCDICint aflag = __EBCDIC; /* Convert EBCDIC to ASCII or stay EBCDIC ? */#endif#ifdef CMS_MVSint bflag = 0; /* Use text mode as default */#endif#ifdef QDOSchar _version[] = VERSION;#endif/* Temporary zip file name and file pointer */local char *tempzip;local FILE *tempzf;#if CRYPT/* Pointer to crc_table, needed in crypt.c */ulg near *crc_32_tab;#endif/* Local functions */local void freeup OF((void));local int finish OF((int));#ifndef WINDLLlocal void handler OF((int));local void license OF((void));#ifndef VMSCLIlocal void help OF((void));#endif /* !VMSCLI */#endif /* !WINDLL */local int get_filters OF((int argc, char **argv));#ifndef WINDLLlocal void check_zipfile OF((char *zipname, char *zippath));local void version_info OF((void));local void zipstdout OF((void));#endiflocal void freeup()/* Free all allocations in the found list and the zfiles list */{ struct flist far *f; /* steps through found list */ struct zlist far *z; /* pointer to next entry in zfiles list */ for (f = found; f != NULL; f = fexpel(f)) ; while (zfiles != NULL) { z = zfiles->nxt; if (zfiles->zname && zfiles->zname != zfiles->name) free((zvoid *)(zfiles->zname)); if (zfiles->name) free((zvoid *)(zfiles->name)); if (zfiles->iname) free((zvoid *)(zfiles->iname)); if (zfiles->cext && zfiles->cextra && zfiles->cextra != zfiles->extra) free((zvoid *)(zfiles->cextra)); if (zfiles->ext && zfiles->extra) free((zvoid *)(zfiles->extra)); if (zfiles->com && zfiles->comment) free((zvoid *)(zfiles->comment)); farfree((zvoid far *)zfiles); zfiles = z; zcount--; }}local int finish(e)int e; /* exit code *//* Process -o and -m options (if specified), free up malloc'ed stuff, and exit with the code e. */{ int r; /* return value from trash() */ ulg t; /* latest time in zip file */ struct zlist far *z; /* pointer into zfile list */ /* If latest, set time to zip file to latest file in zip file */ if (latest && zipfile && strcmp(zipfile, "-")) { diag("changing time of zip file to time of latest file in it"); /* find latest time in zip file */ if (zfiles == NULL) zipwarn("zip file is empty, can't make it as old as latest entry", ""); else { t = 0; for (z = zfiles; z != NULL; z = z->nxt) /* Ignore directories in time comparisons */#ifdef USE_EF_UT_TIME if (z->zname[z->nam-1] != '/') { iztimes z_utim; ulg z_tim; z_tim = ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ? unix2dostime(&z_utim.mtime) : z->tim); if (t < z_tim) t = z_tim; }#else /* !USE_EF_UT_TIME */ if (z->zname[z->nam-1] != '/' && t < z->tim) t = z->tim;#endif /* ?USE_EF_UT_TIME */ /* set modified time of zip file to that time */ if (t != 0) stamp(zipfile, t); else zipwarn( "zip file has only directories, can't make it as old as latest entry", ""); } } if (tempath != NULL) { free((zvoid *)tempath); tempath = NULL; } if (zipfile != NULL) { free((zvoid *)zipfile); zipfile = NULL; } if (zcomment != NULL) { free((zvoid *)zcomment); zcomment = NULL; } /* If dispose, delete all files in the zfiles list that are marked */ if (dispose) { diag("deleting files that were added to zip file"); if ((r = trash()) != ZE_OK) ZIPERR(r, "was deleting moved files and directories"); } /* Done! */ freeup(); return e;}void ziperr(c, h)int c; /* error code from the ZE_ class */char *h; /* message about how it happened *//* Issue a message for the error, clean up files and memory, and exit. */{#ifndef WINDLL static int error_level = 0; if (error_level++ > 0) EXIT(0); /* avoid recursive ziperr() */#endif if (h != NULL) { if (PERR(c)) perror("zip error"); fflush(mesg); fprintf(stderr, "\nzip error: %s (%s)\n", errors[c-1], h); } if (tempzip != NULL) { if (tempzip != zipfile) { if (tempzf != NULL) fclose(tempzf);#ifndef DEBUG destroy(tempzip);#endif free((zvoid *)tempzip); } else { /* -g option, attempt to restore the old file */ int k = 0; /* keep count for end header */ ulg cb = cenbeg; /* get start of central */ struct zlist far *z; /* steps through zfiles linked list */ fprintf(stderr, "attempting to restore %s to its previous state\n", zipfile); fseek(tempzf, cenbeg, SEEK_SET); tempzn = cenbeg; for (z = zfiles; z != NULL; z = z->nxt) { putcentral(z, tempzf); tempzn += 4 + CENHEAD + z->nam + z->cext + z->com; k++; } putend(k, tempzn - cb, cb, zcomlen, zcomment, tempzf); tempzf = NULL; fclose(tempzf); } } if (key != NULL) { free((zvoid *)key); key = NULL; } if (tempath != NULL) { free((zvoid *)tempath); tempath = NULL; } if (zipfile != NULL) { free((zvoid *)zipfile); zipfile = NULL; } if (zcomment != NULL) { free((zvoid *)zcomment); zcomment = NULL; } freeup();#ifndef WINDLL EXIT(c);#else return;#endif}void error(h) char *h;/* Internal error, should never happen */{ ziperr(ZE_LOGIC, h);}#ifndef WINDLLlocal void handler(s)int s; /* signal number (ignored) *//* Upon getting a user interrupt, turn echo back on for tty and abort cleanly using ziperr(). */{#if defined(AMIGA) && defined(__SASC) _abort();#else#if !defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS) echon(); putc('\n', stderr);#endif /* !MSDOS */#endif /* AMIGA && __SASC */ ziperr(ZE_ABORT, "aborting"); s++; /* keep some compilers happy */}#endif /* !WINDLL */void zipwarn(a, b)char *a, *b; /* message strings juxtaposed in output *//* Print a warning message to stderr and return. */{ if (noisy) fprintf(stderr, "\tzip warning: %s%s\n", a, b);}#ifndef WINDLLlocal void license()/* Print license information to stdout. */{ extent i; /* counter for copyright array */ for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { printf(copyright[i], "zip"); putchar('\n'); } for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++) puts(disclaimer[i]);}#ifdef VMSCLIvoid help()#elselocal void help()#endif/* Print help (along with license info) to stdout. */{ extent i; /* counter for help array */ /* help array */ static ZCONST char *text[] = {#ifdef VMS"Zip %s (%s). Usage: zip==\"$disk:[dir]zip.exe\"",#else"Zip %s (%s). Usage:",#endif"zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]"," The default action is to add or replace zipfile entries from list, which"," can include the special name - to compress standard input."," If zipfile and list are omitted, zip compresses stdin to stdout."," -f freshen: only changed files -u update: only changed or new files"," -d delete entries in zipfile -m move into zipfile (delete files)"," -R recurse into directories -j junk (don't record) directory names"," -0 store only -l convert LF to CR LF (-ll CR LF to LF)"," -1 compress faster -9 compress better"," -q quiet operation -v verbose operation/print version info"," -c add one-line comments -z add zipfile comment"," -@ read names from stdin -o make zipfile as old as latest entry"," -x exclude the following names -i include only the following names",#ifdef EBCDIC#ifdef CMS_MVS" -a translate to ASCII -B force binary read (text is default)",#else /* !CMS_MVS */" -a translate to ASCII",#endif /* ?CMS_MVS */#endif /* EBCDIC */#ifdef VMS" \"-F\" fix zipfile(\"-FF\" try harder) \"-D\" do not add directory entries"," \"-A\" adjust self-extracting exe \"-J\" junk zipfile prefix (unzipsfx)"," \"-T\" test zipfile integrity \"-X\" eXclude eXtra file attributes"," \"-V\" save VMS file attributes -w append version number to stored name",#else" -F fix zipfile (-FF try harder) -D do not add directory entries"," -A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)"," -T test zipfile integrity -X eXclude eXtra file attributes",#endif /* VMS */#ifdef WIN32" -! use privileges (if granted) to obtain all aspects of WinNT security",#endif /* WIN32 */#ifdef OS2" -E use the .LONGNAME Extended attribute (if found) as filename",#endif /* OS2 */#ifdef S_IFLNK" -y store symbolic links as the link instead of the referenced file",#endif /* !S_IFLNK */#if defined(MSDOS) || defined(OS2)" -$ include volume label -S include system and hidden files",#endif#ifdef AMIGA# if CRYPT" -N store filenotes as comments -e encrypt"," -h show this help -n don't compress these suffixes"# else" -N store filenotes as comments -n don't compress these suffixes"# endif#else /* !AMIGA */# if CRYPT" -e encrypt -n don't compress these suffixes"# else" -h show this help -n don't compress these suffixes"# endif#endif /* ?AMIGA */#ifdef RISCOS," -I don't scan through Image files"#endif }; for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { printf(copyright[i], "zip"); putchar('\n'); } for (i = 0; i < sizeof(text)/sizeof(char *); i++) { printf(text[i], VERSION, REVDATE); putchar('\n'); }}/* * XXX version_info() in a separate file */local void version_info()/* Print verbose info about program version and compile time options to stdout. */{ extent i; /* counter in text arrays */ char *envptr; /* Options info array */ static ZCONST char *comp_opts[] = {#ifdef ASM_CRC "ASM_CRC",#endif#ifdef ASMV "ASMV",#endif#ifdef DYN_ALLOC "DYN_ALLOC",#endif#ifdef MMAP "MMAP",#endif#ifdef BIG_MEM "BIG_MEM",#endif#ifdef MEDIUM_MEM "MEDIUM_MEM",#endif#ifdef SMALL_MEM "SMALL_MEM",#endif#ifdef DEBUG "DEBUG",#endif#ifdef USE_EF_UT_TIME "USE_EF_UT_TIME",#endif#ifdef NTSD_EAS "NTSD_EAS",#endif#ifdef VMS#ifdef VMSCLI "VMSCLI",#endif#ifdef VMS_IM_EXTRA "VMS_IM_EXTRA",#endif#ifdef VMS_PK_EXTRA "VMS_PK_EXTRA",#endif#endif /* VMS */#if CRYPT && defined(PASSWD_FROM_STDIN) "PASSWD_FROM_STDIN",#endif /* CRYPT & PASSWD_FROM_STDIN */ NULL }; static ZCONST char *zipenv_names[] = {#ifndef VMS# ifndef RISCOS "ZIP"# else /* RISCOS */ "Zip$Options"# endif /* ?RISCOS */#else /* VMS */ "ZIP_OPTS"#endif /* ?VMS */ ,"ZIPOPT"#ifdef AZTEC_C , /* extremely lame compiler bug workaround */#endif#if (defined(__EMX__) && !defined(__RSXNT__)) ,"EMX" ,"EMXOPT"#endif#ifdef __GO32__ ,"GO32" ,"GO32TMP"#endif#ifdef RISCOS ,"Zip$Exts"#endif }; for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { printf(copyright[i], "zip"); putchar('\n'); } for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++) { printf(versinfolines[i], "Zip", VERSION, REVDATE); putchar('\n'); } version_local(); puts("Zip special compilation options:");#if WSIZE != 0x8000 printf("\tWSIZE=%u\n", WSIZE);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -