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