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

📄 zip.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (action == DELETE) {        /* only delete files in date range */#ifdef USE_EF_UT_TIME        z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?                unix2dostime(&z_utim.mtime) : z->tim;#else /* !USE_EF_UT_TIME */#       define z_tim  z->tim#endif /* ?USE_EF_UT_TIME */        if (z_tim < before || (after && z_tim >= after)) {          /* include in archive */          z->mark = 0;        } else {          /* delete file */          k++;        }      } else if (#ifdef USE_EF_UT_TIME          ((t = filetime(z->name, (ulg *)NULL, (long *)NULL, &f_utim))#else /* !USE_EF_UT_TIME */          ((t = filetime(z->name, (ulg *)NULL, (long *)NULL, (iztimes *)NULL))#endif /* ?USE_EF_UT_TIME */              == 0 ||           t < before || (after && t >= after) ||           ((action == UPDATE || action == FRESHEN) &&#ifdef USE_EF_UT_TIME            ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?             f_utim.mtime <= ROUNDED_TIME(z_utim.mtime) : t <= z->tim)#else /* !USE_EF_UT_TIME */            t <= z->tim#endif /* ?USE_EF_UT_TIME */           )))      {        z->mark = comadd ? 2 : 0;        z->trash = t && t >= before &&                   (after == 0 || t < after);   /* delete if -um or -fm */        if (verbose) {          fprintf(mesg, "zip diagnostic: %s %s\n", z->zname,                 z->trash ? "up to date" : "missing or early");        }      }      else        k++;    }  /* Remove entries from found list that do not exist or are too old */  diag("stating new entries");  Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));  for (f = found; f != NULL;) {    Trace((stderr, "zip diagnostic: new file=%s\n", f->zname));    if (action == DELETE || action == FRESHEN ||        (t = filetime(f->name, (ulg *)NULL, (long *)NULL, (iztimes *)NULL))           == 0 ||        t < before || (after && t >= after) ||        (namecmp(f->zname, zipfile) == 0 && strcmp(zipfile, "-")))      f = fexpel(f);    else      f = f->nxt;  }#ifdef MACOS  PrintStatProgress("done");#endif  /* Make sure there's something left to do */  if (k == 0 && found == NULL &&      !(zfiles != NULL &&        (latest || fix || adjust || junk_sfx || comadd || zipedit))) {    if (test && (zfiles != NULL || zipbeg != 0)) {#ifndef WINDLL      check_zipfile(zipfile, argv[0]);#endif      RETURN(finish(ZE_OK));    }    if (action == UPDATE || action == FRESHEN) {      RETURN(finish(ZE_NONE));    }    else if (zfiles == NULL && (latest || fix || adjust || junk_sfx)) {      ZIPERR(ZE_NAME, zipfile);    }#ifndef WINDLL    else if (recurse && (pcount == 0) && (first_listarg > 0)) {#ifdef VMS      strcpy(errbuf, "try: zip \"");      for (i = 1; i < (first_listarg - 1); i++)        strcat(strcat(errbuf, argv[i]), "\" ");      strcat(strcat(errbuf, argv[i]), " *.* -i");#else /* !VMS */      strcpy(errbuf, "try: zip");      for (i = 1; i < first_listarg; i++)        strcat(strcat(errbuf, " "), argv[i]);#  ifdef AMIGA      strcat(errbuf, " \"\" -i");#  else      strcat(errbuf, " . -i");#  endif#endif /* ?VMS */      for (i = first_listarg; i < argc; i++)        strcat(strcat(errbuf, " "), argv[i]);      ZIPERR(ZE_NONE, errbuf);    }#endif /* !WINDLL */    else {      ZIPERR(ZE_NONE, zipfile);    }  }  d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */#if CRYPT  /* Initialize the crc_32_tab pointer, when encryption was requested. */  if (key != NULL) {    crc_32_tab = get_crc_table();#ifdef EBCDIC    /* convert encryption key to ASCII (ISO variant for 8-bit ASCII chars) */    strtoasc(key, key);#endif /* EBCDIC */  }#endif /* CRYPT */  /* Before we get carried away, make sure zip file is writeable. This   * has the undesired side effect of leaving one empty junk file on a WORM,   * so when the zipfile does not exist already and when -b is specified,   * the writability check is made in replace().   */  if (strcmp(zipfile, "-"))  {    if (tempdir && zfiles == NULL && zipbeg == 0) {      a = 0;    } else {      x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) :                                          fopen(zipfile, FOPM);      /* Note: FOPW and FOPM expand to several parameters for VMS */      if (x == NULL) {        ZIPERR(ZE_CREAT, zipfile);      }      fclose(x);      a = getfileattr(zipfile);      if (zfiles == NULL && zipbeg == 0)        destroy(zipfile);    }  }  else    a = 0;  /* Throw away the garbage in front of the zip file for -J */  if (junk_sfx) zipbeg = 0;  /* Open zip file and temporary output file */  diag("opening zip file and creating temporary zip file");  x = NULL;  tempzn = 0;  if (strcmp(zipfile, "-") == 0)  {#ifdef MSDOS    /* It is nonsense to emit the binary data stream of a zipfile to     * the (text mode) console.  This case should already have been caught     * in a call to zipstdout() far above.  Therefore, if the following     * failsafe check detects a console attached to stdout, zip is stopped     * with an "internal logic error"!  */    if (isatty(fileno(stdout)))      ZIPERR(ZE_LOGIC, "tried to write binary zipfile data to console!");    /* Set stdout mode to binary for MSDOS systems */#  ifdef __HIGHC__    setmode(stdout, _BINARY);#  else    setmode(fileno(stdout), O_BINARY);#  endif    tempzf = y = fdopen(fileno(stdout), FOPW);#else    tempzf = y = stdout;#endif    /* tempzip must be malloced so a later free won't barf */    tempzip = malloc(4);    if (tempzip == NULL) {      ZIPERR(ZE_MEM, "allocating temp filename");    }    strcpy(tempzip, "-");  }  else if (d) /* d true if just appending (-g) */  {    if ((y = fopen(zipfile, FOPM)) == NULL) {      ZIPERR(ZE_NAME, zipfile);    }    tempzip = zipfile;    tempzf = y;    if (fseek(y, cenbeg, SEEK_SET)) {      ZIPERR(ferror(y) ? ZE_READ : ZE_EOF, zipfile);    }    tempzn = cenbeg;  }  else  {    if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL) {      ZIPERR(ZE_NAME, zipfile);    }    if ((tempzip = tempname(zipfile)) == NULL) {      ZIPERR(ZE_MEM, "allocating temp filename");    }    if ((tempzf = y = fopen(tempzip, FOPW_TMP)) == NULL) {      ZIPERR(ZE_TEMP, tempzip);    }  }#if (!defined(VMS) && !defined(CMS_MVS))  /* Use large buffer to speed up stdio: */#if (defined(_IOFBF) || !defined(BUFSIZ))  zipbuf = (char *)malloc(ZBSZ);#else  zipbuf = (char *)malloc(BUFSIZ);#endif  if (zipbuf == NULL) {    ZIPERR(ZE_MEM, tempzip);  }# ifdef _IOFBF  setvbuf(y, zipbuf, _IOFBF, ZBSZ);# else  setbuf(y, zipbuf);# endif /* _IOBUF */#endif /* !VMS  && !CMS_MVS */  if (strcmp(zipfile, "-") != 0 && !d)  /* this must go *after* set[v]buf */  {    if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK) {      ZIPERR(r, r == ZE_TEMP ? tempzip : zipfile);    }    tempzn = zipbeg;  }  o = 0;                                /* no ZE_OPEN errors yet */  /* Process zip file, updating marked files */#ifdef DEBUG  if (zfiles != NULL)    diag("going through old zip file");#endif  w = &zfiles;  while ((z = *w) != NULL) {    if (z->mark == 1)    {      /* if not deleting, zip it up */      if (action != DELETE)      {        if (noisy)        {          if (action == FRESHEN)             fprintf(mesg, "freshening: %s", z->zname);          else             fprintf(mesg, "updating: %s", z->zname);          fflush(mesg);        }        if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)        {          if (noisy)          {#if (!defined(MACOS) && !defined(WINDLL))            putc('\n', mesg);            fflush(mesg);#else            fprintf(stdout, "\n");#endif          }          sprintf(errbuf, "was zipping %s", z->name);          ZIPERR(r, errbuf);        }        if (r == ZE_OPEN || r == ZE_MISS)        {          o = 1;          if (noisy)          {#if (!defined(MACOS) && !defined(WINDLL))            putc('\n', mesg);            fflush(mesg);#else            fprintf(stdout, "\n");#endif          }          if (r == ZE_OPEN) {            if (bad_open_is_error) {              sprintf(errbuf, "was zipping %s", z->name);              ZIPERR(r, errbuf);            } else {              perror(z->zname);              zipwarn("could not open for reading: ", z->zname);            }          } else {            zipwarn("file and directory with the same name: ", z->zname);          }          zipwarn("will just copy entry over: ", z->zname);          if ((r = zipcopy(z, x, y)) != ZE_OK)          {            sprintf(errbuf, "was copying %s", z->zname);            ZIPERR(r, errbuf);          }          z->mark = 0;        }        w = &z->nxt;      }      else      {        if (noisy)        {          fprintf(mesg, "deleting: %s\n", z->zname);          fflush(mesg);        }#ifdef WINDLL        if (lpZipUserFunctions->ServiceApplication != NULL) {          if ((*lpZipUserFunctions->ServiceApplication)(z->zname, 0))            ZIPERR(ZE_ABORT, "User terminated operation");        }#endif        v = z->nxt;                     /* delete entry from list */        free((zvoid *)(z->iname));        free((zvoid *)(z->zname));        if (z->ext)          free((zvoid *)(z->extra));        if (z->cext && z->cextra != z->extra)          free((zvoid *)(z->cextra));        if (z->com)          free((zvoid *)(z->comment));        farfree((zvoid far *)z);        *w = v;        zcount--;      }    }    else    {      /* copy the original entry verbatim */      if (!d && (r = zipcopy(z, x, y)) != ZE_OK)      {        sprintf(errbuf, "was copying %s", z->zname);        ZIPERR(r, errbuf);      }      w = &z->nxt;    }  }  /* Process the edited found list, adding them to the zip file */  diag("zipping up new entries, if any");  Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));  for (f = found; f != NULL; f = fexpel(f))  {    /* add a new zfiles entry and set the name */    if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {      ZIPERR(ZE_MEM, "was adding files to zip file");    }    z->nxt = NULL;    z->name = f->name;    f->name = NULL;    z->iname = f->iname;    f->iname = NULL;    z->zname = f->zname;    f->zname = NULL;    z->ext = z->cext = z->com = 0;    z->extra = z->cextra = NULL;    z->mark = 1;    z->dosflag = f->dosflag;    /* zip it up */    if (noisy)    {      fprintf(mesg, "  adding: %s", z->zname);      fflush(mesg);    }    if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN && r != ZE_MISS)    {      if (noisy)      {#if (!defined(MACOS) && !defined(WINDLL))        putc('\n', mesg);        fflush(mesg);#else        fprintf(stdout, "\n");#endif      }      sprintf(errbuf, "was zipping %s", z->zname);      ZIPERR(r, errbuf);    }    if (r == ZE_OPEN || r == ZE_MISS)    {      o = 1;      if (noisy)      {#if (!defined(MACOS) && !defined(WINDLL))        putc('\n', mesg);        fflush(mesg);#else        fprintf(stdout, "\n");#endif      }      if (r == ZE_OPEN) {        if (bad_open_is_error) {          sprintf(errbuf, "was zipping %s", z->name);          ZIPERR(r, errbuf);        } else {          perror("zip warning");          zipwarn("could not open for reading: ", z->zname);        }      } else {        zipwarn("file and directory with the same name: ", z->zname);      }      free((zvoid *)(z->name));      free((zvoid *)(z->iname));      free((zvoid *)(z->zname));      farfree((zvoid far *)z);    }    else    {      *w = z;      w = &z->nxt;      zcount++;    }  }  if (key != NULL)  {    free((zvoid *)key);    key = NULL;  }  /* Get one line comment for each new entry */#if defined(AMIGA) || defined(MACOS)  if (comadd || filenotes)  {    if (comadd)#else  if (comadd)  {#endif    {      if (comment_stream == NULL) {#ifndef RISCOS        comment_stream = (FILE*)fdopen(fileno(stderr), "r");#else        comment_stream = stderr;#endif      }      if ((e = malloc(MAXCOM + 1)) == NULL) {        ZIPERR(ZE_MEM, "was reading comment lines");    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -