📄 zip.c
字号:
/* Copyright (c) 1990-2006 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2005-Feb-10 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//* * zip.c by Mark Adler. */#define __ZIP_C#include "zip.h"#include <time.h> /* for tzset() declaration */#ifdef WINDLL# include <windows.h># include <setjmp.h># include "windll/windll.h"#endif#define DEFCPYRT /* main module: enable copyright string defines! */#include "revision.h"#include "crypt.h"#include "ttyio.h"#ifdef VMS# include <stsdef.h># include "vms/vmsmunch.h"#endif#ifdef MACOS# include "macglob.h" extern MacZipGlobals MacZip; extern int error_level;#endif#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)# include <process.h># if (!defined(P_WAIT) && defined(_P_WAIT))# define P_WAIT _P_WAIT# endif#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 */#if defined(AMIGA) || defined(MACOS)local int filenotes = 0; /* 1=take comments from AmigaDOS/MACOS 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#ifdef WINDLLjmp_buf zipdll_error_return;#endif/* Temporary zip file name and file pointer */#ifndef MACOSlocal char *tempzip;local FILE *tempzf;#elsechar *tempzip;FILE *tempzf;#endif#if CRYPT/* Pointer to crc_table, needed in crypt.c */# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))ZCONST ulg near *crc_32_tab;# elseZCONST uLongf *crc_32_tab;# endif#endif /* CRYPT *//* Local functions */local void freeup OF((void));local int finish OF((int));#if (!defined(MACOS) && !defined(WINDLL))local void handler OF((int));local void license OF((void));#ifndef VMSCLIlocal void help OF((void));#endif /* !VMSCLI */#endif /* !MACOS && !WINDLL */local int get_filters OF((int argc, char **argv));#if (!defined(MACOS) && !defined(WINDLL))local void check_zipfile OF((char *zipname, char *zippath));local void version_info OF((void));local void zipstdout OF((void));#endif /* !MACOS && !WINDLL */local void freeup()/* Free all allocations in the 'found' list, the 'zfiles' list and the 'patterns' 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--; } if (patterns != NULL) { while (pcount-- > 0) { if (patterns[pcount].zname != NULL) free((zvoid *)(patterns[pcount].zname)); } free((zvoid *)patterns); patterns = NULL; }}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->iname[z->nam-1] != (char)0x2f) /* ascii '/' */ { 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->iname[z->nam-1] != (char)0x2f /* ascii '/' */ && 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 */ZCONST char *h; /* message about how it happened *//* Issue a message for the error, clean up files and memory, and exit. */{#ifndef WINDLL#ifndef MACOS static int error_level = 0;#endif if (error_level++ > 0) /* avoid recursive ziperr() printouts (his should never happen) */ EXIT(ZE_LOGIC); /* ziperr recursion is an internal logic error! */#endif /* !WINDLL */ if (h != NULL) { if (PERR(c)) perror("zip I/O error"); fflush(mesg); fprintf(stderr, "\nzip error: %s (%s)\n", ziperrors[c-1], h);#ifdef DOS check_for_windows("Zip");#endif } 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); fclose(tempzf); tempzf = NULL; } } 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 longjmp(zipdll_error_return, c);#endif}void error(h) ZCONST char *h;/* Internal error, should never happen */{ ziperr(ZE_LOGIC, h);}#if (!defined(MACOS) && !defined(WINDLL))local 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 /* !MACOS && !WINDLL */void zipwarn(a, b)ZCONST 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); fflush(stderr); }}#ifndef WINDLLlocal void license()/* Print license information to stdout. */{ extent i; /* counter for copyright array */#if 0 for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { printf(copyright[i], "zip"); putchar('\n'); }#endif for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++) puts(swlicense[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#ifdef MACOS"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]"," The default action is to add or replace zipfile entries from list."," "," -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"," -o make zipfile as old as latest entry"," -F fix zipfile (-FF try harder) -D do not add directory entries"," -T test zipfile integrity -X eXclude eXtra file attributes",# if CRYPT" -e encrypt -n don't compress these suffixes"# else" -h show this help -n don't compress these suffixes"# endif," "," Macintosh specific:"," -jj record Fullpath (+ Volname) -N store finder-comments as comments"," -df zip only datafork of a file -S include finder invisible/system files"#else /* !MACOS */#ifdef VM_CMS"zip [-options] [-b fm] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",#else /* !VM_CMS */"zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]",#endif /* ?VM_CMS */" 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",#ifdef THEOS" -0 store only -l convert CR to CR LF (-ll CR LF to CR)",#else" -0 store only -l convert LF to CR LF (-ll CR LF to LF)",#endif" -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 TANDEM" -Bn set Enscribe formatting options",#endif#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 (\"-VV\" also save allocated blocks past EOF)",#else /* !VMS */" -F fix zipfile (-FF try harder) -D do not add directory entries",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -