📄 zip.c
字号:
#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 = (ulg near *)get_crc_table();#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) {#if defined(MSDOS) || defined(__human68k__) /* 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)) == 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) {#ifndef 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) {#ifndef WINDLL putc('\n', mesg); fflush(mesg);#else fprintf(stdout,"\n");#endif } if (r == ZE_OPEN) { 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); } 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"); sprintf(errbuf, "zip diagnostic: fcount=%d\n", (int)fcount); diag(errbuf); 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) {#ifndef 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) {#ifndef WINDLL putc('\n', mesg); fflush(mesg);#else fprintf(stdout,"\n");#endif } if (r == ZE_OPEN) { 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 */#ifdef AMIGA 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"); } } for (z = zfiles; z != NULL; z = z->nxt) if (z->mark)#ifdef AMIGA if (filenotes && (p = GetComment(z->zname))) { if (z->comment = malloc(k = strlen(p)+1)) { z->com = k; strcpy(z->comment, p); } else { free((zvoid *)e); ZIPERR(ZE_MEM, "was reading filenotes"); } } else if (comadd)#endif { if (noisy) fprintf(mesg, "Enter comment for %s:\n", z->zname); if (fgets(e, MAXCOM+1, comment_stream) != NULL) { if ((p = malloc((k = strlen(e))+1)) == NULL) { free((zvoid *)e); ZIPERR(ZE_MEM, "was reading comment lines"); } strcpy(p, e); if (p[k-1] == '\n') p[--k] = 0; z->comment = p; z->com = k; } }#ifdef AMIGA if (comadd) free((zvoid *)e); GetComment(NULL); /* makes it free its internal storage */#else free((zvoid *)e);#endif } /* Get multi-line comment for the zip file */ if (zipedit) {#ifndef WINDLL 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"); } if (noisy && zcomlen) { fputs("current zip file comment is:\n", mesg); fwrite(zcomment, 1, zcomlen, mesg); if (zcomment[zcomlen-1] != '\n') putc('\n', mesg); free((zvoid *)zcomment); } if ((zcomment = malloc(1)) == NULL) ZIPERR(ZE_MEM, "was setting comments to null"); zcomment[0] = '\0'; if (noisy) fputs("enter new zip file comment (end with .):\n", mesg);#if (defined(AMIGA) && (defined(LATTICE)||defined(__SASC))) flushall(); /* tty input/output is out of sync here */#endif while (fgets(e, MAXCOM+1, comment_stream) != NULL && strcmp(e, ".\n")) { if (e[(r = strlen(e)) - 1] == '\n') e[--r] = 0; if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL) { free((zvoid *)e); ZIPERR(ZE_MEM, "was reading comment lines"); } if (*zcomment) strcat(strcat(strcpy(p, zcomment), "\r\n"), e); else strcpy(p, *e ? e : "\r\n"); free((zvoid *)zcomment); zcomment = p; } free((zvoid *)e);#else /* WINDLL */ comment(zcomlen); if ((p = malloc(strlen(szCommentBuf)+1)) == NULL) { ZIPERR(ZE_MEM, "was setting comments to null"); } if (szCommentBuf[0] != '\0') lstrcpy(p, szCommentBuf); else p[0] = '\0'; free((zvoid *)zcomment); GlobalUnlock(hStr); GlobalFree(hStr); zcomment = p;#endif /* WINDLL */ zcomlen = strlen(zcomment); } /* Write central directory and end header to temporary zip */ diag("writing central directory"); k = 0; /* keep count for end header */ c = tempzn; /* get start of central */ n = t = 0; for (z = zfiles; z != NULL; z = z->nxt) { if ((r = putcentral(z, y)) != ZE_OK) { ZIPERR(r, tempzip); } tempzn += 4 + CENHEAD + z->nam + z->cext + z->com; n += z->len; t += z->siz; k++; } if (k == 0) zipwarn("zip file empty", ""); if (verbose) fprintf(mesg, "total bytes=%lu, compressed=%lu -> %d%% savings\n", n, t, percent(n, t)); t = tempzn - c; /* compute length of central */ diag("writing end of central directory"); if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK) { ZIPERR(r, tempzip); } tempzf = NULL; if (fclose(y)) { ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip); } if (x != NULL) fclose(x); /* Free some memory before spawning unzip */ lm_free();#ifndef WINDLL /* Test new zip file before overwriting old one or removing input files */ if (test) check_zipfile(tempzip, argv[0]);#endif /* Replace old zip file with new zip file, leaving only the new one */ if (strcmp(zipfile, "-") && !d) { diag("replacing old zip file with new zip file"); if ((r = replace(zipfile, tempzip)) != ZE_OK) { zipwarn("new zip file left as: ", tempzip); free((zvoid *)tempzip); tempzip = NULL; ZIPERR(r, "was replacing the original zip file"); } free((zvoid *)tempzip); } tempzip = NULL; if (a && strcmp(zipfile, "-")) { setfileattr(zipfile, a);#ifdef VMS /* If the zip file existed previously, restore its record format: */ if (x != NULL) (void)VMSmunch(zipfile, RESTORE_RTYPE, NULL);#endif }#ifdef __BEOS__ /* Set the filetype of the zipfile to "application/zip" */ setfiletype( zipfile, "application/zip" );#endif#ifdef RISCOS /* Set the filetype of the zipfile to &DDC */ setfiletype(zipfile,0xDDC);#endif /* Finish up (process -o, -m, clean up). Exit code depends on o. */#if (!defined(VMS) && !defined(CMS_MVS)) free((zvoid *) zipbuf);#endif /* !VMS && !CMS_MVS */ RETURN(finish(o ? ZE_OPEN : ZE_OK));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -