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