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