Index: cmd/signtool/zip.c |
=================================================================== |
--- a/cmd/signtool/zip.c |
+++ b/cmd/signtool/zip.c |
@@ -2,688 +2,619 @@ |
* License, v. 2.0. If a copy of the MPL was not distributed with this |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
#include "signtool.h" |
#include "zip.h" |
#include "zlib.h" |
#include "prmem.h" |
-static void inttox (int in, char *out); |
-static void longtox (long in, char *out); |
+static void inttox(int in, char *out); |
+static void longtox(long in, char *out); |
/**************************************************************** |
* |
* J z i p O p e n |
* |
- * Opens a new ZIP file and creates a new ZIPfile structure to |
+ * Opens a new ZIP file and creates a new ZIPfile structure to |
* control the process of installing files into a zip. |
*/ |
-ZIPfile* |
-JzipOpen(char *filename, char *comment) |
-{ |
- ZIPfile * zipfile; |
- PRExplodedTime prtime; |
+ZIPfile *JzipOpen(char *filename, char *comment) { |
+ ZIPfile *zipfile; |
+ PRExplodedTime prtime; |
- zipfile = PORT_ZAlloc(sizeof(ZIPfile)); |
- if (!zipfile) |
- out_of_memory(); |
+ zipfile = PORT_ZAlloc(sizeof(ZIPfile)); |
+ if (!zipfile) out_of_memory(); |
- /* Construct time and date */ |
- PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime); |
- zipfile->date = ((prtime.tm_year - 1980) << 9) | |
- ((prtime.tm_month + 1) << 5) | |
- prtime.tm_mday; |
- zipfile->time = (prtime.tm_hour << 11) | |
- (prtime.tm_min << 5) | |
- (prtime.tm_sec & 0x3f); |
+ /* Construct time and date */ |
+ PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime); |
+ zipfile->date = ((prtime.tm_year - 1980) << 9) | |
+ ((prtime.tm_month + 1) << 5) | prtime.tm_mday; |
+ zipfile->time = |
+ (prtime.tm_hour << 11) | (prtime.tm_min << 5) | (prtime.tm_sec & 0x3f); |
- zipfile->fp = NULL; |
- if (filename && |
- (zipfile->fp = PR_Open(filename, |
- PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777)) == NULL) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "%s: can't open output jar, %s.%s\n", |
- PROGRAM_NAME, |
- filename, nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit (ERRX); |
+ zipfile->fp = NULL; |
+ if (filename && |
+ (zipfile->fp = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, |
+ 0777)) == NULL) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
} |
+ PR_fprintf(errorFD, "%s: can't open output jar, %s.%s\n", PROGRAM_NAME, |
+ filename, nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
- zipfile->list = NULL; |
- if (filename) { |
- zipfile->filename = PORT_ZAlloc(strlen(filename) + 1); |
- if (!zipfile->filename) |
- out_of_memory(); |
- PORT_Strcpy(zipfile->filename, filename); |
- } |
- if (comment) { |
- zipfile->comment = PORT_ZAlloc(strlen(comment) + 1); |
- if (!zipfile->comment) |
- out_of_memory(); |
- PORT_Strcpy(zipfile->comment, comment); |
- } |
+ zipfile->list = NULL; |
+ if (filename) { |
+ zipfile->filename = PORT_ZAlloc(strlen(filename) + 1); |
+ if (!zipfile->filename) out_of_memory(); |
+ PORT_Strcpy(zipfile->filename, filename); |
+ } |
+ if (comment) { |
+ zipfile->comment = PORT_ZAlloc(strlen(comment) + 1); |
+ if (!zipfile->comment) out_of_memory(); |
+ PORT_Strcpy(zipfile->comment, comment); |
+ } |
- return zipfile; |
+ return zipfile; |
} |
- |
-static |
-void* |
-my_alloc_func(void*opaque, uInt items, uInt size) |
-{ |
- return PORT_Alloc(items * size); |
+static void *my_alloc_func(void *opaque, uInt items, uInt size) { |
+ return PORT_Alloc(items * size); |
} |
+static void my_free_func(void *opaque, void *address) { PORT_Free(address); } |
-static |
-void |
-my_free_func(void*opaque, void*address) |
-{ |
- PORT_Free(address); |
+static void handle_zerror(int err, char *msg) { |
+ if (!msg) { |
+ msg = ""; |
+ } |
+ |
+ errorCount++; /* unless Z_OK...see below */ |
+ |
+ switch (err) { |
+ case Z_OK: |
+ PR_fprintf(errorFD, "No error: %s\n", msg); |
+ errorCount--; /* this was incremented above */ |
+ break; |
+ case Z_MEM_ERROR: |
+ PR_fprintf(errorFD, "Deflation ran out of memory: %s\n", msg); |
+ break; |
+ case Z_STREAM_ERROR: |
+ PR_fprintf(errorFD, "Invalid compression level: %s\n", msg); |
+ break; |
+ case Z_VERSION_ERROR: |
+ PR_fprintf(errorFD, "Incompatible compression library version: %s\n", |
+ msg); |
+ break; |
+ case Z_DATA_ERROR: |
+ PR_fprintf(errorFD, "Compression data error: %s\n", msg); |
+ break; |
+ default: |
+ PR_fprintf(errorFD, "Unknown error in compression library: %s\n", msg); |
+ break; |
+ } |
} |
- |
-static |
-void |
-handle_zerror(int err, char *msg) |
-{ |
- if (!msg) { |
- msg = ""; |
- } |
- |
- errorCount++; /* unless Z_OK...see below */ |
- |
- switch (err) { |
- case Z_OK: |
- PR_fprintf(errorFD, "No error: %s\n", msg); |
- errorCount--; /* this was incremented above */ |
- break; |
- case Z_MEM_ERROR: |
- PR_fprintf(errorFD, "Deflation ran out of memory: %s\n", msg); |
- break; |
- case Z_STREAM_ERROR: |
- PR_fprintf(errorFD, "Invalid compression level: %s\n", msg); |
- break; |
- case Z_VERSION_ERROR: |
- PR_fprintf(errorFD, "Incompatible compression library version: %s\n", |
- msg); |
- break; |
- case Z_DATA_ERROR: |
- PR_fprintf(errorFD, "Compression data error: %s\n", msg); |
- break; |
- default: |
- PR_fprintf(errorFD, "Unknown error in compression library: %s\n", msg); |
- break; |
- } |
-} |
- |
- |
- |
- |
/**************************************************************** |
* |
* J z i p A d d |
* |
* Adds a new file into a ZIP file. The ZIP file must have already |
* been opened with JzipOpen. |
*/ |
-int |
-JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level) |
-{ |
- ZIPentry * entry; |
- PRFileDesc * readfp; |
- PRFileDesc * zipfp; |
- unsigned long crc; |
- unsigned long local_size_pos; |
- int num; |
- int err; |
- int deflate_percent; |
- z_stream zstream; |
- Bytef inbuf[BUFSIZ]; |
- Bytef outbuf[BUFSIZ]; |
+int JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, |
+ int compression_level) { |
+ ZIPentry *entry; |
+ PRFileDesc *readfp; |
+ PRFileDesc *zipfp; |
+ unsigned long crc; |
+ unsigned long local_size_pos; |
+ int num; |
+ int err; |
+ int deflate_percent; |
+ z_stream zstream; |
+ Bytef inbuf[BUFSIZ]; |
+ Bytef outbuf[BUFSIZ]; |
+ if (!fullname || !filename || !zipfile) { |
+ return -1; |
+ } |
- if ( !fullname || !filename || !zipfile) { |
- return - 1; |
+ zipfp = zipfile->fp; |
+ if (!zipfp) return -1; |
+ |
+ if ((readfp = PR_Open(fullname, PR_RDONLY, 0777)) == NULL) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr : ""); |
+ errorCount++; |
+ if (nsprErr) PR_Free(nsprErr); |
+ exit(ERRX); |
+ } |
+ |
+ /* |
+ * Make sure the input file is not the output file. |
+ * Add a few bytes to the end of the JAR file and see if the input file |
+ * twitches |
+ */ |
+ { |
+ PRInt32 endOfJar; |
+ PRInt32 inputSize; |
+ PRBool isSame; |
+ |
+ inputSize = PR_Available(readfp); |
+ |
+ endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR); |
+ |
+ if (PR_Write(zipfp, "abcde", 5) < 5) { |
+ char *nsprErr; |
+ |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing to zip file: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
} |
- zipfp = zipfile->fp; |
- if (!zipfp) |
- return - 1; |
+ isSame = (PR_Available(readfp) != inputSize); |
+ PR_Seek(zipfp, endOfJar, PR_SEEK_SET); |
- if ( (readfp = PR_Open(fullname, PR_RDONLY, 0777)) == NULL) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr : |
- ""); |
- errorCount++; |
- if (nsprErr) |
- PR_Free(nsprErr); |
- exit(ERRX); |
+ if (isSame) { |
+ /* It's the same file! Forget it! */ |
+ PR_Close(readfp); |
+ return 0; |
} |
+ } |
- /* |
- * Make sure the input file is not the output file. |
- * Add a few bytes to the end of the JAR file and see if the input file |
- * twitches |
- */ |
- { |
- PRInt32 endOfJar; |
- PRInt32 inputSize; |
- PRBool isSame; |
+ if (verbosity >= 0) { |
+ PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename); |
+ } |
- inputSize = PR_Available(readfp); |
+ entry = PORT_ZAlloc(sizeof(ZIPentry)); |
+ if (!entry) out_of_memory(); |
- endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR); |
+ entry->filename = PORT_Strdup(filename); |
+ entry->comment = NULL; |
- if (PR_Write(zipfp, "abcde", 5) < 5) { |
- char *nsprErr; |
+ /* Set up local file header */ |
+ longtox(LSIG, entry->local.signature); |
+ inttox(strlen(filename), entry->local.filename_len); |
+ inttox(zipfile->time, entry->local.time); |
+ inttox(zipfile->date, entry->local.date); |
+ inttox(Z_DEFLATED, entry->local.method); |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing to zip file: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
+ /* Set up central directory entry */ |
+ longtox(CSIG, entry->central.signature); |
+ inttox(strlen(filename), entry->central.filename_len); |
+ if (entry->comment) { |
+ inttox(strlen(entry->comment), entry->central.commentfield_len); |
+ } |
+ longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR), entry->central.localhdr_offset); |
+ inttox(zipfile->time, entry->central.time); |
+ inttox(zipfile->date, entry->central.date); |
+ inttox(Z_DEFLATED, entry->central.method); |
- isSame = (PR_Available(readfp) != inputSize); |
+ /* Compute crc. Too bad we have to process the whole file to do this*/ |
+ crc = crc32(0L, NULL, 0); |
+ while ((num = PR_Read(readfp, inbuf, BUFSIZ)) > 0) { |
+ crc = crc32(crc, inbuf, num); |
+ } |
+ PR_Seek(readfp, 0L, PR_SEEK_SET); |
- PR_Seek(zipfp, endOfJar, PR_SEEK_SET); |
+ /* Store CRC */ |
+ longtox(crc, entry->local.crc32); |
+ longtox(crc, entry->central.crc32); |
- if (isSame) { |
- /* It's the same file! Forget it! */ |
- PR_Close(readfp); |
- return 0; |
- } |
+ /* Stick this entry onto the end of the list */ |
+ entry->next = NULL; |
+ if (zipfile->list == NULL) { |
+ /* First entry */ |
+ zipfile->list = entry; |
+ } else { |
+ ZIPentry *pe; |
+ |
+ pe = zipfile->list; |
+ while (pe->next != NULL) { |
+ pe = pe->next; |
} |
+ pe->next = entry; |
+ } |
- if (verbosity >= 0) { |
- PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename); |
+ /* |
+ * Start writing stuff out |
+ */ |
+ |
+ local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18; |
+ /* File header */ |
+ if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal)) < |
+ sizeof(struct ZipLocal)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
} |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
- entry = PORT_ZAlloc(sizeof(ZIPentry)); |
- if (!entry) |
- out_of_memory(); |
+ /* File Name */ |
+ if (PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
- entry->filename = PORT_Strdup(filename); |
- entry->comment = NULL; |
+ /* |
+ * File data |
+ */ |
+ /* Initialize zstream */ |
+ zstream.zalloc = my_alloc_func; |
+ zstream.zfree = my_free_func; |
+ zstream.opaque = NULL; |
+ zstream.next_in = inbuf; |
+ zstream.avail_in = BUFSIZ; |
+ zstream.next_out = outbuf; |
+ zstream.avail_out = BUFSIZ; |
+ /* Setting the windowBits to -MAX_WBITS is an undocumented feature of |
+ * zlib (see deflate.c in zlib). It is the same thing that Java does |
+ * when you specify the nowrap option for deflation in java.util.zip. |
+ * It causes zlib to leave out its headers and footers, which don't |
+ * work in PKZIP files. |
+ */ |
+ err = deflateInit2(&zstream, compression_level, Z_DEFLATED, -MAX_WBITS, |
+ 8 /*default*/, Z_DEFAULT_STRATEGY); |
+ if (err != Z_OK) { |
+ handle_zerror(err, zstream.msg); |
+ exit(ERRX); |
+ } |
- /* Set up local file header */ |
- longtox(LSIG, entry->local.signature); |
- inttox(strlen(filename), entry->local.filename_len); |
- inttox(zipfile->time, entry->local.time); |
- inttox(zipfile->date, entry->local.date); |
- inttox(Z_DEFLATED, entry->local.method); |
+ while ((zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ)) > 0) { |
+ zstream.next_in = inbuf; |
+ /* Process this chunk of data */ |
+ while (zstream.avail_in > 0) { |
+ err = deflate(&zstream, Z_NO_FLUSH); |
+ if (err != Z_OK) { |
+ handle_zerror(err, zstream.msg); |
+ exit(ERRX); |
+ } |
+ if (zstream.avail_out <= 0) { |
+ if (PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ zstream.next_out = outbuf; |
+ zstream.avail_out = BUFSIZ; |
+ } |
+ } |
+ } |
- /* Set up central directory entry */ |
- longtox(CSIG, entry->central.signature); |
- inttox(strlen(filename), entry->central.filename_len); |
- if (entry->comment) { |
- inttox(strlen(entry->comment), entry->central.commentfield_len); |
+ /* Now flush everything */ |
+ while (1) { |
+ err = deflate(&zstream, Z_FINISH); |
+ if (err == Z_STREAM_END) { |
+ break; |
+ } else if (err == Z_OK) { |
+ /* output buffer full, repeat */ |
+ } else { |
+ handle_zerror(err, zstream.msg); |
+ exit(ERRX); |
} |
- longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR), |
- entry->central.localhdr_offset); |
- inttox(zipfile->time, entry->central.time); |
- inttox(zipfile->date, entry->central.date); |
- inttox(Z_DEFLATED, entry->central.method); |
+ if (PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ zstream.avail_out = BUFSIZ; |
+ zstream.next_out = outbuf; |
+ } |
- /* Compute crc. Too bad we have to process the whole file to do this*/ |
- crc = crc32(0L, NULL, 0); |
- while ( (num = PR_Read(readfp, inbuf, BUFSIZ)) > 0) { |
- crc = crc32(crc, inbuf, num); |
+ /* If there's any output left, write it out. */ |
+ if (zstream.next_out != outbuf) { |
+ if (PR_Write(zipfp, outbuf, zstream.next_out - outbuf) < |
+ zstream.next_out - outbuf) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
} |
- PR_Seek(readfp, 0L, PR_SEEK_SET); |
+ zstream.avail_out = BUFSIZ; |
+ zstream.next_out = outbuf; |
+ } |
- /* Store CRC */ |
- longtox(crc, entry->local.crc32); |
- longtox(crc, entry->central.crc32); |
+ /* Now that we know the compressed size, write this to the headers */ |
+ longtox(zstream.total_in, entry->local.orglen); |
+ longtox(zstream.total_out, entry->local.size); |
+ if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ if (PR_Write(zipfp, entry->local.size, 8) != 8) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ longtox(zstream.total_in, entry->central.orglen); |
+ longtox(zstream.total_out, entry->central.size); |
- /* Stick this entry onto the end of the list */ |
- entry->next = NULL; |
- if ( zipfile->list == NULL ) { |
- /* First entry */ |
- zipfile->list = entry; |
- } else { |
- ZIPentry * pe; |
+ /* Close out the deflation operation */ |
+ err = deflateEnd(&zstream); |
+ if (err != Z_OK) { |
+ handle_zerror(err, zstream.msg); |
+ exit(ERRX); |
+ } |
- pe = zipfile->list; |
- while (pe->next != NULL) { |
- pe = pe->next; |
- } |
- pe->next = entry; |
- } |
+ PR_Close(readfp); |
- /* |
- * Start writing stuff out |
- */ |
+ if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) { |
+ deflate_percent = |
+ (int)((zstream.total_in - zstream.total_out) * 100 / zstream.total_in); |
+ } else { |
+ deflate_percent = 0; |
+ } |
+ if (verbosity >= 0) { |
+ PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent); |
+ } |
- local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18; |
- /* File header */ |
- if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal )) |
- < sizeof(struct ZipLocal )) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : |
- ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- |
- /* File Name */ |
- if ( PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : |
- ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- |
- /* |
- * File data |
- */ |
- /* Initialize zstream */ |
- zstream.zalloc = my_alloc_func; |
- zstream.zfree = my_free_func; |
- zstream.opaque = NULL; |
- zstream.next_in = inbuf; |
- zstream.avail_in = BUFSIZ; |
- zstream.next_out = outbuf; |
- zstream.avail_out = BUFSIZ; |
- /* Setting the windowBits to -MAX_WBITS is an undocumented feature of |
- * zlib (see deflate.c in zlib). It is the same thing that Java does |
- * when you specify the nowrap option for deflation in java.util.zip. |
- * It causes zlib to leave out its headers and footers, which don't |
- * work in PKZIP files. |
- */ |
- err = deflateInit2(&zstream, compression_level, Z_DEFLATED, |
- -MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY); |
- if (err != Z_OK) { |
- handle_zerror(err, zstream.msg); |
- exit(ERRX); |
- } |
- |
- while ( (zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ)) > 0) { |
- zstream.next_in = inbuf; |
- /* Process this chunk of data */ |
- while (zstream.avail_in > 0) { |
- err = deflate(&zstream, Z_NO_FLUSH); |
- if (err != Z_OK) { |
- handle_zerror(err, zstream.msg); |
- exit(ERRX); |
- } |
- if (zstream.avail_out <= 0) { |
- if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- zstream.next_out = outbuf; |
- zstream.avail_out = BUFSIZ; |
- } |
- } |
- } |
- |
- /* Now flush everything */ |
- while (1) { |
- err = deflate(&zstream, Z_FINISH); |
- if (err == Z_STREAM_END) { |
- break; |
- } else if (err == Z_OK) { |
- /* output buffer full, repeat */ |
- } else { |
- handle_zerror(err, zstream.msg); |
- exit(ERRX); |
- } |
- if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- zstream.avail_out = BUFSIZ; |
- zstream.next_out = outbuf; |
- } |
- |
- /* If there's any output left, write it out. */ |
- if (zstream.next_out != outbuf) { |
- if ( PR_Write(zipfp, outbuf, zstream.next_out - outbuf) < |
- zstream.next_out - outbuf) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- zstream.avail_out = BUFSIZ; |
- zstream.next_out = outbuf; |
- } |
- |
- /* Now that we know the compressed size, write this to the headers */ |
- longtox(zstream.total_in, entry->local.orglen); |
- longtox(zstream.total_out, entry->local.size); |
- if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- if ( PR_Write(zipfp, entry->local.size, 8) != 8) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Accessing zip file: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- longtox(zstream.total_in, entry->central.orglen); |
- longtox(zstream.total_out, entry->central.size); |
- |
- /* Close out the deflation operation */ |
- err = deflateEnd(&zstream); |
- if (err != Z_OK) { |
- handle_zerror(err, zstream.msg); |
- exit(ERRX); |
- } |
- |
- PR_Close(readfp); |
- |
- if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) { |
- deflate_percent = (int) |
- ((zstream.total_in - zstream.total_out) *100 / zstream.total_in); |
- } else { |
- deflate_percent = 0; |
- } |
- if (verbosity >= 0) { |
- PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent); |
- } |
- |
- return 0; |
+ return 0; |
} |
- |
/******************************************************************** |
* J z i p C l o s e |
* |
* Finishes the ZipFile. ALSO DELETES THE ZIPFILE STRUCTURE PASSED IN!! |
*/ |
-int |
-JzipClose(ZIPfile *zipfile) |
-{ |
- ZIPentry * pe, *dead; |
- PRFileDesc * zipfp; |
- struct ZipEnd zipend; |
- unsigned int entrycount = 0; |
+int JzipClose(ZIPfile *zipfile) { |
+ ZIPentry *pe, *dead; |
+ PRFileDesc *zipfp; |
+ struct ZipEnd zipend; |
+ unsigned int entrycount = 0; |
- if (!zipfile) { |
- return - 1; |
+ if (!zipfile) { |
+ return -1; |
+ } |
+ |
+ if (!zipfile->filename) { |
+ /* bogus */ |
+ return 0; |
+ } |
+ |
+ zipfp = zipfile->fp; |
+ zipfile->central_start = PR_Seek(zipfp, 0L, PR_SEEK_CUR); |
+ |
+ /* Write out all the central directories */ |
+ pe = zipfile->list; |
+ while (pe) { |
+ entrycount++; |
+ |
+ /* Write central directory info */ |
+ if (PR_Write(zipfp, &pe->central, sizeof(struct ZipCentral)) < |
+ sizeof(struct ZipCentral)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
} |
- if (!zipfile->filename) { |
- /* bogus */ |
- return 0; |
+ /* Write filename */ |
+ if (PR_Write(zipfp, pe->filename, strlen(pe->filename)) < |
+ strlen(pe->filename)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
} |
- zipfp = zipfile->fp; |
- zipfile->central_start = PR_Seek(zipfp, 0L, PR_SEEK_CUR); |
- |
- /* Write out all the central directories */ |
- pe = zipfile->list; |
- while (pe) { |
- entrycount++; |
- |
- /* Write central directory info */ |
- if ( PR_Write(zipfp, &pe->central, sizeof(struct ZipCentral )) |
- < sizeof(struct ZipCentral )) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- |
- /* Write filename */ |
- if ( PR_Write(zipfp, pe->filename, strlen(pe->filename)) |
- < strlen(pe->filename)) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- |
- /* Write file comment */ |
- if (pe->comment) { |
- if ( PR_Write(zipfp, pe->comment, strlen(pe->comment)) |
- < strlen(pe->comment)) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
- } |
- |
- /* Delete the structure */ |
- dead = pe; |
- pe = pe->next; |
- if (dead->filename) { |
- PORT_Free(dead->filename); |
- } |
- if (dead->comment) { |
- PORT_Free(dead->comment); |
- } |
- PORT_Free(dead); |
- } |
- zipfile->central_end = PR_Seek(zipfile->fp, 0L, PR_SEEK_CUR); |
- |
- /* Create the ZipEnd structure */ |
- PORT_Memset(&zipend, 0, sizeof(zipend)); |
- longtox(ESIG, zipend.signature); |
- inttox(entrycount, zipend.total_entries_disk); |
- inttox(entrycount, zipend.total_entries_archive); |
- longtox(zipfile->central_end - zipfile->central_start, |
- zipend.central_dir_size); |
- longtox(zipfile->central_start, zipend.offset_central_dir); |
- if (zipfile->comment) { |
- inttox(strlen(zipfile->comment), zipend.commentfield_len); |
+ /* Write file comment */ |
+ if (pe->comment) { |
+ if (PR_Write(zipfp, pe->comment, strlen(pe->comment)) < |
+ strlen(pe->comment)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
} |
- /* Write out ZipEnd xtructure */ |
- if ( PR_Write(zipfp, &zipend, sizeof(zipend)) < sizeof(zipend)) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
+ /* Delete the structure */ |
+ dead = pe; |
+ pe = pe->next; |
+ if (dead->filename) { |
+ PORT_Free(dead->filename); |
} |
+ if (dead->comment) { |
+ PORT_Free(dead->comment); |
+ } |
+ PORT_Free(dead); |
+ } |
+ zipfile->central_end = PR_Seek(zipfile->fp, 0L, PR_SEEK_CUR); |
- /* Write out Zipfile comment */ |
- if (zipfile->comment) { |
- if ( PR_Write(zipfp, zipfile->comment, strlen(zipfile->comment)) |
- < strlen(zipfile->comment)) { |
- char *nsprErr; |
- if (PR_GetErrorTextLength()) { |
- nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
- PR_GetErrorText(nsprErr); |
- } else { |
- nsprErr = NULL; |
- } |
- PR_fprintf(errorFD, "Writing zip data: %s\n", |
- nsprErr ? nsprErr : ""); |
- if (nsprErr) |
- PR_Free(nsprErr); |
- errorCount++; |
- exit(ERRX); |
- } |
+ /* Create the ZipEnd structure */ |
+ PORT_Memset(&zipend, 0, sizeof(zipend)); |
+ longtox(ESIG, zipend.signature); |
+ inttox(entrycount, zipend.total_entries_disk); |
+ inttox(entrycount, zipend.total_entries_archive); |
+ longtox(zipfile->central_end - zipfile->central_start, |
+ zipend.central_dir_size); |
+ longtox(zipfile->central_start, zipend.offset_central_dir); |
+ if (zipfile->comment) { |
+ inttox(strlen(zipfile->comment), zipend.commentfield_len); |
+ } |
+ |
+ /* Write out ZipEnd xtructure */ |
+ if (PR_Write(zipfp, &zipend, sizeof(zipend)) < sizeof(zipend)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
} |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
- PR_Close(zipfp); |
+ /* Write out Zipfile comment */ |
+ if (zipfile->comment) { |
+ if (PR_Write(zipfp, zipfile->comment, strlen(zipfile->comment)) < |
+ strlen(zipfile->comment)) { |
+ char *nsprErr; |
+ if (PR_GetErrorTextLength()) { |
+ nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1); |
+ PR_GetErrorText(nsprErr); |
+ } else { |
+ nsprErr = NULL; |
+ } |
+ PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : ""); |
+ if (nsprErr) PR_Free(nsprErr); |
+ errorCount++; |
+ exit(ERRX); |
+ } |
+ } |
- /* Free the memory of the zipfile structure */ |
- if (zipfile->filename) { |
- PORT_Free(zipfile->filename); |
- } |
- if (zipfile->comment) { |
- PORT_Free(zipfile->comment); |
- } |
- PORT_Free(zipfile); |
+ PR_Close(zipfp); |
- return 0; |
+ /* Free the memory of the zipfile structure */ |
+ if (zipfile->filename) { |
+ PORT_Free(zipfile->filename); |
+ } |
+ if (zipfile->comment) { |
+ PORT_Free(zipfile->comment); |
+ } |
+ PORT_Free(zipfile); |
+ |
+ return 0; |
} |
- |
/********************************************** |
* i n t t o x |
* |
* Converts a two byte ugly endianed integer |
* to our platform's integer. |
* |
*/ |
-static void inttox (int in, char *out) |
-{ |
- out [0] = (in & 0xFF); |
- out [1] = (in & 0xFF00) >> 8; |
+static void inttox(int in, char *out) { |
+ out[0] = (in & 0xFF); |
+ out[1] = (in & 0xFF00) >> 8; |
} |
- |
/********************************************* |
* l o n g t o x |
* |
* Converts a four byte ugly endianed integer |
* to our platform's integer. |
* |
*/ |
-static void longtox (long in, char *out) |
-{ |
- out [0] = (in & 0xFF); |
- out [1] = (in & 0xFF00) >> 8; |
- out [2] = (in & 0xFF0000) >> 16; |
- out [3] = (in & 0xFF000000) >> 24; |
+static void longtox(long in, char *out) { |
+ out[0] = (in & 0xFF); |
+ out[1] = (in & 0xFF00) >> 8; |
+ out[2] = (in & 0xFF0000) >> 16; |
+ out[3] = (in & 0xFF000000) >> 24; |
} |
- |
- |