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