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

📄 zipfile.c

📁 汇编源代码大全
💻 C
📖 第 1 页 / 共 2 页
字号:
          return ferror(f) ? ZE_READ : ZE_EOF;      }    }    /* Point to start of header list and read central headers */    z = zfiles;    s = p;                              /* save start of central */    if (fix) {      if (LG(b) != CENSIG && noisy) {        fprintf(mesg, "zip warning: %s %s truncated.\n", zipfile,                fix > 1 ? "has been" : "would be");        if (fix == 1) {          fprintf(mesg,   "Retry with option -qF to truncate, with -FF to attempt full recovery\n");          err(ZE_FORM, NULL);        }      }    } else while (LG(b) == CENSIG)    {      if (z == NULL)      {        warn("extraneous central header signature", "");        return ZE_FORM;      }      /* Read central header */      if (fread(b, CENHEAD, 1, f) != 1)        return ferror(f) ? ZE_READ : ZE_EOF;      /* Compare local header with that part of central header (except         for the reserved bits in the general purpose flags and except         for length of extra fields--authentication can make these         different in central and local headers) */      z->lflg = SH(LOCFLG + (uch far *)z);      /* Save reserved bits */      r = b[CENFLG+1];      ((uch far *)z)[LOCFLG+1] &= 0x1f; /* Zero out reserved bits */      b[CENFLG+1] &= 0x1f;      for (m = 0, u = (char far *)z, n = 0; n < LOCHEAD - 2; n++)        if (u[n] != b[n+2])        {          if (!m && noisy)            warn("local and central headers differ for ", z->zname);          m = 1;          sprintf(errbuf, " offset %d--local = %02x, central = %02x",                  n, (uch)u[n], (uch)b[n+2]);          if (noisy) warn(errbuf, "");          b[n+2] = u[n]; /* fix the zipfile */        }      if (m)        return ZE_FORM;      b[CENFLG+1] = r;                  /* Restore reserved bits */      /* Overwrite local header with translated central header */      z->vem = SH(CENVEM + b);      z->ver = SH(CENVER + b);      z->flg = SH(CENFLG + b);          /* may be different from z->lflg */      z->how = SH(CENHOW + b);      z->tim = LG(CENTIM + b);          /* time and date into one long */      z->crc = LG(CENCRC + b);      z->siz = LG(CENSIZ + b);      z->len = LG(CENLEN + b);      z->nam = SH(CENNAM + b);      z->cext = SH(CENEXT + b);         /* may be different from z->ext */      z->com = SH(CENCOM + b);      z->dsk = SH(CENDSK + b);      z->att = SH(CENATT + b);      z->atx = LG(CENATX + b);      z->dosflag = (z->vem & 0xff00) == 0;      if (z->off != LG(CENOFF + b))      {        warn("local offset in central header incorrect for ", z->zname);        return ZE_FORM;      }      /* Compare name and extra fields and read comment field */      if ((t = malloc(z->nam)) == NULL)        return ZE_MEM;      if (fread(t, z->nam, 1, f) != 1)      {        free((voidp *)t);        return ferror(f) ? ZE_READ : ZE_EOF;      }      if (memcmp(t, z->zname, z->nam))      {        free((voidp *)t);        warn("names in local and central differ for ", z->zname);        return ZE_FORM;      }      free((voidp *)t);      if (z->cext)      {        if ((z->cextra = malloc(z->cext)) == NULL)          return ZE_MEM;        if (fread(z->cextra, z->cext, 1, f) != 1)        {          free((voidp *)(z->cextra));          return ferror(f) ? ZE_READ : ZE_EOF;        }        if (z->ext == z->cext && memcmp(z->extra, z->cextra, z->ext) == 0)        {          free((voidp *)(z->cextra));          z->cextra = z->extra;        }      }      if (z->com)      {        if ((z->comment = malloc(z->com)) == NULL)          return ZE_MEM;        if (fread(z->comment, z->com, 1, f) != 1)        {          free((voidp *)(z->comment));          return ferror(f) ? ZE_READ : ZE_EOF;        }      }      /* Note oddities */      if (verbose)      {        if (z->vem != 10 && z->vem != 11 && z->vem != 20 &&            (n = z->vem >> 8) != 3 && n != 2 && n != 6 && n != 0)        {          sprintf(errbuf, "made by version %d.%d on system type %d: ",            (ush)(z->vem & 0xff) / (ush)10,            (ush)(z->vem & 0xff) % (ush)10, z->vem >> 8);          warn(errbuf, z->zname);        }        if (z->ver != 10 && z->ver != 11 && z->ver != 20)        {          sprintf(errbuf, "needs unzip %d.%d on system type %d: ",            (ush)(z->ver & 0xff) / (ush)10,            (ush)(z->ver & 0xff) % (ush)10, z->ver >> 8);          warn(errbuf, z->zname);        }        if (z->flg != z->lflg)        {          sprintf(errbuf, "local flags = 0x%04x, central = 0x%04x: ",                  z->lflg, z->flg);          warn(errbuf, z->zname);        }        else if (z->flg & ~0xf)        {          sprintf(errbuf, "undefined bits used in flags = 0x%04x: ", z->flg);          warn(errbuf, z->zname);        }        if (z->how > DEFLATE)        {          sprintf(errbuf, "unknown compression method %u: ", z->how);          warn(errbuf, z->zname);        }        if (z->dsk)        {          sprintf(errbuf, "starts on disk %u: ", z->dsk);          warn(errbuf, z->zname);        }        if (z->att & ~1)        {          sprintf(errbuf, "unknown internal attributes = 0x%04x: ", z->att);          warn(errbuf, z->zname);        }        if (((n = z->vem >> 8) != 3) && n != 2 && z->atx & ~0xffL)        {          sprintf(errbuf, "unknown external attributes = 0x%08lx: ", z->atx);          warn(errbuf, z->zname);        }        if (z->ext || z->cext)          if (z->ext == z->cext && z->extra == z->cextra)          {            sprintf(errbuf, "has %d bytes of extra data: ", z->ext);            warn(errbuf, z->zname);          }          else          {            sprintf(errbuf,                    "local extra (%d bytes) != central extra (%d bytes): ",                    z->ext, z->cext);            warn(errbuf, z->zname);          }      }      /* Clear actions */      z->mark = 0;      z->trash = 0;      /* Update file offset */      p += 4 + CENHEAD + z->nam + z->cext + z->com;      /* Advance to next header structure */      z = z->nxt;      /* Read next signature */      if (fread(b, 4, 1, f) != 1)        return ferror(f) ? ZE_READ : ZE_EOF;    }        /* Read end header */    if (!fix) {      if (z != NULL || LG(b) != ENDSIG)      {        warn("missing end signature--probably not a zip file (did you", "");        warn("remember to use binary mode when you transferred it?)", "");        return ZE_FORM;      }      if (fread(b, ENDHEAD, 1, f) != 1)        return ferror(f) ? ZE_READ : ZE_EOF;      if (SH(ENDDSK + b) || SH(ENDBEG + b) ||          SH(ENDSUB + b) != SH(ENDTOT + b))        warn("multiple disk information ignored", "");      if (zcount != SH(ENDSUB + b))      {        warn("count in end of central directory incorrect", "");        return ZE_FORM;      }      if (LG(ENDSIZ + b) != p - s)      {        warn("central directory size is incorrect (made by stzip?)", "");        /* stzip 0.9 gets this wrong, so be tolerant */        /* return ZE_FORM; */      }      if (LG(ENDOFF + b) != s)      {        warn("central directory start is incorrect", "");        return ZE_FORM;      }    }    cenbeg = s;    zcomlen = fix ? 0 : SH(ENDCOM + b);    if (zcomlen)    {      if ((zcomment = malloc(zcomlen)) == NULL)        return ZE_MEM;      if (fread(zcomment, zcomlen, 1, f) != 1)      {        free((voidp *)zcomment);        return ferror(f) ? ZE_READ : ZE_EOF;      }    }    if (zipbeg)    {      sprintf(errbuf, " has a preamble of %ld bytes", zipbeg);      warn(zipfile, errbuf);    }    if (!fix && getc(f) != EOF)      warn("garbage at end of zip file ignored", "");    /* Done with zip file for now */    fclose(f);        /* If one or more files, sort by name */    if (zcount)    {      if ((x = zsort =          (struct zlist far **)malloc(zcount * sizeof(struct zlist far *))) ==          NULL)        return ZE_MEM;      for (z = zfiles; z != NULL; z = z->nxt)        *x++ = z;      qsort((char *)zsort, zcount, sizeof(struct zlist far *), zqcmp);    }  }  return ZE_OK;}int putlocal(z, f)struct zlist far *z;    /* zip entry to write local header for */FILE *f;                /* file to write to *//* Write a local header described by *z to file *f.  Return an error code   in the ZE_ class. */{  PUTLG(LOCSIG, f);  PUTSH(z->ver, f);  PUTSH(z->lflg, f);  PUTSH(z->how, f);  PUTLG(z->tim, f);  PUTLG(z->crc, f);  PUTLG(z->siz, f);  PUTLG(z->len, f);  PUTSH(z->nam, f);  PUTSH(z->ext, f);  if (fwrite(z->zname, 1, z->nam, f) != z->nam ||      (z->ext && fwrite(z->extra, 1, z->ext, f) != z->ext))    return ZE_TEMP;  return ZE_OK;}int putextended(z, f)struct zlist far *z;    /* zip entry to write local header for */FILE *f;                /* file to write to *//* Write an extended local header described by *z to file *f. * Return an error code in the ZE_ class. */{  PUTLG(EXTLOCSIG, f);  PUTLG(z->crc, f);  PUTLG(z->siz, f);  PUTLG(z->len, f);  return ZE_OK;}int putcentral(z, f)struct zlist far *z;    /* zip entry to write central header for */FILE *f;                /* file to write to *//* Write a central header described by *z to file *f.  Return an error code   in the ZE_ class. */{  PUTLG(CENSIG, f);  PUTSH(z->vem, f);  PUTSH(z->ver, f);  PUTSH(z->flg, f);  PUTSH(z->how, f);  PUTLG(z->tim, f);  PUTLG(z->crc, f);  PUTLG(z->siz, f);  PUTLG(z->len, f);  PUTSH(z->nam, f);  PUTSH(z->cext, f);  PUTSH(z->com, f);  PUTSH(z->dsk, f);  PUTSH(z->att, f);  PUTLG(z->atx, f);  PUTLG(z->off, f);  if (fwrite(z->zname, 1, z->nam, f) != z->nam ||      (z->cext && fwrite(z->cextra, 1, z->cext, f) != z->cext) ||      (z->com && fwrite(z->comment, 1, z->com, f) != z->com))    return ZE_TEMP;  return ZE_OK;}int putend(n, s, c, m, z, f)int n;                  /* number of entries in central directory */ulg s;                  /* size of central directory */ulg c;                  /* offset of central directory */extent m;               /* length of zip file comment (0 if none) */char *z;                /* zip file comment if m != 0 */FILE *f;                /* file to write to *//* Write the end of central directory data to file *f.  Return an error code   in the ZE_ class. */{  PUTLG(ENDSIG, f);  PUTSH(0, f);  PUTSH(0, f);  PUTSH(n, f);  PUTSH(n, f);  PUTLG(s, f);  PUTLG(c, f);  PUTSH(m, f);  if (m && fwrite(z, 1, m, f) != m)    return ZE_TEMP;  return ZE_OK;}#ifndef UTILlocal void cutpath(p)char *p;                /* path string *//* Cut the last path component off the name *p in place. * This should work on both internal and external names. */{  char *r;              /* pointer to last path delimiter */#ifdef VMS                      /* change [w.x.y]z to [w.x]y.DIR */  if ((r = strrchr(p, ']')) != NULL)  {    *r = 0;    if ((r = strrchr(p, '.')) != NULL)    {      *r = ']';      strcat(r, ".DIR;1");     /* this assumes a little padding--see PAD */    } else {      *p = 0;    }  } else {    *p = 0;  }#endif /* ?VMS */  if ((r = strrchr(p, '/')) != NULL)    *r = 0;  else    *p = 0;}int trash()/* Delete the compressed files and the directories that contained the deleted   files, if empty.  Return an error code in the ZE_ class.  Failure of   destroy() or deletedir() is ignored. */{  extent i;             /* counter on deleted names */  extent n;             /* number of directories to delete */  struct zlist far **s; /* table of zip entries to handle, sorted */  struct zlist far *z;  /* current zip entry */  /* Delete marked names and count directories */  n = 0;  for (z = zfiles; z != NULL; z = z->nxt)    if (z->mark || z->trash)    {      z->mark = 1;      if (z->zname[z->nam - 1] != '/') { /* don't unlink directory */        if (verbose)          fprintf(mesg, "zip diagnostic: trashing file %s\n", z->name);        destroy(z->name);        /* Try to delete all paths that lead up to marked names. This is         * necessary only without the -D option.         */        if (!dirnames) {          cutpath(z->name);          cutpath(z->zname);          if (z->zname[0] != '\0') {            strcat(z->zname, "/");          }          z->nam = strlen(z->zname);          if (z->nam > 0) n++;        }      } else {        n++;      }    }  /* Construct the list of all marked directories. Some may be duplicated   * if -D was used.   */  if (n)  {    if ((s = (struct zlist far **)malloc(n*sizeof(struct zlist far *))) ==        NULL)      return ZE_MEM;    n = 0;    for (z = zfiles; z != NULL; z = z->nxt) {      if (z->mark && z->nam > 0 && z->zname[z->nam - 1] == '/'          && (n == 0 || strcmp(z->zname, s[n-1]->zname) != 0)) {        s[n++] = z;      }    }    /* Sort the files in reverse order to get subdirectories first.     * To avoid problems with strange naming conventions as in VMS,     * we sort on the internal names, so x/y/z will always be removed     * before x/y. On VMS, x/y/z > x/y but [x.y.z] < [x.y]     */    qsort((char *)s, n, sizeof(struct zlist far *), rqcmp);    for (i = 0; i < n; i++) {      char *p = s[i]->name;      if (*p == '\0') continue;      if (p[strlen(p) - 1] == '/') { /* keep VMS [x.y]z.dir;1 intact */        p[strlen(p) - 1] = '\0';      }      if (i == 0 || strcmp(s[i]->zname, s[i-1]->zname) != 0) {        if (verbose) {          fprintf(mesg, "zip diagnostic: trashing directory %s (if empty)\n",                  s[i]->name);        }        deletedir(s[i]->name);      }    }    free((voidp *)s);  }  return ZE_OK;}#endif /* !UTIL */

⌨️ 快捷键说明

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