|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly, ! 4: Kai Uwe Rommel and Igor Mandrichenko. ! 5: Permission is granted to any individual or institution to use, copy, or ! 6: redistribute this software so long as all of the original files are included ! 7: unmodified, that it is not sold for profit, and that this copyright notice ! 8: is retained. ! 9: ! 10: */ ! 11: ! 12: /* ! 13: * zipnote.c by Mark Adler. ! 14: */ ! 15: ! 16: #define UTIL ! 17: #include "revision.h" ! 18: #include "zip.h" ! 19: #include <signal.h> ! 20: ! 21: ! 22: /* Character to mark zip entry names in the comment file */ ! 23: #define MARK '@' ! 24: ! 25: /* Temporary zip file name and file pointer */ ! 26: local char *tempzip; ! 27: local FILE *tempzf; ! 28: ! 29: ! 30: /* Local functions */ ! 31: #ifdef PROTO ! 32: local void handler(int); ! 33: local void license(void); ! 34: local void help(void); ! 35: local void putclean(char *, int); ! 36: local int catalloc(char * far *, char *); ! 37: void main(int, char **); ! 38: #endif /* PROTO */ ! 39: ! 40: ! 41: ! 42: void err(c, h) ! 43: int c; /* error code from the ZE_ class */ ! 44: char *h; /* message about how it happened */ ! 45: /* Issue a message for the error, clean up files and memory, and exit. */ ! 46: { ! 47: if (PERR(c)) ! 48: perror("zipnote error"); ! 49: fprintf(stderr, "zipnote error: %s (%s)\n", errors[c-1], h); ! 50: if (tempzf != NULL) ! 51: fclose(tempzf); ! 52: if (tempzip != NULL) ! 53: { ! 54: destroy(tempzip); ! 55: free((voidp *)tempzip); ! 56: } ! 57: if (zipfile != NULL) ! 58: free((voidp *)zipfile); ! 59: #ifdef VMS ! 60: exit(0); ! 61: #else /* !VMS */ ! 62: exit(c); ! 63: #endif /* ?VMS */ ! 64: } ! 65: ! 66: ! 67: local void handler(s) ! 68: int s; /* signal number (ignored) */ ! 69: /* Upon getting a user interrupt, abort cleanly using err(). */ ! 70: { ! 71: #ifndef MSDOS ! 72: putc('\n', stderr); ! 73: #endif /* !MSDOS */ ! 74: err(ZE_ABORT, "aborting"); ! 75: s++; /* keep some compilers happy */ ! 76: } ! 77: ! 78: ! 79: void warn(a, b) ! 80: char *a, *b; /* message strings juxtaposed in output */ ! 81: /* Print a warning message to stderr and return. */ ! 82: { ! 83: fprintf(stderr, "zipnote warning: %s%s\n", a, b); ! 84: } ! 85: ! 86: ! 87: local void license() ! 88: /* Print license information to stdout. */ ! 89: { ! 90: extent i; /* counter for copyright array */ ! 91: ! 92: for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { ! 93: printf(copyright[i], "zipnote"); ! 94: putchar('\n'); ! 95: } ! 96: for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++) ! 97: puts(disclaimer[i]); ! 98: } ! 99: ! 100: ! 101: local void help() ! 102: /* Print help (along with license info) to stdout. */ ! 103: { ! 104: extent i; /* counter for help array */ ! 105: ! 106: /* help array */ ! 107: static char *text[] = { ! 108: "", ! 109: "ZipNote %d.%d (%s)", ! 110: "Usage: zipnote [-w] [-b path] zipfile", ! 111: " the default action is to write the comments in zipfile to stdout", ! 112: " -w write the zipfile comments from stdin", ! 113: " -b use \"path\" for the temporary zip file", ! 114: " -h show this help -L show software license", ! 115: "", ! 116: "Example:", ! 117: #ifdef VMS ! 118: " define/user sys$output foo.tmp", ! 119: " zipnote foo.zip", ! 120: " edit foo.tmp", ! 121: " ... then you edit the comments, save, and exit ...", ! 122: " define/user sys$input foo.tmp", ! 123: " zipnote -w foo.zip" ! 124: #else /* !VMS */ ! 125: " zipnote foo.zip > foo.tmp", ! 126: " ed foo.tmp", ! 127: " ... then you edit the comments, save, and exit ...", ! 128: " zipnote -w foo.zip < foo.tmp" ! 129: #endif /* ?VMS */ ! 130: }; ! 131: ! 132: for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { ! 133: printf(copyright[i], "zipnote"); ! 134: putchar('\n'); ! 135: } ! 136: for (i = 0; i < sizeof(text)/sizeof(char *); i++) ! 137: { ! 138: printf(text[i], REVISION / 10, REVISION % 10, REVDATE); ! 139: putchar('\n'); ! 140: } ! 141: } ! 142: ! 143: ! 144: local void putclean(s, n) ! 145: char *s; /* string to write to stdout */ ! 146: int n; /* length of string */ ! 147: /* Write the string s to stdout, filtering out control characters that are ! 148: not tab or newline (mainly to remove carriage returns), and prefix MARK's ! 149: and backslashes with a backslash. Also, terminate with a newline if ! 150: needed. */ ! 151: { ! 152: int c; /* next character in string */ ! 153: int e; /* last character written */ ! 154: ! 155: e = '\n'; /* if empty, write nothing */ ! 156: while (n--) ! 157: { ! 158: c = *(uch *)s++; ! 159: if (c == MARK || c == '\\') ! 160: putchar('\\'); ! 161: if (c >= ' ' || c == '\t' || c == '\n') ! 162: putchar(e = c); ! 163: } ! 164: if (e != '\n') ! 165: putchar('\n'); ! 166: } ! 167: ! 168: ! 169: local int catalloc(a, s) ! 170: char * far *a; /* pointer to a pointer to a malloc'ed string */ ! 171: char *s; /* string to concatenate on a */ ! 172: /* Concatentate the string s to the malloc'ed string pointed to by a. ! 173: Preprocess s by removing backslash escape characters. */ ! 174: { ! 175: char *p; /* temporary pointer */ ! 176: char *q; /* temporary pointer */ ! 177: ! 178: for (p = q = s; *q; *p++ = *q++) ! 179: if (*q == '\\' && *(q+1)) ! 180: q++; ! 181: *p = 0; ! 182: if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL) ! 183: return ZE_MEM; ! 184: strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s); ! 185: free((voidp *)*a); ! 186: *a = p; ! 187: return ZE_OK; ! 188: } ! 189: ! 190: ! 191: void main(argc, argv) ! 192: int argc; /* number of tokens in command line */ ! 193: char **argv; /* command line tokens */ ! 194: /* Write the comments in the zipfile to stdout, or read them from stdin. */ ! 195: { ! 196: char a[FNMAX+1]; /* input line buffer */ ! 197: ulg c; /* start of central directory */ ! 198: int k; /* next argument type */ ! 199: char *q; /* steps through option arguments */ ! 200: int r; /* arg counter, temporary variable */ ! 201: ulg s; /* length of central directory */ ! 202: int t; /* attributes of zip file */ ! 203: int w; /* true if updating zip file from stdin */ ! 204: FILE *x, *y; /* input and output zip files */ ! 205: struct zlist far *z; /* steps through zfiles linked list */ ! 206: ! 207: ! 208: /* If no args, show help */ ! 209: if (argc == 1) ! 210: { ! 211: help(); ! 212: exit(0); ! 213: } ! 214: ! 215: init_upper(); /* build case map table */ ! 216: ! 217: /* Go through args */ ! 218: zipfile = tempzip = NULL; ! 219: tempzf = NULL; ! 220: signal(SIGINT, handler); ! 221: signal(SIGTERM, handler); ! 222: k = w = 0; ! 223: for (r = 1; r < argc; r++) ! 224: if (*argv[r] == '-') ! 225: if (argv[r][1]) ! 226: for (q = argv[r]+1; *q; q++) ! 227: switch(*q) ! 228: { ! 229: case 'b': /* Specify path for temporary file */ ! 230: if (k) ! 231: err(ZE_PARMS, "use -b before zip file name"); ! 232: else ! 233: k = 1; /* Next non-option is path */ ! 234: break; ! 235: case 'h': /* Show help */ ! 236: help(); exit(0); ! 237: case 'l': case 'L': /* Show copyright and disclaimer */ ! 238: license(); exit(0); ! 239: case 'w': ! 240: w = 1; break; ! 241: default: ! 242: err(ZE_PARMS, "unknown option"); ! 243: } ! 244: else ! 245: err(ZE_PARMS, "zip file cannot be stdin"); ! 246: else ! 247: if (k == 0) ! 248: if (zipfile == NULL) ! 249: { ! 250: if ((zipfile = ziptyp(argv[r])) == NULL) ! 251: err(ZE_MEM, "was processing arguments"); ! 252: } ! 253: else ! 254: err(ZE_PARMS, "can only specify one zip file"); ! 255: else ! 256: { ! 257: tempath = argv[r]; ! 258: k = 0; ! 259: } ! 260: if (zipfile == NULL) ! 261: err(ZE_PARMS, "need to specify zip file"); ! 262: ! 263: /* Read zip file */ ! 264: if ((r = readzipfile()) != ZE_OK) ! 265: err(r, zipfile); ! 266: if (zfiles == NULL) ! 267: err(ZE_NAME, zipfile); ! 268: ! 269: /* Put comments to stdout, if not -w */ ! 270: if (!w) ! 271: { ! 272: for (z = zfiles; z != NULL; z = z->nxt) ! 273: { ! 274: printf("%c %s\n", MARK, z->zname); ! 275: putclean(z->comment, z->com); ! 276: putchar(MARK); putchar('\n'); ! 277: } ! 278: putchar(MARK); putchar('\n'); ! 279: putclean(zcomment, zcomlen); ! 280: exit(ZE_OK); ! 281: } ! 282: ! 283: /* If updating comments, make sure zip file is writeable */ ! 284: if ((x = fopen(zipfile, "a")) == NULL) ! 285: err(ZE_CREAT, zipfile); ! 286: fclose(x); ! 287: t = getfileattr(zipfile); ! 288: ! 289: /* Process stdin, replacing comments */ ! 290: for (z = zfiles; z != NULL; z = z->nxt) ! 291: { ! 292: if (gets(a) == NULL || a[0] != MARK || a[1] != ' ' || ! 293: strcmp(a + 2, z->zname)) ! 294: err(ZE_NOTE, "missing entry name"); ! 295: if (z->com) ! 296: free((voidp *)z->comment); ! 297: z->comment = malloc(1); *(z->comment) = 0; ! 298: while (gets(a) != NULL && *a != MARK) ! 299: if ((r = catalloc(&(z->comment), a)) != ZE_OK) ! 300: err(r, "was building new comments"); ! 301: if (a[1]) ! 302: err(ZE_NOTE, "missing comment end line"); ! 303: z->com = strlen(z->comment); ! 304: } ! 305: if (gets(a) == NULL || a[0] != MARK || a[1]) ! 306: err(ZE_NOTE, "missing zip file comment marker line"); ! 307: zcomment = malloc(1); *zcomment = 0; ! 308: while (gets(a) != NULL) ! 309: if ((r = catalloc(&zcomment, a)) != ZE_OK) ! 310: err(r, "was building new comments"); ! 311: zcomlen = strlen(zcomment); ! 312: ! 313: /* Open output zip file for writing */ ! 314: if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) ! 315: err(ZE_TEMP, tempzip); ! 316: ! 317: /* Open input zip file again, copy preamble if any */ ! 318: if ((x = fopen(zipfile, FOPR)) == NULL) ! 319: err(ZE_NAME, zipfile); ! 320: if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK) ! 321: err(r, r == ZE_TEMP ? tempzip : zipfile); ! 322: ! 323: /* Go through local entries, copying them over as is */ ! 324: for (z = zfiles; z != NULL; z = z->nxt) ! 325: if ((r = zipcopy(z, x, y)) != ZE_OK) ! 326: err(r, "was copying an entry"); ! 327: fclose(x); ! 328: ! 329: /* Write central directory and end of central directory with new comments */ ! 330: if ((c = ftell(y)) == -1L) /* get start of central */ ! 331: err(ZE_TEMP, tempzip); ! 332: for (z = zfiles; z != NULL; z = z->nxt) ! 333: if ((r = putcentral(z, y)) != ZE_OK) ! 334: err(r, tempzip); ! 335: if ((s = ftell(y)) == -1L) /* get end of central */ ! 336: err(ZE_TEMP, tempzip); ! 337: s -= c; /* compute length of central */ ! 338: if ((r = putend((int)zcount, s, c, zcomlen, zcomment, y)) != ZE_OK) ! 339: err(r, tempzip); ! 340: tempzf = NULL; ! 341: if (fclose(y)) ! 342: err(ZE_TEMP, tempzip); ! 343: if ((r = replace(zipfile, tempzip)) != ZE_OK) ! 344: { ! 345: warn("new zip file left as: ", tempzip); ! 346: free((voidp *)tempzip); ! 347: tempzip = NULL; ! 348: err(r, "was replacing the original zip file"); ! 349: } ! 350: free((voidp *)tempzip); ! 351: tempzip = NULL; ! 352: setfileattr(zipfile, t); ! 353: free((voidp *)zipfile); ! 354: zipfile = NULL; ! 355: ! 356: /* Done! */ ! 357: exit(ZE_OK); ! 358: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.