1 : /******************************************************************************
2 : * $Id: cpl_minizip_zip.cpp 23818 2012-01-28 20:16:38Z rouault $
3 : *
4 : * Project: CPL - Common Portability Library
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : * Purpose: Adjusted minizip "zip.c" source code for zip services.
7 : *
8 : * Modified version by Even Rouault. :
9 : * - Decoration of symbol names unz* -> cpl_unz*
10 : * - Undef EXPORT so that we are sure the symbols are not exported
11 : * - Remove old C style function prototypes
12 : * - Added CPL* simplified API at bottom.
13 : *
14 : * Original licence available in port/LICENCE_minizip
15 : *
16 : *****************************************************************************/
17 :
18 : /* zip.c -- IO on .zip files using zlib
19 : Version 1.01e, February 12th, 2005
20 :
21 : 27 Dec 2004 Rolf Kalbermatter
22 : Modification to zipOpen2 to support globalComment retrieval.
23 :
24 : Copyright (C) 1998-2005 Gilles Vollant
25 :
26 : Read zip.h for more info
27 : */
28 :
29 :
30 : #include <stdio.h>
31 : #include <stdlib.h>
32 : #include <string.h>
33 : #include <time.h>
34 : #include "zlib.h"
35 : #include "cpl_minizip_zip.h"
36 : #include "cpl_conv.h"
37 : #include "cpl_string.h"
38 :
39 : #ifdef STDC
40 : # include <stddef.h>
41 : # include <string.h>
42 : # include <stdlib.h>
43 : #endif
44 : #ifdef NO_ERRNO_H
45 : extern int errno;
46 : #else
47 : # include <errno.h>
48 : #endif
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 (0x0) /* platform depedent */
57 : #endif
58 :
59 : #ifndef Z_BUFSIZE
60 : #define Z_BUFSIZE (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 : #ifndef SEEK_CUR
82 : #define SEEK_CUR 1
83 : #endif
84 :
85 : #ifndef SEEK_END
86 : #define SEEK_END 2
87 : #endif
88 :
89 : #ifndef SEEK_SET
90 : #define SEEK_SET 0
91 : #endif
92 :
93 : #ifndef DEF_MEM_LEVEL
94 : #if MAX_MEM_LEVEL >= 8
95 : # define DEF_MEM_LEVEL 8
96 : #else
97 : # define DEF_MEM_LEVEL MAX_MEM_LEVEL
98 : #endif
99 : #endif
100 : const char zip_copyright[] =
101 : " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
102 :
103 :
104 : #define SIZEDATA_INDATABLOCK (4096-(4*4))
105 :
106 : #define LOCALHEADERMAGIC (0x04034b50)
107 : #define CENTRALHEADERMAGIC (0x02014b50)
108 : #define ENDHEADERMAGIC (0x06054b50)
109 :
110 : #define FLAG_LOCALHEADER_OFFSET (0x06)
111 : #define CRC_LOCALHEADER_OFFSET (0x0e)
112 :
113 : #define SIZECENTRALHEADER (0x2e) /* 46 */
114 :
115 : typedef struct linkedlist_datablock_internal_s
116 : {
117 : struct linkedlist_datablock_internal_s* next_datablock;
118 : uLong avail_in_this_block;
119 : uLong filled_in_this_block;
120 : uLong unused; /* for future use and alignement */
121 : unsigned char data[SIZEDATA_INDATABLOCK];
122 : } linkedlist_datablock_internal;
123 :
124 : typedef struct linkedlist_data_s
125 : {
126 : linkedlist_datablock_internal* first_block;
127 : linkedlist_datablock_internal* last_block;
128 : } linkedlist_data;
129 :
130 :
131 : typedef struct
132 : {
133 : z_stream stream; /* zLib stream structure for inflate */
134 : int stream_initialised; /* 1 is stream is initialised */
135 : uInt pos_in_buffered_data; /* last written byte in buffered_data */
136 :
137 : uLong pos_local_header; /* offset of the local header of the file
138 : currenty writing */
139 : char* central_header; /* central header data for the current file */
140 : uLong size_centralheader; /* size of the central header for cur file */
141 : uLong flag; /* flag of the file currently writing */
142 :
143 : int method; /* compression method of file currenty wr.*/
144 : int raw; /* 1 for directly writing raw data */
145 : Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
146 : uLong dosDate;
147 : uLong crc32;
148 : int encrypt;
149 : #ifndef NOCRYPT
150 : unsigned long keys[3]; /* keys defining the pseudo-random sequence */
151 : const unsigned long* pcrc_32_tab;
152 : int crypt_header_size;
153 : #endif
154 : } curfile_info;
155 :
156 : typedef struct
157 : {
158 : zlib_filefunc_def z_filefunc;
159 : voidpf filestream; /* io structore of the zipfile */
160 : linkedlist_data central_dir;/* datablock with central dir in construction*/
161 : int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
162 : curfile_info ci; /* info on the file curretly writing */
163 :
164 : uLong begin_pos; /* position of the beginning of the zipfile */
165 : uLong add_position_when_writting_offset;
166 : uLong number_entry;
167 : #ifndef NO_ADDFILEINEXISTINGZIP
168 : char *globalcomment;
169 : #endif
170 : } zip_internal;
171 :
172 :
173 :
174 : #ifndef NOCRYPT
175 : #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
176 : #include "crypt.h"
177 : #endif
178 :
179 36 : local linkedlist_datablock_internal* allocate_new_datablock()
180 : {
181 : linkedlist_datablock_internal* ldi;
182 : ldi = (linkedlist_datablock_internal*)
183 36 : ALLOC(sizeof(linkedlist_datablock_internal));
184 36 : if (ldi!=NULL)
185 : {
186 36 : ldi->next_datablock = NULL ;
187 36 : ldi->filled_in_this_block = 0 ;
188 36 : ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
189 : }
190 36 : return ldi;
191 : }
192 :
193 36 : local void free_datablock(linkedlist_datablock_internal*ldi)
194 : {
195 108 : while (ldi!=NULL)
196 : {
197 36 : linkedlist_datablock_internal* ldinext = ldi->next_datablock;
198 36 : TRYFREE(ldi);
199 36 : ldi = ldinext;
200 : }
201 36 : }
202 :
203 36 : local void init_linkedlist(linkedlist_data*ll)
204 : {
205 36 : ll->first_block = ll->last_block = NULL;
206 36 : }
207 :
208 122 : local int add_data_in_datablock(linkedlist_data*ll,
209 : const void *buf, uLong len)
210 : {
211 : linkedlist_datablock_internal* ldi;
212 : const unsigned char* from_copy;
213 :
214 122 : if (ll==NULL)
215 0 : return ZIP_INTERNALERROR;
216 :
217 122 : if (ll->last_block == NULL)
218 : {
219 36 : ll->first_block = ll->last_block = allocate_new_datablock();
220 36 : if (ll->first_block == NULL)
221 0 : return ZIP_INTERNALERROR;
222 : }
223 :
224 122 : ldi = ll->last_block;
225 122 : from_copy = (unsigned char*)buf;
226 :
227 366 : while (len>0)
228 : {
229 : uInt copy_this;
230 : uInt i;
231 : unsigned char* to_copy;
232 :
233 122 : if (ldi->avail_in_this_block==0)
234 : {
235 0 : ldi->next_datablock = allocate_new_datablock();
236 0 : if (ldi->next_datablock == NULL)
237 0 : return ZIP_INTERNALERROR;
238 0 : ldi = ldi->next_datablock ;
239 0 : ll->last_block = ldi;
240 : }
241 :
242 122 : if (ldi->avail_in_this_block < len)
243 0 : copy_this = (uInt)ldi->avail_in_this_block;
244 : else
245 122 : copy_this = (uInt)len;
246 :
247 122 : to_copy = &(ldi->data[ldi->filled_in_this_block]);
248 :
249 10422 : for (i=0;i<copy_this;i++)
250 10300 : *(to_copy+i)=*(from_copy+i);
251 :
252 122 : ldi->filled_in_this_block += copy_this;
253 122 : ldi->avail_in_this_block -= copy_this;
254 122 : from_copy += copy_this ;
255 122 : len -= copy_this;
256 : }
257 122 : return ZIP_OK;
258 : }
259 :
260 :
261 :
262 : /****************************************************************************/
263 :
264 : #ifndef NO_ADDFILEINEXISTINGZIP
265 : /* ===========================================================================
266 : Inputs a long in LSB order to the given file
267 : nbByte == 1, 2 or 4 (byte, short or long)
268 : */
269 :
270 : local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
271 : voidpf filestream, uLong x, int nbByte));
272 :
273 1718 : local int ziplocal_putValue (const zlib_filefunc_def*pzlib_filefunc_def,
274 : voidpf filestream, uLong x, int nbByte)
275 : {
276 : unsigned char buf[4];
277 : int n;
278 7130 : for (n = 0; n < nbByte; n++)
279 : {
280 5412 : buf[n] = (unsigned char)(x & 0xff);
281 5412 : x >>= 8;
282 : }
283 1718 : if (x != 0)
284 : { /* data overflow - hack for ZIP64 (X Roche) */
285 0 : for (n = 0; n < nbByte; n++)
286 : {
287 0 : buf[n] = 0xff;
288 : }
289 : }
290 :
291 1718 : if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
292 0 : return ZIP_ERRNO;
293 : else
294 1718 : return ZIP_OK;
295 : }
296 :
297 : local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
298 2176 : local void ziplocal_putValue_inmemory (void *dest, uLong x, int nbByte)
299 : {
300 2176 : unsigned char* buf=(unsigned char*)dest;
301 : int n;
302 8728 : for (n = 0; n < nbByte; n++) {
303 6552 : buf[n] = (unsigned char)(x & 0xff);
304 6552 : x >>= 8;
305 : }
306 :
307 2176 : if (x != 0)
308 : { /* data overflow - hack for ZIP64 */
309 0 : for (n = 0; n < nbByte; n++)
310 : {
311 0 : buf[n] = 0xff;
312 : }
313 : }
314 2176 : }
315 :
316 : /****************************************************************************/
317 :
318 :
319 0 : local uLong ziplocal_TmzDateToDosDate(const tm_zip*ptm,uLong dosDate)
320 : {
321 0 : uLong year = (uLong)ptm->tm_year;
322 0 : if (year>1980)
323 0 : year-=1980;
324 0 : else if (year>80)
325 0 : year-=80;
326 : return
327 : (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
328 0 : ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
329 : }
330 :
331 :
332 : /****************************************************************************/
333 :
334 : local int ziplocal_getByte OF((
335 : const zlib_filefunc_def* pzlib_filefunc_def,
336 : voidpf filestream,
337 : int *pi));
338 :
339 264 : local int ziplocal_getByte(const zlib_filefunc_def* pzlib_filefunc_def,
340 : voidpf filestream, int *pi)
341 : {
342 : unsigned char c;
343 264 : int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
344 264 : if (err==1)
345 : {
346 264 : *pi = (int)c;
347 264 : return ZIP_OK;
348 : }
349 : else
350 : {
351 0 : if (ZERROR(*pzlib_filefunc_def,filestream))
352 0 : return ZIP_ERRNO;
353 : else
354 0 : return ZIP_EOF;
355 : }
356 : }
357 :
358 :
359 : /* ===========================================================================
360 : Reads a long in LSB order from the given gz_stream. Sets
361 : */
362 : local int ziplocal_getShort OF((
363 : const zlib_filefunc_def* pzlib_filefunc_def,
364 : voidpf filestream,
365 : uLong *pX));
366 :
367 60 : local int ziplocal_getShort (const zlib_filefunc_def* pzlib_filefunc_def,
368 : voidpf filestream, uLong *pX)
369 : {
370 : uLong x ;
371 : int i;
372 : int err;
373 :
374 60 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
375 60 : x = (uLong)i;
376 :
377 60 : if (err==ZIP_OK)
378 60 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
379 60 : x += ((uLong)i)<<8;
380 :
381 60 : if (err==ZIP_OK)
382 60 : *pX = x;
383 : else
384 0 : *pX = 0;
385 60 : return err;
386 : }
387 :
388 : local int ziplocal_getLong OF((
389 : const zlib_filefunc_def* pzlib_filefunc_def,
390 : voidpf filestream,
391 : uLong *pX));
392 :
393 36 : local int ziplocal_getLong (
394 : const zlib_filefunc_def* pzlib_filefunc_def,
395 : voidpf filestream,
396 : uLong *pX )
397 : {
398 : uLong x ;
399 : int i;
400 : int err;
401 :
402 36 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
403 36 : x = (uLong)i;
404 :
405 36 : if (err==ZIP_OK)
406 36 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
407 36 : x += ((uLong)i)<<8;
408 :
409 36 : if (err==ZIP_OK)
410 36 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
411 36 : x += ((uLong)i)<<16;
412 :
413 36 : if (err==ZIP_OK)
414 36 : err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
415 36 : x += ((uLong)i)<<24;
416 :
417 36 : if (err==ZIP_OK)
418 36 : *pX = x;
419 : else
420 0 : *pX = 0;
421 36 : return err;
422 : }
423 :
424 : #ifndef BUFREADCOMMENT
425 : #define BUFREADCOMMENT (0x400)
426 : #endif
427 : /*
428 : Locate the Central directory of a zipfile (at the end, just before
429 : the global comment)
430 : */
431 : local uLong ziplocal_SearchCentralDir OF((
432 : const zlib_filefunc_def* pzlib_filefunc_def,
433 : voidpf filestream));
434 :
435 12 : local uLong ziplocal_SearchCentralDir(
436 : const zlib_filefunc_def* pzlib_filefunc_def,
437 : voidpf filestream )
438 : {
439 : unsigned char* buf;
440 : uLong uSizeFile;
441 : uLong uBackRead;
442 12 : uLong uMaxBack=0xffff; /* maximum size of global comment */
443 12 : uLong uPosFound=0;
444 :
445 12 : if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
446 0 : return 0;
447 :
448 :
449 12 : uSizeFile = (uLong) ZTELL(*pzlib_filefunc_def,filestream);
450 :
451 12 : if (uMaxBack>uSizeFile)
452 12 : uMaxBack = uSizeFile;
453 :
454 12 : buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
455 12 : if (buf==NULL)
456 0 : return 0;
457 :
458 12 : uBackRead = 4;
459 24 : while (uBackRead<uMaxBack)
460 : {
461 : uLong uReadSize,uReadPos ;
462 : int i;
463 12 : if (uBackRead+BUFREADCOMMENT>uMaxBack)
464 8 : uBackRead = uMaxBack;
465 : else
466 4 : uBackRead+=BUFREADCOMMENT;
467 12 : uReadPos = uSizeFile-uBackRead ;
468 :
469 : uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
470 12 : (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
471 12 : if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
472 0 : break;
473 :
474 12 : if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
475 0 : break;
476 :
477 240 : for (i=(int)uReadSize-3; (i--)>0;)
478 228 : if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
479 : ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
480 : {
481 12 : uPosFound = uReadPos+i;
482 12 : break;
483 : }
484 :
485 12 : if (uPosFound!=0)
486 12 : break;
487 : }
488 12 : TRYFREE(buf);
489 12 : return uPosFound;
490 : }
491 : #endif /* !NO_ADDFILEINEXISTINGZIP*/
492 :
493 : /************************************************************/
494 36 : extern zipFile ZEXPORT cpl_zipOpen2 (
495 : const char *pathname,
496 : int append,
497 : zipcharpc* globalcomment,
498 : zlib_filefunc_def* pzlib_filefunc_def )
499 : {
500 : zip_internal ziinit;
501 : zip_internal* zi;
502 36 : int err=ZIP_OK;
503 :
504 :
505 36 : if (pzlib_filefunc_def==NULL)
506 36 : cpl_fill_fopen_filefunc(&ziinit.z_filefunc);
507 : else
508 0 : ziinit.z_filefunc = *pzlib_filefunc_def;
509 :
510 : ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
511 : (ziinit.z_filefunc.opaque,
512 : pathname,
513 : (append == APPEND_STATUS_CREATE) ?
514 : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
515 36 : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
516 :
517 36 : if (ziinit.filestream == NULL)
518 0 : return NULL;
519 36 : ziinit.begin_pos = (uLong) ZTELL(ziinit.z_filefunc,ziinit.filestream);
520 36 : ziinit.in_opened_file_inzip = 0;
521 36 : ziinit.ci.stream_initialised = 0;
522 36 : ziinit.number_entry = 0;
523 36 : ziinit.add_position_when_writting_offset = 0;
524 36 : init_linkedlist(&(ziinit.central_dir));
525 :
526 :
527 36 : zi = (zip_internal*)ALLOC(sizeof(zip_internal));
528 36 : if (zi==NULL)
529 : {
530 0 : ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
531 0 : return NULL;
532 : }
533 :
534 : /* now we add file in a zipfile */
535 : # ifndef NO_ADDFILEINEXISTINGZIP
536 36 : ziinit.globalcomment = NULL;
537 36 : if (append == APPEND_STATUS_ADDINZIP)
538 : {
539 : uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
540 :
541 : uLong size_central_dir; /* size of the central directory */
542 : uLong offset_central_dir; /* offset of start of central directory */
543 : uLong central_pos,uL;
544 :
545 : uLong number_disk; /* number of the current dist, used for
546 : spaning ZIP, unsupported, always 0*/
547 : uLong number_disk_with_CD; /* number the the disk with central dir, used
548 : for spaning ZIP, unsupported, always 0*/
549 : uLong number_entry;
550 : uLong number_entry_CD; /* total number of entries in
551 : the central dir
552 : (same than number_entry on nospan) */
553 : uLong size_comment;
554 :
555 12 : central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
556 12 : if (central_pos==0)
557 0 : err=ZIP_ERRNO;
558 :
559 12 : if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
560 : central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
561 0 : err=ZIP_ERRNO;
562 :
563 : /* the signature, already checked */
564 12 : if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
565 0 : err=ZIP_ERRNO;
566 :
567 : /* number of this disk */
568 12 : if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
569 0 : err=ZIP_ERRNO;
570 :
571 : /* number of the disk with the start of the central directory */
572 12 : if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
573 0 : err=ZIP_ERRNO;
574 :
575 : /* total number of entries in the central dir on this disk */
576 12 : if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
577 0 : err=ZIP_ERRNO;
578 :
579 : /* total number of entries in the central dir */
580 12 : if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
581 0 : err=ZIP_ERRNO;
582 :
583 12 : if ((number_entry_CD!=number_entry) ||
584 : (number_disk_with_CD!=0) ||
585 : (number_disk!=0))
586 0 : err=ZIP_BADZIPFILE;
587 :
588 : /* size of the central directory */
589 12 : if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
590 0 : err=ZIP_ERRNO;
591 :
592 : /* offset of start of central directory with respect to the
593 : starting disk number */
594 12 : if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
595 0 : err=ZIP_ERRNO;
596 :
597 : /* zipfile global comment length */
598 12 : if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
599 0 : err=ZIP_ERRNO;
600 :
601 12 : if ((central_pos<offset_central_dir+size_central_dir) &&
602 : (err==ZIP_OK))
603 0 : err=ZIP_BADZIPFILE;
604 :
605 12 : if (err!=ZIP_OK)
606 : {
607 0 : ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
608 0 : return NULL;
609 : }
610 :
611 12 : if (size_comment>0)
612 : {
613 0 : ziinit.globalcomment = (char*) ALLOC(size_comment+1);
614 0 : if (ziinit.globalcomment)
615 : {
616 0 : size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
617 0 : ziinit.globalcomment[size_comment]=0;
618 : }
619 : }
620 :
621 : byte_before_the_zipfile = central_pos -
622 12 : (offset_central_dir+size_central_dir);
623 12 : ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
624 :
625 : {
626 12 : uLong size_central_dir_to_read = size_central_dir;
627 12 : size_t buf_size = SIZEDATA_INDATABLOCK;
628 12 : void* buf_read = (void*)ALLOC(buf_size);
629 12 : if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
630 : offset_central_dir + byte_before_the_zipfile,
631 : ZLIB_FILEFUNC_SEEK_SET) != 0)
632 0 : err=ZIP_ERRNO;
633 :
634 36 : while ((size_central_dir_to_read>0) && (err==ZIP_OK))
635 : {
636 12 : uLong read_this = SIZEDATA_INDATABLOCK;
637 12 : if (read_this > size_central_dir_to_read)
638 12 : read_this = size_central_dir_to_read;
639 12 : if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
640 0 : err=ZIP_ERRNO;
641 :
642 12 : if (err==ZIP_OK)
643 : err = add_data_in_datablock(&ziinit.central_dir,buf_read,
644 12 : (uLong)read_this);
645 12 : size_central_dir_to_read-=read_this;
646 : }
647 12 : TRYFREE(buf_read);
648 : }
649 12 : ziinit.begin_pos = byte_before_the_zipfile;
650 12 : ziinit.number_entry = number_entry_CD;
651 :
652 12 : if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
653 : offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
654 0 : err=ZIP_ERRNO;
655 : }
656 :
657 36 : if (globalcomment)
658 : {
659 0 : *globalcomment = ziinit.globalcomment;
660 : }
661 : # endif /* !NO_ADDFILEINEXISTINGZIP*/
662 :
663 36 : if (err != ZIP_OK)
664 : {
665 : # ifndef NO_ADDFILEINEXISTINGZIP
666 0 : TRYFREE(ziinit.globalcomment);
667 : # endif /* !NO_ADDFILEINEXISTINGZIP*/
668 0 : TRYFREE(zi);
669 0 : return NULL;
670 : }
671 : else
672 : {
673 36 : *zi = ziinit;
674 36 : return (zipFile)zi;
675 : }
676 : }
677 :
678 36 : extern zipFile ZEXPORT cpl_zipOpen (const char *pathname, int append)
679 : {
680 36 : return cpl_zipOpen2(pathname,append,NULL,NULL);
681 : }
682 :
683 110 : extern int ZEXPORT cpl_zipOpenNewFileInZip3 (
684 : zipFile file,
685 : const char* filename,
686 : const zip_fileinfo* zipfi,
687 : const void* extrafield_local,
688 : uInt size_extrafield_local,
689 : const void* extrafield_global,
690 : uInt size_extrafield_global,
691 : const char* comment,
692 : int method,
693 : int level,
694 : int raw,
695 : int windowBits,
696 : int memLevel,
697 : int strategy,
698 : const char* password,
699 : uLong crcForCrypting )
700 : {
701 : zip_internal* zi;
702 : uInt size_filename;
703 : uInt size_comment;
704 : uInt i;
705 110 : int err = ZIP_OK;
706 :
707 : # ifdef NOCRYPT
708 110 : if (password != NULL)
709 0 : return ZIP_PARAMERROR;
710 : # endif
711 :
712 110 : if (file == NULL)
713 0 : return ZIP_PARAMERROR;
714 110 : if ((method!=0) && (method!=Z_DEFLATED))
715 0 : return ZIP_PARAMERROR;
716 :
717 110 : zi = (zip_internal*)file;
718 :
719 110 : if (zi->in_opened_file_inzip == 1)
720 : {
721 0 : err = cpl_zipCloseFileInZip (file);
722 0 : if (err != ZIP_OK)
723 0 : return err;
724 : }
725 :
726 :
727 110 : if (filename==NULL)
728 0 : filename="-";
729 :
730 110 : if (comment==NULL)
731 0 : size_comment = 0;
732 : else
733 110 : size_comment = (uInt)strlen(comment);
734 :
735 110 : size_filename = (uInt)strlen(filename);
736 :
737 110 : if (zipfi == NULL)
738 110 : zi->ci.dosDate = 0;
739 : else
740 : {
741 0 : if (zipfi->dosDate != 0)
742 0 : zi->ci.dosDate = zipfi->dosDate;
743 0 : else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
744 : }
745 :
746 110 : zi->ci.flag = 0;
747 110 : if ((level==8) || (level==9))
748 0 : zi->ci.flag |= 2;
749 110 : if (level==2)
750 0 : zi->ci.flag |= 4;
751 110 : if (level==1)
752 0 : zi->ci.flag |= 6;
753 110 : if (password != NULL)
754 0 : zi->ci.flag |= 1;
755 :
756 110 : zi->ci.crc32 = 0;
757 110 : zi->ci.method = method;
758 110 : zi->ci.encrypt = 0;
759 110 : zi->ci.stream_initialised = 0;
760 110 : zi->ci.pos_in_buffered_data = 0;
761 110 : zi->ci.raw = raw;
762 110 : zi->ci.pos_local_header = (uLong) ZTELL(zi->z_filefunc,zi->filestream) ;
763 : zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
764 110 : size_extrafield_global + size_comment;
765 110 : zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
766 :
767 110 : ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
768 : /* version info */
769 110 : ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
770 110 : ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
771 110 : ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
772 110 : ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
773 110 : ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
774 110 : ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
775 110 : ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
776 110 : ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
777 110 : ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
778 110 : ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
779 110 : ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
780 110 : ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
781 :
782 110 : if (zipfi==NULL)
783 110 : ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
784 : else
785 0 : ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
786 :
787 110 : if (zipfi==NULL)
788 110 : ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
789 : else
790 0 : ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
791 :
792 110 : ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
793 :
794 3455 : for (i=0;i<size_filename;i++)
795 3345 : *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
796 :
797 110 : for (i=0;i<size_extrafield_global;i++)
798 : *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
799 0 : *(((const char*)extrafield_global)+i);
800 :
801 110 : for (i=0;i<size_comment;i++)
802 : *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
803 0 : size_extrafield_global+i) = *(comment+i);
804 110 : if (zi->ci.central_header == NULL)
805 0 : return ZIP_INTERNALERROR;
806 :
807 : /* write the local header */
808 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
809 :
810 110 : if (err==ZIP_OK)
811 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
812 110 : if (err==ZIP_OK)
813 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
814 :
815 110 : if (err==ZIP_OK)
816 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
817 :
818 110 : if (err==ZIP_OK)
819 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
820 :
821 110 : if (err==ZIP_OK)
822 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
823 110 : if (err==ZIP_OK)
824 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
825 110 : if (err==ZIP_OK)
826 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
827 :
828 110 : if (err==ZIP_OK)
829 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
830 :
831 110 : if (err==ZIP_OK)
832 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
833 :
834 110 : if ((err==ZIP_OK) && (size_filename>0))
835 110 : if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
836 0 : err = ZIP_ERRNO;
837 :
838 110 : if ((err==ZIP_OK) && (size_extrafield_local>0))
839 0 : if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
840 : !=size_extrafield_local)
841 0 : err = ZIP_ERRNO;
842 :
843 110 : zi->ci.stream.avail_in = (uInt)0;
844 110 : zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
845 110 : zi->ci.stream.next_out = zi->ci.buffered_data;
846 110 : zi->ci.stream.total_in = 0;
847 110 : zi->ci.stream.total_out = 0;
848 :
849 110 : if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
850 : {
851 108 : zi->ci.stream.zalloc = (alloc_func)0;
852 108 : zi->ci.stream.zfree = (free_func)0;
853 108 : zi->ci.stream.opaque = (voidpf)0;
854 :
855 108 : if (windowBits>0)
856 0 : windowBits = -windowBits;
857 :
858 : err = deflateInit2(&zi->ci.stream, level,
859 108 : Z_DEFLATED, windowBits, memLevel, strategy);
860 :
861 108 : if (err==Z_OK)
862 108 : zi->ci.stream_initialised = 1;
863 : }
864 : # ifndef NOCRYPT
865 : zi->ci.crypt_header_size = 0;
866 : if ((err==Z_OK) && (password != NULL))
867 : {
868 : unsigned char bufHead[RAND_HEAD_LEN];
869 : unsigned int sizeHead;
870 : zi->ci.encrypt = 1;
871 : zi->ci.pcrc_32_tab = get_crc_table();
872 : /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
873 :
874 : sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
875 : zi->ci.crypt_header_size = sizeHead;
876 :
877 : if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
878 : err = ZIP_ERRNO;
879 : }
880 : # endif
881 :
882 110 : if (err==Z_OK)
883 110 : zi->in_opened_file_inzip = 1;
884 110 : return err;
885 : }
886 :
887 110 : extern int ZEXPORT cpl_zipOpenNewFileInZip2(
888 : zipFile file,
889 : const char* filename,
890 : const zip_fileinfo* zipfi,
891 : const void* extrafield_local,
892 : uInt size_extrafield_local,
893 : const void* extrafield_global,
894 : uInt size_extrafield_global,
895 : const char* comment,
896 : int method,
897 : int level,
898 : int raw )
899 : {
900 : return cpl_zipOpenNewFileInZip3 (file, filename, zipfi,
901 : extrafield_local, size_extrafield_local,
902 : extrafield_global, size_extrafield_global,
903 : comment, method, level, raw,
904 : -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
905 110 : NULL, 0);
906 : }
907 :
908 110 : extern int ZEXPORT cpl_zipOpenNewFileInZip (
909 : zipFile file,
910 : const char* filename,
911 : const zip_fileinfo* zipfi,
912 : const void* extrafield_local,
913 : uInt size_extrafield_local,
914 : const void* extrafield_global,
915 : uInt size_extrafield_global,
916 : const char* comment,
917 : int method,
918 : int level )
919 : {
920 : return cpl_zipOpenNewFileInZip2 (file, filename, zipfi,
921 : extrafield_local, size_extrafield_local,
922 : extrafield_global, size_extrafield_global,
923 110 : comment, method, level, 0);
924 : }
925 :
926 125 : local int zipFlushWriteBuffer(
927 : zip_internal* zi )
928 : {
929 125 : int err=ZIP_OK;
930 :
931 125 : if (zi->ci.encrypt != 0)
932 : {
933 : #ifndef NOCRYPT
934 : uInt i;
935 : int t;
936 : for (i=0;i<zi->ci.pos_in_buffered_data;i++)
937 : zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
938 : zi->ci.buffered_data[i],t);
939 : #endif
940 : }
941 125 : if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
942 : !=zi->ci.pos_in_buffered_data)
943 0 : err = ZIP_ERRNO;
944 125 : zi->ci.pos_in_buffered_data = 0;
945 125 : return err;
946 : }
947 :
948 2398 : extern int ZEXPORT cpl_zipWriteInFileInZip (
949 : zipFile file,
950 : const void* buf,
951 : unsigned len )
952 : {
953 : zip_internal* zi;
954 2398 : int err=ZIP_OK;
955 :
956 2398 : if (file == NULL)
957 0 : return ZIP_PARAMERROR;
958 2398 : zi = (zip_internal*)file;
959 :
960 2398 : if (zi->in_opened_file_inzip == 0)
961 0 : return ZIP_PARAMERROR;
962 :
963 2398 : zi->ci.stream.next_in = (Bytef*)buf;
964 2398 : zi->ci.stream.avail_in = len;
965 2398 : zi->ci.crc32 = crc32(zi->ci.crc32,(const Bytef *) buf,len);
966 :
967 7194 : while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
968 : {
969 2398 : if (zi->ci.stream.avail_out == 0)
970 : {
971 15 : if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
972 0 : err = ZIP_ERRNO;
973 15 : zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
974 15 : zi->ci.stream.next_out = zi->ci.buffered_data;
975 : }
976 :
977 :
978 2398 : if(err != ZIP_OK)
979 0 : break;
980 :
981 4794 : if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
982 : {
983 2396 : uLong uTotalOutBefore = zi->ci.stream.total_out;
984 2396 : err=deflate(&zi->ci.stream, Z_NO_FLUSH);
985 2396 : zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
986 :
987 : }
988 : else
989 : {
990 : uInt copy_this,i;
991 2 : if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
992 2 : copy_this = zi->ci.stream.avail_in;
993 : else
994 0 : copy_this = zi->ci.stream.avail_out;
995 94 : for (i=0;i<copy_this;i++)
996 : *(((char*)zi->ci.stream.next_out)+i) =
997 92 : *(((const char*)zi->ci.stream.next_in)+i);
998 : {
999 2 : zi->ci.stream.avail_in -= copy_this;
1000 2 : zi->ci.stream.avail_out-= copy_this;
1001 2 : zi->ci.stream.next_in+= copy_this;
1002 2 : zi->ci.stream.next_out+= copy_this;
1003 2 : zi->ci.stream.total_in+= copy_this;
1004 2 : zi->ci.stream.total_out+= copy_this;
1005 2 : zi->ci.pos_in_buffered_data += copy_this;
1006 : }
1007 : }
1008 : }
1009 :
1010 2398 : return err;
1011 : }
1012 :
1013 110 : extern int ZEXPORT cpl_zipCloseFileInZipRaw (
1014 : zipFile file,
1015 : uLong uncompressed_size,
1016 : uLong crc32 )
1017 : {
1018 : zip_internal* zi;
1019 : uLong compressed_size;
1020 110 : int err=ZIP_OK;
1021 :
1022 110 : if (file == NULL)
1023 0 : return ZIP_PARAMERROR;
1024 110 : zi = (zip_internal*)file;
1025 :
1026 110 : if (zi->in_opened_file_inzip == 0)
1027 0 : return ZIP_PARAMERROR;
1028 110 : zi->ci.stream.avail_in = 0;
1029 :
1030 110 : if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1031 324 : while (err==ZIP_OK)
1032 : {
1033 : uLong uTotalOutBefore;
1034 108 : if (zi->ci.stream.avail_out == 0)
1035 : {
1036 0 : if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1037 0 : err = ZIP_ERRNO;
1038 0 : zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1039 0 : zi->ci.stream.next_out = zi->ci.buffered_data;
1040 : }
1041 108 : uTotalOutBefore = zi->ci.stream.total_out;
1042 108 : err=deflate(&zi->ci.stream, Z_FINISH);
1043 108 : zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1044 : }
1045 :
1046 110 : if (err==Z_STREAM_END)
1047 108 : err=ZIP_OK; /* this is normal */
1048 :
1049 110 : if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1050 110 : if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1051 0 : err = ZIP_ERRNO;
1052 :
1053 110 : if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1054 : {
1055 108 : err=deflateEnd(&zi->ci.stream);
1056 108 : zi->ci.stream_initialised = 0;
1057 : }
1058 :
1059 110 : if (!zi->ci.raw)
1060 : {
1061 110 : crc32 = (uLong)zi->ci.crc32;
1062 110 : uncompressed_size = (uLong)zi->ci.stream.total_in;
1063 : }
1064 110 : compressed_size = (uLong)zi->ci.stream.total_out;
1065 : # ifndef NOCRYPT
1066 : compressed_size += zi->ci.crypt_header_size;
1067 : # endif
1068 :
1069 110 : ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1070 : ziplocal_putValue_inmemory(zi->ci.central_header+20,
1071 110 : compressed_size,4); /*compr size*/
1072 110 : if (zi->ci.stream.data_type == Z_ASCII)
1073 86 : ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1074 : ziplocal_putValue_inmemory(zi->ci.central_header+24,
1075 110 : uncompressed_size,4); /*uncompr size*/
1076 :
1077 110 : if (err==ZIP_OK)
1078 : err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1079 110 : (uLong)zi->ci.size_centralheader);
1080 110 : free(zi->ci.central_header);
1081 :
1082 110 : if (err==ZIP_OK)
1083 : {
1084 110 : long cur_pos_inzip = (uLong) ZTELL(zi->z_filefunc,zi->filestream);
1085 110 : if (ZSEEK(zi->z_filefunc,zi->filestream,
1086 : zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1087 0 : err = ZIP_ERRNO;
1088 :
1089 110 : if (err==ZIP_OK)
1090 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1091 :
1092 110 : if (err==ZIP_OK) /* compressed size, unknown */
1093 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1094 :
1095 110 : if (err==ZIP_OK) /* uncompressed size, unknown */
1096 110 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1097 :
1098 110 : if (ZSEEK(zi->z_filefunc,zi->filestream,
1099 : cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1100 0 : err = ZIP_ERRNO;
1101 : }
1102 :
1103 110 : zi->number_entry ++;
1104 110 : zi->in_opened_file_inzip = 0;
1105 :
1106 110 : return err;
1107 : }
1108 :
1109 110 : extern int ZEXPORT cpl_zipCloseFileInZip (
1110 : zipFile file )
1111 : {
1112 110 : return cpl_zipCloseFileInZipRaw (file,0,0);
1113 : }
1114 :
1115 36 : extern int ZEXPORT cpl_zipClose (
1116 : zipFile file,
1117 : const char* global_comment)
1118 : {
1119 : zip_internal* zi;
1120 36 : int err = 0;
1121 36 : uLong size_centraldir = 0;
1122 : uLong centraldir_pos_inzip;
1123 : uInt size_global_comment;
1124 36 : if (file == NULL)
1125 0 : return ZIP_PARAMERROR;
1126 36 : zi = (zip_internal*)file;
1127 :
1128 36 : if (zi->in_opened_file_inzip == 1)
1129 : {
1130 0 : err = cpl_zipCloseFileInZip (file);
1131 : }
1132 :
1133 : #ifndef NO_ADDFILEINEXISTINGZIP
1134 36 : if (global_comment==NULL)
1135 36 : global_comment = zi->globalcomment;
1136 : #endif
1137 36 : if (global_comment==NULL)
1138 36 : size_global_comment = 0;
1139 : else
1140 0 : size_global_comment = (uInt)strlen(global_comment);
1141 :
1142 36 : centraldir_pos_inzip = (uLong) ZTELL(zi->z_filefunc,zi->filestream);
1143 36 : if (err==ZIP_OK)
1144 : {
1145 36 : linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1146 108 : while (ldi!=NULL)
1147 : {
1148 36 : if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1149 36 : if (ZWRITE(zi->z_filefunc,zi->filestream,
1150 : ldi->data,ldi->filled_in_this_block)
1151 : !=ldi->filled_in_this_block )
1152 0 : err = ZIP_ERRNO;
1153 :
1154 36 : size_centraldir += ldi->filled_in_this_block;
1155 36 : ldi = ldi->next_datablock;
1156 : }
1157 : }
1158 36 : free_datablock(zi->central_dir.first_block);
1159 :
1160 36 : if (err==ZIP_OK) /* Magic End */
1161 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1162 :
1163 36 : if (err==ZIP_OK) /* number of this disk */
1164 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1165 :
1166 36 : if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1167 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1168 :
1169 36 : if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1170 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1171 :
1172 36 : if (err==ZIP_OK) /* total number of entries in the central dir */
1173 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1174 :
1175 36 : if (err==ZIP_OK) /* size of the central directory */
1176 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1177 :
1178 36 : if (err==ZIP_OK) /* offset of start of central directory with respect to the
1179 : starting disk number */
1180 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1181 36 : (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1182 :
1183 36 : if (err==ZIP_OK) /* zipfile comment length */
1184 36 : err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1185 :
1186 36 : if ((err==ZIP_OK) && (size_global_comment>0))
1187 0 : if (ZWRITE(zi->z_filefunc,zi->filestream,
1188 : global_comment,size_global_comment) != size_global_comment)
1189 0 : err = ZIP_ERRNO;
1190 :
1191 36 : if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1192 0 : if (err == ZIP_OK)
1193 0 : err = ZIP_ERRNO;
1194 :
1195 : #ifndef NO_ADDFILEINEXISTINGZIP
1196 36 : TRYFREE(zi->globalcomment);
1197 : #endif
1198 36 : TRYFREE(zi);
1199 :
1200 36 : return err;
1201 : }
1202 :
1203 : /************************************************************************/
1204 : /* ==================================================================== */
1205 : /* The following is a simplified CPL API for creating ZIP files */
1206 : /* exported from cpl_conv.h. */
1207 : /* ==================================================================== */
1208 : /************************************************************************/
1209 :
1210 : /************************************************************************/
1211 : /* CPLCreateZip() */
1212 : /************************************************************************/
1213 :
1214 36 : void *CPLCreateZip( const char *pszZipFilename, char **papszOptions )
1215 :
1216 : {
1217 : (void) papszOptions;
1218 :
1219 36 : int bAppend = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "APPEND", "FALSE"));
1220 :
1221 36 : return cpl_zipOpen( pszZipFilename, bAppend ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE);
1222 : }
1223 :
1224 : /************************************************************************/
1225 : /* CPLCreateFileInZip() */
1226 : /************************************************************************/
1227 :
1228 110 : CPLErr CPLCreateFileInZip( void *hZip, const char *pszFilename,
1229 : char **papszOptions )
1230 :
1231 : {
1232 : int nErr;
1233 :
1234 : (void) papszOptions;
1235 :
1236 110 : if( hZip == NULL )
1237 0 : return CE_Failure;
1238 :
1239 110 : int bCompressed = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "COMPRESSED", "TRUE"));
1240 :
1241 : nErr = cpl_zipOpenNewFileInZip( (zipFile) hZip, pszFilename, NULL,
1242 : NULL, 0, NULL, 0, "",
1243 110 : bCompressed ? Z_DEFLATED : 0, bCompressed ? Z_DEFAULT_COMPRESSION : 0 );
1244 :
1245 110 : if( nErr != ZIP_OK )
1246 0 : return CE_Failure;
1247 : else
1248 110 : return CE_None;
1249 : }
1250 :
1251 : /************************************************************************/
1252 : /* CPLWriteFileInZip() */
1253 : /************************************************************************/
1254 :
1255 2398 : CPLErr CPLWriteFileInZip( void *hZip, const void *pBuffer, int nBufferSize )
1256 :
1257 : {
1258 : int nErr;
1259 :
1260 : nErr = cpl_zipWriteInFileInZip( (zipFile) hZip, pBuffer,
1261 2398 : (unsigned int) nBufferSize );
1262 :
1263 2398 : if( nErr != ZIP_OK )
1264 0 : return CE_Failure;
1265 : else
1266 2398 : return CE_None;
1267 : }
1268 :
1269 : /************************************************************************/
1270 : /* CPLCloseFileInZip() */
1271 : /************************************************************************/
1272 :
1273 110 : CPLErr CPLCloseFileInZip( void *hZip )
1274 :
1275 : {
1276 : int nErr;
1277 :
1278 110 : nErr = cpl_zipCloseFileInZip( (zipFile) hZip );
1279 :
1280 110 : if( nErr != ZIP_OK )
1281 0 : return CE_Failure;
1282 : else
1283 110 : return CE_None;
1284 : }
1285 :
1286 : /************************************************************************/
1287 : /* CPLCloseZip() */
1288 : /************************************************************************/
1289 :
1290 36 : CPLErr CPLCloseZip( void *hZip )
1291 :
1292 : {
1293 : int nErr;
1294 :
1295 36 : nErr = cpl_zipClose((zipFile) hZip, NULL);
1296 :
1297 36 : if( nErr != ZIP_OK )
1298 0 : return CE_Failure;
1299 : else
1300 36 : return CE_None;
1301 : }
|