⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zip.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  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 + -