📄 zipup.c
字号:
} z->tim = tim;#if defined(VMS) && defined(VMS_PK_EXTRA) /* vms_get_attributes must be called after vms_open() */ if (extra_fields) { /* create extra field and change z->att and z->atx if desired */ vms_get_attributes(ifile, z, &f_utim); }#endif /* VMS && VMS_PK_EXTRA */#if defined(MMAP) || defined(BIG_MEM) /* Map ordinary files but not devices. This code should go in fileio.c */ if (!translate_eol && m != STORE && q != -1L && (ulg)q > 0 && (ulg)q + MIN_LOOKAHEAD > (ulg)q) {# ifdef MMAP /* Map the whole input file in memory */ if (window != NULL) free(window); /* window can't be a mapped file here */ window_size = (ulg)q + MIN_LOOKAHEAD; remain = window_size & (PAGESIZE-1); /* If we can't touch the page beyond the end of file, we must * allocate an extra page. */ if (remain > MIN_LOOKAHEAD) { window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0); } else { window = (uch*)valloc(window_size - remain + PAGESIZE); if (window != NULL) { window = (uch*)mmap((char*)window, window_size - remain, PROT_READ, MAP_PRIVATE | MAP_FIXED, ifile, 0); } else { window = (uch*)(-1); } } if (window == (uch*)(-1)) { Trace((mesg, " mmap failure on %s\n", z->name)); window = NULL; window_size = 0L; remain = (ulg)-1L; } else { remain = (ulg)q; }# else /* !MMAP, must be BIG_MEM */ /* Read the whole input file at once */ window_size = (ulg)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 = (ulg)zread(ifile, (char*)window, q+1); if (remain != (ulg)q) { fprintf(mesg, " q=%lu, remain=%lu ", (ulg)q, remain); error("can't read whole file at once"); } } else { window_size = 0L; }# endif /* ?MMAP */ }#endif /* MMAP || BIG_MEM */ } /* strcmp(z->name, "-") == 0 */ if (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 = (ush)(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/WIN32 but under DOS. unzip is confused otherwise. */#else /* !(OS2 || WIN32) */ z->vem = (ush)(dosify ? 20 : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER);#endif /* ?(OS2 || WIN32) */ z->ver = (ush)(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 = (ush)m; /* may be changed later */ z->siz = (ulg)(m == STORE && q >= 0 ? q : 0); /* will be changed later */ z->len = (ulg)(q != -1L ? 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) { if (ifile != fbad) zclose(ifile); 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)) { if (ifile != fbad) zclose(ifile); ZIPERR(ZE_WRITE, "unexpected error on zip file"); } last_o = o; o = ftell(y); /* for debugging only, ftell can fail on pipes */ if (ferror(y)) clearerr(y); if (last_o > o) { /* could be wrap around */ ZIPERR(ZE_BIG, "seek wrap - zip file too big to write"); } /* Write stored or deflated file to zip file */ isize = 0L; crc = CRCVAL_INITIAL; if (m == DEFLATE) { if (set_type) z->att = (ush)UNKNOWN; /* is finally set in filecompress() */ s = filecompress(z, y, &m);#ifndef PGP if (z->att == (ush)BINARY && translate_eol) { zipwarn("-l used on binary file", ""); }#endif } else if (!isdir) { if ((b = malloc(SBSZ)) == NULL) return ZE_MEM; if (l) { k = rdsymlnk(z->name, b, SBSZ);/* * 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 { while ((k = file_read(b, SBSZ)) > 0 && k != (extent) EOF) { if (zfwrite(b, 1, k, y) != k) { if (ifile != fbad) zclose(ifile); free((zvoid *)b); return ZE_TEMP; }#ifndef WINDLL if (verbose) putc('.', stderr); fflush(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 != (ulg)-1L) { 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) && !defined(__mpexl) /* 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 (!translate_eol && q != -1L && isize != (ulg)q) { Trace((mesg, " i=%lu, q=%lu ", isize, q)); zipwarn(" file size changed while zipping ", z->name); }#endif /* !TANDEM */#endif /* !VMS && !CMS_MVS && !__mpexl */#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 = (ush)m; z->ver = (ush)(m == STORE ? 10 : 20); /* Need PKUNZIP 2.0 unless STORED */ 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); }#ifdef WINDLL if (lpZipUserFunctions->ServiceApplication != NULL) { if ((*lpZipUserFunctions->ServiceApplication)(z->zname, isize)) { ZIPERR(ZE_ABORT, "User terminated operation"); } }#endif return ZE_OK;}local unsigned 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 != (ulg)-1L) { /* 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 ((ulg)size > remain) size = (unsigned)remain; if (size > WSIZE) size = WSIZE; /* don't touch all pages at once */ remain -= (ulg)size; len = size; } else#endif /* MMAP || BIG_MEM */ if (translate_eol == 0) { len = zread(ifile, buf, size); if (len == (unsigned)EOF || len == 0) return len;#ifdef OS390 b = buf; if (aflag == ASCII) { while (*b != '\0') { *b = (char)ascii[(uch)*b]; b++; } }#endif } 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 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) = CR, *buf++ = LF, 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 len; buf[len] = '\n'; /* I should check if next char is really a \n */#ifdef EBCDIC if (aflag == ASCII) { do { char c;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -