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