source: Vago/Libs/quazip-0.7.2/quazip/zip.c@ 1079

Last change on this file since 1079 was 1050, checked in by s10k, 8 years ago
File size: 70.1 KB
RevLine 
[1050]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 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
24
25*/
26
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <time.h>
32#include "zlib.h"
33#if (ZLIB_VERNUM < 0x1270)
34typedef uLongf z_crc_t;
35#endif
36#include "zip.h"
37
38#ifdef STDC
39# include <stddef.h>
40# include <string.h>
41# include <stdlib.h>
42#endif
43#ifdef NO_ERRNO_H
44 extern int errno;
45#else
46# include <errno.h>
47#endif
48
49
50#ifndef local
51# define local static
52#endif
53/* compile with -Dlocal if your debugger can't find static symbols */
54
55#ifndef VERSIONMADEBY
56# define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */
57#endif
58
59#ifndef Z_BUFSIZE
60#define Z_BUFSIZE (64*1024) /* (16384) */
61#endif
62
63#ifndef Z_MAXFILENAMEINZIP
64#define Z_MAXFILENAMEINZIP (256)
65#endif
66
67#ifndef ALLOC
68# define ALLOC(size) (malloc(size))
69#endif
70#ifndef TRYFREE
71# define TRYFREE(p) {if (p) free(p);}
72#endif
73
74/*
75#define SIZECENTRALDIRITEM (0x2e)
76#define SIZEZIPLOCALHEADER (0x1e)
77*/
78
79/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
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
85#ifndef SEEK_CUR
86#define SEEK_CUR 1
87#endif
88
89#ifndef SEEK_END
90#define SEEK_END 2
91#endif
92
93#ifndef SEEK_SET
94#define SEEK_SET 0
95#endif
96
97#ifndef DEF_MEM_LEVEL
98#if MAX_MEM_LEVEL >= 8
99# define DEF_MEM_LEVEL 8
100#else
101# define DEF_MEM_LEVEL MAX_MEM_LEVEL
102#endif
103#endif
104const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
105
106
107#define SIZEDATA_INDATABLOCK (4096-(4*4))
108
109#define LOCALHEADERMAGIC (0x04034b50)
110#define DESCRIPTORHEADERMAGIC (0x08074b50)
111#define CENTRALHEADERMAGIC (0x02014b50)
112#define ENDHEADERMAGIC (0x06054b50)
113#define ZIP64ENDHEADERMAGIC (0x6064b50)
114#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
115
116#define FLAG_LOCALHEADER_OFFSET (0x06)
117#define CRC_LOCALHEADER_OFFSET (0x0e)
118
119#define SIZECENTRALHEADER (0x2e) /* 46 */
120
121typedef struct linkedlist_datablock_internal_s
122{
123 struct linkedlist_datablock_internal_s* next_datablock;
124 uLong avail_in_this_block;
125 uLong filled_in_this_block;
126 uLong unused; /* for future use and alignement */
127 unsigned char data[SIZEDATA_INDATABLOCK];
128} linkedlist_datablock_internal;
129
130typedef struct linkedlist_data_s
131{
132 linkedlist_datablock_internal* first_block;
133 linkedlist_datablock_internal* last_block;
134} linkedlist_data;
135
136
137typedef struct
138{
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
144 int stream_initialised; /* 1 is stream is initialised */
145 uInt pos_in_buffered_data; /* last written byte in buffered_data */
146
147 ZPOS64_T pos_local_header; /* offset of the local header of the file
148 currenty writing */
149 char* central_header; /* central header data for the current file */
150 uLong size_centralExtra;
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 */
153 uLong flag; /* flag of the file currently writing */
154
155 int method; /* compression method of file currenty wr.*/
156 int raw; /* 1 for directly writing raw data */
157 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
158 uLong dosDate;
159 uLong crc32;
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;
165#ifndef NOCRYPT
166 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
167 const z_crc_t FAR * pcrc_32_tab;
168 int crypt_header_size;
169#endif
170} curfile64_info;
171
172typedef struct
173{
174 zlib_filefunc64_32_def z_filefunc;
175 voidpf filestream; /* io structore of the zipfile */
176 linkedlist_data central_dir;/* datablock with central dir in construction*/
177 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
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;
183
184#ifndef NO_ADDFILEINEXISTINGZIP
185 char *globalcomment;
186#endif
187
188 unsigned flags;
189
190} zip64_internal;
191
192
193#ifndef NOCRYPT
194#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
195#include "crypt.h"
196#endif
197
198local linkedlist_datablock_internal* allocate_new_datablock()
199{
200 linkedlist_datablock_internal* ldi;
201 ldi = (linkedlist_datablock_internal*)
202 ALLOC(sizeof(linkedlist_datablock_internal));
203 if (ldi!=NULL)
204 {
205 ldi->next_datablock = NULL ;
206 ldi->filled_in_this_block = 0 ;
207 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
208 }
209 return ldi;
210}
211
212local void free_datablock(linkedlist_datablock_internal* ldi)
213{
214 while (ldi!=NULL)
215 {
216 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
217 TRYFREE(ldi);
218 ldi = ldinext;
219 }
220}
221
222local void init_linkedlist(linkedlist_data* ll)
223{
224 ll->first_block = ll->last_block = NULL;
225}
226
227local void free_linkedlist(linkedlist_data* ll)
228{
229 free_datablock(ll->first_block);
230 ll->first_block = ll->last_block = NULL;
231}
232
233
234local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
235{
236 linkedlist_datablock_internal* ldi;
237 const unsigned char* from_copy;
238
239 if (ll==NULL)
240 return ZIP_INTERNALERROR;
241
242 if (ll->last_block == NULL)
243 {
244 ll->first_block = ll->last_block = allocate_new_datablock();
245 if (ll->first_block == NULL)
246 return ZIP_INTERNALERROR;
247 }
248
249 ldi = ll->last_block;
250 from_copy = (unsigned char*)buf;
251
252 while (len>0)
253 {
254 uInt copy_this;
255 uInt i;
256 unsigned char* to_copy;
257
258 if (ldi->avail_in_this_block==0)
259 {
260 ldi->next_datablock = allocate_new_datablock();
261 if (ldi->next_datablock == NULL)
262 return ZIP_INTERNALERROR;
263 ldi = ldi->next_datablock ;
264 ll->last_block = ldi;
265 }
266
267 if (ldi->avail_in_this_block < len)
268 copy_this = (uInt)ldi->avail_in_this_block;
269 else
270 copy_this = (uInt)len;
271
272 to_copy = &(ldi->data[ldi->filled_in_this_block]);
273
274 for (i=0;i<copy_this;i++)
275 *(to_copy+i)=*(from_copy+i);
276
277 ldi->filled_in_this_block += copy_this;
278 ldi->avail_in_this_block -= copy_this;
279 from_copy += copy_this ;
280 len -= copy_this;
281 }
282 return ZIP_OK;
283}
284
285
286
287/****************************************************************************/
288
289#ifndef NO_ADDFILEINEXISTINGZIP
290/* ===========================================================================
291 Inputs a long in LSB order to the given file
292 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
293*/
294
295local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
296local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
297{
298 unsigned char buf[8];
299 int n;
300 for (n = 0; n < nbByte; n++)
301 {
302 buf[n] = (unsigned char)(x & 0xff);
303 x >>= 8;
304 }
305 if (x != 0)
306 { /* data overflow - hack for ZIP64 (X Roche) */
307 for (n = 0; n < nbByte; n++)
308 {
309 buf[n] = 0xff;
310 }
311 }
312
313 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
314 return ZIP_ERRNO;
315 else
316 return ZIP_OK;
317}
318
319local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
320local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
321{
322 unsigned char* buf=(unsigned char*)dest;
323 int n;
324 for (n = 0; n < nbByte; n++) {
325 buf[n] = (unsigned char)(x & 0xff);
326 x >>= 8;
327 }
328
329 if (x != 0)
330 { /* data overflow - hack for ZIP64 */
331 for (n = 0; n < nbByte; n++)
332 {
333 buf[n] = 0xff;
334 }
335 }
336}
337
338/****************************************************************************/
339
340
341local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
342{
343 uLong year = (uLong)ptm->tm_year;
344 if (year>=1980)
345 year-=1980;
346 else if (year>=80)
347 year-=80;
348 return
349 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
350 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
351}
352
353
354/****************************************************************************/
355
356local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
357
358local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
359{
360 unsigned char c;
361 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
362 if (err==1)
363 {
364 *pi = (int)c;
365 return ZIP_OK;
366 }
367 else
368 {
369 if (ZERROR64(*pzlib_filefunc_def,filestream))
370 return ZIP_ERRNO;
371 else
372 return ZIP_EOF;
373 }
374}
375
376
377/* ===========================================================================
378 Reads a long in LSB order from the given gz_stream. Sets
379*/
380local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
381
382local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
383{
384 uLong x ;
385 int i = 0;
386 int err;
387
388 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
389 x = (uLong)i;
390
391 if (err==ZIP_OK)
392 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
393 x += ((uLong)i)<<8;
394
395 if (err==ZIP_OK)
396 *pX = x;
397 else
398 *pX = 0;
399 return err;
400}
401
402local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
403
404local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
405{
406 uLong x ;
407 int i = 0;
408 int err;
409
410 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
411 x = (uLong)i;
412
413 if (err==ZIP_OK)
414 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
415 x += ((uLong)i)<<8;
416
417 if (err==ZIP_OK)
418 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
419 x += ((uLong)i)<<16;
420
421 if (err==ZIP_OK)
422 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
423 x += ((uLong)i)<<24;
424
425 if (err==ZIP_OK)
426 *pX = x;
427 else
428 *pX = 0;
429 return err;
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
480#ifndef BUFREADCOMMENT
481#define BUFREADCOMMENT (0x400)
482#endif
483/*
484 Locate the Central directory of a zipfile (at the end, just before
485 the global comment)
486*/
487local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
488
489local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
490{
491 unsigned char* buf;
492 ZPOS64_T uSizeFile;
493 ZPOS64_T uBackRead;
494 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
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);
502
503 if (uMaxBack>uSizeFile)
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}
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));
550
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 ;
584
585 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
586 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
587 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
588 break;
589
590 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
591 break;
592
593 for (i=(int)uReadSize-3; (i--)>0;)
594 {
595 /* Signature "0x07064b50" Zip64 end of central directory locater */
596 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
597 {
598 uPosFound = uReadPos+i;
599 break;
600 }
601 }
602
603 if (uPosFound!=0)
604 break;
605 }
606
607 TRYFREE(buf);
608 if (uPosFound == 0)
609 return 0;
610
611 /* Zip64 end of central directory locator */
612 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
613 return 0;
614
615 /* the signature, already checked */
616 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
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;
634
635 /* Goto Zip64 end of central directory record */
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;
845 }
846 TRYFREE(buf_read);
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;
855}
856
857
858#endif /* !NO_ADDFILEINEXISTINGZIP*/
859
860
861/************************************************************/
862extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
863 unsigned flags)
864{
865 zip64_internal ziinit;
866 zip64_internal* zi;
867 int err=ZIP_OK;
868
869 ziinit.flags = flags;
870 ziinit.z_filefunc.zseek32_file = NULL;
871 ziinit.z_filefunc.ztell32_file = NULL;
872 if (pzlib_filefunc64_32_def==NULL)
873 fill_qiodevice64_filefunc(&ziinit.z_filefunc.zfile_func64);
874 else
875 ziinit.z_filefunc = *pzlib_filefunc64_32_def;
876
877 ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
878 file,
879 (append == APPEND_STATUS_CREATE) ?
880 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
881 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
882
883 if (ziinit.filestream == NULL)
884 return NULL;
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);
890 ziinit.in_opened_file_inzip = 0;
891 ziinit.ci.stream_initialised = 0;
892 ziinit.number_entry = 0;
893 ziinit.add_position_when_writting_offset = 0;
894 init_linkedlist(&(ziinit.central_dir));
895
896
897
898 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
899 if (zi==NULL)
900 {
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 }
906 return NULL;
907 }
908
909 /* now we add file in a zipfile */
910# ifndef NO_ADDFILEINEXISTINGZIP
911 ziinit.globalcomment = NULL;
912 if (append == APPEND_STATUS_ADDINZIP)
913 {
914 /* Read and Cache Central Directory Records */
915 err = LoadCentralDirectoryRecord(&ziinit);
916 }
917
918 if (globalcomment)
919 {
920 *globalcomment = ziinit.globalcomment;
921 }
922# endif /* !NO_ADDFILEINEXISTINGZIP*/
923
924 if (err != ZIP_OK)
925 {
926# ifndef NO_ADDFILEINEXISTINGZIP
927 TRYFREE(ziinit.globalcomment);
928# endif /* !NO_ADDFILEINEXISTINGZIP*/
929 TRYFREE(zi);
930 return NULL;
931 }
932 else
933 {
934 *zi = ziinit;
935 return (zipFile)zi;
936 }
937}
938
939extern zipFile ZEXPORT zipOpen2 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
940{
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)
973{
974 return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS);
975}
976
977int Write_LocalFileHeader(zip64_internal* zi, const char* filename,
978 uInt size_extrafield_local,
979 const void* extrafield_local,
980 uLong version_to_extract)
981{
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;
1086 uInt size_filename;
1087 uInt size_comment;
1088 uInt i;
1089 int err = ZIP_OK;
1090 uLong version_to_extract;
1091
1092# ifdef NOCRYPT
1093 if (password != NULL)
1094 return ZIP_PARAMERROR;
1095# endif
1096
1097 if (file == NULL)
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
1104 if ((method!=0) && (method!=Z_DEFLATED))
1105 return ZIP_PARAMERROR;
1106#endif
1107
1108 zi = (zip64_internal*)file;
1109
1110 if (zi->in_opened_file_inzip == 1)
1111 {
1112 err = zipCloseFileInZip (file);
1113 if (err != ZIP_OK)
1114 return err;
1115 }
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 }
1127
1128 if (filename==NULL)
1129 filename="-";
1130
1131 if (comment==NULL)
1132 size_comment = 0;
1133 else
1134 size_comment = (uInt)strlen(comment);
1135
1136 size_filename = (uInt)strlen(filename);
1137
1138 if (zipfi == NULL)
1139 zi->ci.dosDate = 0;
1140 else
1141 {
1142 if (zipfi->dosDate != 0)
1143 zi->ci.dosDate = zipfi->dosDate;
1144 else
1145 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
1146 }
1147
1148 zi->ci.flag = flagBase;
1149 if ((level==8) || (level==9))
1150 zi->ci.flag |= 2;
1151 if (level==2)
1152 zi->ci.flag |= 4;
1153 if (level==1)
1154 zi->ci.flag |= 6;
1155 if (password != NULL)
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;
1161
1162 zi->ci.crc32 = 0;
1163 zi->ci.method = method;
1164 zi->ci.encrypt = 0;
1165 zi->ci.stream_initialised = 0;
1166 zi->ci.pos_in_buffered_data = 0;
1167 zi->ci.raw = raw;
1168 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
1169
1170 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
1171 zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */
1172
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);
1177 /* version info */
1178 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
1179 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2);
1180 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
1181 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
1182 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
1183 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
1184 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
1185 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
1186 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
1187 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
1188 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
1189 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
1190
1191 if (zipfi==NULL)
1192 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
1193 else
1194 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
1195
1196 if (zipfi==NULL)
1197 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
1198 else
1199 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
1200
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);
1205
1206 for (i=0;i<size_filename;i++)
1207 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
1208
1209 for (i=0;i<size_extrafield_global;i++)
1210 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
1211 *(((const char*)extrafield_global)+i);
1212
1213 for (i=0;i<size_comment;i++)
1214 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
1215 size_extrafield_global+i) = *(comment+i);
1216 if (zi->ci.central_header == NULL)
1217 return ZIP_INTERNALERROR;
1218
1219 zi->ci.zip64 = zip64;
1220 zi->ci.totalCompressedData = 0;
1221 zi->ci.totalUncompressedData = 0;
1222 zi->ci.pos_zip64extrainfo = 0;
1223
1224 err = Write_LocalFileHeader(zi, filename, size_extrafield_local,
1225 extrafield_local, version_to_extract);
1226
1227#ifdef HAVE_BZIP2
1228 zi->ci.bstream.avail_in = (uInt)0;
1229 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1230 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1231 zi->ci.bstream.total_in_hi32 = 0;
1232 zi->ci.bstream.total_in_lo32 = 0;
1233 zi->ci.bstream.total_out_hi32 = 0;
1234 zi->ci.bstream.total_out_lo32 = 0;
1235#endif
1236
1237 zi->ci.stream.avail_in = (uInt)0;
1238 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1239 zi->ci.stream.next_out = zi->ci.buffered_data;
1240 zi->ci.stream.total_in = 0;
1241 zi->ci.stream.total_out = 0;
1242 zi->ci.stream.data_type = Z_BINARY;
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
1247 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1248#endif
1249 {
1250 if(zi->ci.method == Z_DEFLATED)
1251 {
1252 zi->ci.stream.zalloc = (alloc_func)0;
1253 zi->ci.stream.zfree = (free_func)0;
1254 zi->ci.stream.opaque = (voidpf)0;
1255
1256 if (windowBits>0)
1257 windowBits = -windowBits;
1258
1259 err = deflateInit2(&zi->ci.stream, level, 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 }
1277
1278 }
1279
1280# ifndef NOCRYPT
1281 zi->ci.crypt_header_size = 0;
1282 if ((err==Z_OK) && (password != NULL))
1283 {
1284 unsigned char bufHead[RAND_HEAD_LEN];
1285 unsigned int sizeHead;
1286 zi->ci.encrypt = 1;
1287 zi->ci.pcrc_32_tab = get_crc_table();
1288 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
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 }
1292 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
1293 zi->ci.crypt_header_size = sizeHead;
1294
1295 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
1296 err = ZIP_ERRNO;
1297 }
1298# endif
1299
1300 if (err==Z_OK)
1301 zi->in_opened_file_inzip = 1;
1302 return err;
1303}
1304
1305extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1306 const void* extrafield_local, uInt size_extrafield_local,
1307 const void* extrafield_global, uInt size_extrafield_global,
1308 const char* comment, int method, int level, int raw,
1309 int windowBits,int memLevel, int strategy,
1310 const char* password, uLong crcForCrypting,
1311 uLong versionMadeBy, uLong flagBase)
1312{
1313 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1314 extrafield_local, size_extrafield_local,
1315 extrafield_global, size_extrafield_global,
1316 comment, method, level, raw,
1317 windowBits, memLevel, strategy,
1318 password, crcForCrypting, versionMadeBy, flagBase, 0);
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)
1368{
1369 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1370 extrafield_local, size_extrafield_local,
1371 extrafield_global, size_extrafield_global,
1372 comment, method, level, raw,
1373 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
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);
1388}
1389
1390extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1391 const void* extrafield_local, uInt size_extrafield_local,
1392 const void*extrafield_global, uInt size_extrafield_global,
1393 const char* comment, int method, int level)
1394{
1395 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1396 extrafield_local, size_extrafield_local,
1397 extrafield_global, size_extrafield_global,
1398 comment, method, level, 0,
1399 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1400 NULL, 0, VERSIONMADEBY, 0, 0);
1401}
1402
1403local int zip64FlushWriteBuffer(zip64_internal* zi)
1404{
1405 int err=ZIP_OK;
1406
1407 if (zi->ci.encrypt != 0)
1408 {
1409#ifndef NOCRYPT
1410 uInt i;
1411 int t;
1412 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
1413 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
1414#endif
1415 }
1416
1417 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
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
1437 zi->ci.pos_in_buffered_data = 0;
1438
1439 return err;
1440}
1441
1442extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
1443{
1444 zip64_internal* zi;
1445 int err=ZIP_OK;
1446
1447 if (file == NULL)
1448 return ZIP_PARAMERROR;
1449 zi = (zip64_internal*)file;
1450
1451 if (zi->in_opened_file_inzip == 0)
1452 return ZIP_PARAMERROR;
1453
1454 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
1455
1456#ifdef HAVE_BZIP2
1457 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
1458 {
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)
1466 {
1467 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1468 err = ZIP_ERRNO;
1469 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1470 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1471 }
1472
1473
1474 if(err != BZ_RUN_OK)
1475 break;
1476
1477 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1478 {
1479 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
1480/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */
1481 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
1482
1483 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
1484 }
1485 }
1486
1487 if(err == BZ_RUN_OK)
1488 err = ZIP_OK;
1489 }
1490 else
1491#endif
1492 {
1493 zi->ci.stream.next_in = (Bytef*)buf;
1494 zi->ci.stream.avail_in = len;
1495
1496 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
1497 {
1498 if (zi->ci.stream.avail_out == 0)
1499 {
1500 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1501 err = ZIP_ERRNO;
1502 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1503 zi->ci.stream.next_out = zi->ci.buffered_data;
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(...) */
1544 }
1545
1546 return err;
1547}
1548
1549extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
1550{
1551 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
1552}
1553
1554extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
1555{
1556 zip64_internal* zi;
1557 ZPOS64_T compressed_size;
1558 uLong invalidValue = 0xffffffff;
1559 short datasize = 0;
1560 int err=ZIP_OK;
1561
1562 if (file == NULL)
1563 return ZIP_PARAMERROR;
1564 zi = (zip64_internal*)file;
1565
1566 if (zi->in_opened_file_inzip == 0)
1567 return ZIP_PARAMERROR;
1568 zi->ci.stream.avail_in = 0;
1569
1570 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
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))
1588 {
1589#ifdef HAVE_BZIP2
1590 err = BZ_FINISH_OK;
1591 while (err==BZ_FINISH_OK)
1592 {
1593 uLong uTotalOutBefore;
1594 if (zi->ci.bstream.avail_out == 0)
1595 {
1596 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1597 err = ZIP_ERRNO;
1598 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1599 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1600 }
1601 uTotalOutBefore = zi->ci.bstream.total_out_lo32;
1602 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
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
1612 }
1613
1614 if (err==Z_STREAM_END)
1615 err=ZIP_OK; /* this is normal */
1616
1617 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1618 {
1619 if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
1620 err = ZIP_ERRNO;
1621 }
1622
1623 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1624 {
1625 int tmp_err = deflateEnd(&zi->ci.stream);
1626 if (err == ZIP_OK)
1627 err = tmp_err;
1628 zi->ci.stream_initialised = 0;
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
1639
1640 if (!zi->ci.raw)
1641 {
1642 crc32 = (uLong)zi->ci.crc32;
1643 uncompressed_size = zi->ci.totalUncompressedData;
1644 }
1645 compressed_size = zi->ci.totalCompressedData;
1646
1647# ifndef NOCRYPT
1648 compressed_size += zi->ci.crypt_header_size;
1649# endif
1650
1651 /* update Current Item crc and sizes, */
1652 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
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 */
1670 if (zi->ci.stream.data_type == Z_ASCII)
1671 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1672
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 }
1736
1737 if (err==ZIP_OK)
1738 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
1739
1740 free(zi->ci.central_header);
1741
1742 if (err==ZIP_OK)
1743 {
1744 if ((zi->flags & ZIP_SEQUENTIAL) == 0) {
1745 /* Update the LocalFileHeader with the new values. */
1746
1747 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1748
1749 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1750 err = ZIP_ERRNO;
1751
1752 if (err==ZIP_OK)
1753 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1754
1755 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff)
1756 {
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 }
1802 }
1803
1804 zi->number_entry ++;
1805 zi->in_opened_file_inzip = 0;
1806
1807 return err;
1808}
1809
1810extern int ZEXPORT zipCloseFileInZip (zipFile file)
1811{
1812 return zipCloseFileInZipRaw (file,0,0);
1813}
1814
1815int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
1816{
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)
1943{
1944 zip64_internal* zi;
1945 int err = 0;
1946 uLong size_centraldir = 0;
1947 ZPOS64_T centraldir_pos_inzip;
1948 ZPOS64_T pos;
1949
1950 if (file == NULL)
1951 return ZIP_PARAMERROR;
1952
1953 zi = (zip64_internal*)file;
1954
1955 if (zi->in_opened_file_inzip == 1)
1956 {
1957 err = zipCloseFileInZip (file);
1958 }
1959
1960#ifndef NO_ADDFILEINEXISTINGZIP
1961 if (global_comment==NULL)
1962 global_comment = zi->globalcomment;
1963#endif
1964
1965 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1966
1967 if (err==ZIP_OK)
1968 {
1969 linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
1970 while (ldi!=NULL)
1971 {
1972 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1973 {
1974 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
1975 err = ZIP_ERRNO;
1976 }
1977
1978 size_centraldir += ldi->filled_in_this_block;
1979 ldi = ldi->next_datablock;
1980 }
1981 }
1982 free_linkedlist(&(zi->central_dir));
1983
1984 pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1985 if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
1986 {
1987 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
1988 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
1989
1990 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
1991 }
1992
1993 if (err==ZIP_OK)
1994 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
1995
1996 if(err == ZIP_OK)
1997 err = Write_GlobalComment(zi, global_comment);
1998
1999 if ((zi->flags & ZIP_AUTO_CLOSE) != 0) {
2000 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2001 if (err == ZIP_OK)
2002 err = ZIP_ERRNO;
2003 }
2004 } else {
2005 if (ZFAKECLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2006 if (err == ZIP_OK)
2007 err = ZIP_ERRNO;
2008 }
2009 }
2010
2011#ifndef NO_ADDFILEINEXISTINGZIP
2012 TRYFREE(zi->globalcomment);
2013#endif
2014 TRYFREE(zi);
2015
2016 return err;
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}
Note: See TracBrowser for help on using the repository browser.