diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:20:15 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:20:15 -0700 |
commit | c34c1fcbb19852ca35216ad66276f4f86af3fc22 (patch) | |
tree | 4bd0972d6c682e474725eca372f6551d539f8768 /contrib/minizip/zip.c | |
parent | 02b6cf579f02ec78c052735020a5d3c5723ed641 (diff) | |
download | zlib-1.1.2.tar.gz zlib-1.1.2.tar.bz2 zlib-1.1.2.zip |
zlib 1.1.2v1.1.2
Diffstat (limited to 'contrib/minizip/zip.c')
-rw-r--r-- | contrib/minizip/zip.c | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c new file mode 100644 index 0000000..ddb2334 --- /dev/null +++ b/contrib/minizip/zip.c | |||
@@ -0,0 +1,716 @@ | |||
1 | /* zip.c -- IO on .zip files using zlib | ||
2 | Version 0.15 beta, Mar 19th, 1998, | ||
3 | |||
4 | Read zip.h for more info | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | #include "zlib.h" | ||
12 | #include "zip.h" | ||
13 | |||
14 | #ifdef STDC | ||
15 | # include <stddef.h> | ||
16 | # include <string.h> | ||
17 | # include <stdlib.h> | ||
18 | #endif | ||
19 | #ifdef NO_ERRNO_H | ||
20 | extern int errno; | ||
21 | #else | ||
22 | # include <errno.h> | ||
23 | #endif | ||
24 | |||
25 | |||
26 | #ifndef local | ||
27 | # define local static | ||
28 | #endif | ||
29 | /* compile with -Dlocal if your debugger can't find static symbols */ | ||
30 | |||
31 | #ifndef VERSIONMADEBY | ||
32 | # define VERSIONMADEBY (0x0) /* platform depedent */ | ||
33 | #endif | ||
34 | |||
35 | #ifndef Z_BUFSIZE | ||
36 | #define Z_BUFSIZE (16384) | ||
37 | #endif | ||
38 | |||
39 | #ifndef Z_MAXFILENAMEINZIP | ||
40 | #define Z_MAXFILENAMEINZIP (256) | ||
41 | #endif | ||
42 | |||
43 | #ifndef ALLOC | ||
44 | # define ALLOC(size) (malloc(size)) | ||
45 | #endif | ||
46 | #ifndef TRYFREE | ||
47 | # define TRYFREE(p) {if (p) free(p);} | ||
48 | #endif | ||
49 | |||
50 | /* | ||
51 | #define SIZECENTRALDIRITEM (0x2e) | ||
52 | #define SIZEZIPLOCALHEADER (0x1e) | ||
53 | */ | ||
54 | |||
55 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ | ||
56 | |||
57 | #ifndef SEEK_CUR | ||
58 | #define SEEK_CUR 1 | ||
59 | #endif | ||
60 | |||
61 | #ifndef SEEK_END | ||
62 | #define SEEK_END 2 | ||
63 | #endif | ||
64 | |||
65 | #ifndef SEEK_SET | ||
66 | #define SEEK_SET 0 | ||
67 | #endif | ||
68 | |||
69 | const char zip_copyright[] = | ||
70 | " zip 0.15 Copyright 1998 Gilles Vollant "; | ||
71 | |||
72 | |||
73 | #define SIZEDATA_INDATABLOCK (4096-(4*4)) | ||
74 | |||
75 | #define LOCALHEADERMAGIC (0x04034b50) | ||
76 | #define CENTRALHEADERMAGIC (0x02014b50) | ||
77 | #define ENDHEADERMAGIC (0x06054b50) | ||
78 | |||
79 | #define FLAG_LOCALHEADER_OFFSET (0x06) | ||
80 | #define CRC_LOCALHEADER_OFFSET (0x0e) | ||
81 | |||
82 | #define SIZECENTRALHEADER (0x2e) /* 46 */ | ||
83 | |||
84 | typedef struct linkedlist_datablock_internal_s | ||
85 | { | ||
86 | struct linkedlist_datablock_internal_s* next_datablock; | ||
87 | uLong avail_in_this_block; | ||
88 | uLong filled_in_this_block; | ||
89 | uLong unused; /* for future use and alignement */ | ||
90 | unsigned char data[SIZEDATA_INDATABLOCK]; | ||
91 | } linkedlist_datablock_internal; | ||
92 | |||
93 | typedef struct linkedlist_data_s | ||
94 | { | ||
95 | linkedlist_datablock_internal* first_block; | ||
96 | linkedlist_datablock_internal* last_block; | ||
97 | } linkedlist_data; | ||
98 | |||
99 | |||
100 | typedef struct | ||
101 | { | ||
102 | z_stream stream; /* zLib stream structure for inflate */ | ||
103 | int stream_initialised; /* 1 is stream is initialised */ | ||
104 | uInt pos_in_buffered_data; /* last written byte in buffered_data */ | ||
105 | |||
106 | uLong pos_local_header; /* offset of the local header of the file | ||
107 | currenty writing */ | ||
108 | char* central_header; /* central header data for the current file */ | ||
109 | uLong size_centralheader; /* size of the central header for cur file */ | ||
110 | uLong flag; /* flag of the file currently writing */ | ||
111 | |||
112 | int method; /* compression method of file currenty wr.*/ | ||
113 | Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ | ||
114 | uLong dosDate; | ||
115 | uLong crc32; | ||
116 | } curfile_info; | ||
117 | |||
118 | typedef struct | ||
119 | { | ||
120 | FILE * filezip; | ||
121 | linkedlist_data central_dir;/* datablock with central dir in construction*/ | ||
122 | int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ | ||
123 | curfile_info ci; /* info on the file curretly writing */ | ||
124 | |||
125 | uLong begin_pos; /* position of the beginning of the zipfile */ | ||
126 | uLong number_entry; | ||
127 | } zip_internal; | ||
128 | |||
129 | local linkedlist_datablock_internal* allocate_new_datablock() | ||
130 | { | ||
131 | linkedlist_datablock_internal* ldi; | ||
132 | ldi = (linkedlist_datablock_internal*) | ||
133 | ALLOC(sizeof(linkedlist_datablock_internal)); | ||
134 | if (ldi!=NULL) | ||
135 | { | ||
136 | ldi->next_datablock = NULL ; | ||
137 | ldi->filled_in_this_block = 0 ; | ||
138 | ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; | ||
139 | } | ||
140 | return ldi; | ||
141 | } | ||
142 | |||
143 | local void free_datablock(ldi) | ||
144 | linkedlist_datablock_internal* ldi; | ||
145 | { | ||
146 | while (ldi!=NULL) | ||
147 | { | ||
148 | linkedlist_datablock_internal* ldinext = ldi->next_datablock; | ||
149 | TRYFREE(ldi); | ||
150 | ldi = ldinext; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | local void init_linkedlist(ll) | ||
155 | linkedlist_data* ll; | ||
156 | { | ||
157 | ll->first_block = ll->last_block = NULL; | ||
158 | } | ||
159 | |||
160 | local void free_linkedlist(ll) | ||
161 | linkedlist_data* ll; | ||
162 | { | ||
163 | free_datablock(ll->first_block); | ||
164 | ll->first_block = ll->last_block = NULL; | ||
165 | } | ||
166 | |||
167 | |||
168 | local int add_data_in_datablock(ll,buf,len) | ||
169 | linkedlist_data* ll; | ||
170 | const void* buf; | ||
171 | uLong len; | ||
172 | { | ||
173 | linkedlist_datablock_internal* ldi; | ||
174 | const unsigned char* from_copy; | ||
175 | |||
176 | if (ll==NULL) | ||
177 | return ZIP_INTERNALERROR; | ||
178 | |||
179 | if (ll->last_block == NULL) | ||
180 | { | ||
181 | ll->first_block = ll->last_block = allocate_new_datablock(); | ||
182 | if (ll->first_block == NULL) | ||
183 | return ZIP_INTERNALERROR; | ||
184 | } | ||
185 | |||
186 | ldi = ll->last_block; | ||
187 | from_copy = (unsigned char*)buf; | ||
188 | |||
189 | while (len>0) | ||
190 | { | ||
191 | uInt copy_this; | ||
192 | uInt i; | ||
193 | unsigned char* to_copy; | ||
194 | |||
195 | if (ldi->avail_in_this_block==0) | ||
196 | { | ||
197 | ldi->next_datablock = allocate_new_datablock(); | ||
198 | if (ldi->next_datablock == NULL) | ||
199 | return ZIP_INTERNALERROR; | ||
200 | ldi = ldi->next_datablock ; | ||
201 | ll->last_block = ldi; | ||
202 | } | ||
203 | |||
204 | if (ldi->avail_in_this_block < len) | ||
205 | copy_this = (uInt)ldi->avail_in_this_block; | ||
206 | else | ||
207 | copy_this = (uInt)len; | ||
208 | |||
209 | to_copy = &(ldi->data[ldi->filled_in_this_block]); | ||
210 | |||
211 | for (i=0;i<copy_this;i++) | ||
212 | *(to_copy+i)=*(from_copy+i); | ||
213 | |||
214 | ldi->filled_in_this_block += copy_this; | ||
215 | ldi->avail_in_this_block -= copy_this; | ||
216 | from_copy += copy_this ; | ||
217 | len -= copy_this; | ||
218 | } | ||
219 | return ZIP_OK; | ||
220 | } | ||
221 | |||
222 | |||
223 | local int write_datablock(fout,ll) | ||
224 | FILE * fout; | ||
225 | linkedlist_data* ll; | ||
226 | { | ||
227 | linkedlist_datablock_internal* ldi; | ||
228 | ldi = ll->first_block; | ||
229 | while (ldi!=NULL) | ||
230 | { | ||
231 | if (ldi->filled_in_this_block > 0) | ||
232 | if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1) | ||
233 | return ZIP_ERRNO; | ||
234 | ldi = ldi->next_datablock; | ||
235 | } | ||
236 | return ZIP_OK; | ||
237 | } | ||
238 | |||
239 | /****************************************************************************/ | ||
240 | |||
241 | /* =========================================================================== | ||
242 | Outputs a long in LSB order to the given file | ||
243 | nbByte == 1, 2 or 4 (byte, short or long) | ||
244 | */ | ||
245 | local int ziplocal_putValue (file, x, nbByte) | ||
246 | FILE *file; | ||
247 | uLong x; | ||
248 | int nbByte; | ||
249 | { | ||
250 | unsigned char buf[4]; | ||
251 | int n; | ||
252 | for (n = 0; n < nbByte; n++) { | ||
253 | buf[n] = (unsigned char)(x & 0xff); | ||
254 | x >>= 8; | ||
255 | } | ||
256 | if (fwrite(buf,nbByte,1,file)!=1) | ||
257 | return ZIP_ERRNO; | ||
258 | else | ||
259 | return ZIP_OK; | ||
260 | } | ||
261 | |||
262 | |||
263 | local void ziplocal_putValue_inmemory (dest, x, nbByte) | ||
264 | void* dest; | ||
265 | uLong x; | ||
266 | int nbByte; | ||
267 | { | ||
268 | unsigned char* buf=(unsigned char*)dest; | ||
269 | int n; | ||
270 | for (n = 0; n < nbByte; n++) { | ||
271 | buf[n] = (unsigned char)(x & 0xff); | ||
272 | x >>= 8; | ||
273 | } | ||
274 | } | ||
275 | /****************************************************************************/ | ||
276 | |||
277 | |||
278 | local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) | ||
279 | tm_zip* ptm; | ||
280 | uLong dosDate; | ||
281 | { | ||
282 | uLong year = (uLong)ptm->tm_year; | ||
283 | if (year>1980) | ||
284 | year-=1980; | ||
285 | else if (year>80) | ||
286 | year-=80; | ||
287 | return | ||
288 | (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | | ||
289 | ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); | ||
290 | } | ||
291 | |||
292 | |||
293 | /****************************************************************************/ | ||
294 | |||
295 | extern zipFile ZEXPORT zipOpen (pathname, append) | ||
296 | const char *pathname; | ||
297 | int append; | ||
298 | { | ||
299 | zip_internal ziinit; | ||
300 | zip_internal* zi; | ||
301 | |||
302 | ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab"); | ||
303 | if (ziinit.filezip == NULL) | ||
304 | return NULL; | ||
305 | ziinit.begin_pos = ftell(ziinit.filezip); | ||
306 | ziinit.in_opened_file_inzip = 0; | ||
307 | ziinit.ci.stream_initialised = 0; | ||
308 | ziinit.number_entry = 0; | ||
309 | init_linkedlist(&(ziinit.central_dir)); | ||
310 | |||
311 | |||
312 | zi = (zip_internal*)ALLOC(sizeof(zip_internal)); | ||
313 | if (zi==NULL) | ||
314 | { | ||
315 | fclose(ziinit.filezip); | ||
316 | return NULL; | ||
317 | } | ||
318 | |||
319 | *zi = ziinit; | ||
320 | return (zipFile)zi; | ||
321 | } | ||
322 | |||
323 | extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, | ||
324 | extrafield_local, size_extrafield_local, | ||
325 | extrafield_global, size_extrafield_global, | ||
326 | comment, method, level) | ||
327 | zipFile file; | ||
328 | const char* filename; | ||
329 | const zip_fileinfo* zipfi; | ||
330 | const void* extrafield_local; | ||
331 | uInt size_extrafield_local; | ||
332 | const void* extrafield_global; | ||
333 | uInt size_extrafield_global; | ||
334 | const char* comment; | ||
335 | int method; | ||
336 | int level; | ||
337 | { | ||
338 | zip_internal* zi; | ||
339 | uInt size_filename; | ||
340 | uInt size_comment; | ||
341 | uInt i; | ||
342 | int err = ZIP_OK; | ||
343 | |||
344 | if (file == NULL) | ||
345 | return ZIP_PARAMERROR; | ||
346 | if ((method!=0) && (method!=Z_DEFLATED)) | ||
347 | return ZIP_PARAMERROR; | ||
348 | |||
349 | zi = (zip_internal*)file; | ||
350 | |||
351 | if (zi->in_opened_file_inzip == 1) | ||
352 | { | ||
353 | err = zipCloseFileInZip (file); | ||
354 | if (err != ZIP_OK) | ||
355 | return err; | ||
356 | } | ||
357 | |||
358 | |||
359 | if (filename==NULL) | ||
360 | filename="-"; | ||
361 | |||
362 | if (comment==NULL) | ||
363 | size_comment = 0; | ||
364 | else | ||
365 | size_comment = strlen(comment); | ||
366 | |||
367 | size_filename = strlen(filename); | ||
368 | |||
369 | if (zipfi == NULL) | ||
370 | zi->ci.dosDate = 0; | ||
371 | else | ||
372 | { | ||
373 | if (zipfi->dosDate != 0) | ||
374 | zi->ci.dosDate = zipfi->dosDate; | ||
375 | else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); | ||
376 | } | ||
377 | |||
378 | zi->ci.flag = 0; | ||
379 | if ((level==8) || (level==9)) | ||
380 | zi->ci.flag |= 2; | ||
381 | if ((level==2)) | ||
382 | zi->ci.flag |= 4; | ||
383 | if ((level==1)) | ||
384 | zi->ci.flag |= 6; | ||
385 | |||
386 | zi->ci.crc32 = 0; | ||
387 | zi->ci.method = method; | ||
388 | zi->ci.stream_initialised = 0; | ||
389 | zi->ci.pos_in_buffered_data = 0; | ||
390 | zi->ci.pos_local_header = ftell(zi->filezip); | ||
391 | zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + | ||
392 | size_extrafield_global + size_comment; | ||
393 | zi->ci.central_header = (char*)ALLOC(zi->ci.size_centralheader); | ||
394 | |||
395 | ziplocal_putValue_inmemory(zi->ci.central_header,CENTRALHEADERMAGIC,4); | ||
396 | /* version info */ | ||
397 | ziplocal_putValue_inmemory(zi->ci.central_header+4,VERSIONMADEBY,2); | ||
398 | ziplocal_putValue_inmemory(zi->ci.central_header+6,20,2); | ||
399 | ziplocal_putValue_inmemory(zi->ci.central_header+8,zi->ci.flag,2); | ||
400 | ziplocal_putValue_inmemory(zi->ci.central_header+10,zi->ci.method,2); | ||
401 | ziplocal_putValue_inmemory(zi->ci.central_header+12,zi->ci.dosDate,4); | ||
402 | ziplocal_putValue_inmemory(zi->ci.central_header+16,0,4); /*crc*/ | ||
403 | ziplocal_putValue_inmemory(zi->ci.central_header+20,0,4); /*compr size*/ | ||
404 | ziplocal_putValue_inmemory(zi->ci.central_header+24,0,4); /*uncompr size*/ | ||
405 | ziplocal_putValue_inmemory(zi->ci.central_header+28,size_filename,2); | ||
406 | ziplocal_putValue_inmemory(zi->ci.central_header+30,size_extrafield_global,2); | ||
407 | ziplocal_putValue_inmemory(zi->ci.central_header+32,size_comment,2); | ||
408 | ziplocal_putValue_inmemory(zi->ci.central_header+34,0,2); /*disk nm start*/ | ||
409 | |||
410 | if (zipfi==NULL) | ||
411 | ziplocal_putValue_inmemory(zi->ci.central_header+36,0,2); | ||
412 | else | ||
413 | ziplocal_putValue_inmemory(zi->ci.central_header+36,zipfi->internal_fa,2); | ||
414 | |||
415 | if (zipfi==NULL) | ||
416 | ziplocal_putValue_inmemory(zi->ci.central_header+38,0,4); | ||
417 | else | ||
418 | ziplocal_putValue_inmemory(zi->ci.central_header+38,zipfi->external_fa,4); | ||
419 | |||
420 | ziplocal_putValue_inmemory(zi->ci.central_header+42,zi->ci.pos_local_header,4); | ||
421 | |||
422 | for (i=0;i<size_filename;i++) | ||
423 | *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); | ||
424 | |||
425 | for (i=0;i<size_extrafield_global;i++) | ||
426 | *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = | ||
427 | *(((const char*)extrafield_global)+i); | ||
428 | |||
429 | for (i=0;i<size_comment;i++) | ||
430 | *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ | ||
431 | size_extrafield_global+i) = *(filename+i); | ||
432 | if (zi->ci.central_header == NULL) | ||
433 | return ZIP_INTERNALERROR; | ||
434 | |||
435 | /* write the local header */ | ||
436 | err = ziplocal_putValue(zi->filezip,LOCALHEADERMAGIC,4); | ||
437 | |||
438 | if (err==ZIP_OK) | ||
439 | err = ziplocal_putValue(zi->filezip,20,2);/* version needed to extract */ | ||
440 | if (err==ZIP_OK) | ||
441 | err = ziplocal_putValue(zi->filezip,zi->ci.flag,2); | ||
442 | |||
443 | if (err==ZIP_OK) | ||
444 | err = ziplocal_putValue(zi->filezip,zi->ci.method,2); | ||
445 | |||
446 | if (err==ZIP_OK) | ||
447 | err = ziplocal_putValue(zi->filezip,zi->ci.dosDate,4); | ||
448 | |||
449 | if (err==ZIP_OK) | ||
450 | err = ziplocal_putValue(zi->filezip,0,4); /* crc 32, unknown */ | ||
451 | if (err==ZIP_OK) | ||
452 | err = ziplocal_putValue(zi->filezip,0,4); /* compressed size, unknown */ | ||
453 | if (err==ZIP_OK) | ||
454 | err = ziplocal_putValue(zi->filezip,0,4); /* uncompressed size, unknown */ | ||
455 | |||
456 | if (err==ZIP_OK) | ||
457 | err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2); | ||
458 | |||
459 | if (err==ZIP_OK) | ||
460 | err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2); | ||
461 | |||
462 | if ((err==ZIP_OK) && (size_filename>0)) | ||
463 | if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1) | ||
464 | err = ZIP_ERRNO; | ||
465 | |||
466 | if ((err==ZIP_OK) && (size_extrafield_local>0)) | ||
467 | if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip) | ||
468 | !=1) | ||
469 | err = ZIP_ERRNO; | ||
470 | |||
471 | zi->ci.stream.avail_in = (uInt)0; | ||
472 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
473 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
474 | zi->ci.stream.total_in = 0; | ||
475 | zi->ci.stream.total_out = 0; | ||
476 | |||
477 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED)) | ||
478 | { | ||
479 | zi->ci.stream.zalloc = (alloc_func)0; | ||
480 | zi->ci.stream.zfree = (free_func)0; | ||
481 | zi->ci.stream.opaque = (voidpf)0; | ||
482 | |||
483 | err = deflateInit2(&zi->ci.stream, level, | ||
484 | Z_DEFLATED, -MAX_WBITS, /*DEF_MEM_LEVEL*/8, 0); | ||
485 | |||
486 | if (err==Z_OK) | ||
487 | zi->ci.stream_initialised = 1; | ||
488 | } | ||
489 | |||
490 | |||
491 | if (err==Z_OK) | ||
492 | zi->in_opened_file_inzip = 1; | ||
493 | return err; | ||
494 | } | ||
495 | |||
496 | extern int ZEXPORT zipWriteInFileInZip (file, buf, len) | ||
497 | zipFile file; | ||
498 | const voidp buf; | ||
499 | unsigned len; | ||
500 | { | ||
501 | zip_internal* zi; | ||
502 | int err=ZIP_OK; | ||
503 | |||
504 | if (file == NULL) | ||
505 | return ZIP_PARAMERROR; | ||
506 | zi = (zip_internal*)file; | ||
507 | |||
508 | if (zi->in_opened_file_inzip == 0) | ||
509 | return ZIP_PARAMERROR; | ||
510 | |||
511 | zi->ci.stream.next_in = buf; | ||
512 | zi->ci.stream.avail_in = len; | ||
513 | zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); | ||
514 | |||
515 | while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) | ||
516 | { | ||
517 | if (zi->ci.stream.avail_out == 0) | ||
518 | { | ||
519 | if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) | ||
520 | !=1) | ||
521 | err = ZIP_ERRNO; | ||
522 | zi->ci.pos_in_buffered_data = 0; | ||
523 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
524 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
525 | } | ||
526 | |||
527 | if (zi->ci.method == Z_DEFLATED) | ||
528 | { | ||
529 | uLong uTotalOutBefore = zi->ci.stream.total_out; | ||
530 | err=deflate(&zi->ci.stream, Z_NO_FLUSH); | ||
531 | zi->ci.pos_in_buffered_data += zi->ci.stream.total_out - uTotalOutBefore ; | ||
532 | |||
533 | } | ||
534 | else | ||
535 | { | ||
536 | uInt copy_this,i; | ||
537 | if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) | ||
538 | copy_this = zi->ci.stream.avail_in; | ||
539 | else | ||
540 | copy_this = zi->ci.stream.avail_out; | ||
541 | for (i=0;i<copy_this;i++) | ||
542 | *(((char*)zi->ci.stream.next_out)+i) = | ||
543 | *(((const char*)zi->ci.stream.next_in)+i); | ||
544 | { | ||
545 | zi->ci.stream.avail_in -= copy_this; | ||
546 | zi->ci.stream.avail_out-= copy_this; | ||
547 | zi->ci.stream.next_in+= copy_this; | ||
548 | zi->ci.stream.next_out+= copy_this; | ||
549 | zi->ci.stream.total_in+= copy_this; | ||
550 | zi->ci.stream.total_out+= copy_this; | ||
551 | zi->ci.pos_in_buffered_data += copy_this; | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | extern int ZEXPORT zipCloseFileInZip (file) | ||
560 | zipFile file; | ||
561 | { | ||
562 | zip_internal* zi; | ||
563 | int err=ZIP_OK; | ||
564 | |||
565 | if (file == NULL) | ||
566 | return ZIP_PARAMERROR; | ||
567 | zi = (zip_internal*)file; | ||
568 | |||
569 | if (zi->in_opened_file_inzip == 0) | ||
570 | return ZIP_PARAMERROR; | ||
571 | zi->ci.stream.avail_in = 0; | ||
572 | |||
573 | if (zi->ci.method == Z_DEFLATED) | ||
574 | while (err==ZIP_OK) | ||
575 | { | ||
576 | uLong uTotalOutBefore; | ||
577 | if (zi->ci.stream.avail_out == 0) | ||
578 | { | ||
579 | if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) | ||
580 | !=1) | ||
581 | err = ZIP_ERRNO; | ||
582 | zi->ci.pos_in_buffered_data = 0; | ||
583 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
584 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
585 | } | ||
586 | uTotalOutBefore = zi->ci.stream.total_out; | ||
587 | err=deflate(&zi->ci.stream, Z_FINISH); | ||
588 | zi->ci.pos_in_buffered_data += zi->ci.stream.total_out - uTotalOutBefore ; | ||
589 | } | ||
590 | |||
591 | if (err==Z_STREAM_END) | ||
592 | err=ZIP_OK; /* this is normal */ | ||
593 | |||
594 | if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) | ||
595 | if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) | ||
596 | !=1) | ||
597 | err = ZIP_ERRNO; | ||
598 | |||
599 | if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK)) | ||
600 | { | ||
601 | err=deflateEnd(&zi->ci.stream); | ||
602 | zi->ci.stream_initialised = 0; | ||
603 | } | ||
604 | |||
605 | ziplocal_putValue_inmemory(zi->ci.central_header+16,zi->ci.crc32,4); /*crc*/ | ||
606 | ziplocal_putValue_inmemory(zi->ci.central_header+20, | ||
607 | zi->ci.stream.total_out,4); /*compr size*/ | ||
608 | ziplocal_putValue_inmemory(zi->ci.central_header+24, | ||
609 | zi->ci.stream.total_in,4); /*uncompr size*/ | ||
610 | |||
611 | if (err==ZIP_OK) | ||
612 | err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, | ||
613 | (uLong)zi->ci.size_centralheader); | ||
614 | free(zi->ci.central_header); | ||
615 | |||
616 | if (err==ZIP_OK) | ||
617 | { | ||
618 | long cur_pos_inzip = ftell(zi->filezip); | ||
619 | if (fseek(zi->filezip, | ||
620 | zi->ci.pos_local_header + 14,SEEK_SET)!=0) | ||
621 | err = ZIP_ERRNO; | ||
622 | |||
623 | if (err==ZIP_OK) | ||
624 | err = ziplocal_putValue(zi->filezip,zi->ci.crc32,4); /* crc 32, unknown */ | ||
625 | |||
626 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
627 | err = ziplocal_putValue(zi->filezip,zi->ci.stream.total_out,4); | ||
628 | |||
629 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
630 | err = ziplocal_putValue(zi->filezip,zi->ci.stream.total_in,4); | ||
631 | |||
632 | if (fseek(zi->filezip, | ||
633 | cur_pos_inzip,SEEK_SET)!=0) | ||
634 | err = ZIP_ERRNO; | ||
635 | } | ||
636 | |||
637 | zi->number_entry ++; | ||
638 | zi->in_opened_file_inzip = 0; | ||
639 | |||
640 | return err; | ||
641 | } | ||
642 | |||
643 | extern int ZEXPORT zipClose (file, global_comment) | ||
644 | zipFile file; | ||
645 | const char* global_comment; | ||
646 | { | ||
647 | zip_internal* zi; | ||
648 | int err = 0; | ||
649 | uLong size_centraldir = 0; | ||
650 | uLong centraldir_pos_inzip ; | ||
651 | uInt size_global_comment; | ||
652 | if (file == NULL) | ||
653 | return ZIP_PARAMERROR; | ||
654 | zi = (zip_internal*)file; | ||
655 | |||
656 | if (zi->in_opened_file_inzip == 1) | ||
657 | { | ||
658 | err = zipCloseFileInZip (file); | ||
659 | } | ||
660 | |||
661 | if (global_comment==NULL) | ||
662 | size_global_comment = 0; | ||
663 | else | ||
664 | size_global_comment = strlen(global_comment); | ||
665 | |||
666 | |||
667 | centraldir_pos_inzip = ftell(zi->filezip); | ||
668 | if (err==ZIP_OK) | ||
669 | { | ||
670 | linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; | ||
671 | while (ldi!=NULL) | ||
672 | { | ||
673 | if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) | ||
674 | if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block, | ||
675 | 1,zi->filezip) !=1 ) | ||
676 | err = ZIP_ERRNO; | ||
677 | |||
678 | size_centraldir += ldi->filled_in_this_block; | ||
679 | ldi = ldi->next_datablock; | ||
680 | } | ||
681 | } | ||
682 | free_datablock(zi->central_dir.first_block); | ||
683 | |||
684 | if (err==ZIP_OK) /* Magic End */ | ||
685 | err = ziplocal_putValue(zi->filezip,ENDHEADERMAGIC,4); | ||
686 | |||
687 | if (err==ZIP_OK) /* number of this disk */ | ||
688 | err = ziplocal_putValue(zi->filezip,0,2); | ||
689 | |||
690 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
691 | err = ziplocal_putValue(zi->filezip,0,2); | ||
692 | |||
693 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
694 | err = ziplocal_putValue(zi->filezip,zi->number_entry,2); | ||
695 | |||
696 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
697 | err = ziplocal_putValue(zi->filezip,zi->number_entry,2); | ||
698 | |||
699 | if (err==ZIP_OK) /* size of the central directory */ | ||
700 | err = ziplocal_putValue(zi->filezip,size_centraldir,4); | ||
701 | |||
702 | if (err==ZIP_OK) /* offset of start of central directory with respect to the | ||
703 | starting disk number */ | ||
704 | err = ziplocal_putValue(zi->filezip,centraldir_pos_inzip ,4); | ||
705 | |||
706 | if (err==ZIP_OK) /* zipfile comment length */ | ||
707 | err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2); | ||
708 | |||
709 | if ((err==ZIP_OK) && (size_global_comment>0)) | ||
710 | if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 ) | ||
711 | err = ZIP_ERRNO; | ||
712 | fclose(zi->filezip); | ||
713 | TRYFREE(zi); | ||
714 | |||
715 | return err; | ||
716 | } | ||