security/nss/cmd/signtool/zip.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "signtool.h"
michael@0 6 #include "zip.h"
michael@0 7 #include "zlib.h"
michael@0 8 #include "prmem.h"
michael@0 9
michael@0 10 static void inttox (int in, char *out);
michael@0 11 static void longtox (long in, char *out);
michael@0 12
michael@0 13 /****************************************************************
michael@0 14 *
michael@0 15 * J z i p O p e n
michael@0 16 *
michael@0 17 * Opens a new ZIP file and creates a new ZIPfile structure to
michael@0 18 * control the process of installing files into a zip.
michael@0 19 */
michael@0 20 ZIPfile*
michael@0 21 JzipOpen(char *filename, char *comment)
michael@0 22 {
michael@0 23 ZIPfile * zipfile;
michael@0 24 PRExplodedTime prtime;
michael@0 25
michael@0 26 zipfile = PORT_ZAlloc(sizeof(ZIPfile));
michael@0 27 if (!zipfile)
michael@0 28 out_of_memory();
michael@0 29
michael@0 30 /* Construct time and date */
michael@0 31 PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime);
michael@0 32 zipfile->date = ((prtime.tm_year - 1980) << 9) |
michael@0 33 ((prtime.tm_month + 1) << 5) |
michael@0 34 prtime.tm_mday;
michael@0 35 zipfile->time = (prtime.tm_hour << 11) |
michael@0 36 (prtime.tm_min << 5) |
michael@0 37 (prtime.tm_sec & 0x3f);
michael@0 38
michael@0 39 zipfile->fp = NULL;
michael@0 40 if (filename &&
michael@0 41 (zipfile->fp = PR_Open(filename,
michael@0 42 PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777)) == NULL) {
michael@0 43 char *nsprErr;
michael@0 44 if (PR_GetErrorTextLength()) {
michael@0 45 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 46 PR_GetErrorText(nsprErr);
michael@0 47 } else {
michael@0 48 nsprErr = NULL;
michael@0 49 }
michael@0 50 PR_fprintf(errorFD, "%s: can't open output jar, %s.%s\n",
michael@0 51 PROGRAM_NAME,
michael@0 52 filename, nsprErr ? nsprErr : "");
michael@0 53 if (nsprErr)
michael@0 54 PR_Free(nsprErr);
michael@0 55 errorCount++;
michael@0 56 exit (ERRX);
michael@0 57 }
michael@0 58
michael@0 59 zipfile->list = NULL;
michael@0 60 if (filename) {
michael@0 61 zipfile->filename = PORT_ZAlloc(strlen(filename) + 1);
michael@0 62 if (!zipfile->filename)
michael@0 63 out_of_memory();
michael@0 64 PORT_Strcpy(zipfile->filename, filename);
michael@0 65 }
michael@0 66 if (comment) {
michael@0 67 zipfile->comment = PORT_ZAlloc(strlen(comment) + 1);
michael@0 68 if (!zipfile->comment)
michael@0 69 out_of_memory();
michael@0 70 PORT_Strcpy(zipfile->comment, comment);
michael@0 71 }
michael@0 72
michael@0 73 return zipfile;
michael@0 74 }
michael@0 75
michael@0 76
michael@0 77 static
michael@0 78 void*
michael@0 79 my_alloc_func(void*opaque, uInt items, uInt size)
michael@0 80 {
michael@0 81 return PORT_Alloc(items * size);
michael@0 82 }
michael@0 83
michael@0 84
michael@0 85 static
michael@0 86 void
michael@0 87 my_free_func(void*opaque, void*address)
michael@0 88 {
michael@0 89 PORT_Free(address);
michael@0 90 }
michael@0 91
michael@0 92
michael@0 93 static
michael@0 94 void
michael@0 95 handle_zerror(int err, char *msg)
michael@0 96 {
michael@0 97 if (!msg) {
michael@0 98 msg = "";
michael@0 99 }
michael@0 100
michael@0 101 errorCount++; /* unless Z_OK...see below */
michael@0 102
michael@0 103 switch (err) {
michael@0 104 case Z_OK:
michael@0 105 PR_fprintf(errorFD, "No error: %s\n", msg);
michael@0 106 errorCount--; /* this was incremented above */
michael@0 107 break;
michael@0 108 case Z_MEM_ERROR:
michael@0 109 PR_fprintf(errorFD, "Deflation ran out of memory: %s\n", msg);
michael@0 110 break;
michael@0 111 case Z_STREAM_ERROR:
michael@0 112 PR_fprintf(errorFD, "Invalid compression level: %s\n", msg);
michael@0 113 break;
michael@0 114 case Z_VERSION_ERROR:
michael@0 115 PR_fprintf(errorFD, "Incompatible compression library version: %s\n",
michael@0 116 msg);
michael@0 117 break;
michael@0 118 case Z_DATA_ERROR:
michael@0 119 PR_fprintf(errorFD, "Compression data error: %s\n", msg);
michael@0 120 break;
michael@0 121 default:
michael@0 122 PR_fprintf(errorFD, "Unknown error in compression library: %s\n", msg);
michael@0 123 break;
michael@0 124 }
michael@0 125 }
michael@0 126
michael@0 127
michael@0 128
michael@0 129
michael@0 130 /****************************************************************
michael@0 131 *
michael@0 132 * J z i p A d d
michael@0 133 *
michael@0 134 * Adds a new file into a ZIP file. The ZIP file must have already
michael@0 135 * been opened with JzipOpen.
michael@0 136 */
michael@0 137 int
michael@0 138 JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level)
michael@0 139 {
michael@0 140 ZIPentry * entry;
michael@0 141 PRFileDesc * readfp;
michael@0 142 PRFileDesc * zipfp;
michael@0 143 unsigned long crc;
michael@0 144 unsigned long local_size_pos;
michael@0 145 int num;
michael@0 146 int err;
michael@0 147 int deflate_percent;
michael@0 148 z_stream zstream;
michael@0 149 Bytef inbuf[BUFSIZ];
michael@0 150 Bytef outbuf[BUFSIZ];
michael@0 151
michael@0 152
michael@0 153 if ( !fullname || !filename || !zipfile) {
michael@0 154 return - 1;
michael@0 155 }
michael@0 156
michael@0 157 zipfp = zipfile->fp;
michael@0 158 if (!zipfp)
michael@0 159 return - 1;
michael@0 160
michael@0 161
michael@0 162 if ( (readfp = PR_Open(fullname, PR_RDONLY, 0777)) == NULL) {
michael@0 163 char *nsprErr;
michael@0 164 if (PR_GetErrorTextLength()) {
michael@0 165 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 166 PR_GetErrorText(nsprErr);
michael@0 167 } else {
michael@0 168 nsprErr = NULL;
michael@0 169 }
michael@0 170 PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr :
michael@0 171 "");
michael@0 172 errorCount++;
michael@0 173 if (nsprErr)
michael@0 174 PR_Free(nsprErr);
michael@0 175 exit(ERRX);
michael@0 176 }
michael@0 177
michael@0 178 /*
michael@0 179 * Make sure the input file is not the output file.
michael@0 180 * Add a few bytes to the end of the JAR file and see if the input file
michael@0 181 * twitches
michael@0 182 */
michael@0 183 {
michael@0 184 PRInt32 endOfJar;
michael@0 185 PRInt32 inputSize;
michael@0 186 PRBool isSame;
michael@0 187
michael@0 188 inputSize = PR_Available(readfp);
michael@0 189
michael@0 190 endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR);
michael@0 191
michael@0 192 if (PR_Write(zipfp, "abcde", 5) < 5) {
michael@0 193 char *nsprErr;
michael@0 194
michael@0 195 if (PR_GetErrorTextLength()) {
michael@0 196 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 197 PR_GetErrorText(nsprErr);
michael@0 198 } else {
michael@0 199 nsprErr = NULL;
michael@0 200 }
michael@0 201 PR_fprintf(errorFD, "Writing to zip file: %s\n",
michael@0 202 nsprErr ? nsprErr : "");
michael@0 203 if (nsprErr)
michael@0 204 PR_Free(nsprErr);
michael@0 205 errorCount++;
michael@0 206 exit(ERRX);
michael@0 207 }
michael@0 208
michael@0 209 isSame = (PR_Available(readfp) != inputSize);
michael@0 210
michael@0 211 PR_Seek(zipfp, endOfJar, PR_SEEK_SET);
michael@0 212
michael@0 213 if (isSame) {
michael@0 214 /* It's the same file! Forget it! */
michael@0 215 PR_Close(readfp);
michael@0 216 return 0;
michael@0 217 }
michael@0 218 }
michael@0 219
michael@0 220 if (verbosity >= 0) {
michael@0 221 PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename);
michael@0 222 }
michael@0 223
michael@0 224 entry = PORT_ZAlloc(sizeof(ZIPentry));
michael@0 225 if (!entry)
michael@0 226 out_of_memory();
michael@0 227
michael@0 228 entry->filename = PORT_Strdup(filename);
michael@0 229 entry->comment = NULL;
michael@0 230
michael@0 231 /* Set up local file header */
michael@0 232 longtox(LSIG, entry->local.signature);
michael@0 233 inttox(strlen(filename), entry->local.filename_len);
michael@0 234 inttox(zipfile->time, entry->local.time);
michael@0 235 inttox(zipfile->date, entry->local.date);
michael@0 236 inttox(Z_DEFLATED, entry->local.method);
michael@0 237
michael@0 238 /* Set up central directory entry */
michael@0 239 longtox(CSIG, entry->central.signature);
michael@0 240 inttox(strlen(filename), entry->central.filename_len);
michael@0 241 if (entry->comment) {
michael@0 242 inttox(strlen(entry->comment), entry->central.commentfield_len);
michael@0 243 }
michael@0 244 longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR),
michael@0 245 entry->central.localhdr_offset);
michael@0 246 inttox(zipfile->time, entry->central.time);
michael@0 247 inttox(zipfile->date, entry->central.date);
michael@0 248 inttox(Z_DEFLATED, entry->central.method);
michael@0 249
michael@0 250 /* Compute crc. Too bad we have to process the whole file to do this*/
michael@0 251 crc = crc32(0L, NULL, 0);
michael@0 252 while ( (num = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
michael@0 253 crc = crc32(crc, inbuf, num);
michael@0 254 }
michael@0 255 PR_Seek(readfp, 0L, PR_SEEK_SET);
michael@0 256
michael@0 257 /* Store CRC */
michael@0 258 longtox(crc, entry->local.crc32);
michael@0 259 longtox(crc, entry->central.crc32);
michael@0 260
michael@0 261 /* Stick this entry onto the end of the list */
michael@0 262 entry->next = NULL;
michael@0 263 if ( zipfile->list == NULL ) {
michael@0 264 /* First entry */
michael@0 265 zipfile->list = entry;
michael@0 266 } else {
michael@0 267 ZIPentry * pe;
michael@0 268
michael@0 269 pe = zipfile->list;
michael@0 270 while (pe->next != NULL) {
michael@0 271 pe = pe->next;
michael@0 272 }
michael@0 273 pe->next = entry;
michael@0 274 }
michael@0 275
michael@0 276 /*
michael@0 277 * Start writing stuff out
michael@0 278 */
michael@0 279
michael@0 280 local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18;
michael@0 281 /* File header */
michael@0 282 if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal ))
michael@0 283 < sizeof(struct ZipLocal )) {
michael@0 284 char *nsprErr;
michael@0 285 if (PR_GetErrorTextLength()) {
michael@0 286 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 287 PR_GetErrorText(nsprErr);
michael@0 288 } else {
michael@0 289 nsprErr = NULL;
michael@0 290 }
michael@0 291 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr :
michael@0 292 "");
michael@0 293 if (nsprErr)
michael@0 294 PR_Free(nsprErr);
michael@0 295 errorCount++;
michael@0 296 exit(ERRX);
michael@0 297 }
michael@0 298
michael@0 299 /* File Name */
michael@0 300 if ( PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) {
michael@0 301 char *nsprErr;
michael@0 302 if (PR_GetErrorTextLength()) {
michael@0 303 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 304 PR_GetErrorText(nsprErr);
michael@0 305 } else {
michael@0 306 nsprErr = NULL;
michael@0 307 }
michael@0 308 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr :
michael@0 309 "");
michael@0 310 if (nsprErr)
michael@0 311 PR_Free(nsprErr);
michael@0 312 errorCount++;
michael@0 313 exit(ERRX);
michael@0 314 }
michael@0 315
michael@0 316 /*
michael@0 317 * File data
michael@0 318 */
michael@0 319 /* Initialize zstream */
michael@0 320 zstream.zalloc = my_alloc_func;
michael@0 321 zstream.zfree = my_free_func;
michael@0 322 zstream.opaque = NULL;
michael@0 323 zstream.next_in = inbuf;
michael@0 324 zstream.avail_in = BUFSIZ;
michael@0 325 zstream.next_out = outbuf;
michael@0 326 zstream.avail_out = BUFSIZ;
michael@0 327 /* Setting the windowBits to -MAX_WBITS is an undocumented feature of
michael@0 328 * zlib (see deflate.c in zlib). It is the same thing that Java does
michael@0 329 * when you specify the nowrap option for deflation in java.util.zip.
michael@0 330 * It causes zlib to leave out its headers and footers, which don't
michael@0 331 * work in PKZIP files.
michael@0 332 */
michael@0 333 err = deflateInit2(&zstream, compression_level, Z_DEFLATED,
michael@0 334 -MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY);
michael@0 335 if (err != Z_OK) {
michael@0 336 handle_zerror(err, zstream.msg);
michael@0 337 exit(ERRX);
michael@0 338 }
michael@0 339
michael@0 340 while ( (zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
michael@0 341 zstream.next_in = inbuf;
michael@0 342 /* Process this chunk of data */
michael@0 343 while (zstream.avail_in > 0) {
michael@0 344 err = deflate(&zstream, Z_NO_FLUSH);
michael@0 345 if (err != Z_OK) {
michael@0 346 handle_zerror(err, zstream.msg);
michael@0 347 exit(ERRX);
michael@0 348 }
michael@0 349 if (zstream.avail_out <= 0) {
michael@0 350 if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
michael@0 351 char *nsprErr;
michael@0 352 if (PR_GetErrorTextLength()) {
michael@0 353 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 354 PR_GetErrorText(nsprErr);
michael@0 355 } else {
michael@0 356 nsprErr = NULL;
michael@0 357 }
michael@0 358 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 359 nsprErr ? nsprErr : "");
michael@0 360 if (nsprErr)
michael@0 361 PR_Free(nsprErr);
michael@0 362 errorCount++;
michael@0 363 exit(ERRX);
michael@0 364 }
michael@0 365 zstream.next_out = outbuf;
michael@0 366 zstream.avail_out = BUFSIZ;
michael@0 367 }
michael@0 368 }
michael@0 369 }
michael@0 370
michael@0 371 /* Now flush everything */
michael@0 372 while (1) {
michael@0 373 err = deflate(&zstream, Z_FINISH);
michael@0 374 if (err == Z_STREAM_END) {
michael@0 375 break;
michael@0 376 } else if (err == Z_OK) {
michael@0 377 /* output buffer full, repeat */
michael@0 378 } else {
michael@0 379 handle_zerror(err, zstream.msg);
michael@0 380 exit(ERRX);
michael@0 381 }
michael@0 382 if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
michael@0 383 char *nsprErr;
michael@0 384 if (PR_GetErrorTextLength()) {
michael@0 385 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 386 PR_GetErrorText(nsprErr);
michael@0 387 } else {
michael@0 388 nsprErr = NULL;
michael@0 389 }
michael@0 390 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 391 nsprErr ? nsprErr : "");
michael@0 392 if (nsprErr)
michael@0 393 PR_Free(nsprErr);
michael@0 394 errorCount++;
michael@0 395 exit(ERRX);
michael@0 396 }
michael@0 397 zstream.avail_out = BUFSIZ;
michael@0 398 zstream.next_out = outbuf;
michael@0 399 }
michael@0 400
michael@0 401 /* If there's any output left, write it out. */
michael@0 402 if (zstream.next_out != outbuf) {
michael@0 403 if ( PR_Write(zipfp, outbuf, zstream.next_out - outbuf) <
michael@0 404 zstream.next_out - outbuf) {
michael@0 405 char *nsprErr;
michael@0 406 if (PR_GetErrorTextLength()) {
michael@0 407 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 408 PR_GetErrorText(nsprErr);
michael@0 409 } else {
michael@0 410 nsprErr = NULL;
michael@0 411 }
michael@0 412 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 413 nsprErr ? nsprErr : "");
michael@0 414 if (nsprErr)
michael@0 415 PR_Free(nsprErr);
michael@0 416 errorCount++;
michael@0 417 exit(ERRX);
michael@0 418 }
michael@0 419 zstream.avail_out = BUFSIZ;
michael@0 420 zstream.next_out = outbuf;
michael@0 421 }
michael@0 422
michael@0 423 /* Now that we know the compressed size, write this to the headers */
michael@0 424 longtox(zstream.total_in, entry->local.orglen);
michael@0 425 longtox(zstream.total_out, entry->local.size);
michael@0 426 if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) {
michael@0 427 char *nsprErr;
michael@0 428 if (PR_GetErrorTextLength()) {
michael@0 429 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 430 PR_GetErrorText(nsprErr);
michael@0 431 } else {
michael@0 432 nsprErr = NULL;
michael@0 433 }
michael@0 434 PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : "");
michael@0 435 if (nsprErr)
michael@0 436 PR_Free(nsprErr);
michael@0 437 errorCount++;
michael@0 438 exit(ERRX);
michael@0 439 }
michael@0 440 if ( PR_Write(zipfp, entry->local.size, 8) != 8) {
michael@0 441 char *nsprErr;
michael@0 442 if (PR_GetErrorTextLength()) {
michael@0 443 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 444 PR_GetErrorText(nsprErr);
michael@0 445 } else {
michael@0 446 nsprErr = NULL;
michael@0 447 }
michael@0 448 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
michael@0 449 if (nsprErr)
michael@0 450 PR_Free(nsprErr);
michael@0 451 errorCount++;
michael@0 452 exit(ERRX);
michael@0 453 }
michael@0 454 if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) {
michael@0 455 char *nsprErr;
michael@0 456 if (PR_GetErrorTextLength()) {
michael@0 457 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 458 PR_GetErrorText(nsprErr);
michael@0 459 } else {
michael@0 460 nsprErr = NULL;
michael@0 461 }
michael@0 462 PR_fprintf(errorFD, "Accessing zip file: %s\n",
michael@0 463 nsprErr ? nsprErr : "");
michael@0 464 if (nsprErr)
michael@0 465 PR_Free(nsprErr);
michael@0 466 errorCount++;
michael@0 467 exit(ERRX);
michael@0 468 }
michael@0 469 longtox(zstream.total_in, entry->central.orglen);
michael@0 470 longtox(zstream.total_out, entry->central.size);
michael@0 471
michael@0 472 /* Close out the deflation operation */
michael@0 473 err = deflateEnd(&zstream);
michael@0 474 if (err != Z_OK) {
michael@0 475 handle_zerror(err, zstream.msg);
michael@0 476 exit(ERRX);
michael@0 477 }
michael@0 478
michael@0 479 PR_Close(readfp);
michael@0 480
michael@0 481 if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) {
michael@0 482 deflate_percent = (int)
michael@0 483 ((zstream.total_in - zstream.total_out) *100 / zstream.total_in);
michael@0 484 } else {
michael@0 485 deflate_percent = 0;
michael@0 486 }
michael@0 487 if (verbosity >= 0) {
michael@0 488 PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent);
michael@0 489 }
michael@0 490
michael@0 491 return 0;
michael@0 492 }
michael@0 493
michael@0 494
michael@0 495 /********************************************************************
michael@0 496 * J z i p C l o s e
michael@0 497 *
michael@0 498 * Finishes the ZipFile. ALSO DELETES THE ZIPFILE STRUCTURE PASSED IN!!
michael@0 499 */
michael@0 500 int
michael@0 501 JzipClose(ZIPfile *zipfile)
michael@0 502 {
michael@0 503 ZIPentry * pe, *dead;
michael@0 504 PRFileDesc * zipfp;
michael@0 505 struct ZipEnd zipend;
michael@0 506 unsigned int entrycount = 0;
michael@0 507
michael@0 508 if (!zipfile) {
michael@0 509 return - 1;
michael@0 510 }
michael@0 511
michael@0 512 if (!zipfile->filename) {
michael@0 513 /* bogus */
michael@0 514 return 0;
michael@0 515 }
michael@0 516
michael@0 517 zipfp = zipfile->fp;
michael@0 518 zipfile->central_start = PR_Seek(zipfp, 0L, PR_SEEK_CUR);
michael@0 519
michael@0 520 /* Write out all the central directories */
michael@0 521 pe = zipfile->list;
michael@0 522 while (pe) {
michael@0 523 entrycount++;
michael@0 524
michael@0 525 /* Write central directory info */
michael@0 526 if ( PR_Write(zipfp, &pe->central, sizeof(struct ZipCentral ))
michael@0 527 < sizeof(struct ZipCentral )) {
michael@0 528 char *nsprErr;
michael@0 529 if (PR_GetErrorTextLength()) {
michael@0 530 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 531 PR_GetErrorText(nsprErr);
michael@0 532 } else {
michael@0 533 nsprErr = NULL;
michael@0 534 }
michael@0 535 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 536 nsprErr ? nsprErr : "");
michael@0 537 if (nsprErr)
michael@0 538 PR_Free(nsprErr);
michael@0 539 errorCount++;
michael@0 540 exit(ERRX);
michael@0 541 }
michael@0 542
michael@0 543 /* Write filename */
michael@0 544 if ( PR_Write(zipfp, pe->filename, strlen(pe->filename))
michael@0 545 < strlen(pe->filename)) {
michael@0 546 char *nsprErr;
michael@0 547 if (PR_GetErrorTextLength()) {
michael@0 548 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 549 PR_GetErrorText(nsprErr);
michael@0 550 } else {
michael@0 551 nsprErr = NULL;
michael@0 552 }
michael@0 553 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 554 nsprErr ? nsprErr : "");
michael@0 555 if (nsprErr)
michael@0 556 PR_Free(nsprErr);
michael@0 557 errorCount++;
michael@0 558 exit(ERRX);
michael@0 559 }
michael@0 560
michael@0 561 /* Write file comment */
michael@0 562 if (pe->comment) {
michael@0 563 if ( PR_Write(zipfp, pe->comment, strlen(pe->comment))
michael@0 564 < strlen(pe->comment)) {
michael@0 565 char *nsprErr;
michael@0 566 if (PR_GetErrorTextLength()) {
michael@0 567 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 568 PR_GetErrorText(nsprErr);
michael@0 569 } else {
michael@0 570 nsprErr = NULL;
michael@0 571 }
michael@0 572 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 573 nsprErr ? nsprErr : "");
michael@0 574 if (nsprErr)
michael@0 575 PR_Free(nsprErr);
michael@0 576 errorCount++;
michael@0 577 exit(ERRX);
michael@0 578 }
michael@0 579 }
michael@0 580
michael@0 581 /* Delete the structure */
michael@0 582 dead = pe;
michael@0 583 pe = pe->next;
michael@0 584 if (dead->filename) {
michael@0 585 PORT_Free(dead->filename);
michael@0 586 }
michael@0 587 if (dead->comment) {
michael@0 588 PORT_Free(dead->comment);
michael@0 589 }
michael@0 590 PORT_Free(dead);
michael@0 591 }
michael@0 592 zipfile->central_end = PR_Seek(zipfile->fp, 0L, PR_SEEK_CUR);
michael@0 593
michael@0 594 /* Create the ZipEnd structure */
michael@0 595 PORT_Memset(&zipend, 0, sizeof(zipend));
michael@0 596 longtox(ESIG, zipend.signature);
michael@0 597 inttox(entrycount, zipend.total_entries_disk);
michael@0 598 inttox(entrycount, zipend.total_entries_archive);
michael@0 599 longtox(zipfile->central_end - zipfile->central_start,
michael@0 600 zipend.central_dir_size);
michael@0 601 longtox(zipfile->central_start, zipend.offset_central_dir);
michael@0 602 if (zipfile->comment) {
michael@0 603 inttox(strlen(zipfile->comment), zipend.commentfield_len);
michael@0 604 }
michael@0 605
michael@0 606 /* Write out ZipEnd xtructure */
michael@0 607 if ( PR_Write(zipfp, &zipend, sizeof(zipend)) < sizeof(zipend)) {
michael@0 608 char *nsprErr;
michael@0 609 if (PR_GetErrorTextLength()) {
michael@0 610 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 611 PR_GetErrorText(nsprErr);
michael@0 612 } else {
michael@0 613 nsprErr = NULL;
michael@0 614 }
michael@0 615 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 616 nsprErr ? nsprErr : "");
michael@0 617 if (nsprErr)
michael@0 618 PR_Free(nsprErr);
michael@0 619 errorCount++;
michael@0 620 exit(ERRX);
michael@0 621 }
michael@0 622
michael@0 623 /* Write out Zipfile comment */
michael@0 624 if (zipfile->comment) {
michael@0 625 if ( PR_Write(zipfp, zipfile->comment, strlen(zipfile->comment))
michael@0 626 < strlen(zipfile->comment)) {
michael@0 627 char *nsprErr;
michael@0 628 if (PR_GetErrorTextLength()) {
michael@0 629 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
michael@0 630 PR_GetErrorText(nsprErr);
michael@0 631 } else {
michael@0 632 nsprErr = NULL;
michael@0 633 }
michael@0 634 PR_fprintf(errorFD, "Writing zip data: %s\n",
michael@0 635 nsprErr ? nsprErr : "");
michael@0 636 if (nsprErr)
michael@0 637 PR_Free(nsprErr);
michael@0 638 errorCount++;
michael@0 639 exit(ERRX);
michael@0 640 }
michael@0 641 }
michael@0 642
michael@0 643 PR_Close(zipfp);
michael@0 644
michael@0 645 /* Free the memory of the zipfile structure */
michael@0 646 if (zipfile->filename) {
michael@0 647 PORT_Free(zipfile->filename);
michael@0 648 }
michael@0 649 if (zipfile->comment) {
michael@0 650 PORT_Free(zipfile->comment);
michael@0 651 }
michael@0 652 PORT_Free(zipfile);
michael@0 653
michael@0 654 return 0;
michael@0 655 }
michael@0 656
michael@0 657
michael@0 658 /**********************************************
michael@0 659 * i n t t o x
michael@0 660 *
michael@0 661 * Converts a two byte ugly endianed integer
michael@0 662 * to our platform's integer.
michael@0 663 *
michael@0 664 */
michael@0 665
michael@0 666 static void inttox (int in, char *out)
michael@0 667 {
michael@0 668 out [0] = (in & 0xFF);
michael@0 669 out [1] = (in & 0xFF00) >> 8;
michael@0 670 }
michael@0 671
michael@0 672
michael@0 673 /*********************************************
michael@0 674 * l o n g t o x
michael@0 675 *
michael@0 676 * Converts a four byte ugly endianed integer
michael@0 677 * to our platform's integer.
michael@0 678 *
michael@0 679 */
michael@0 680
michael@0 681 static void longtox (long in, char *out)
michael@0 682 {
michael@0 683 out [0] = (in & 0xFF);
michael@0 684 out [1] = (in & 0xFF00) >> 8;
michael@0 685 out [2] = (in & 0xFF0000) >> 16;
michael@0 686 out [3] = (in & 0xFF000000) >> 24;
michael@0 687 }
michael@0 688
michael@0 689

mercurial