diff options
Diffstat (limited to 'contrib/minizip/zip.c')
-rw-r--r-- | contrib/minizip/zip.c | 1830 |
1 files changed, 1307 insertions, 523 deletions
diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c index 7fbe002..e12da4c 100644 --- a/contrib/minizip/zip.c +++ b/contrib/minizip/zip.c | |||
@@ -1,12 +1,23 @@ | |||
1 | /* zip.c -- IO on .zip files using zlib | 1 | /* zip.c -- IO on .zip files using zlib |
2 | Version 1.01e, February 12th, 2005 | 2 | Version 1.1, January 7th, 2010 |
3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
3 | 4 | ||
4 | 27 Dec 2004 Rolf Kalbermatter | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) |
5 | Modification to zipOpen2 to support globalComment retrieval. | ||
6 | 6 | ||
7 | Copyright (C) 1998-2005 Gilles Vollant | 7 | Modifications for Zip64 support |
8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
9 | |||
10 | For more info read MiniZip_info.txt | ||
11 | |||
12 | Changes | ||
13 | Okt-2009 - Mathias Svensson - Remove old C style function prototypes | ||
14 | Okt-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives | ||
15 | Okt-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. | ||
16 | Okt-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data | ||
17 | It is used when recreting zip archive with RAW when deleting items from a zip. | ||
18 | ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. | ||
19 | Okt-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) | ||
8 | 20 | ||
9 | Read zip.h for more info | ||
10 | */ | 21 | */ |
11 | 22 | ||
12 | 23 | ||
@@ -39,7 +50,7 @@ | |||
39 | #endif | 50 | #endif |
40 | 51 | ||
41 | #ifndef Z_BUFSIZE | 52 | #ifndef Z_BUFSIZE |
42 | #define Z_BUFSIZE (16384) | 53 | #define Z_BUFSIZE (64*1024) //(16384) |
43 | #endif | 54 | #endif |
44 | 55 | ||
45 | #ifndef Z_MAXFILENAMEINZIP | 56 | #ifndef Z_MAXFILENAMEINZIP |
@@ -60,6 +71,10 @@ | |||
60 | 71 | ||
61 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ | 72 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ |
62 | 73 | ||
74 | |||
75 | // NOT sure that this work on ALL platform | ||
76 | #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) | ||
77 | |||
63 | #ifndef SEEK_CUR | 78 | #ifndef SEEK_CUR |
64 | #define SEEK_CUR 1 | 79 | #define SEEK_CUR 1 |
65 | #endif | 80 | #endif |
@@ -79,8 +94,7 @@ | |||
79 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL | 94 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL |
80 | #endif | 95 | #endif |
81 | #endif | 96 | #endif |
82 | const char zip_copyright[] = | 97 | const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; |
83 | " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; | ||
84 | 98 | ||
85 | 99 | ||
86 | #define SIZEDATA_INDATABLOCK (4096-(4*4)) | 100 | #define SIZEDATA_INDATABLOCK (4096-(4*4)) |
@@ -88,6 +102,8 @@ const char zip_copyright[] = | |||
88 | #define LOCALHEADERMAGIC (0x04034b50) | 102 | #define LOCALHEADERMAGIC (0x04034b50) |
89 | #define CENTRALHEADERMAGIC (0x02014b50) | 103 | #define CENTRALHEADERMAGIC (0x02014b50) |
90 | #define ENDHEADERMAGIC (0x06054b50) | 104 | #define ENDHEADERMAGIC (0x06054b50) |
105 | #define ZIP64ENDHEADERMAGIC (0x6064b50) | ||
106 | #define ZIP64ENDLOCHEADERMAGIC (0x7064b50) | ||
91 | 107 | ||
92 | #define FLAG_LOCALHEADER_OFFSET (0x06) | 108 | #define FLAG_LOCALHEADER_OFFSET (0x06) |
93 | #define CRC_LOCALHEADER_OFFSET (0x0e) | 109 | #define CRC_LOCALHEADER_OFFSET (0x0e) |
@@ -113,13 +129,19 @@ typedef struct linkedlist_data_s | |||
113 | typedef struct | 129 | typedef struct |
114 | { | 130 | { |
115 | z_stream stream; /* zLib stream structure for inflate */ | 131 | z_stream stream; /* zLib stream structure for inflate */ |
132 | #ifdef HAVE_BZIP2 | ||
133 | bz_stream bstream; /* bzLib stream structure for bziped */ | ||
134 | #endif | ||
135 | |||
116 | int stream_initialised; /* 1 is stream is initialised */ | 136 | int stream_initialised; /* 1 is stream is initialised */ |
117 | uInt pos_in_buffered_data; /* last written byte in buffered_data */ | 137 | uInt pos_in_buffered_data; /* last written byte in buffered_data */ |
118 | 138 | ||
119 | uLong pos_local_header; /* offset of the local header of the file | 139 | ZPOS64_T pos_local_header; /* offset of the local header of the file |
120 | currenty writing */ | 140 | currenty writing */ |
121 | char* central_header; /* central header data for the current file */ | 141 | char* central_header; /* central header data for the current file */ |
142 | uLong size_centralExtra; | ||
122 | uLong size_centralheader; /* size of the central header for cur file */ | 143 | uLong size_centralheader; /* size of the central header for cur file */ |
144 | uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ | ||
123 | uLong flag; /* flag of the file currently writing */ | 145 | uLong flag; /* flag of the file currently writing */ |
124 | 146 | ||
125 | int method; /* compression method of file currenty wr.*/ | 147 | int method; /* compression method of file currenty wr.*/ |
@@ -128,29 +150,34 @@ typedef struct | |||
128 | uLong dosDate; | 150 | uLong dosDate; |
129 | uLong crc32; | 151 | uLong crc32; |
130 | int encrypt; | 152 | int encrypt; |
153 | int zip64; /* Add ZIP64 extened information in the extra field */ | ||
154 | ZPOS64_T pos_zip64extrainfo; | ||
155 | ZPOS64_T totalCompressedData; | ||
156 | ZPOS64_T totalUncompressedData; | ||
131 | #ifndef NOCRYPT | 157 | #ifndef NOCRYPT |
132 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ | 158 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ |
133 | const unsigned long* pcrc_32_tab; | 159 | const unsigned long* pcrc_32_tab; |
134 | int crypt_header_size; | 160 | int crypt_header_size; |
135 | #endif | 161 | #endif |
136 | } curfile_info; | 162 | } curfile64_info; |
137 | 163 | ||
138 | typedef struct | 164 | typedef struct |
139 | { | 165 | { |
140 | zlib_filefunc_def z_filefunc; | 166 | zlib_filefunc64_32_def z_filefunc; |
141 | voidpf filestream; /* io structore of the zipfile */ | 167 | voidpf filestream; /* io structore of the zipfile */ |
142 | linkedlist_data central_dir;/* datablock with central dir in construction*/ | 168 | linkedlist_data central_dir;/* datablock with central dir in construction*/ |
143 | int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ | 169 | int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ |
144 | curfile_info ci; /* info on the file curretly writing */ | 170 | curfile64_info ci; /* info on the file curretly writing */ |
171 | |||
172 | ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ | ||
173 | ZPOS64_T add_position_when_writting_offset; | ||
174 | ZPOS64_T number_entry; | ||
145 | 175 | ||
146 | uLong begin_pos; /* position of the beginning of the zipfile */ | ||
147 | uLong add_position_when_writting_offset; | ||
148 | uLong number_entry; | ||
149 | #ifndef NO_ADDFILEINEXISTINGZIP | 176 | #ifndef NO_ADDFILEINEXISTINGZIP |
150 | char *globalcomment; | 177 | char *globalcomment; |
151 | #endif | 178 | #endif |
152 | } zip_internal; | ||
153 | 179 | ||
180 | } zip64_internal; | ||
154 | 181 | ||
155 | 182 | ||
156 | #ifndef NOCRYPT | 183 | #ifndef NOCRYPT |
@@ -172,8 +199,7 @@ local linkedlist_datablock_internal* allocate_new_datablock() | |||
172 | return ldi; | 199 | return ldi; |
173 | } | 200 | } |
174 | 201 | ||
175 | local void free_datablock(ldi) | 202 | local void free_datablock(linkedlist_datablock_internal* ldi) |
176 | linkedlist_datablock_internal* ldi; | ||
177 | { | 203 | { |
178 | while (ldi!=NULL) | 204 | while (ldi!=NULL) |
179 | { | 205 | { |
@@ -183,24 +209,19 @@ local void free_datablock(ldi) | |||
183 | } | 209 | } |
184 | } | 210 | } |
185 | 211 | ||
186 | local void init_linkedlist(ll) | 212 | local void init_linkedlist(linkedlist_data* ll) |
187 | linkedlist_data* ll; | ||
188 | { | 213 | { |
189 | ll->first_block = ll->last_block = NULL; | 214 | ll->first_block = ll->last_block = NULL; |
190 | } | 215 | } |
191 | 216 | ||
192 | local void free_linkedlist(ll) | 217 | local void free_linkedlist(linkedlist_data* ll) |
193 | linkedlist_data* ll; | ||
194 | { | 218 | { |
195 | free_datablock(ll->first_block); | 219 | free_datablock(ll->first_block); |
196 | ll->first_block = ll->last_block = NULL; | 220 | ll->first_block = ll->last_block = NULL; |
197 | } | 221 | } |
198 | 222 | ||
199 | 223 | ||
200 | local int add_data_in_datablock(ll,buf,len) | 224 | local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) |
201 | linkedlist_data* ll; | ||
202 | const void* buf; | ||
203 | uLong len; | ||
204 | { | 225 | { |
205 | linkedlist_datablock_internal* ldi; | 226 | linkedlist_datablock_internal* ldi; |
206 | const unsigned char* from_copy; | 227 | const unsigned char* from_copy; |
@@ -258,18 +279,13 @@ local int add_data_in_datablock(ll,buf,len) | |||
258 | #ifndef NO_ADDFILEINEXISTINGZIP | 279 | #ifndef NO_ADDFILEINEXISTINGZIP |
259 | /* =========================================================================== | 280 | /* =========================================================================== |
260 | Inputs a long in LSB order to the given file | 281 | Inputs a long in LSB order to the given file |
261 | nbByte == 1, 2 or 4 (byte, short or long) | 282 | nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) |
262 | */ | 283 | */ |
263 | 284 | ||
264 | local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, | 285 | local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); |
265 | voidpf filestream, uLong x, int nbByte)); | 286 | local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) |
266 | local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) | ||
267 | const zlib_filefunc_def* pzlib_filefunc_def; | ||
268 | voidpf filestream; | ||
269 | uLong x; | ||
270 | int nbByte; | ||
271 | { | 287 | { |
272 | unsigned char buf[4]; | 288 | unsigned char buf[8]; |
273 | int n; | 289 | int n; |
274 | for (n = 0; n < nbByte; n++) | 290 | for (n = 0; n < nbByte; n++) |
275 | { | 291 | { |
@@ -284,17 +300,14 @@ local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) | |||
284 | } | 300 | } |
285 | } | 301 | } |
286 | 302 | ||
287 | if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) | 303 | if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) |
288 | return ZIP_ERRNO; | 304 | return ZIP_ERRNO; |
289 | else | 305 | else |
290 | return ZIP_OK; | 306 | return ZIP_OK; |
291 | } | 307 | } |
292 | 308 | ||
293 | local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); | 309 | local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); |
294 | local void ziplocal_putValue_inmemory (dest, x, nbByte) | 310 | local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) |
295 | void* dest; | ||
296 | uLong x; | ||
297 | int nbByte; | ||
298 | { | 311 | { |
299 | unsigned char* buf=(unsigned char*)dest; | 312 | unsigned char* buf=(unsigned char*)dest; |
300 | int n; | 313 | int n; |
@@ -315,14 +328,12 @@ local void ziplocal_putValue_inmemory (dest, x, nbByte) | |||
315 | /****************************************************************************/ | 328 | /****************************************************************************/ |
316 | 329 | ||
317 | 330 | ||
318 | local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) | 331 | local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) |
319 | const tm_zip* ptm; | ||
320 | uLong dosDate; | ||
321 | { | 332 | { |
322 | uLong year = (uLong)ptm->tm_year; | 333 | uLong year = (uLong)ptm->tm_year; |
323 | if (year>1980) | 334 | if (year>=1980) |
324 | year-=1980; | 335 | year-=1980; |
325 | else if (year>80) | 336 | else if (year>=80) |
326 | year-=80; | 337 | year-=80; |
327 | return | 338 | return |
328 | (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | | 339 | (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | |
@@ -332,18 +343,12 @@ local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) | |||
332 | 343 | ||
333 | /****************************************************************************/ | 344 | /****************************************************************************/ |
334 | 345 | ||
335 | local int ziplocal_getByte OF(( | 346 | local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); |
336 | const zlib_filefunc_def* pzlib_filefunc_def, | ||
337 | voidpf filestream, | ||
338 | int *pi)); | ||
339 | 347 | ||
340 | local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) | 348 | local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) |
341 | const zlib_filefunc_def* pzlib_filefunc_def; | ||
342 | voidpf filestream; | ||
343 | int *pi; | ||
344 | { | 349 | { |
345 | unsigned char c; | 350 | unsigned char c; |
346 | int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); | 351 | int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); |
347 | if (err==1) | 352 | if (err==1) |
348 | { | 353 | { |
349 | *pi = (int)c; | 354 | *pi = (int)c; |
@@ -351,7 +356,7 @@ local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) | |||
351 | } | 356 | } |
352 | else | 357 | else |
353 | { | 358 | { |
354 | if (ZERROR(*pzlib_filefunc_def,filestream)) | 359 | if (ZERROR64(*pzlib_filefunc_def,filestream)) |
355 | return ZIP_ERRNO; | 360 | return ZIP_ERRNO; |
356 | else | 361 | else |
357 | return ZIP_EOF; | 362 | return ZIP_EOF; |
@@ -362,25 +367,19 @@ local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) | |||
362 | /* =========================================================================== | 367 | /* =========================================================================== |
363 | Reads a long in LSB order from the given gz_stream. Sets | 368 | Reads a long in LSB order from the given gz_stream. Sets |
364 | */ | 369 | */ |
365 | local int ziplocal_getShort OF(( | 370 | local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); |
366 | const zlib_filefunc_def* pzlib_filefunc_def, | 371 | |
367 | voidpf filestream, | 372 | local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) |
368 | uLong *pX)); | ||
369 | |||
370 | local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) | ||
371 | const zlib_filefunc_def* pzlib_filefunc_def; | ||
372 | voidpf filestream; | ||
373 | uLong *pX; | ||
374 | { | 373 | { |
375 | uLong x ; | 374 | uLong x ; |
376 | int i; | 375 | int i = 0; |
377 | int err; | 376 | int err; |
378 | 377 | ||
379 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 378 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
380 | x = (uLong)i; | 379 | x = (uLong)i; |
381 | 380 | ||
382 | if (err==ZIP_OK) | 381 | if (err==ZIP_OK) |
383 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 382 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
384 | x += ((uLong)i)<<8; | 383 | x += ((uLong)i)<<8; |
385 | 384 | ||
386 | if (err==ZIP_OK) | 385 | if (err==ZIP_OK) |
@@ -390,33 +389,27 @@ local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) | |||
390 | return err; | 389 | return err; |
391 | } | 390 | } |
392 | 391 | ||
393 | local int ziplocal_getLong OF(( | 392 | local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); |
394 | const zlib_filefunc_def* pzlib_filefunc_def, | ||
395 | voidpf filestream, | ||
396 | uLong *pX)); | ||
397 | 393 | ||
398 | local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) | 394 | local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) |
399 | const zlib_filefunc_def* pzlib_filefunc_def; | ||
400 | voidpf filestream; | ||
401 | uLong *pX; | ||
402 | { | 395 | { |
403 | uLong x ; | 396 | uLong x ; |
404 | int i; | 397 | int i = 0; |
405 | int err; | 398 | int err; |
406 | 399 | ||
407 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 400 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
408 | x = (uLong)i; | 401 | x = (uLong)i; |
409 | 402 | ||
410 | if (err==ZIP_OK) | 403 | if (err==ZIP_OK) |
411 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 404 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
412 | x += ((uLong)i)<<8; | 405 | x += ((uLong)i)<<8; |
413 | 406 | ||
414 | if (err==ZIP_OK) | 407 | if (err==ZIP_OK) |
415 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 408 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
416 | x += ((uLong)i)<<16; | 409 | x += ((uLong)i)<<16; |
417 | 410 | ||
418 | if (err==ZIP_OK) | 411 | if (err==ZIP_OK) |
419 | err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); | 412 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); |
420 | x += ((uLong)i)<<24; | 413 | x += ((uLong)i)<<24; |
421 | 414 | ||
422 | if (err==ZIP_OK) | 415 | if (err==ZIP_OK) |
@@ -426,6 +419,54 @@ local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) | |||
426 | return err; | 419 | return err; |
427 | } | 420 | } |
428 | 421 | ||
422 | local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); | ||
423 | |||
424 | |||
425 | local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) | ||
426 | { | ||
427 | ZPOS64_T x; | ||
428 | int i = 0; | ||
429 | int err; | ||
430 | |||
431 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
432 | x = (ZPOS64_T)i; | ||
433 | |||
434 | if (err==ZIP_OK) | ||
435 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
436 | x += ((ZPOS64_T)i)<<8; | ||
437 | |||
438 | if (err==ZIP_OK) | ||
439 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
440 | x += ((ZPOS64_T)i)<<16; | ||
441 | |||
442 | if (err==ZIP_OK) | ||
443 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
444 | x += ((ZPOS64_T)i)<<24; | ||
445 | |||
446 | if (err==ZIP_OK) | ||
447 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
448 | x += ((ZPOS64_T)i)<<32; | ||
449 | |||
450 | if (err==ZIP_OK) | ||
451 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
452 | x += ((ZPOS64_T)i)<<40; | ||
453 | |||
454 | if (err==ZIP_OK) | ||
455 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
456 | x += ((ZPOS64_T)i)<<48; | ||
457 | |||
458 | if (err==ZIP_OK) | ||
459 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
460 | x += ((ZPOS64_T)i)<<56; | ||
461 | |||
462 | if (err==ZIP_OK) | ||
463 | *pX = x; | ||
464 | else | ||
465 | *pX = 0; | ||
466 | |||
467 | return err; | ||
468 | } | ||
469 | |||
429 | #ifndef BUFREADCOMMENT | 470 | #ifndef BUFREADCOMMENT |
430 | #define BUFREADCOMMENT (0x400) | 471 | #define BUFREADCOMMENT (0x400) |
431 | #endif | 472 | #endif |
@@ -433,87 +474,391 @@ local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) | |||
433 | Locate the Central directory of a zipfile (at the end, just before | 474 | Locate the Central directory of a zipfile (at the end, just before |
434 | the global comment) | 475 | the global comment) |
435 | */ | 476 | */ |
436 | local uLong ziplocal_SearchCentralDir OF(( | 477 | local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); |
437 | const zlib_filefunc_def* pzlib_filefunc_def, | ||
438 | voidpf filestream)); | ||
439 | 478 | ||
440 | local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) | 479 | local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) |
441 | const zlib_filefunc_def* pzlib_filefunc_def; | ||
442 | voidpf filestream; | ||
443 | { | 480 | { |
444 | unsigned char* buf; | 481 | unsigned char* buf; |
445 | uLong uSizeFile; | 482 | ZPOS64_T uSizeFile; |
446 | uLong uBackRead; | 483 | ZPOS64_T uBackRead; |
447 | uLong uMaxBack=0xffff; /* maximum size of global comment */ | 484 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ |
448 | uLong uPosFound=0; | 485 | ZPOS64_T uPosFound=0; |
486 | |||
487 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
488 | return 0; | ||
489 | |||
490 | |||
491 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
492 | |||
493 | if (uMaxBack>uSizeFile) | ||
494 | uMaxBack = uSizeFile; | ||
495 | |||
496 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
497 | if (buf==NULL) | ||
498 | return 0; | ||
499 | |||
500 | uBackRead = 4; | ||
501 | while (uBackRead<uMaxBack) | ||
502 | { | ||
503 | uLong uReadSize; | ||
504 | ZPOS64_T uReadPos ; | ||
505 | int i; | ||
506 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
507 | uBackRead = uMaxBack; | ||
508 | else | ||
509 | uBackRead+=BUFREADCOMMENT; | ||
510 | uReadPos = uSizeFile-uBackRead ; | ||
511 | |||
512 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | ||
513 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | ||
514 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
515 | break; | ||
516 | |||
517 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | ||
518 | break; | ||
519 | |||
520 | for (i=(int)uReadSize-3; (i--)>0;) | ||
521 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | ||
522 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) | ||
523 | { | ||
524 | uPosFound = uReadPos+i; | ||
525 | break; | ||
526 | } | ||
449 | 527 | ||
450 | if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | 528 | if (uPosFound!=0) |
451 | return 0; | 529 | break; |
530 | } | ||
531 | TRYFREE(buf); | ||
532 | return uPosFound; | ||
533 | } | ||
452 | 534 | ||
535 | /* | ||
536 | Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before | ||
537 | the global comment) | ||
538 | */ | ||
539 | local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); | ||
453 | 540 | ||
454 | uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); | 541 | local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) |
542 | { | ||
543 | unsigned char* buf; | ||
544 | ZPOS64_T uSizeFile; | ||
545 | ZPOS64_T uBackRead; | ||
546 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | ||
547 | ZPOS64_T uPosFound=0; | ||
548 | uLong uL; | ||
549 | ZPOS64_T relativeOffset; | ||
550 | |||
551 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
552 | return 0; | ||
553 | |||
554 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
555 | |||
556 | if (uMaxBack>uSizeFile) | ||
557 | uMaxBack = uSizeFile; | ||
558 | |||
559 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
560 | if (buf==NULL) | ||
561 | return 0; | ||
562 | |||
563 | uBackRead = 4; | ||
564 | while (uBackRead<uMaxBack) | ||
565 | { | ||
566 | uLong uReadSize; | ||
567 | ZPOS64_T uReadPos; | ||
568 | int i; | ||
569 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
570 | uBackRead = uMaxBack; | ||
571 | else | ||
572 | uBackRead+=BUFREADCOMMENT; | ||
573 | uReadPos = uSizeFile-uBackRead ; | ||
455 | 574 | ||
456 | if (uMaxBack>uSizeFile) | 575 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? |
457 | uMaxBack = uSizeFile; | 576 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); |
577 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
578 | break; | ||
458 | 579 | ||
459 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | 580 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) |
460 | if (buf==NULL) | 581 | break; |
461 | return 0; | ||
462 | 582 | ||
463 | uBackRead = 4; | 583 | for (i=(int)uReadSize-3; (i--)>0;) |
464 | while (uBackRead<uMaxBack) | ||
465 | { | 584 | { |
466 | uLong uReadSize,uReadPos ; | 585 | // Signature "0x07064b50" Zip64 end of central directory locater |
467 | int i; | 586 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) |
468 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | 587 | { |
469 | uBackRead = uMaxBack; | 588 | uPosFound = uReadPos+i; |
470 | else | 589 | break; |
471 | uBackRead+=BUFREADCOMMENT; | 590 | } |
472 | uReadPos = uSizeFile-uBackRead ; | 591 | } |
473 | 592 | ||
474 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | 593 | if (uPosFound!=0) |
475 | (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); | 594 | break; |
476 | if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | 595 | } |
477 | break; | ||
478 | 596 | ||
479 | if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | 597 | TRYFREE(buf); |
480 | break; | 598 | if (uPosFound == 0) |
599 | return 0; | ||
481 | 600 | ||
482 | for (i=(int)uReadSize-3; (i--)>0;) | 601 | /* Zip64 end of central directory locator */ |
483 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | 602 | if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) |
484 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) | 603 | return 0; |
485 | { | 604 | |
486 | uPosFound = uReadPos+i; | 605 | /* the signature, already checked */ |
487 | break; | 606 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) |
488 | } | 607 | return 0; |
489 | 608 | ||
490 | if (uPosFound!=0) | 609 | /* number of the disk with the start of the zip64 end of central directory */ |
491 | break; | 610 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) |
611 | return 0; | ||
612 | if (uL != 0) | ||
613 | return 0; | ||
614 | |||
615 | /* relative offset of the zip64 end of central directory record */ | ||
616 | if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) | ||
617 | return 0; | ||
618 | |||
619 | /* total number of disks */ | ||
620 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
621 | return 0; | ||
622 | if (uL != 1) | ||
623 | return 0; | ||
624 | |||
625 | /* Goto Zip64 end of central directory record */ | ||
626 | if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
627 | return 0; | ||
628 | |||
629 | /* the signature */ | ||
630 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
631 | return 0; | ||
632 | |||
633 | if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' | ||
634 | return 0; | ||
635 | |||
636 | return relativeOffset; | ||
637 | } | ||
638 | |||
639 | int LoadCentralDirectoryRecord(zip64_internal* pziinit) | ||
640 | { | ||
641 | int err=ZIP_OK; | ||
642 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | ||
643 | |||
644 | ZPOS64_T size_central_dir; /* size of the central directory */ | ||
645 | ZPOS64_T offset_central_dir; /* offset of start of central directory */ | ||
646 | ZPOS64_T central_pos; | ||
647 | uLong uL; | ||
648 | |||
649 | uLong number_disk; /* number of the current dist, used for | ||
650 | spaning ZIP, unsupported, always 0*/ | ||
651 | uLong number_disk_with_CD; /* number the the disk with central dir, used | ||
652 | for spaning ZIP, unsupported, always 0*/ | ||
653 | ZPOS64_T number_entry; | ||
654 | ZPOS64_T number_entry_CD; /* total number of entries in | ||
655 | the central dir | ||
656 | (same than number_entry on nospan) */ | ||
657 | uLong VersionMadeBy; | ||
658 | uLong VersionNeeded; | ||
659 | uLong size_comment; | ||
660 | |||
661 | int hasZIP64Record = 0; | ||
662 | |||
663 | // check first if we find a ZIP64 record | ||
664 | central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); | ||
665 | if(central_pos > 0) | ||
666 | { | ||
667 | hasZIP64Record = 1; | ||
668 | } | ||
669 | else if(central_pos == 0) | ||
670 | { | ||
671 | central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); | ||
672 | } | ||
673 | |||
674 | /* disable to allow appending to empty ZIP archive | ||
675 | if (central_pos==0) | ||
676 | err=ZIP_ERRNO; | ||
677 | */ | ||
678 | |||
679 | if(hasZIP64Record) | ||
680 | { | ||
681 | ZPOS64_T sizeEndOfCentralDirectory; | ||
682 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
683 | err=ZIP_ERRNO; | ||
684 | |||
685 | /* the signature, already checked */ | ||
686 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) | ||
687 | err=ZIP_ERRNO; | ||
688 | |||
689 | /* size of zip64 end of central directory record */ | ||
690 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) | ||
691 | err=ZIP_ERRNO; | ||
692 | |||
693 | /* version made by */ | ||
694 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) | ||
695 | err=ZIP_ERRNO; | ||
696 | |||
697 | /* version needed to extract */ | ||
698 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) | ||
699 | err=ZIP_ERRNO; | ||
700 | |||
701 | /* number of this disk */ | ||
702 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) | ||
703 | err=ZIP_ERRNO; | ||
704 | |||
705 | /* number of the disk with the start of the central directory */ | ||
706 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) | ||
707 | err=ZIP_ERRNO; | ||
708 | |||
709 | /* total number of entries in the central directory on this disk */ | ||
710 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) | ||
711 | err=ZIP_ERRNO; | ||
712 | |||
713 | /* total number of entries in the central directory */ | ||
714 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) | ||
715 | err=ZIP_ERRNO; | ||
716 | |||
717 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) | ||
718 | err=ZIP_BADZIPFILE; | ||
719 | |||
720 | /* size of the central directory */ | ||
721 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) | ||
722 | err=ZIP_ERRNO; | ||
723 | |||
724 | /* offset of start of central directory with respect to the | ||
725 | starting disk number */ | ||
726 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) | ||
727 | err=ZIP_ERRNO; | ||
728 | |||
729 | // TODO.. | ||
730 | // read the comment from the standard central header. | ||
731 | size_comment = 0; | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | // Read End of central Directory info | ||
736 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
737 | err=ZIP_ERRNO; | ||
738 | |||
739 | /* the signature, already checked */ | ||
740 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) | ||
741 | err=ZIP_ERRNO; | ||
742 | |||
743 | /* number of this disk */ | ||
744 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) | ||
745 | err=ZIP_ERRNO; | ||
746 | |||
747 | /* number of the disk with the start of the central directory */ | ||
748 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) | ||
749 | err=ZIP_ERRNO; | ||
750 | |||
751 | /* total number of entries in the central dir on this disk */ | ||
752 | number_entry = 0; | ||
753 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
754 | err=ZIP_ERRNO; | ||
755 | else | ||
756 | number_entry = uL; | ||
757 | |||
758 | /* total number of entries in the central dir */ | ||
759 | number_entry_CD = 0; | ||
760 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
761 | err=ZIP_ERRNO; | ||
762 | else | ||
763 | number_entry_CD = uL; | ||
764 | |||
765 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) | ||
766 | err=ZIP_BADZIPFILE; | ||
767 | |||
768 | /* size of the central directory */ | ||
769 | size_central_dir = 0; | ||
770 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
771 | err=ZIP_ERRNO; | ||
772 | else | ||
773 | size_central_dir = uL; | ||
774 | |||
775 | /* offset of start of central directory with respect to the starting disk number */ | ||
776 | offset_central_dir = 0; | ||
777 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
778 | err=ZIP_ERRNO; | ||
779 | else | ||
780 | offset_central_dir = uL; | ||
781 | |||
782 | |||
783 | /* zipfile global comment length */ | ||
784 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) | ||
785 | err=ZIP_ERRNO; | ||
786 | } | ||
787 | |||
788 | if ((central_pos<offset_central_dir+size_central_dir) && | ||
789 | (err==ZIP_OK)) | ||
790 | err=ZIP_BADZIPFILE; | ||
791 | |||
792 | if (err!=ZIP_OK) | ||
793 | { | ||
794 | ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); | ||
795 | return ZIP_ERRNO; | ||
796 | } | ||
797 | |||
798 | if (size_comment>0) | ||
799 | { | ||
800 | pziinit->globalcomment = (char*)ALLOC(size_comment+1); | ||
801 | if (pziinit->globalcomment) | ||
802 | { | ||
803 | size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); | ||
804 | pziinit->globalcomment[size_comment]=0; | ||
805 | } | ||
806 | } | ||
807 | |||
808 | byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); | ||
809 | pziinit->add_position_when_writting_offset = byte_before_the_zipfile; | ||
810 | |||
811 | { | ||
812 | ZPOS64_T size_central_dir_to_read = size_central_dir; | ||
813 | size_t buf_size = SIZEDATA_INDATABLOCK; | ||
814 | void* buf_read = (void*)ALLOC(buf_size); | ||
815 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
816 | err=ZIP_ERRNO; | ||
817 | |||
818 | while ((size_central_dir_to_read>0) && (err==ZIP_OK)) | ||
819 | { | ||
820 | ZPOS64_T read_this = SIZEDATA_INDATABLOCK; | ||
821 | if (read_this > size_central_dir_to_read) | ||
822 | read_this = size_central_dir_to_read; | ||
823 | |||
824 | if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) | ||
825 | err=ZIP_ERRNO; | ||
826 | |||
827 | if (err==ZIP_OK) | ||
828 | err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); | ||
829 | |||
830 | size_central_dir_to_read-=read_this; | ||
492 | } | 831 | } |
493 | TRYFREE(buf); | 832 | TRYFREE(buf_read); |
494 | return uPosFound; | 833 | } |
834 | pziinit->begin_pos = byte_before_the_zipfile; | ||
835 | pziinit->number_entry = number_entry_CD; | ||
836 | |||
837 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
838 | err=ZIP_ERRNO; | ||
839 | |||
840 | return err; | ||
495 | } | 841 | } |
842 | |||
843 | |||
496 | #endif /* !NO_ADDFILEINEXISTINGZIP*/ | 844 | #endif /* !NO_ADDFILEINEXISTINGZIP*/ |
497 | 845 | ||
846 | |||
498 | /************************************************************/ | 847 | /************************************************************/ |
499 | extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) | 848 | extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) |
500 | const char *pathname; | ||
501 | int append; | ||
502 | zipcharpc* globalcomment; | ||
503 | zlib_filefunc_def* pzlib_filefunc_def; | ||
504 | { | 849 | { |
505 | zip_internal ziinit; | 850 | zip64_internal ziinit; |
506 | zip_internal* zi; | 851 | zip64_internal* zi; |
507 | int err=ZIP_OK; | 852 | int err=ZIP_OK; |
508 | 853 | ||
509 | 854 | ziinit.z_filefunc.zseek32_file = NULL; | |
510 | if (pzlib_filefunc_def==NULL) | 855 | ziinit.z_filefunc.ztell32_file = NULL; |
511 | fill_fopen_filefunc(&ziinit.z_filefunc); | 856 | if (pzlib_filefunc64_32_def==NULL) |
857 | fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); | ||
512 | else | 858 | else |
513 | ziinit.z_filefunc = *pzlib_filefunc_def; | 859 | ziinit.z_filefunc = *pzlib_filefunc64_32_def; |
514 | 860 | ||
515 | ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) | 861 | ziinit.filestream = ZOPEN64(ziinit.z_filefunc, |
516 | (ziinit.z_filefunc.opaque, | ||
517 | pathname, | 862 | pathname, |
518 | (append == APPEND_STATUS_CREATE) ? | 863 | (append == APPEND_STATUS_CREATE) ? |
519 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : | 864 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : |
@@ -521,7 +866,11 @@ extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc | |||
521 | 866 | ||
522 | if (ziinit.filestream == NULL) | 867 | if (ziinit.filestream == NULL) |
523 | return NULL; | 868 | return NULL; |
524 | ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); | 869 | |
870 | if (append == APPEND_STATUS_CREATEAFTER) | ||
871 | ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); | ||
872 | |||
873 | ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); | ||
525 | ziinit.in_opened_file_inzip = 0; | 874 | ziinit.in_opened_file_inzip = 0; |
526 | ziinit.ci.stream_initialised = 0; | 875 | ziinit.ci.stream_initialised = 0; |
527 | ziinit.number_entry = 0; | 876 | ziinit.number_entry = 0; |
@@ -529,10 +878,11 @@ extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc | |||
529 | init_linkedlist(&(ziinit.central_dir)); | 878 | init_linkedlist(&(ziinit.central_dir)); |
530 | 879 | ||
531 | 880 | ||
532 | zi = (zip_internal*)ALLOC(sizeof(zip_internal)); | 881 | |
882 | zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); | ||
533 | if (zi==NULL) | 883 | if (zi==NULL) |
534 | { | 884 | { |
535 | ZCLOSE(ziinit.z_filefunc,ziinit.filestream); | 885 | ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); |
536 | return NULL; | 886 | return NULL; |
537 | } | 887 | } |
538 | 888 | ||
@@ -541,122 +891,8 @@ extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc | |||
541 | ziinit.globalcomment = NULL; | 891 | ziinit.globalcomment = NULL; |
542 | if (append == APPEND_STATUS_ADDINZIP) | 892 | if (append == APPEND_STATUS_ADDINZIP) |
543 | { | 893 | { |
544 | uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | 894 | // Read and Cache Central Directory Records |
545 | 895 | err = LoadCentralDirectoryRecord(&ziinit); | |
546 | uLong size_central_dir; /* size of the central directory */ | ||
547 | uLong offset_central_dir; /* offset of start of central directory */ | ||
548 | uLong central_pos,uL; | ||
549 | |||
550 | uLong number_disk; /* number of the current dist, used for | ||
551 | spaning ZIP, unsupported, always 0*/ | ||
552 | uLong number_disk_with_CD; /* number the the disk with central dir, used | ||
553 | for spaning ZIP, unsupported, always 0*/ | ||
554 | uLong number_entry; | ||
555 | uLong number_entry_CD; /* total number of entries in | ||
556 | the central dir | ||
557 | (same than number_entry on nospan) */ | ||
558 | uLong size_comment; | ||
559 | |||
560 | central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); | ||
561 | if (central_pos==0) | ||
562 | err=ZIP_ERRNO; | ||
563 | |||
564 | if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, | ||
565 | central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
566 | err=ZIP_ERRNO; | ||
567 | |||
568 | /* the signature, already checked */ | ||
569 | if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) | ||
570 | err=ZIP_ERRNO; | ||
571 | |||
572 | /* number of this disk */ | ||
573 | if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) | ||
574 | err=ZIP_ERRNO; | ||
575 | |||
576 | /* number of the disk with the start of the central directory */ | ||
577 | if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) | ||
578 | err=ZIP_ERRNO; | ||
579 | |||
580 | /* total number of entries in the central dir on this disk */ | ||
581 | if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) | ||
582 | err=ZIP_ERRNO; | ||
583 | |||
584 | /* total number of entries in the central dir */ | ||
585 | if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) | ||
586 | err=ZIP_ERRNO; | ||
587 | |||
588 | if ((number_entry_CD!=number_entry) || | ||
589 | (number_disk_with_CD!=0) || | ||
590 | (number_disk!=0)) | ||
591 | err=ZIP_BADZIPFILE; | ||
592 | |||
593 | /* size of the central directory */ | ||
594 | if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) | ||
595 | err=ZIP_ERRNO; | ||
596 | |||
597 | /* offset of start of central directory with respect to the | ||
598 | starting disk number */ | ||
599 | if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) | ||
600 | err=ZIP_ERRNO; | ||
601 | |||
602 | /* zipfile global comment length */ | ||
603 | if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) | ||
604 | err=ZIP_ERRNO; | ||
605 | |||
606 | if ((central_pos<offset_central_dir+size_central_dir) && | ||
607 | (err==ZIP_OK)) | ||
608 | err=ZIP_BADZIPFILE; | ||
609 | |||
610 | if (err!=ZIP_OK) | ||
611 | { | ||
612 | ZCLOSE(ziinit.z_filefunc, ziinit.filestream); | ||
613 | return NULL; | ||
614 | } | ||
615 | |||
616 | if (size_comment>0) | ||
617 | { | ||
618 | ziinit.globalcomment = ALLOC(size_comment+1); | ||
619 | if (ziinit.globalcomment) | ||
620 | { | ||
621 | size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment); | ||
622 | ziinit.globalcomment[size_comment]=0; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | byte_before_the_zipfile = central_pos - | ||
627 | (offset_central_dir+size_central_dir); | ||
628 | ziinit.add_position_when_writting_offset = byte_before_the_zipfile; | ||
629 | |||
630 | { | ||
631 | uLong size_central_dir_to_read = size_central_dir; | ||
632 | size_t buf_size = SIZEDATA_INDATABLOCK; | ||
633 | void* buf_read = (void*)ALLOC(buf_size); | ||
634 | if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, | ||
635 | offset_central_dir + byte_before_the_zipfile, | ||
636 | ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
637 | err=ZIP_ERRNO; | ||
638 | |||
639 | while ((size_central_dir_to_read>0) && (err==ZIP_OK)) | ||
640 | { | ||
641 | uLong read_this = SIZEDATA_INDATABLOCK; | ||
642 | if (read_this > size_central_dir_to_read) | ||
643 | read_this = size_central_dir_to_read; | ||
644 | if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) | ||
645 | err=ZIP_ERRNO; | ||
646 | |||
647 | if (err==ZIP_OK) | ||
648 | err = add_data_in_datablock(&ziinit.central_dir,buf_read, | ||
649 | (uLong)read_this); | ||
650 | size_central_dir_to_read-=read_this; | ||
651 | } | ||
652 | TRYFREE(buf_read); | ||
653 | } | ||
654 | ziinit.begin_pos = byte_before_the_zipfile; | ||
655 | ziinit.number_entry = number_entry_CD; | ||
656 | |||
657 | if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, | ||
658 | offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
659 | err=ZIP_ERRNO; | ||
660 | } | 896 | } |
661 | 897 | ||
662 | if (globalcomment) | 898 | if (globalcomment) |
@@ -680,37 +916,150 @@ extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc | |||
680 | } | 916 | } |
681 | } | 917 | } |
682 | 918 | ||
683 | extern zipFile ZEXPORT zipOpen (pathname, append) | 919 | extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) |
684 | const char *pathname; | 920 | { |
685 | int append; | 921 | if (pzlib_filefunc32_def != NULL) |
922 | { | ||
923 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
924 | fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); | ||
925 | return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); | ||
926 | } | ||
927 | else | ||
928 | return zipOpen3(pathname, append, globalcomment, NULL); | ||
929 | } | ||
930 | |||
931 | extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) | ||
932 | { | ||
933 | if (pzlib_filefunc_def != NULL) | ||
934 | { | ||
935 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
936 | zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; | ||
937 | zlib_filefunc64_32_def_fill.ztell32_file = NULL; | ||
938 | zlib_filefunc64_32_def_fill.zseek32_file = NULL; | ||
939 | return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); | ||
940 | } | ||
941 | else | ||
942 | return zipOpen3(pathname, append, globalcomment, NULL); | ||
943 | } | ||
944 | |||
945 | |||
946 | |||
947 | extern zipFile ZEXPORT zipOpen (const char* pathname, int append) | ||
948 | { | ||
949 | return zipOpen3((const void*)pathname,append,NULL,NULL); | ||
950 | } | ||
951 | |||
952 | extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) | ||
686 | { | 953 | { |
687 | return zipOpen2(pathname,append,NULL,NULL); | 954 | return zipOpen3(pathname,append,NULL,NULL); |
688 | } | 955 | } |
689 | 956 | ||
690 | extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | 957 | int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) |
691 | extrafield_local, size_extrafield_local, | ||
692 | extrafield_global, size_extrafield_global, | ||
693 | comment, method, level, raw, | ||
694 | windowBits, memLevel, strategy, | ||
695 | password, crcForCrypting) | ||
696 | zipFile file; | ||
697 | const char* filename; | ||
698 | const zip_fileinfo* zipfi; | ||
699 | const void* extrafield_local; | ||
700 | uInt size_extrafield_local; | ||
701 | const void* extrafield_global; | ||
702 | uInt size_extrafield_global; | ||
703 | const char* comment; | ||
704 | int method; | ||
705 | int level; | ||
706 | int raw; | ||
707 | int windowBits; | ||
708 | int memLevel; | ||
709 | int strategy; | ||
710 | const char* password; | ||
711 | uLong crcForCrypting; | ||
712 | { | 958 | { |
713 | zip_internal* zi; | 959 | /* write the local header */ |
960 | int err; | ||
961 | uInt size_filename = (uInt)strlen(filename); | ||
962 | uInt size_extrafield = size_extrafield_local; | ||
963 | |||
964 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); | ||
965 | |||
966 | if (err==ZIP_OK) | ||
967 | { | ||
968 | if(zi->ci.zip64) | ||
969 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ | ||
970 | else | ||
971 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ | ||
972 | } | ||
973 | |||
974 | if (err==ZIP_OK) | ||
975 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); | ||
976 | |||
977 | if (err==ZIP_OK) | ||
978 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); | ||
979 | |||
980 | if (err==ZIP_OK) | ||
981 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); | ||
982 | |||
983 | // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later | ||
984 | if (err==ZIP_OK) | ||
985 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ | ||
986 | if (err==ZIP_OK) | ||
987 | { | ||
988 | if(zi->ci.zip64) | ||
989 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ | ||
990 | else | ||
991 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ | ||
992 | } | ||
993 | if (err==ZIP_OK) | ||
994 | { | ||
995 | if(zi->ci.zip64) | ||
996 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ | ||
997 | else | ||
998 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ | ||
999 | } | ||
1000 | |||
1001 | if (err==ZIP_OK) | ||
1002 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); | ||
1003 | |||
1004 | if(zi->ci.zip64) | ||
1005 | { | ||
1006 | size_extrafield += 20; | ||
1007 | } | ||
1008 | |||
1009 | if (err==ZIP_OK) | ||
1010 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); | ||
1011 | |||
1012 | if ((err==ZIP_OK) && (size_filename > 0)) | ||
1013 | { | ||
1014 | if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) | ||
1015 | err = ZIP_ERRNO; | ||
1016 | } | ||
1017 | |||
1018 | if ((err==ZIP_OK) && (size_extrafield_local > 0)) | ||
1019 | { | ||
1020 | if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) | ||
1021 | err = ZIP_ERRNO; | ||
1022 | } | ||
1023 | |||
1024 | |||
1025 | if ((err==ZIP_OK) && (zi->ci.zip64)) | ||
1026 | { | ||
1027 | // write the Zip64 extended info | ||
1028 | short HeaderID = 1; | ||
1029 | short DataSize = 16; | ||
1030 | ZPOS64_T CompressedSize = 0; | ||
1031 | ZPOS64_T UncompressedSize = 0; | ||
1032 | |||
1033 | // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) | ||
1034 | zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1035 | |||
1036 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); | ||
1037 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); | ||
1038 | |||
1039 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); | ||
1040 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); | ||
1041 | } | ||
1042 | |||
1043 | return err; | ||
1044 | } | ||
1045 | |||
1046 | /* | ||
1047 | NOTE. | ||
1048 | When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped | ||
1049 | before calling this function it can be done with zipRemoveExtraInfoBlock | ||
1050 | |||
1051 | It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize | ||
1052 | unnecessary allocations. | ||
1053 | */ | ||
1054 | extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1055 | const void* extrafield_local, uInt size_extrafield_local, | ||
1056 | const void* extrafield_global, uInt size_extrafield_global, | ||
1057 | const char* comment, int method, int level, int raw, | ||
1058 | int windowBits,int memLevel, int strategy, | ||
1059 | const char* password, uLong crcForCrypting, | ||
1060 | uLong versionMadeBy, uLong flagBase, int zip64) | ||
1061 | { | ||
1062 | zip64_internal* zi; | ||
714 | uInt size_filename; | 1063 | uInt size_filename; |
715 | uInt size_comment; | 1064 | uInt size_comment; |
716 | uInt i; | 1065 | uInt i; |
@@ -723,10 +1072,16 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
723 | 1072 | ||
724 | if (file == NULL) | 1073 | if (file == NULL) |
725 | return ZIP_PARAMERROR; | 1074 | return ZIP_PARAMERROR; |
1075 | |||
1076 | #ifdef HAVE_BZIP2 | ||
1077 | if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) | ||
1078 | return ZIP_PARAMERROR; | ||
1079 | #else | ||
726 | if ((method!=0) && (method!=Z_DEFLATED)) | 1080 | if ((method!=0) && (method!=Z_DEFLATED)) |
727 | return ZIP_PARAMERROR; | 1081 | return ZIP_PARAMERROR; |
1082 | #endif | ||
728 | 1083 | ||
729 | zi = (zip_internal*)file; | 1084 | zi = (zip64_internal*)file; |
730 | 1085 | ||
731 | if (zi->in_opened_file_inzip == 1) | 1086 | if (zi->in_opened_file_inzip == 1) |
732 | { | 1087 | { |
@@ -735,7 +1090,6 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
735 | return err; | 1090 | return err; |
736 | } | 1091 | } |
737 | 1092 | ||
738 | |||
739 | if (filename==NULL) | 1093 | if (filename==NULL) |
740 | filename="-"; | 1094 | filename="-"; |
741 | 1095 | ||
@@ -752,10 +1106,11 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
752 | { | 1106 | { |
753 | if (zipfi->dosDate != 0) | 1107 | if (zipfi->dosDate != 0) |
754 | zi->ci.dosDate = zipfi->dosDate; | 1108 | zi->ci.dosDate = zipfi->dosDate; |
755 | else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); | 1109 | else |
1110 | zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); | ||
756 | } | 1111 | } |
757 | 1112 | ||
758 | zi->ci.flag = 0; | 1113 | zi->ci.flag = flagBase; |
759 | if ((level==8) || (level==9)) | 1114 | if ((level==8) || (level==9)) |
760 | zi->ci.flag |= 2; | 1115 | zi->ci.flag |= 2; |
761 | if ((level==2)) | 1116 | if ((level==2)) |
@@ -771,37 +1126,43 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
771 | zi->ci.stream_initialised = 0; | 1126 | zi->ci.stream_initialised = 0; |
772 | zi->ci.pos_in_buffered_data = 0; | 1127 | zi->ci.pos_in_buffered_data = 0; |
773 | zi->ci.raw = raw; | 1128 | zi->ci.raw = raw; |
774 | zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; | 1129 | zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); |
775 | zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + | ||
776 | size_extrafield_global + size_comment; | ||
777 | zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); | ||
778 | 1130 | ||
779 | ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); | 1131 | zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; |
1132 | zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data | ||
1133 | |||
1134 | zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); | ||
1135 | |||
1136 | zi->ci.size_centralExtra = size_extrafield_global; | ||
1137 | zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); | ||
780 | /* version info */ | 1138 | /* version info */ |
781 | ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); | 1139 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); |
782 | ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); | 1140 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); |
783 | ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); | 1141 | zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); |
784 | ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); | 1142 | zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); |
785 | ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); | 1143 | zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); |
786 | ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ | 1144 | zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ |
787 | ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ | 1145 | zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ |
788 | ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ | 1146 | zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ |
789 | ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); | 1147 | zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); |
790 | ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); | 1148 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); |
791 | ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); | 1149 | zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); |
792 | ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ | 1150 | zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ |
793 | 1151 | ||
794 | if (zipfi==NULL) | 1152 | if (zipfi==NULL) |
795 | ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); | 1153 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); |
796 | else | 1154 | else |
797 | ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); | 1155 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); |
798 | 1156 | ||
799 | if (zipfi==NULL) | 1157 | if (zipfi==NULL) |
800 | ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); | 1158 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); |
801 | else | 1159 | else |
802 | ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); | 1160 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); |
803 | 1161 | ||
804 | ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); | 1162 | if(zi->ci.pos_local_header >= 0xffffffff) |
1163 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); | ||
1164 | else | ||
1165 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); | ||
805 | 1166 | ||
806 | for (i=0;i<size_filename;i++) | 1167 | for (i=0;i<size_filename;i++) |
807 | *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); | 1168 | *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); |
@@ -816,63 +1177,66 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
816 | if (zi->ci.central_header == NULL) | 1177 | if (zi->ci.central_header == NULL) |
817 | return ZIP_INTERNALERROR; | 1178 | return ZIP_INTERNALERROR; |
818 | 1179 | ||
819 | /* write the local header */ | 1180 | zi->ci.zip64 = zip64; |
820 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); | 1181 | zi->ci.totalCompressedData = 0; |
821 | 1182 | zi->ci.totalUncompressedData = 0; | |
822 | if (err==ZIP_OK) | 1183 | zi->ci.pos_zip64extrainfo = 0; |
823 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ | 1184 | |
824 | if (err==ZIP_OK) | 1185 | err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); |
825 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); | 1186 | |
826 | 1187 | #ifdef HAVE_BZIP2 | |
827 | if (err==ZIP_OK) | 1188 | zi->ci.bstream.avail_in = (uInt)0; |
828 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); | 1189 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; |
829 | 1190 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; | |
830 | if (err==ZIP_OK) | 1191 | zi->ci.bstream.total_in_hi32 = 0; |
831 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); | 1192 | zi->ci.bstream.total_in_lo32 = 0; |
832 | 1193 | zi->ci.bstream.total_out_hi32 = 0; | |
833 | if (err==ZIP_OK) | 1194 | zi->ci.bstream.total_out_lo32 = 0; |
834 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ | 1195 | #endif |
835 | if (err==ZIP_OK) | ||
836 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ | ||
837 | if (err==ZIP_OK) | ||
838 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ | ||
839 | |||
840 | if (err==ZIP_OK) | ||
841 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); | ||
842 | |||
843 | if (err==ZIP_OK) | ||
844 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); | ||
845 | |||
846 | if ((err==ZIP_OK) && (size_filename>0)) | ||
847 | if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) | ||
848 | err = ZIP_ERRNO; | ||
849 | |||
850 | if ((err==ZIP_OK) && (size_extrafield_local>0)) | ||
851 | if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) | ||
852 | !=size_extrafield_local) | ||
853 | err = ZIP_ERRNO; | ||
854 | 1196 | ||
855 | zi->ci.stream.avail_in = (uInt)0; | 1197 | zi->ci.stream.avail_in = (uInt)0; |
856 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | 1198 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; |
857 | zi->ci.stream.next_out = zi->ci.buffered_data; | 1199 | zi->ci.stream.next_out = zi->ci.buffered_data; |
858 | zi->ci.stream.total_in = 0; | 1200 | zi->ci.stream.total_in = 0; |
859 | zi->ci.stream.total_out = 0; | 1201 | zi->ci.stream.total_out = 0; |
1202 | zi->ci.stream.data_type = Z_BINARY; | ||
860 | 1203 | ||
1204 | #ifdef HAVE_BZIP2 | ||
1205 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1206 | #else | ||
861 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | 1207 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) |
1208 | #endif | ||
862 | { | 1209 | { |
863 | zi->ci.stream.zalloc = (alloc_func)0; | 1210 | if(zi->ci.method == Z_DEFLATED) |
864 | zi->ci.stream.zfree = (free_func)0; | 1211 | { |
865 | zi->ci.stream.opaque = (voidpf)0; | 1212 | zi->ci.stream.zalloc = (alloc_func)0; |
1213 | zi->ci.stream.zfree = (free_func)0; | ||
1214 | zi->ci.stream.opaque = (voidpf)0; | ||
866 | 1215 | ||
867 | if (windowBits>0) | 1216 | if (windowBits>0) |
868 | windowBits = -windowBits; | 1217 | windowBits = -windowBits; |
869 | 1218 | ||
870 | err = deflateInit2(&zi->ci.stream, level, | 1219 | err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); |
871 | Z_DEFLATED, windowBits, memLevel, strategy); | 1220 | |
1221 | if (err==Z_OK) | ||
1222 | zi->ci.stream_initialised = Z_DEFLATED; | ||
1223 | } | ||
1224 | else if(zi->ci.method == Z_BZIP2ED) | ||
1225 | { | ||
1226 | #ifdef HAVE_BZIP2 | ||
1227 | // Init BZip stuff here | ||
1228 | zi->ci.bstream.bzalloc = 0; | ||
1229 | zi->ci.bstream.bzfree = 0; | ||
1230 | zi->ci.bstream.opaque = (voidpf)0; | ||
1231 | |||
1232 | err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); | ||
1233 | if(err == BZ_OK) | ||
1234 | zi->ci.stream_initialised = Z_BZIP2ED; | ||
1235 | #endif | ||
1236 | } | ||
872 | 1237 | ||
873 | if (err==Z_OK) | ||
874 | zi->ci.stream_initialised = 1; | ||
875 | } | 1238 | } |
1239 | |||
876 | # ifndef NOCRYPT | 1240 | # ifndef NOCRYPT |
877 | zi->ci.crypt_header_size = 0; | 1241 | zi->ci.crypt_header_size = 0; |
878 | if ((err==Z_OK) && (password != NULL)) | 1242 | if ((err==Z_OK) && (password != NULL)) |
@@ -886,7 +1250,7 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
886 | sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); | 1250 | sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); |
887 | zi->ci.crypt_header_size = sizeHead; | 1251 | zi->ci.crypt_header_size = sizeHead; |
888 | 1252 | ||
889 | if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) | 1253 | if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) |
890 | err = ZIP_ERRNO; | 1254 | err = ZIP_ERRNO; |
891 | } | 1255 | } |
892 | # endif | 1256 | # endif |
@@ -896,53 +1260,105 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, | |||
896 | return err; | 1260 | return err; |
897 | } | 1261 | } |
898 | 1262 | ||
899 | extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, | 1263 | extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, |
900 | extrafield_local, size_extrafield_local, | 1264 | const void* extrafield_local, uInt size_extrafield_local, |
901 | extrafield_global, size_extrafield_global, | 1265 | const void* extrafield_global, uInt size_extrafield_global, |
902 | comment, method, level, raw) | 1266 | const char* comment, int method, int level, int raw, |
903 | zipFile file; | 1267 | int windowBits,int memLevel, int strategy, |
904 | const char* filename; | 1268 | const char* password, uLong crcForCrypting, |
905 | const zip_fileinfo* zipfi; | 1269 | uLong versionMadeBy, uLong flagBase) |
906 | const void* extrafield_local; | 1270 | { |
907 | uInt size_extrafield_local; | 1271 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, |
908 | const void* extrafield_global; | 1272 | extrafield_local, size_extrafield_local, |
909 | uInt size_extrafield_global; | 1273 | extrafield_global, size_extrafield_global, |
910 | const char* comment; | 1274 | comment, method, level, raw, |
911 | int method; | 1275 | windowBits, memLevel, strategy, |
912 | int level; | 1276 | password, crcForCrypting, versionMadeBy, flagBase, 0); |
913 | int raw; | 1277 | } |
1278 | |||
1279 | extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1280 | const void* extrafield_local, uInt size_extrafield_local, | ||
1281 | const void* extrafield_global, uInt size_extrafield_global, | ||
1282 | const char* comment, int method, int level, int raw, | ||
1283 | int windowBits,int memLevel, int strategy, | ||
1284 | const char* password, uLong crcForCrypting) | ||
1285 | { | ||
1286 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1287 | extrafield_local, size_extrafield_local, | ||
1288 | extrafield_global, size_extrafield_global, | ||
1289 | comment, method, level, raw, | ||
1290 | windowBits, memLevel, strategy, | ||
1291 | password, crcForCrypting, VERSIONMADEBY, 0, 0); | ||
1292 | } | ||
1293 | |||
1294 | extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1295 | const void* extrafield_local, uInt size_extrafield_local, | ||
1296 | const void* extrafield_global, uInt size_extrafield_global, | ||
1297 | const char* comment, int method, int level, int raw, | ||
1298 | int windowBits,int memLevel, int strategy, | ||
1299 | const char* password, uLong crcForCrypting, int zip64) | ||
1300 | { | ||
1301 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1302 | extrafield_local, size_extrafield_local, | ||
1303 | extrafield_global, size_extrafield_global, | ||
1304 | comment, method, level, raw, | ||
1305 | windowBits, memLevel, strategy, | ||
1306 | password, crcForCrypting, VERSIONMADEBY, 0, zip64); | ||
1307 | } | ||
1308 | |||
1309 | extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1310 | const void* extrafield_local, uInt size_extrafield_local, | ||
1311 | const void* extrafield_global, uInt size_extrafield_global, | ||
1312 | const char* comment, int method, int level, int raw) | ||
1313 | { | ||
1314 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1315 | extrafield_local, size_extrafield_local, | ||
1316 | extrafield_global, size_extrafield_global, | ||
1317 | comment, method, level, raw, | ||
1318 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1319 | NULL, 0, VERSIONMADEBY, 0, 0); | ||
1320 | } | ||
1321 | |||
1322 | extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1323 | const void* extrafield_local, uInt size_extrafield_local, | ||
1324 | const void* extrafield_global, uInt size_extrafield_global, | ||
1325 | const char* comment, int method, int level, int raw, int zip64) | ||
914 | { | 1326 | { |
915 | return zipOpenNewFileInZip3 (file, filename, zipfi, | 1327 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, |
916 | extrafield_local, size_extrafield_local, | 1328 | extrafield_local, size_extrafield_local, |
917 | extrafield_global, size_extrafield_global, | 1329 | extrafield_global, size_extrafield_global, |
918 | comment, method, level, raw, | 1330 | comment, method, level, raw, |
919 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | 1331 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, |
920 | NULL, 0); | 1332 | NULL, 0, VERSIONMADEBY, 0, zip64); |
1333 | } | ||
1334 | |||
1335 | extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1336 | const void* extrafield_local, uInt size_extrafield_local, | ||
1337 | const void*extrafield_global, uInt size_extrafield_global, | ||
1338 | const char* comment, int method, int level, int zip64) | ||
1339 | { | ||
1340 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1341 | extrafield_local, size_extrafield_local, | ||
1342 | extrafield_global, size_extrafield_global, | ||
1343 | comment, method, level, 0, | ||
1344 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1345 | NULL, 0, VERSIONMADEBY, 0, zip64); | ||
921 | } | 1346 | } |
922 | 1347 | ||
923 | extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, | 1348 | extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, |
924 | extrafield_local, size_extrafield_local, | 1349 | const void* extrafield_local, uInt size_extrafield_local, |
925 | extrafield_global, size_extrafield_global, | 1350 | const void*extrafield_global, uInt size_extrafield_global, |
926 | comment, method, level) | 1351 | const char* comment, int method, int level) |
927 | zipFile file; | ||
928 | const char* filename; | ||
929 | const zip_fileinfo* zipfi; | ||
930 | const void* extrafield_local; | ||
931 | uInt size_extrafield_local; | ||
932 | const void* extrafield_global; | ||
933 | uInt size_extrafield_global; | ||
934 | const char* comment; | ||
935 | int method; | ||
936 | int level; | ||
937 | { | 1352 | { |
938 | return zipOpenNewFileInZip2 (file, filename, zipfi, | 1353 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, |
939 | extrafield_local, size_extrafield_local, | 1354 | extrafield_local, size_extrafield_local, |
940 | extrafield_global, size_extrafield_global, | 1355 | extrafield_global, size_extrafield_global, |
941 | comment, method, level, 0); | 1356 | comment, method, level, 0, |
1357 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1358 | NULL, 0, VERSIONMADEBY, 0, 0); | ||
942 | } | 1359 | } |
943 | 1360 | ||
944 | local int zipFlushWriteBuffer(zi) | 1361 | local int zip64FlushWriteBuffer(zip64_internal* zi) |
945 | zip_internal* zi; | ||
946 | { | 1362 | { |
947 | int err=ZIP_OK; | 1363 | int err=ZIP_OK; |
948 | 1364 | ||
@@ -952,169 +1368,372 @@ local int zipFlushWriteBuffer(zi) | |||
952 | uInt i; | 1368 | uInt i; |
953 | int t; | 1369 | int t; |
954 | for (i=0;i<zi->ci.pos_in_buffered_data;i++) | 1370 | for (i=0;i<zi->ci.pos_in_buffered_data;i++) |
955 | zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, | 1371 | zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); |
956 | zi->ci.buffered_data[i],t); | ||
957 | #endif | 1372 | #endif |
958 | } | 1373 | } |
959 | if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) | 1374 | |
960 | !=zi->ci.pos_in_buffered_data) | 1375 | if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) |
961 | err = ZIP_ERRNO; | 1376 | err = ZIP_ERRNO; |
1377 | |||
1378 | zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; | ||
1379 | |||
1380 | #ifdef HAVE_BZIP2 | ||
1381 | if(zi->ci.method == Z_BZIP2ED) | ||
1382 | { | ||
1383 | zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; | ||
1384 | zi->ci.bstream.total_in_lo32 = 0; | ||
1385 | zi->ci.bstream.total_in_hi32 = 0; | ||
1386 | } | ||
1387 | else | ||
1388 | #endif | ||
1389 | { | ||
1390 | zi->ci.totalUncompressedData += zi->ci.stream.total_in; | ||
1391 | zi->ci.stream.total_in = 0; | ||
1392 | } | ||
1393 | |||
1394 | |||
962 | zi->ci.pos_in_buffered_data = 0; | 1395 | zi->ci.pos_in_buffered_data = 0; |
1396 | |||
963 | return err; | 1397 | return err; |
964 | } | 1398 | } |
965 | 1399 | ||
966 | extern int ZEXPORT zipWriteInFileInZip (file, buf, len) | 1400 | extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) |
967 | zipFile file; | ||
968 | const void* buf; | ||
969 | unsigned len; | ||
970 | { | 1401 | { |
971 | zip_internal* zi; | 1402 | zip64_internal* zi; |
972 | int err=ZIP_OK; | 1403 | int err=ZIP_OK; |
973 | 1404 | ||
974 | if (file == NULL) | 1405 | if (file == NULL) |
975 | return ZIP_PARAMERROR; | 1406 | return ZIP_PARAMERROR; |
976 | zi = (zip_internal*)file; | 1407 | zi = (zip64_internal*)file; |
977 | 1408 | ||
978 | if (zi->in_opened_file_inzip == 0) | 1409 | if (zi->in_opened_file_inzip == 0) |
979 | return ZIP_PARAMERROR; | 1410 | return ZIP_PARAMERROR; |
980 | 1411 | ||
981 | zi->ci.stream.next_in = (void*)buf; | 1412 | zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); |
982 | zi->ci.stream.avail_in = len; | ||
983 | zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); | ||
984 | 1413 | ||
985 | while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) | 1414 | #ifdef HAVE_BZIP2 |
1415 | if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) | ||
986 | { | 1416 | { |
987 | if (zi->ci.stream.avail_out == 0) | 1417 | zi->ci.bstream.next_in = (void*)buf; |
1418 | zi->ci.bstream.avail_in = len; | ||
1419 | err = BZ_RUN_OK; | ||
1420 | |||
1421 | while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) | ||
1422 | { | ||
1423 | if (zi->ci.bstream.avail_out == 0) | ||
988 | { | 1424 | { |
989 | if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) | 1425 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) |
990 | err = ZIP_ERRNO; | 1426 | err = ZIP_ERRNO; |
991 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | 1427 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; |
992 | zi->ci.stream.next_out = zi->ci.buffered_data; | 1428 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; |
993 | } | 1429 | } |
994 | 1430 | ||
995 | 1431 | ||
996 | if(err != ZIP_OK) | 1432 | if(err != BZ_RUN_OK) |
997 | break; | 1433 | break; |
998 | 1434 | ||
999 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | 1435 | if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) |
1000 | { | 1436 | { |
1001 | uLong uTotalOutBefore = zi->ci.stream.total_out; | 1437 | uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; |
1002 | err=deflate(&zi->ci.stream, Z_NO_FLUSH); | 1438 | // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; |
1003 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; | 1439 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); |
1004 | 1440 | ||
1441 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; | ||
1005 | } | 1442 | } |
1006 | else | 1443 | } |
1007 | { | 1444 | |
1008 | uInt copy_this,i; | 1445 | if(err == BZ_RUN_OK) |
1009 | if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) | 1446 | err = ZIP_OK; |
1010 | copy_this = zi->ci.stream.avail_in; | 1447 | } |
1011 | else | 1448 | else |
1012 | copy_this = zi->ci.stream.avail_out; | 1449 | #endif |
1013 | for (i=0;i<copy_this;i++) | 1450 | { |
1014 | *(((char*)zi->ci.stream.next_out)+i) = | 1451 | zi->ci.stream.next_in = (Bytef*)buf; |
1015 | *(((const char*)zi->ci.stream.next_in)+i); | 1452 | zi->ci.stream.avail_in = len; |
1016 | { | 1453 | |
1017 | zi->ci.stream.avail_in -= copy_this; | 1454 | while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) |
1018 | zi->ci.stream.avail_out-= copy_this; | 1455 | { |
1019 | zi->ci.stream.next_in+= copy_this; | 1456 | if (zi->ci.stream.avail_out == 0) |
1020 | zi->ci.stream.next_out+= copy_this; | 1457 | { |
1021 | zi->ci.stream.total_in+= copy_this; | 1458 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) |
1022 | zi->ci.stream.total_out+= copy_this; | 1459 | err = ZIP_ERRNO; |
1023 | zi->ci.pos_in_buffered_data += copy_this; | 1460 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; |
1024 | } | 1461 | zi->ci.stream.next_out = zi->ci.buffered_data; |
1025 | } | 1462 | } |
1463 | |||
1464 | |||
1465 | if(err != ZIP_OK) | ||
1466 | break; | ||
1467 | |||
1468 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | ||
1469 | { | ||
1470 | uLong uTotalOutBefore = zi->ci.stream.total_out; | ||
1471 | err=deflate(&zi->ci.stream, Z_NO_FLUSH); | ||
1472 | if(uTotalOutBefore > zi->ci.stream.total_out) | ||
1473 | { | ||
1474 | int bBreak = 0; | ||
1475 | bBreak++; | ||
1476 | } | ||
1477 | |||
1478 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; | ||
1479 | } | ||
1480 | else | ||
1481 | { | ||
1482 | uInt copy_this,i; | ||
1483 | if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) | ||
1484 | copy_this = zi->ci.stream.avail_in; | ||
1485 | else | ||
1486 | copy_this = zi->ci.stream.avail_out; | ||
1487 | |||
1488 | for (i = 0; i < copy_this; i++) | ||
1489 | *(((char*)zi->ci.stream.next_out)+i) = | ||
1490 | *(((const char*)zi->ci.stream.next_in)+i); | ||
1491 | { | ||
1492 | zi->ci.stream.avail_in -= copy_this; | ||
1493 | zi->ci.stream.avail_out-= copy_this; | ||
1494 | zi->ci.stream.next_in+= copy_this; | ||
1495 | zi->ci.stream.next_out+= copy_this; | ||
1496 | zi->ci.stream.total_in+= copy_this; | ||
1497 | zi->ci.stream.total_out+= copy_this; | ||
1498 | zi->ci.pos_in_buffered_data += copy_this; | ||
1499 | } | ||
1500 | } | ||
1501 | }// while(...) | ||
1026 | } | 1502 | } |
1027 | 1503 | ||
1028 | return err; | 1504 | return err; |
1029 | } | 1505 | } |
1030 | 1506 | ||
1031 | extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) | 1507 | extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) |
1032 | zipFile file; | ||
1033 | uLong uncompressed_size; | ||
1034 | uLong crc32; | ||
1035 | { | 1508 | { |
1036 | zip_internal* zi; | 1509 | return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); |
1037 | uLong compressed_size; | 1510 | } |
1511 | |||
1512 | extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) | ||
1513 | { | ||
1514 | zip64_internal* zi; | ||
1515 | ZPOS64_T compressed_size; | ||
1516 | uLong invalidValue = 0xffffffff; | ||
1517 | short datasize = 0; | ||
1038 | int err=ZIP_OK; | 1518 | int err=ZIP_OK; |
1039 | 1519 | ||
1040 | if (file == NULL) | 1520 | if (file == NULL) |
1041 | return ZIP_PARAMERROR; | 1521 | return ZIP_PARAMERROR; |
1042 | zi = (zip_internal*)file; | 1522 | zi = (zip64_internal*)file; |
1043 | 1523 | ||
1044 | if (zi->in_opened_file_inzip == 0) | 1524 | if (zi->in_opened_file_inzip == 0) |
1045 | return ZIP_PARAMERROR; | 1525 | return ZIP_PARAMERROR; |
1046 | zi->ci.stream.avail_in = 0; | 1526 | zi->ci.stream.avail_in = 0; |
1047 | 1527 | ||
1048 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | 1528 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) |
1049 | while (err==ZIP_OK) | 1529 | { |
1530 | while (err==ZIP_OK) | ||
1531 | { | ||
1532 | uLong uTotalOutBefore; | ||
1533 | if (zi->ci.stream.avail_out == 0) | ||
1534 | { | ||
1535 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) | ||
1536 | err = ZIP_ERRNO; | ||
1537 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
1538 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
1539 | } | ||
1540 | uTotalOutBefore = zi->ci.stream.total_out; | ||
1541 | err=deflate(&zi->ci.stream, Z_FINISH); | ||
1542 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; | ||
1543 | } | ||
1544 | } | ||
1545 | else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1050 | { | 1546 | { |
1547 | #ifdef HAVE_BZIP2 | ||
1548 | err = BZ_FINISH_OK; | ||
1549 | while (err==BZ_FINISH_OK) | ||
1550 | { | ||
1051 | uLong uTotalOutBefore; | 1551 | uLong uTotalOutBefore; |
1052 | if (zi->ci.stream.avail_out == 0) | 1552 | if (zi->ci.bstream.avail_out == 0) |
1053 | { | 1553 | { |
1054 | if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) | 1554 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) |
1055 | err = ZIP_ERRNO; | 1555 | err = ZIP_ERRNO; |
1056 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | 1556 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; |
1057 | zi->ci.stream.next_out = zi->ci.buffered_data; | 1557 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; |
1058 | } | 1558 | } |
1059 | uTotalOutBefore = zi->ci.stream.total_out; | 1559 | uTotalOutBefore = zi->ci.bstream.total_out_lo32; |
1060 | err=deflate(&zi->ci.stream, Z_FINISH); | 1560 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); |
1061 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; | 1561 | if(err == BZ_STREAM_END) |
1562 | err = Z_STREAM_END; | ||
1563 | |||
1564 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); | ||
1565 | } | ||
1566 | |||
1567 | if(err == BZ_FINISH_OK) | ||
1568 | err = ZIP_OK; | ||
1569 | #endif | ||
1062 | } | 1570 | } |
1063 | 1571 | ||
1064 | if (err==Z_STREAM_END) | 1572 | if (err==Z_STREAM_END) |
1065 | err=ZIP_OK; /* this is normal */ | 1573 | err=ZIP_OK; /* this is normal */ |
1066 | 1574 | ||
1067 | if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) | 1575 | if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) |
1068 | if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) | 1576 | { |
1577 | if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) | ||
1069 | err = ZIP_ERRNO; | 1578 | err = ZIP_ERRNO; |
1579 | } | ||
1070 | 1580 | ||
1071 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | 1581 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) |
1072 | { | 1582 | { |
1073 | err=deflateEnd(&zi->ci.stream); | 1583 | int tmp_err = deflateEnd(&zi->ci.stream); |
1584 | if (err == ZIP_OK) | ||
1585 | err = tmp_err; | ||
1074 | zi->ci.stream_initialised = 0; | 1586 | zi->ci.stream_initialised = 0; |
1075 | } | 1587 | } |
1588 | #ifdef HAVE_BZIP2 | ||
1589 | else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1590 | { | ||
1591 | int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); | ||
1592 | if (err==ZIP_OK) | ||
1593 | err = tmperr; | ||
1594 | zi->ci.stream_initialised = 0; | ||
1595 | } | ||
1596 | #endif | ||
1076 | 1597 | ||
1077 | if (!zi->ci.raw) | 1598 | if (!zi->ci.raw) |
1078 | { | 1599 | { |
1079 | crc32 = (uLong)zi->ci.crc32; | 1600 | crc32 = (uLong)zi->ci.crc32; |
1080 | uncompressed_size = (uLong)zi->ci.stream.total_in; | 1601 | uncompressed_size = zi->ci.totalUncompressedData; |
1081 | } | 1602 | } |
1082 | compressed_size = (uLong)zi->ci.stream.total_out; | 1603 | compressed_size = zi->ci.totalCompressedData; |
1604 | |||
1083 | # ifndef NOCRYPT | 1605 | # ifndef NOCRYPT |
1084 | compressed_size += zi->ci.crypt_header_size; | 1606 | compressed_size += zi->ci.crypt_header_size; |
1085 | # endif | 1607 | # endif |
1086 | 1608 | ||
1087 | ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ | 1609 | // update Current Item crc and sizes, |
1088 | ziplocal_putValue_inmemory(zi->ci.central_header+20, | 1610 | if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) |
1089 | compressed_size,4); /*compr size*/ | 1611 | { |
1612 | /*version Made by*/ | ||
1613 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); | ||
1614 | /*version needed*/ | ||
1615 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); | ||
1616 | |||
1617 | } | ||
1618 | |||
1619 | zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ | ||
1620 | |||
1621 | |||
1622 | if(compressed_size >= 0xffffffff) | ||
1623 | zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ | ||
1624 | else | ||
1625 | zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ | ||
1626 | |||
1627 | /// set internal file attributes field | ||
1090 | if (zi->ci.stream.data_type == Z_ASCII) | 1628 | if (zi->ci.stream.data_type == Z_ASCII) |
1091 | ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); | 1629 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); |
1092 | ziplocal_putValue_inmemory(zi->ci.central_header+24, | 1630 | |
1093 | uncompressed_size,4); /*uncompr size*/ | 1631 | if(uncompressed_size >= 0xffffffff) |
1632 | zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ | ||
1633 | else | ||
1634 | zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ | ||
1635 | |||
1636 | // Add ZIP64 extra info field for uncompressed size | ||
1637 | if(uncompressed_size >= 0xffffffff) | ||
1638 | datasize += 8; | ||
1639 | |||
1640 | // Add ZIP64 extra info field for compressed size | ||
1641 | if(compressed_size >= 0xffffffff) | ||
1642 | datasize += 8; | ||
1643 | |||
1644 | // Add ZIP64 extra info field for relative offset to local file header of current file | ||
1645 | if(zi->ci.pos_local_header >= 0xffffffff) | ||
1646 | datasize += 8; | ||
1647 | |||
1648 | if(datasize > 0) | ||
1649 | { | ||
1650 | char* p = NULL; | ||
1651 | |||
1652 | if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) | ||
1653 | { | ||
1654 | // we can not write more data to the buffer that we have room for. | ||
1655 | return ZIP_BADZIPFILE; | ||
1656 | } | ||
1657 | |||
1658 | p = zi->ci.central_header + zi->ci.size_centralheader; | ||
1659 | |||
1660 | // Add Extra Information Header for 'ZIP64 information' | ||
1661 | zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID | ||
1662 | p += 2; | ||
1663 | zip64local_putValue_inmemory(p, datasize, 2); // DataSize | ||
1664 | p += 2; | ||
1665 | |||
1666 | if(uncompressed_size >= 0xffffffff) | ||
1667 | { | ||
1668 | zip64local_putValue_inmemory(p, uncompressed_size, 8); | ||
1669 | p += 8; | ||
1670 | } | ||
1094 | 1671 | ||
1672 | if(compressed_size >= 0xffffffff) | ||
1673 | { | ||
1674 | zip64local_putValue_inmemory(p, compressed_size, 8); | ||
1675 | p += 8; | ||
1676 | } | ||
1677 | |||
1678 | if(zi->ci.pos_local_header >= 0xffffffff) | ||
1679 | { | ||
1680 | zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); | ||
1681 | p += 8; | ||
1682 | } | ||
1683 | |||
1684 | // Update how much extra free space we got in the memory buffer | ||
1685 | // and increase the centralheader size so the new ZIP64 fields are included | ||
1686 | // ( 4 below is the size of HeaderID and DataSize field ) | ||
1687 | zi->ci.size_centralExtraFree -= datasize + 4; | ||
1688 | zi->ci.size_centralheader += datasize + 4; | ||
1689 | |||
1690 | // Update the extra info size field | ||
1691 | zi->ci.size_centralExtra += datasize + 4; | ||
1692 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); | ||
1693 | } | ||
1694 | |||
1095 | if (err==ZIP_OK) | 1695 | if (err==ZIP_OK) |
1096 | err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, | 1696 | err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); |
1097 | (uLong)zi->ci.size_centralheader); | 1697 | |
1098 | free(zi->ci.central_header); | 1698 | free(zi->ci.central_header); |
1099 | 1699 | ||
1100 | if (err==ZIP_OK) | 1700 | if (err==ZIP_OK) |
1101 | { | 1701 | { |
1102 | long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); | 1702 | // Update the LocalFileHeader with the new values. |
1103 | if (ZSEEK(zi->z_filefunc,zi->filestream, | 1703 | |
1104 | zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) | 1704 | ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); |
1705 | |||
1706 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1105 | err = ZIP_ERRNO; | 1707 | err = ZIP_ERRNO; |
1106 | 1708 | ||
1107 | if (err==ZIP_OK) | 1709 | if (err==ZIP_OK) |
1108 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ | 1710 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ |
1109 | 1711 | ||
1110 | if (err==ZIP_OK) /* compressed size, unknown */ | 1712 | if(uncompressed_size >= 0xffffffff) |
1111 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); | 1713 | { |
1714 | if(zi->ci.pos_zip64extrainfo > 0) | ||
1715 | { | ||
1716 | // Update the size in the ZIP64 extended field. | ||
1717 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1718 | err = ZIP_ERRNO; | ||
1719 | |||
1720 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1721 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); | ||
1722 | |||
1723 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
1724 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); | ||
1725 | } | ||
1726 | } | ||
1727 | else | ||
1728 | { | ||
1729 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1730 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); | ||
1112 | 1731 | ||
1113 | if (err==ZIP_OK) /* uncompressed size, unknown */ | 1732 | if (err==ZIP_OK) /* uncompressed size, unknown */ |
1114 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); | 1733 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); |
1734 | } | ||
1115 | 1735 | ||
1116 | if (ZSEEK(zi->z_filefunc,zi->filestream, | 1736 | if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) |
1117 | cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1118 | err = ZIP_ERRNO; | 1737 | err = ZIP_ERRNO; |
1119 | } | 1738 | } |
1120 | 1739 | ||
@@ -1124,24 +1743,150 @@ extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) | |||
1124 | return err; | 1743 | return err; |
1125 | } | 1744 | } |
1126 | 1745 | ||
1127 | extern int ZEXPORT zipCloseFileInZip (file) | 1746 | extern int ZEXPORT zipCloseFileInZip (zipFile file) |
1128 | zipFile file; | ||
1129 | { | 1747 | { |
1130 | return zipCloseFileInZipRaw (file,0,0); | 1748 | return zipCloseFileInZipRaw (file,0,0); |
1131 | } | 1749 | } |
1132 | 1750 | ||
1133 | extern int ZEXPORT zipClose (file, global_comment) | 1751 | int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) |
1134 | zipFile file; | 1752 | { |
1135 | const char* global_comment; | 1753 | int err = ZIP_OK; |
1754 | ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; | ||
1755 | |||
1756 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); | ||
1757 | |||
1758 | /*num disks*/ | ||
1759 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1760 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1761 | |||
1762 | /*relative offset*/ | ||
1763 | if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ | ||
1764 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); | ||
1765 | |||
1766 | /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ | ||
1767 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1768 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); | ||
1769 | |||
1770 | return err; | ||
1771 | } | ||
1772 | |||
1773 | int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) | ||
1136 | { | 1774 | { |
1137 | zip_internal* zi; | 1775 | int err = ZIP_OK; |
1776 | |||
1777 | uLong Zip64DataSize = 44; | ||
1778 | |||
1779 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); | ||
1780 | |||
1781 | if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ | ||
1782 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? | ||
1783 | |||
1784 | if (err==ZIP_OK) /* version made by */ | ||
1785 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); | ||
1786 | |||
1787 | if (err==ZIP_OK) /* version needed */ | ||
1788 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); | ||
1789 | |||
1790 | if (err==ZIP_OK) /* number of this disk */ | ||
1791 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1792 | |||
1793 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1794 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1795 | |||
1796 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
1797 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); | ||
1798 | |||
1799 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
1800 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); | ||
1801 | |||
1802 | if (err==ZIP_OK) /* size of the central directory */ | ||
1803 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); | ||
1804 | |||
1805 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ | ||
1806 | { | ||
1807 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | ||
1808 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); | ||
1809 | } | ||
1810 | return err; | ||
1811 | } | ||
1812 | int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) | ||
1813 | { | ||
1814 | int err = ZIP_OK; | ||
1815 | |||
1816 | /*signature*/ | ||
1817 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); | ||
1818 | |||
1819 | if (err==ZIP_OK) /* number of this disk */ | ||
1820 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1821 | |||
1822 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1823 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1824 | |||
1825 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
1826 | { | ||
1827 | { | ||
1828 | if(zi->number_entry >= 0xFFFF) | ||
1829 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record | ||
1830 | else | ||
1831 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1832 | } | ||
1833 | } | ||
1834 | |||
1835 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
1836 | { | ||
1837 | if(zi->number_entry >= 0xFFFF) | ||
1838 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record | ||
1839 | else | ||
1840 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1841 | } | ||
1842 | |||
1843 | if (err==ZIP_OK) /* size of the central directory */ | ||
1844 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); | ||
1845 | |||
1846 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ | ||
1847 | { | ||
1848 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | ||
1849 | if(pos >= 0xffffffff) | ||
1850 | { | ||
1851 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); | ||
1852 | } | ||
1853 | else | ||
1854 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); | ||
1855 | } | ||
1856 | |||
1857 | return err; | ||
1858 | } | ||
1859 | |||
1860 | int Write_GlobalComment(zip64_internal* zi, const char* global_comment) | ||
1861 | { | ||
1862 | int err = ZIP_OK; | ||
1863 | uInt size_global_comment = 0; | ||
1864 | |||
1865 | if(global_comment != NULL) | ||
1866 | size_global_comment = (uInt)strlen(global_comment); | ||
1867 | |||
1868 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); | ||
1869 | |||
1870 | if (err == ZIP_OK && size_global_comment > 0) | ||
1871 | { | ||
1872 | if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) | ||
1873 | err = ZIP_ERRNO; | ||
1874 | } | ||
1875 | return err; | ||
1876 | } | ||
1877 | |||
1878 | extern int ZEXPORT zipClose (zipFile file, const char* global_comment) | ||
1879 | { | ||
1880 | zip64_internal* zi; | ||
1138 | int err = 0; | 1881 | int err = 0; |
1139 | uLong size_centraldir = 0; | 1882 | uLong size_centraldir = 0; |
1140 | uLong centraldir_pos_inzip; | 1883 | ZPOS64_T centraldir_pos_inzip; |
1141 | uInt size_global_comment; | 1884 | ZPOS64_T pos; |
1885 | |||
1142 | if (file == NULL) | 1886 | if (file == NULL) |
1143 | return ZIP_PARAMERROR; | 1887 | return ZIP_PARAMERROR; |
1144 | zi = (zip_internal*)file; | 1888 | |
1889 | zi = (zip64_internal*)file; | ||
1145 | 1890 | ||
1146 | if (zi->in_opened_file_inzip == 1) | 1891 | if (zi->in_opened_file_inzip == 1) |
1147 | { | 1892 | { |
@@ -1152,61 +1897,42 @@ extern int ZEXPORT zipClose (file, global_comment) | |||
1152 | if (global_comment==NULL) | 1897 | if (global_comment==NULL) |
1153 | global_comment = zi->globalcomment; | 1898 | global_comment = zi->globalcomment; |
1154 | #endif | 1899 | #endif |
1155 | if (global_comment==NULL) | 1900 | |
1156 | size_global_comment = 0; | 1901 | centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); |
1157 | else | ||
1158 | size_global_comment = (uInt)strlen(global_comment); | ||
1159 | 1902 | ||
1160 | centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); | ||
1161 | if (err==ZIP_OK) | 1903 | if (err==ZIP_OK) |
1162 | { | 1904 | { |
1163 | linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; | 1905 | linkedlist_datablock_internal* ldi = zi->central_dir.first_block; |
1164 | while (ldi!=NULL) | 1906 | while (ldi!=NULL) |
1165 | { | 1907 | { |
1166 | if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) | 1908 | if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) |
1167 | if (ZWRITE(zi->z_filefunc,zi->filestream, | 1909 | { |
1168 | ldi->data,ldi->filled_in_this_block) | 1910 | if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) |
1169 | !=ldi->filled_in_this_block ) | ||
1170 | err = ZIP_ERRNO; | 1911 | err = ZIP_ERRNO; |
1912 | } | ||
1171 | 1913 | ||
1172 | size_centraldir += ldi->filled_in_this_block; | 1914 | size_centraldir += ldi->filled_in_this_block; |
1173 | ldi = ldi->next_datablock; | 1915 | ldi = ldi->next_datablock; |
1174 | } | 1916 | } |
1175 | } | 1917 | } |
1176 | free_datablock(zi->central_dir.first_block); | 1918 | free_linkedlist(&(zi->central_dir)); |
1177 | |||
1178 | if (err==ZIP_OK) /* Magic End */ | ||
1179 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); | ||
1180 | |||
1181 | if (err==ZIP_OK) /* number of this disk */ | ||
1182 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1183 | |||
1184 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1185 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1186 | |||
1187 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
1188 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1189 | |||
1190 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
1191 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1192 | |||
1193 | if (err==ZIP_OK) /* size of the central directory */ | ||
1194 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); | ||
1195 | 1919 | ||
1196 | if (err==ZIP_OK) /* offset of start of central directory with respect to the | 1920 | pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; |
1197 | starting disk number */ | 1921 | if(pos >= 0xffffffff) |
1198 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, | 1922 | { |
1199 | (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); | 1923 | ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); |
1924 | Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); | ||
1925 | |||
1926 | Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); | ||
1927 | } | ||
1200 | 1928 | ||
1201 | if (err==ZIP_OK) /* zipfile comment length */ | 1929 | if (err==ZIP_OK) |
1202 | err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); | 1930 | err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); |
1203 | 1931 | ||
1204 | if ((err==ZIP_OK) && (size_global_comment>0)) | 1932 | if(err == ZIP_OK) |
1205 | if (ZWRITE(zi->z_filefunc,zi->filestream, | 1933 | err = Write_GlobalComment(zi, global_comment); |
1206 | global_comment,size_global_comment) != size_global_comment) | ||
1207 | err = ZIP_ERRNO; | ||
1208 | 1934 | ||
1209 | if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) | 1935 | if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) |
1210 | if (err == ZIP_OK) | 1936 | if (err == ZIP_OK) |
1211 | err = ZIP_ERRNO; | 1937 | err = ZIP_ERRNO; |
1212 | 1938 | ||
@@ -1217,3 +1943,61 @@ extern int ZEXPORT zipClose (file, global_comment) | |||
1217 | 1943 | ||
1218 | return err; | 1944 | return err; |
1219 | } | 1945 | } |
1946 | |||
1947 | extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) | ||
1948 | { | ||
1949 | char* p = pData; | ||
1950 | int size = 0; | ||
1951 | char* pNewHeader; | ||
1952 | char* pTmp; | ||
1953 | short header; | ||
1954 | short dataSize; | ||
1955 | |||
1956 | int retVal = ZIP_OK; | ||
1957 | |||
1958 | if(pData == NULL || *dataLen < 4) | ||
1959 | return ZIP_PARAMERROR; | ||
1960 | |||
1961 | pNewHeader = (char*)ALLOC(*dataLen); | ||
1962 | pTmp = pNewHeader; | ||
1963 | |||
1964 | while(p < (pData + *dataLen)) | ||
1965 | { | ||
1966 | header = *(short*)p; | ||
1967 | dataSize = *(((short*)p)+1); | ||
1968 | |||
1969 | if( header == sHeader ) // Header found. | ||
1970 | { | ||
1971 | p += dataSize + 4; // skip it. do not copy to temp buffer | ||
1972 | } | ||
1973 | else | ||
1974 | { | ||
1975 | // Extra Info block should not be removed, So copy it to the temp buffer. | ||
1976 | memcpy(pTmp, p, dataSize + 4); | ||
1977 | p += dataSize + 4; | ||
1978 | size += dataSize + 4; | ||
1979 | } | ||
1980 | |||
1981 | } | ||
1982 | |||
1983 | if(size < *dataLen) | ||
1984 | { | ||
1985 | // clean old extra info block. | ||
1986 | memset(pData,0, *dataLen); | ||
1987 | |||
1988 | // copy the new extra info block over the old | ||
1989 | if(size > 0) | ||
1990 | memcpy(pData, pNewHeader, size); | ||
1991 | |||
1992 | // set the new extra info size | ||
1993 | *dataLen = size; | ||
1994 | |||
1995 | retVal = ZIP_OK; | ||
1996 | } | ||
1997 | else | ||
1998 | retVal = ZIP_ERRNO; | ||
1999 | |||
2000 | TRYFREE(pNewHeader); | ||
2001 | |||
2002 | return retVal; | ||
2003 | } | ||