zipup.c

来自「infozip2.2源码」· C语言 代码 · 共 739 行 · 第 1/2 页

C
739
字号
      }    }#else /* !MMAP */# ifdef BIG_MEM    /* Read the whole input file at once */    if (q > 0 && !translate_eol) {      window_size = q + MIN_LOOKAHEAD;      window = window ? (uch*) realloc(window, (unsigned)window_size)                      : (uch*) malloc((unsigned)window_size);      /* Just use normal code if big malloc or realloc fails: */      if (window != NULL) {        remain = zread(ifile, (char*)window, q+1);        if (remain != q) {          fprintf(mesg, " q=%ld, remain=%ld ", q, remain);          error("can't read whole file at once");        }      } else {        window_size = 0L;      }    }# endif /* BIG_MEM */#endif /* ?MMAP */  } /* strcmp(z->name, "-") == 0 */  if (l || q == 0)    m = STORE;  if (m == BEST)    m = DEFLATE;  /* Do not create STORED files with extended local headers if the   * input size is not known, because such files could not be extracted.   * So if the zip file is not seekable and the input file is not   * on disk, obey the -0 option by forcing deflation with stored block.   * Note however that using "zip -0" as filter is not very useful...   * ??? to be done.   */  /* Fill in header information and write local header to zip file.   * This header will later be re-written since compressed length and   * crc are not yet known.   */  /* (Assume ext, cext, com, and zname already filled in.) */#if defined(OS2) || defined(WIN32)  z->vem = z->dosflag ? (dosify ? 20 :  /* Made under MSDOS by PKZIP 2.0 */                        (0 + Z_MAJORVER * 10 + Z_MINORVER))         : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER;  /* For a FAT file system, we cheat and pretend that the file   * was not made on OS2 but under DOS. unzip is confused otherwise.   */#else /* !(OS2 || WIN32) */  z->vem = dosify ? 20 : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER;#endif /* ?(OS2 || WIN32) */  z->ver = m == STORE ? 10 : 20;     /* Need PKUNZIP 2.0 except for store */  z->crc = 0;  /* to be updated later */  /* Assume first that we will need an extended local header: */  z->flg = 8;  /* to be updated later */#if CRYPT  if (key != NULL) {    z->flg |= 1;    /* Since we do not yet know the crc here, we pretend that the crc     * is the modification time:     */    z->crc = z->tim << 16;  }#endif /* CRYPT */  z->lflg = z->flg;  z->how = m;                             /* may be changed later  */  z->siz = m == STORE && q >= 0 ? q : 0;  /* will be changed later  */  z->len = q >= 0 ? q : 0;                /* may be changed later  */  z->dsk = 0;  if (z->att == (ush)UNKNOWN) {      z->att = BINARY;                    /* set sensible value in header */      set_type = 1;  }  /* Attributes from filetime(), flag bits from set_extra_field(): */#if defined(DOS) || defined(OS2) || defined(WIN32)  z->atx = z->dosflag ? a & 0xff : a | (z->atx & 0x0000ff00);#else  z->atx = dosify ? a & 0xff : a | (z->atx & 0x0000ff00);#endif /* DOS || OS2 || WIN32 */  z->off = tempzn;  if ((r = putlocal(z, y)) != ZE_OK)    return r;  tempzn += 4 + LOCHEAD + z->nam + z->ext;#if CRYPT  if (key != NULL) {    crypthead(key, z->crc, y);    z->siz += RAND_HEAD_LEN;  /* to be updated later */    tempzn += RAND_HEAD_LEN;  }#endif /* CRYPT */  if (ferror(y))    ZIPERR(ZE_WRITE, "unexpected error on zip file");  o = ftell(y); /* for debugging only, ftell can fail on pipes */  if (ferror(y))    clearerr(y);  /* Write stored or deflated file to zip file */  isize = 0L;  crc = CRCVAL_INITIAL;  if (m == DEFLATE) {     bi_init(y);     if (set_type) z->att = (ush)UNKNOWN; /* will be changed in deflate() */     ct_init(&z->att, &m);     lm_init(level, &z->flg);     s = deflate();  }  else if (!isdir)  {#ifdef SBSZ    if ((b = malloc(SBSZ)) == NULL)#else    if ((b = malloc(CBSZ)) == NULL)#endif       return ZE_MEM;    if (l) {#ifdef SBSZ      k = rdsymlnk(z->name, b, SBSZ);#else      k = rdsymlnk(z->name, b, CBSZ);#endif/* * compute crc first because zfwrite will alter the buffer b points to !! */      crc = crc32(crc, (uch *) b, k);      if (zfwrite(b, 1, k, y) != k)      {        free((zvoid *)b);        return ZE_TEMP;      }      isize = k;#ifdef MINIX      q = k;#endif /* MINIX */    }    else    {#ifdef SBSZ      while ((k = file_read(b, SBSZ)) > 0 && k != (extent) EOF)#else      while ((k = file_read(b, CBSZ)) > 0 && k != (extent) EOF)#endif      {        if (zfwrite(b, 1, k, y) != k)        {          free((zvoid *)b);          return ZE_TEMP;        }#ifndef WINDLL        if (verbose) putc('.', stderr);#else        if (verbose) fprintf(stdout,"%c",'.');#endif      }    }    free((zvoid *)b);    s = isize;  }  if (ifile != fbad && zerr(ifile)) {    perror("\nzip warning");    zipwarn("could not read input file: ", z->zname);  }  if (ifile != fbad)    zclose(ifile);#ifdef MMAP  if (remain >= 0L) {    munmap((caddr_t) window, window_size);    window = NULL;  }#endif /*MMAP */  tempzn += s;  p = tempzn; /* save for future fseek() */#if (!defined(MSDOS) || defined(OS2))#if !defined(VMS) && !defined(CMS_MVS)  /* Check input size (but not in VMS -- variable record lengths mess it up)   * and not on MSDOS -- diet in TSR mode reports an incorrect file size)   */#ifndef TANDEM /* Tandem EOF does not match byte count unless Unstructured */  if (q >= 0 && isize != (ulg)q && !translate_eol)  {    Trace((mesg, " i=%ld, q=%ld ", isize, q));    zipwarn(" file size changed while zipping ", z->name);  }#endif /* !TANDEM */#endif /* !VMS && !CMS_MVS */#endif /* (!MSDOS || OS2) */  /* Try to rewrite the local header with correct information */  z->crc = crc;  z->siz = s;#if CRYPT  if (key != NULL)    z->siz += RAND_HEAD_LEN;#endif /* CRYPT */  z->len = isize;#ifdef BROKEN_FSEEK  if (!fseekable(y) || fseek(y, z->off, SEEK_SET))#else  if (fseek(y, z->off, SEEK_SET))#endif  {    if (z->how != (ush) m)       error("can't rewrite method");    if (m == STORE && q < 0)       ZIPERR(ZE_PARMS, "zip -0 not supported for I/O on pipes or devices");    if ((r = putextended(z, y)) != ZE_OK)      return r;    tempzn += 16L;    z->flg = z->lflg; /* if flg modified by inflate */  } else {     /* seek ok, ftell() should work, check compressed size */#if !defined(VMS) && !defined(CMS_MVS)    if (p - o != s) {      fprintf(mesg, " s=%ld, actual=%ld ", s, p-o);      error("incorrect compressed size");    }#endif /* !VMS && !CMS_MVS */    z->how = m;    z->ver = m == STORE ? 10 : 20;     /* Need PKUNZIP 2.0 except for store */    if ((z->flg & 1) == 0)      z->flg &= ~8; /* clear the extended local header flag */    z->lflg = z->flg;    /* rewrite the local header: */    if ((r = putlocal(z, y)) != ZE_OK)      return r;    if (fseek(y, p, SEEK_SET))      return ZE_READ;    if ((z->flg & 1) != 0) {      /* encrypted file, extended header still required */      if ((r = putextended(z, y)) != ZE_OK)        return r;      tempzn += 16L;    }  }  /* Free the local extra field which is no longer needed */  if (z->ext) {    if (z->extra != z->cextra) {      free((zvoid *)(z->extra));      z->extra = NULL;    }    z->ext = 0;  }  /* Display statistics */  if (noisy)  {    if (verbose)      fprintf(mesg, "\t(in=%lu) (out=%lu)", isize, s);    if (m == DEFLATE)      fprintf(mesg, " (deflated %d%%)\n", percent(isize, s));    else      fprintf(mesg, " (stored 0%%)\n");    fflush(mesg);  }  return ZE_OK;}int file_read(buf, size)  char *buf;  unsigned size;/* Read a new buffer from the current input file, perform end-of-line * translation, and update the crc and input file size. * IN assertion: size >= 2 (for end-of-line translation) */{  unsigned len;  char *b;#if defined(MMAP) || defined(BIG_MEM)  if (remain == 0L) {    return 0;  } else if (remain > 0L) {    /* The window data is already in place. We still compute the crc     * by 32K blocks instead of once on whole file to keep a certain     * locality of reference.     */    Assert (buf == (char*)window + isize, "are you lost?");    if (size > remain) size = remain;    if (size > WSIZE) size = WSIZE; /* don't touch all pages at once */    remain -= (long) size;    len = size;  } else#endif /* MMAP || BIG_MEM */  if (translate_eol == 0) {    len = zread(ifile, buf, size);    if (len == (unsigned)EOF || len == 0) return (int)len;  } else if (translate_eol == 1) {    /* Transform LF to CR LF */    size >>= 1;    b = buf+size;    size = len = zread(ifile, b, size);    if (len == (unsigned)EOF || len == 0) return (int)len;#ifdef EBCDIC    if (aflag == ASCII)    {       do {          char c;          if ((c = *b++) == '\n') {             *buf++ = CR; *buf++ = LF; len++;          } else {            *buf++ = (char)ascii[(uch)c];          }       } while (--size != 0);    }    else#endif /* EBCDIC */    {       do {          if ((*buf++ = *b++) == '\n') *(buf-1) = '\r', *buf++ = '\n', len++;       } while (--size != 0);    }    buf -= len;  } else {    /* Transform CR LF to LF and suppress final ^Z */    b = buf;    size = len = zread(ifile, buf, size-1);    if (len == (unsigned)EOF || len == 0) return (int)len;    buf[len] = '\n'; /* I should check if next char is really a \n */#ifdef EBCDIC    if (aflag == ASCII)    {       do {          char c;          if ((c = *b++) == '\r' && *b == '\n') {             len--;          } else {             *buf++ = (char)(c == '\n' ? LF : ascii[(uch)c]);          }       } while (--size != 0);    }    else#endif /* EBCDIC */    {       do {          if (( *buf++ = *b++) == '\r' && *b == '\n') buf--, len--;       } while (--size != 0);    }    if (len == 0) {       zread(ifile, buf, 1); len = 1; /* keep single \r if EOF */#ifdef EBCDIC       if (aflag == ASCII) {          *buf = (char)(*buf == '\n' ? LF : ascii[(uch)(*buf)]);       }#endif    } else {       buf -= len;       if (buf[len-1] == CTRLZ) len--; /* suppress final ^Z */    }  }  crc = crc32(crc, (uch *) buf, len);  isize += (ulg)len;  return (int)len;}#endif /* !UTIL */

⌨️ 快捷键说明

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