1 : /* Modified version by Even Rouault. :
2 : - Addition of cpl_unzGetCurrentFileZStreamPos
3 : - Decoration of symbol names unz* -> cpl_unz*
4 : - Undef EXPORT so that we are sure the symbols are not exported
5 : - Remove old C style function prototypes
6 : - Add support for ZIP64
7 :
8 : Copyright (C) 2007-2008 Even Rouault
9 :
10 : Original licence available in port/LICENCE_minizip
11 : */
12 :
13 :
14 : /* unzip.c -- IO for uncompress .zip files using zlib
15 : Version 1.01e, February 12th, 2005
16 :
17 : Copyright (C) 1998-2005 Gilles Vollant
18 :
19 : Read unzip.h for more info
20 : */
21 :
22 : /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
23 : compatibility with older software. The following is from the original crypt.c. Code
24 : woven in by Terry Thorsen 1/2003.
25 : */
26 : /*
27 : Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
28 :
29 : See the accompanying file LICENSE, version 2000-Apr-09 or later
30 : (the contents of which are also included in zip.h) for terms of use.
31 : If, for some reason, all these files are missing, the Info-ZIP license
32 : also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
33 : */
34 : /*
35 : crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
36 :
37 : The encryption/decryption parts of this source code (as opposed to the
38 : non-echoing password parts) were originally written in Europe. The
39 : whole source package can be freely distributed, including from the USA.
40 : (Prior to January 2000, re-export from the US was a violation of US law.)
41 : */
42 :
43 : /*
44 : This encryption code is a direct transcription of the algorithm from
45 : Roger Schlafly, described by Phil Katz in the file appnote.txt. This
46 : file (appnote.txt) is distributed with the PKZIP program (even in the
47 : version without encryption capabilities).
48 : */
49 :
50 :
51 : #include <stdio.h>
52 : #include <stdlib.h>
53 : #include <string.h>
54 :
55 : #include "zlib.h"
56 : #include "cpl_minizip_unzip.h"
57 :
58 : #ifdef STDC
59 : # include <stddef.h>
60 : # include <string.h>
61 : # include <stdlib.h>
62 : #endif
63 : #ifdef NO_ERRNO_H
64 : extern int errno;
65 : #else
66 : # include <errno.h>
67 : #endif
68 :
69 :
70 : #ifndef local
71 : # define local static
72 : #endif
73 : /* compile with -Dlocal if your debugger can't find static symbols */
74 :
75 :
76 : #ifndef CASESENSITIVITYDEFAULT_NO
77 : # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
78 : # define CASESENSITIVITYDEFAULT_NO
79 : # endif
80 : #endif
81 :
82 :
83 : #ifndef UNZ_BUFSIZE
84 : #define UNZ_BUFSIZE (16384)
85 : #endif
86 :
87 : #ifndef UNZ_MAXFILENAMEINZIP
88 : #define UNZ_MAXFILENAMEINZIP (256)
89 : #endif
90 :
91 : #ifndef ALLOC
92 : # define ALLOC(size) (malloc(size))
93 : #endif
94 : #ifndef TRYFREE
95 : # define TRYFREE(p) {if (p) free(p);}
96 : #endif
97 :
98 : #define SIZECENTRALDIRITEM (0x2e)
99 : #define SIZEZIPLOCALHEADER (0x1e)
100 :
101 :
102 : const char unz_copyright[] =
103 : " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
104 :
105 : /* unz_file_info_interntal contain internal info about a file in zipfile*/
106 : typedef struct unz_file_info_internal_s
107 : {
108 : uLong64 offset_curfile;/* relative offset of local header 4 bytes */
109 : } unz_file_info_internal;
110 :
111 :
112 : /* file_in_zip_read_info_s contain internal information about a file in zipfile,
113 : when reading and decompress it */
114 : typedef struct
115 : {
116 : char *read_buffer; /* internal buffer for compressed data */
117 : z_stream stream; /* zLib stream structure for inflate */
118 :
119 : uLong64 pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
120 : uLong stream_initialised; /* flag set if stream structure is initialised*/
121 :
122 : uLong64 offset_local_extrafield;/* offset of the local extra field */
123 : uInt size_local_extrafield;/* size of the local extra field */
124 : uLong64 pos_local_extrafield; /* position in the local extra field in read*/
125 :
126 : uLong crc32; /* crc32 of all data uncompressed */
127 : uLong crc32_wait; /* crc32 we must obtain after decompress all */
128 : uLong64 rest_read_compressed; /* number of byte to be decompressed */
129 : uLong64 rest_read_uncompressed;/*number of byte to be obtained after decomp*/
130 : zlib_filefunc_def z_filefunc;
131 : voidpf filestream; /* io structore of the zipfile */
132 : uLong compression_method; /* compression method (0==store) */
133 : uLong64 byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
134 : int raw;
135 : } file_in_zip_read_info_s;
136 :
137 :
138 : /* unz_s contain internal information about the zipfile
139 : */
140 : typedef struct
141 : {
142 : zlib_filefunc_def z_filefunc;
143 : voidpf filestream; /* io structore of the zipfile */
144 : unz_global_info gi; /* public global information */
145 : uLong64 byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
146 : uLong64 num_file; /* number of the current file in the zipfile*/
147 : uLong64 pos_in_central_dir; /* pos of the current file in the central dir*/
148 : uLong64 current_file_ok; /* flag about the usability of the current file*/
149 : uLong64 central_pos; /* position of the beginning of the central dir*/
150 :
151 : uLong64 size_central_dir; /* size of the central directory */
152 : uLong64 offset_central_dir; /* offset of start of central directory with
153 : respect to the starting disk number */
154 :
155 : unz_file_info cur_file_info; /* public info about the current file in zip*/
156 : unz_file_info_internal cur_file_info_internal; /* private info about it*/
157 : file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
158 : file if we are decompressing it */
159 : int encrypted;
160 :
161 : int isZip64;
162 :
163 : # ifndef NOUNCRYPT
164 : unsigned long keys[3]; /* keys defining the pseudo-random sequence */
165 : const unsigned long* pcrc_32_tab;
166 : # endif
167 : } unz_s;
168 :
169 :
170 : #ifndef NOUNCRYPT
171 : #include "crypt.h"
172 : #endif
173 :
174 : /* ===========================================================================
175 : Read a byte from a gz_stream; update next_in and avail_in. Return EOF
176 : for end of file.
177 : IN assertion: the stream s has been sucessfully opened for reading.
178 : */
179 :
180 :
181 : local int unzlocal_getByte OF((
182 : const zlib_filefunc_def* pzlib_filefunc_def,
183 : voidpf filestream,
184 : int *pi));
185 :
186 2950 : local int unzlocal_getByte(const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, int *pi)
187 : {
188 : unsigned char c;
189 2950 : int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
190 2950 : if (err==1)
191 : {
192 2950 : *pi = (int)c;
193 2950 : return UNZ_OK;
194 : }
195 : else
196 : {
197 0 : if (ZERROR(*pzlib_filefunc_def,filestream))
198 0 : return UNZ_ERRNO;
199 : else
200 0 : return UNZ_EOF;
201 : }
202 : }
203 :
204 :
205 : /* ===========================================================================
206 : Reads a long in LSB order from the given gz_stream. Sets
207 : */
208 : local int unzlocal_getShort OF((
209 : const zlib_filefunc_def* pzlib_filefunc_def,
210 : voidpf filestream,
211 : uLong *pX));
212 :
213 689 : local int unzlocal_getShort (const zlib_filefunc_def* pzlib_filefunc_def,
214 : voidpf filestream,
215 : uLong *pX)
216 : {
217 : uLong x ;
218 : int i;
219 : int err;
220 :
221 689 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
222 689 : x = (uLong)i;
223 :
224 689 : if (err==UNZ_OK)
225 689 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
226 689 : x += ((uLong)i)<<8;
227 :
228 689 : if (err==UNZ_OK)
229 689 : *pX = x;
230 : else
231 0 : *pX = 0;
232 689 : return err;
233 : }
234 :
235 : local int unzlocal_getLong OF((
236 : const zlib_filefunc_def* pzlib_filefunc_def,
237 : voidpf filestream,
238 : uLong *pX));
239 :
240 393 : local int unzlocal_getLong (const zlib_filefunc_def* pzlib_filefunc_def,
241 : voidpf filestream,
242 : uLong *pX)
243 : {
244 : uLong x ;
245 : int i;
246 : int err;
247 :
248 393 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
249 393 : x = (uLong)i;
250 :
251 393 : if (err==UNZ_OK)
252 393 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
253 393 : x += ((uLong)i)<<8;
254 :
255 393 : if (err==UNZ_OK)
256 393 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
257 393 : x += ((uLong)i)<<16;
258 :
259 393 : if (err==UNZ_OK)
260 393 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
261 393 : x += ((uLong)i)<<24;
262 :
263 393 : if (err==UNZ_OK)
264 393 : *pX = x;
265 : else
266 0 : *pX = 0;
267 393 : return err;
268 : }
269 :
270 : local int unzlocal_getLong64 OF((
271 : const zlib_filefunc_def* pzlib_filefunc_def,
272 : voidpf filestream,
273 : uLong64 *pX));
274 :
275 :
276 0 : local int unzlocal_getLong64 (const zlib_filefunc_def* pzlib_filefunc_def,
277 : voidpf filestream,
278 : uLong64 *pX)
279 : {
280 : uLong64 x ;
281 : int i;
282 : int err;
283 :
284 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
285 0 : x = (uLong64)i;
286 :
287 0 : if (err==UNZ_OK)
288 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
289 0 : x += ((uLong64)i)<<8;
290 :
291 0 : if (err==UNZ_OK)
292 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
293 0 : x += ((uLong64)i)<<16;
294 :
295 0 : if (err==UNZ_OK)
296 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
297 0 : x += ((uLong64)i)<<24;
298 :
299 0 : if (err==UNZ_OK)
300 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
301 0 : x += ((uLong64)i)<<32;
302 :
303 0 : if (err==UNZ_OK)
304 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
305 0 : x += ((uLong64)i)<<40;
306 :
307 0 : if (err==UNZ_OK)
308 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
309 0 : x += ((uLong64)i)<<48;
310 :
311 0 : if (err==UNZ_OK)
312 0 : err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
313 0 : x += ((uLong64)i)<<56;
314 :
315 0 : if (err==UNZ_OK)
316 0 : *pX = x;
317 : else
318 0 : *pX = 0;
319 0 : return err;
320 : }
321 :
322 : /* My own strcmpi / strcasecmp */
323 0 : local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
324 : {
325 0 : for (;;)
326 : {
327 0 : char c1=*(fileName1++);
328 0 : char c2=*(fileName2++);
329 0 : if ((c1>='a') && (c1<='z'))
330 0 : c1 -= 0x20;
331 0 : if ((c2>='a') && (c2<='z'))
332 0 : c2 -= 0x20;
333 0 : if (c1=='\0')
334 0 : return ((c2=='\0') ? 0 : -1);
335 0 : if (c2=='\0')
336 0 : return 1;
337 0 : if (c1<c2)
338 0 : return -1;
339 0 : if (c1>c2)
340 0 : return 1;
341 : }
342 : }
343 :
344 :
345 : #ifdef CASESENSITIVITYDEFAULT_NO
346 : #define CASESENSITIVITYDEFAULTVALUE 2
347 : #else
348 : #define CASESENSITIVITYDEFAULTVALUE 1
349 : #endif
350 :
351 : #ifndef STRCMPCASENOSENTIVEFUNCTION
352 : #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
353 : #endif
354 :
355 : /*
356 : Compare two filename (fileName1,fileName2).
357 : If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
358 : If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
359 : or strcasecmp)
360 : If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
361 : (like 1 on Unix, 2 on Windows)
362 :
363 : */
364 0 : extern int ZEXPORT cpl_unzStringFileNameCompare (const char* fileName1,
365 : const char* fileName2,
366 : int iCaseSensitivity)
367 :
368 : {
369 0 : if (iCaseSensitivity==0)
370 0 : iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
371 :
372 0 : if (iCaseSensitivity==1)
373 0 : return strcmp(fileName1,fileName2);
374 :
375 0 : return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
376 : }
377 :
378 : #ifndef BUFREADCOMMENT
379 : #define BUFREADCOMMENT (0x400)
380 : #endif
381 :
382 : /*
383 : Locate the Central directory of a zipfile (at the end, just before
384 : the global comment)
385 : */
386 : local uLong64 unzlocal_SearchCentralDir OF((
387 : const zlib_filefunc_def* pzlib_filefunc_def,
388 : voidpf filestream));
389 :
390 19 : local uLong64 unzlocal_SearchCentralDir(const zlib_filefunc_def* pzlib_filefunc_def,
391 : voidpf filestream)
392 : {
393 : unsigned char* buf;
394 : uLong64 uSizeFile;
395 : uLong64 uBackRead;
396 19 : uLong64 uMaxBack=0xffff; /* maximum size of global comment */
397 19 : uLong64 uPosFound=0;
398 :
399 19 : if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
400 0 : return 0;
401 :
402 :
403 19 : uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
404 :
405 19 : if (uMaxBack>uSizeFile)
406 19 : uMaxBack = uSizeFile;
407 :
408 19 : buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
409 19 : if (buf==NULL)
410 0 : return 0;
411 :
412 19 : uBackRead = 4;
413 38 : while (uBackRead<uMaxBack)
414 : {
415 : uLong uReadSize;
416 : uLong64 uReadPos ;
417 : int i;
418 19 : if (uBackRead+BUFREADCOMMENT>uMaxBack)
419 19 : uBackRead = uMaxBack;
420 : else
421 0 : uBackRead+=BUFREADCOMMENT;
422 19 : uReadPos = uSizeFile-uBackRead ;
423 :
424 : uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
425 19 : (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
426 19 : if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
427 0 : break;
428 :
429 19 : if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
430 0 : break;
431 :
432 380 : for (i=(int)uReadSize-3; (i--)>0;)
433 361 : if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
434 : ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
435 : {
436 19 : uPosFound = uReadPos+i;
437 19 : break;
438 : }
439 :
440 19 : if (uPosFound!=0)
441 19 : break;
442 : }
443 19 : TRYFREE(buf);
444 19 : return uPosFound;
445 : }
446 :
447 :
448 : /*
449 : Locate the Central directory 64 of a zipfile (at the end, just before
450 : the global comment)
451 : */
452 : local uLong64 unzlocal_SearchCentralDir64 OF((
453 : const zlib_filefunc_def* pzlib_filefunc_def,
454 : voidpf filestream));
455 :
456 19 : local uLong64 unzlocal_SearchCentralDir64(const zlib_filefunc_def* pzlib_filefunc_def,
457 : voidpf filestream)
458 : {
459 : unsigned char* buf;
460 : uLong64 uSizeFile;
461 : uLong64 uBackRead;
462 19 : uLong64 uMaxBack=0xffff; /* maximum size of global comment */
463 19 : uLong64 uPosFound=0;
464 : uLong uL;
465 :
466 19 : if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
467 0 : return 0;
468 :
469 :
470 19 : uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
471 :
472 19 : if (uMaxBack>uSizeFile)
473 19 : uMaxBack = uSizeFile;
474 :
475 19 : buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
476 19 : if (buf==NULL)
477 0 : return 0;
478 :
479 19 : uBackRead = 4;
480 57 : while (uBackRead<uMaxBack)
481 : {
482 : uLong uReadSize;
483 : uLong64 uReadPos;
484 : int i;
485 19 : if (uBackRead+BUFREADCOMMENT>uMaxBack)
486 19 : uBackRead = uMaxBack;
487 : else
488 0 : uBackRead+=BUFREADCOMMENT;
489 19 : uReadPos = uSizeFile-uBackRead ;
490 :
491 : uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
492 19 : (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
493 19 : if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
494 0 : break;
495 :
496 19 : if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
497 0 : break;
498 :
499 10906 : for (i=(int)uReadSize-3; (i--)>0;)
500 10868 : if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
501 : ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
502 : {
503 0 : uPosFound = uReadPos+i;
504 0 : break;
505 : }
506 :
507 19 : if (uPosFound!=0)
508 0 : break;
509 : }
510 19 : TRYFREE(buf);
511 19 : if (uPosFound == 0)
512 19 : return 0;
513 :
514 : /* Zip64 end of central directory locator */
515 0 : if (ZSEEK(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
516 0 : return 0;
517 :
518 : /* the signature, already checked */
519 0 : if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
520 0 : return 0;
521 :
522 : /* number of the disk with the start of the zip64 end of central directory */
523 0 : if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
524 0 : return 0;
525 0 : if (uL != 0)
526 0 : return 0;
527 :
528 : /* relative offset of the zip64 end of central directory record */
529 : uLong64 relativeOffset;
530 0 : if (unzlocal_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
531 0 : return 0;
532 :
533 : /* total number of disks */
534 0 : if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
535 0 : return 0;
536 0 : if (uL != 1)
537 0 : return 0;
538 :
539 : /* Goto end of central directory record */
540 0 : if (ZSEEK(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
541 0 : return 0;
542 :
543 : /* the signature */
544 0 : if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
545 0 : return 0;
546 :
547 0 : if (uL != 0x06064b50)
548 0 : return 0;
549 :
550 0 : return relativeOffset;
551 : }
552 :
553 : /*
554 : Open a Zip file. path contain the full pathname (by example,
555 : on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
556 : "zlib/zlib114.zip".
557 : If the zipfile cannot be opened (file doesn't exist or in not valid), the
558 : return value is NULL.
559 : Else, the return value is a unzFile Handle, usable with other function
560 : of this unzip package.
561 : */
562 19 : extern unzFile ZEXPORT cpl_unzOpen2 (const char *path,
563 : zlib_filefunc_def* pzlib_filefunc_def)
564 : {
565 : unz_s us;
566 : unz_s *s;
567 : uLong64 central_pos;
568 : uLong uL;
569 :
570 : uLong number_disk; /* number of the current dist, used for
571 : spaning ZIP, unsupported, always 0*/
572 : uLong number_disk_with_CD; /* number the the disk with central dir, used
573 : for spaning ZIP, unsupported, always 0*/
574 : uLong64 number_entry_CD; /* total number of entries in
575 : the central dir
576 : (same than number_entry on nospan) */
577 :
578 19 : int err=UNZ_OK;
579 :
580 19 : if (unz_copyright[0]!=' ')
581 0 : return NULL;
582 :
583 19 : if (pzlib_filefunc_def==NULL)
584 19 : cpl_fill_fopen_filefunc(&us.z_filefunc);
585 : else
586 0 : us.z_filefunc = *pzlib_filefunc_def;
587 :
588 : us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
589 : path,
590 : ZLIB_FILEFUNC_MODE_READ |
591 19 : ZLIB_FILEFUNC_MODE_EXISTING);
592 19 : if (us.filestream==NULL)
593 0 : return NULL;
594 :
595 19 : central_pos = unzlocal_SearchCentralDir64(&us.z_filefunc,us.filestream);
596 19 : if (central_pos)
597 : {
598 : uLong uS;
599 : uLong64 uL64;
600 :
601 0 : us.isZip64 = 1;
602 :
603 : //printf("ZIP64 file !\n");
604 :
605 0 : if (ZSEEK(us.z_filefunc, us.filestream,
606 : central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
607 0 : err=UNZ_ERRNO;
608 :
609 : /* the signature, already checked */
610 0 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
611 0 : err=UNZ_ERRNO;
612 :
613 : /* size of zip64 end of central directory record */
614 0 : if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
615 0 : err=UNZ_ERRNO;
616 :
617 : /* version made by */
618 0 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
619 0 : err=UNZ_ERRNO;
620 :
621 : /* version needed to extract */
622 0 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
623 0 : err=UNZ_ERRNO;
624 :
625 : /* number of this disk */
626 0 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
627 0 : err=UNZ_ERRNO;
628 :
629 : /* number of the disk with the start of the central directory */
630 0 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
631 0 : err=UNZ_ERRNO;
632 :
633 : /* total number of entries in the central directory on this disk */
634 0 : if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
635 0 : err=UNZ_ERRNO;
636 :
637 : /* total number of entries in the central directory */
638 0 : if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
639 0 : err=UNZ_ERRNO;
640 :
641 0 : if ((number_entry_CD!=us.gi.number_entry) ||
642 : (number_disk_with_CD!=0) ||
643 : (number_disk!=0))
644 0 : err=UNZ_BADZIPFILE;
645 :
646 : /* size of the central directory */
647 0 : if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
648 0 : err=UNZ_ERRNO;
649 :
650 : /* offset of start of central directory with respect to the
651 : starting disk number */
652 0 : if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
653 0 : err=UNZ_ERRNO;
654 :
655 0 : us.gi.size_comment = 0;
656 : }
657 : else
658 : {
659 19 : central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
660 19 : if (central_pos==0)
661 0 : err=UNZ_ERRNO;
662 :
663 19 : us.isZip64 = 0;
664 :
665 19 : if (ZSEEK(us.z_filefunc, us.filestream,
666 : central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
667 0 : err=UNZ_ERRNO;
668 :
669 : /* the signature, already checked */
670 19 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
671 0 : err=UNZ_ERRNO;
672 :
673 : /* number of this disk */
674 19 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
675 0 : err=UNZ_ERRNO;
676 :
677 : /* number of the disk with the start of the central directory */
678 19 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
679 0 : err=UNZ_ERRNO;
680 :
681 : /* total number of entries in the central dir on this disk */
682 19 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
683 0 : err=UNZ_ERRNO;
684 19 : us.gi.number_entry = uL;
685 :
686 : /* total number of entries in the central dir */
687 19 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
688 0 : err=UNZ_ERRNO;
689 19 : number_entry_CD = uL;
690 :
691 19 : if ((number_entry_CD!=us.gi.number_entry) ||
692 : (number_disk_with_CD!=0) ||
693 : (number_disk!=0))
694 0 : err=UNZ_BADZIPFILE;
695 :
696 : /* size of the central directory */
697 19 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
698 0 : err=UNZ_ERRNO;
699 19 : us.size_central_dir = uL;
700 :
701 : /* offset of start of central directory with respect to the
702 : starting disk number */
703 19 : if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
704 0 : err=UNZ_ERRNO;
705 19 : us.offset_central_dir = uL;
706 :
707 : /* zipfile comment length */
708 19 : if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
709 0 : err=UNZ_ERRNO;
710 : }
711 :
712 19 : if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
713 : (err==UNZ_OK))
714 0 : err=UNZ_BADZIPFILE;
715 :
716 19 : if (err!=UNZ_OK)
717 : {
718 0 : ZCLOSE(us.z_filefunc, us.filestream);
719 0 : return NULL;
720 : }
721 :
722 : us.byte_before_the_zipfile = central_pos -
723 19 : (us.offset_central_dir+us.size_central_dir);
724 19 : us.central_pos = central_pos;
725 19 : us.pfile_in_zip_read = NULL;
726 19 : us.encrypted = 0;
727 :
728 :
729 19 : s=(unz_s*)ALLOC(sizeof(unz_s));
730 19 : *s=us;
731 19 : cpl_unzGoToFirstFile((unzFile)s);
732 19 : return (unzFile)s;
733 : }
734 :
735 :
736 19 : extern unzFile ZEXPORT cpl_unzOpen (const char *path)
737 : {
738 19 : return cpl_unzOpen2(path, NULL);
739 : }
740 :
741 : /*
742 : Close a ZipFile opened with unzipOpen.
743 : If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
744 : these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
745 : return UNZ_OK if there is no problem. */
746 19 : extern int ZEXPORT cpl_unzClose (unzFile file)
747 : {
748 : unz_s* s;
749 19 : if (file==NULL)
750 0 : return UNZ_PARAMERROR;
751 19 : s=(unz_s*)file;
752 :
753 19 : if (s->pfile_in_zip_read!=NULL)
754 0 : cpl_unzCloseCurrentFile(file);
755 :
756 19 : ZCLOSE(s->z_filefunc, s->filestream);
757 19 : TRYFREE(s);
758 19 : return UNZ_OK;
759 : }
760 :
761 :
762 : /*
763 : Write info about the ZipFile in the *pglobal_info structure.
764 : No preparation of the structure is needed
765 : return UNZ_OK if there is no problem. */
766 0 : extern int ZEXPORT cpl_unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info)
767 : {
768 : unz_s* s;
769 0 : if (file==NULL)
770 0 : return UNZ_PARAMERROR;
771 0 : s=(unz_s*)file;
772 0 : *pglobal_info=s->gi;
773 0 : return UNZ_OK;
774 : }
775 :
776 :
777 : /*
778 : Translate date/time from Dos format to tm_unz (readable more easilty)
779 : */
780 43 : local void unzlocal_DosDateToTmuDate (uLong64 ulDosDate, tm_unz* ptm)
781 : {
782 : uLong64 uDate;
783 43 : uDate = (uLong64)(ulDosDate>>16);
784 43 : ptm->tm_mday = (uInt)(uDate&0x1f) ;
785 43 : ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
786 43 : ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
787 :
788 43 : ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
789 43 : ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
790 43 : ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
791 43 : }
792 :
793 : /*
794 : Get Info about the current file in the zipfile, with internal only info
795 : */
796 : local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
797 : unz_file_info *pfile_info,
798 : unz_file_info_internal
799 : *pfile_info_internal,
800 : char *szFileName,
801 : uLong fileNameBufferSize,
802 : void *extraField,
803 : uLong extraFieldBufferSize,
804 : char *szComment,
805 : uLong commentBufferSize));
806 :
807 43 : local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
808 : unz_file_info *pfile_info,
809 : unz_file_info_internal
810 : *pfile_info_internal,
811 : char *szFileName,
812 : uLong fileNameBufferSize,
813 : void *extraField,
814 : uLong extraFieldBufferSize,
815 : char *szComment,
816 : uLong commentBufferSize)
817 : {
818 : unz_s* s;
819 : unz_file_info file_info;
820 : unz_file_info_internal file_info_internal;
821 43 : int err=UNZ_OK;
822 : uLong uMagic;
823 43 : long lSeek=0;
824 : uLong uL;
825 :
826 43 : if (file==NULL)
827 0 : return UNZ_PARAMERROR;
828 43 : s=(unz_s*)file;
829 43 : if (ZSEEK(s->z_filefunc, s->filestream,
830 : s->pos_in_central_dir+s->byte_before_the_zipfile,
831 : ZLIB_FILEFUNC_SEEK_SET)!=0)
832 0 : err=UNZ_ERRNO;
833 :
834 :
835 : /* we check the magic */
836 43 : if (err==UNZ_OK)
837 : {
838 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
839 0 : err=UNZ_ERRNO;
840 43 : else if (uMagic!=0x02014b50)
841 0 : err=UNZ_BADZIPFILE;
842 : }
843 :
844 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
845 0 : err=UNZ_ERRNO;
846 :
847 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
848 0 : err=UNZ_ERRNO;
849 :
850 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
851 0 : err=UNZ_ERRNO;
852 :
853 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
854 0 : err=UNZ_ERRNO;
855 :
856 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
857 0 : err=UNZ_ERRNO;
858 :
859 43 : unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
860 :
861 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
862 0 : err=UNZ_ERRNO;
863 :
864 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
865 0 : err=UNZ_ERRNO;
866 43 : file_info.compressed_size = uL;
867 :
868 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
869 0 : err=UNZ_ERRNO;
870 43 : file_info.uncompressed_size = uL;
871 :
872 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
873 0 : err=UNZ_ERRNO;
874 :
875 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
876 0 : err=UNZ_ERRNO;
877 :
878 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
879 0 : err=UNZ_ERRNO;
880 :
881 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
882 0 : err=UNZ_ERRNO;
883 :
884 43 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
885 0 : err=UNZ_ERRNO;
886 :
887 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
888 0 : err=UNZ_ERRNO;
889 :
890 43 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
891 0 : err=UNZ_ERRNO;
892 43 : file_info_internal.offset_curfile = uL;
893 :
894 43 : lSeek+=file_info.size_filename;
895 43 : if ((err==UNZ_OK) && (szFileName!=NULL))
896 : {
897 : uLong uSizeRead ;
898 5 : if (file_info.size_filename<fileNameBufferSize)
899 : {
900 5 : *(szFileName+file_info.size_filename)='\0';
901 5 : uSizeRead = file_info.size_filename;
902 : }
903 : else
904 0 : uSizeRead = fileNameBufferSize;
905 :
906 5 : if ((file_info.size_filename>0) && (fileNameBufferSize>0))
907 5 : if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
908 0 : err=UNZ_ERRNO;
909 5 : lSeek -= uSizeRead;
910 : }
911 :
912 : #if 0
913 : if ((err==UNZ_OK) && (extraField!=NULL))
914 : {
915 : uLong64 uSizeRead ;
916 : if (file_info.size_file_extra<extraFieldBufferSize)
917 : uSizeRead = file_info.size_file_extra;
918 : else
919 : uSizeRead = extraFieldBufferSize;
920 :
921 : if (lSeek!=0)
922 : {
923 : if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
924 : lSeek=0;
925 : else
926 : err=UNZ_ERRNO;
927 : }
928 :
929 : if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
930 : if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
931 : err=UNZ_ERRNO;
932 : lSeek += file_info.size_file_extra - uSizeRead;
933 : }
934 : else
935 : lSeek+=file_info.size_file_extra;
936 : #endif
937 43 : if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
938 : {
939 43 : if (lSeek!=0)
940 : {
941 38 : if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
942 38 : lSeek=0;
943 : else
944 0 : err=UNZ_ERRNO;
945 : }
946 :
947 43 : uLong acc = 0;
948 172 : while(acc < file_info.size_file_extra)
949 : {
950 : uLong headerId;
951 86 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
952 0 : err=UNZ_ERRNO;
953 :
954 : uLong dataSize;
955 86 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
956 0 : err=UNZ_ERRNO;
957 :
958 : /* ZIP64 extra fields */
959 86 : if (headerId == 0x0001)
960 : {
961 0 : if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
962 0 : err=UNZ_ERRNO;
963 :
964 0 : if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
965 0 : err=UNZ_ERRNO;
966 :
967 : /* Relative Header offset */
968 : uLong64 u64;
969 0 : if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&u64) != UNZ_OK)
970 0 : err=UNZ_ERRNO;
971 :
972 : /* Disk Start Number */
973 : uLong uL;
974 0 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
975 0 : err=UNZ_ERRNO;
976 : }
977 : else
978 : {
979 86 : if (ZSEEK(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
980 0 : err=UNZ_ERRNO;
981 : }
982 :
983 86 : acc += 2 + 2 + dataSize;
984 : }
985 : }
986 :
987 : #if 0
988 : if ((err==UNZ_OK) && (szComment!=NULL))
989 : {
990 : uLong64 uSizeRead ;
991 : if (file_info.size_file_comment<commentBufferSize)
992 : {
993 : *(szComment+file_info.size_file_comment)='\0';
994 : uSizeRead = file_info.size_file_comment;
995 : }
996 : else
997 : uSizeRead = commentBufferSize;
998 :
999 : if (lSeek!=0)
1000 : {
1001 : if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1002 : lSeek=0;
1003 : else
1004 : err=UNZ_ERRNO;
1005 : }
1006 :
1007 : if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1008 : if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1009 : err=UNZ_ERRNO;
1010 : lSeek+=file_info.size_file_comment - uSizeRead;
1011 : }
1012 : else
1013 : lSeek+=file_info.size_file_comment;
1014 : #endif
1015 :
1016 43 : if ((err==UNZ_OK) && (pfile_info!=NULL))
1017 40 : *pfile_info=file_info;
1018 :
1019 43 : if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1020 31 : *pfile_info_internal=file_info_internal;
1021 :
1022 43 : return err;
1023 : }
1024 :
1025 :
1026 :
1027 : /*
1028 : Write info about the ZipFile in the *pglobal_info structure.
1029 : No preparation of the structure is needed
1030 : return UNZ_OK if there is no problem.
1031 : */
1032 12 : extern int ZEXPORT cpl_unzGetCurrentFileInfo (unzFile file,
1033 : unz_file_info * pfile_info,
1034 : char * szFileName, uLong fileNameBufferSize,
1035 : void *extraField, uLong extraFieldBufferSize,
1036 : char* szComment, uLong commentBufferSize)
1037 : {
1038 : return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1039 : szFileName,fileNameBufferSize,
1040 : extraField,extraFieldBufferSize,
1041 12 : szComment,commentBufferSize);
1042 : }
1043 :
1044 : /*
1045 : Set the current file of the zipfile to the first file.
1046 : return UNZ_OK if there is no problem
1047 : */
1048 27 : extern int ZEXPORT cpl_unzGoToFirstFile (unzFile file)
1049 : {
1050 27 : int err=UNZ_OK;
1051 : unz_s* s;
1052 27 : if (file==NULL)
1053 0 : return UNZ_PARAMERROR;
1054 27 : s=(unz_s*)file;
1055 27 : s->pos_in_central_dir=s->offset_central_dir;
1056 27 : s->num_file=0;
1057 : err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1058 : &s->cur_file_info_internal,
1059 27 : NULL,0,NULL,0,NULL,0);
1060 27 : s->current_file_ok = (err == UNZ_OK);
1061 27 : return err;
1062 : }
1063 :
1064 : /*
1065 : Set the current file of the zipfile to the next file.
1066 : return UNZ_OK if there is no problem
1067 : return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1068 : */
1069 5 : extern int ZEXPORT cpl_unzGoToNextFile (unzFile file)
1070 : {
1071 : unz_s* s;
1072 : int err;
1073 :
1074 5 : if (file==NULL)
1075 0 : return UNZ_PARAMERROR;
1076 5 : s=(unz_s*)file;
1077 5 : if (!s->current_file_ok)
1078 0 : return UNZ_END_OF_LIST_OF_FILE;
1079 5 : if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1080 5 : if (s->num_file+1==s->gi.number_entry)
1081 5 : return UNZ_END_OF_LIST_OF_FILE;
1082 :
1083 : s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1084 0 : s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1085 0 : s->num_file++;
1086 : err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1087 : &s->cur_file_info_internal,
1088 0 : NULL,0,NULL,0,NULL,0);
1089 0 : s->current_file_ok = (err == UNZ_OK);
1090 0 : return err;
1091 : }
1092 :
1093 :
1094 : /*
1095 : Try locate the file szFileName in the zipfile.
1096 : For the iCaseSensitivity signification, see unzipStringFileNameCompare
1097 :
1098 : return value :
1099 : UNZ_OK if the file is found. It becomes the current file.
1100 : UNZ_END_OF_LIST_OF_FILE if the file is not found
1101 : */
1102 0 : extern int ZEXPORT cpl_unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1103 : {
1104 : unz_s* s;
1105 : int err;
1106 :
1107 : /* We remember the 'current' position in the file so that we can jump
1108 : * back there if we fail.
1109 : */
1110 : unz_file_info cur_file_infoSaved;
1111 : unz_file_info_internal cur_file_info_internalSaved;
1112 : uLong64 num_fileSaved;
1113 : uLong64 pos_in_central_dirSaved;
1114 :
1115 :
1116 0 : if (file==NULL)
1117 0 : return UNZ_PARAMERROR;
1118 :
1119 0 : if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1120 0 : return UNZ_PARAMERROR;
1121 :
1122 0 : s=(unz_s*)file;
1123 0 : if (!s->current_file_ok)
1124 0 : return UNZ_END_OF_LIST_OF_FILE;
1125 :
1126 : /* Save the current state */
1127 0 : num_fileSaved = s->num_file;
1128 0 : pos_in_central_dirSaved = s->pos_in_central_dir;
1129 0 : cur_file_infoSaved = s->cur_file_info;
1130 0 : cur_file_info_internalSaved = s->cur_file_info_internal;
1131 :
1132 0 : err = cpl_unzGoToFirstFile(file);
1133 :
1134 0 : while (err == UNZ_OK)
1135 : {
1136 : char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1137 : err = cpl_unzGetCurrentFileInfo(file,NULL,
1138 : szCurrentFileName,sizeof(szCurrentFileName)-1,
1139 0 : NULL,0,NULL,0);
1140 0 : if (err == UNZ_OK)
1141 : {
1142 0 : if (cpl_unzStringFileNameCompare(szCurrentFileName,
1143 : szFileName,iCaseSensitivity)==0)
1144 0 : return UNZ_OK;
1145 0 : err = cpl_unzGoToNextFile(file);
1146 : }
1147 : }
1148 :
1149 : /* We failed, so restore the state of the 'current file' to where we
1150 : * were.
1151 : */
1152 0 : s->num_file = num_fileSaved ;
1153 0 : s->pos_in_central_dir = pos_in_central_dirSaved ;
1154 0 : s->cur_file_info = cur_file_infoSaved;
1155 0 : s->cur_file_info_internal = cur_file_info_internalSaved;
1156 0 : return err;
1157 : }
1158 :
1159 :
1160 : /*
1161 : ///////////////////////////////////////////
1162 : // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1163 : // I need random access
1164 : //
1165 : // Further optimization could be realized by adding an ability
1166 : // to cache the directory in memory. The goal being a single
1167 : // comprehensive file read to put the file I need in a memory.
1168 : */
1169 :
1170 : /*
1171 : typedef struct unz_file_pos_s
1172 : {
1173 : uLong64 pos_in_zip_directory; // offset in file
1174 : uLong64 num_of_file; // # of file
1175 : } unz_file_pos;
1176 : */
1177 :
1178 2 : extern int ZEXPORT cpl_unzGetFilePos(unzFile file, unz_file_pos* file_pos)
1179 : {
1180 : unz_s* s;
1181 :
1182 2 : if (file==NULL || file_pos==NULL)
1183 0 : return UNZ_PARAMERROR;
1184 2 : s=(unz_s*)file;
1185 2 : if (!s->current_file_ok)
1186 0 : return UNZ_END_OF_LIST_OF_FILE;
1187 :
1188 2 : file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1189 2 : file_pos->num_of_file = s->num_file;
1190 :
1191 2 : return UNZ_OK;
1192 : }
1193 :
1194 4 : extern int ZEXPORT cpl_unzGoToFilePos(unzFile file, unz_file_pos* file_pos)
1195 : {
1196 : unz_s* s;
1197 : int err;
1198 :
1199 4 : if (file==NULL || file_pos==NULL)
1200 0 : return UNZ_PARAMERROR;
1201 4 : s=(unz_s*)file;
1202 :
1203 : /* jump to the right spot */
1204 4 : s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1205 4 : s->num_file = file_pos->num_of_file;
1206 :
1207 : /* set the current file */
1208 : err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1209 : &s->cur_file_info_internal,
1210 4 : NULL,0,NULL,0,NULL,0);
1211 : /* return results */
1212 4 : s->current_file_ok = (err == UNZ_OK);
1213 4 : return err;
1214 : }
1215 :
1216 : /*
1217 : // Unzip Helper Functions - should be here?
1218 : ///////////////////////////////////////////
1219 : */
1220 :
1221 : /*
1222 : Read the local header of the current zipfile
1223 : Check the coherency of the local header and info in the end of central
1224 : directory about this file
1225 : store in *piSizeVar the size of extra info in local header
1226 : (filename and size of extra field data)
1227 : */
1228 7 : local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
1229 : uLong64 * poffset_local_extrafield,
1230 : uInt * psize_local_extrafield)
1231 : {
1232 : uLong uMagic,uData,uFlags;
1233 : uLong size_filename;
1234 : uLong size_extra_field;
1235 7 : int err=UNZ_OK;
1236 :
1237 7 : *piSizeVar = 0;
1238 7 : *poffset_local_extrafield = 0;
1239 7 : *psize_local_extrafield = 0;
1240 :
1241 7 : if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1242 : s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1243 0 : return UNZ_ERRNO;
1244 :
1245 :
1246 7 : if (err==UNZ_OK)
1247 : {
1248 7 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1249 0 : err=UNZ_ERRNO;
1250 7 : else if (uMagic!=0x04034b50)
1251 0 : err=UNZ_BADZIPFILE;
1252 : }
1253 :
1254 7 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1255 0 : err=UNZ_ERRNO;
1256 : /*
1257 : else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1258 : err=UNZ_BADZIPFILE;
1259 : */
1260 7 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1261 0 : err=UNZ_ERRNO;
1262 :
1263 7 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1264 0 : err=UNZ_ERRNO;
1265 7 : else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1266 0 : err=UNZ_BADZIPFILE;
1267 :
1268 7 : if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1269 : (s->cur_file_info.compression_method!=Z_DEFLATED))
1270 0 : err=UNZ_BADZIPFILE;
1271 :
1272 7 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1273 0 : err=UNZ_ERRNO;
1274 :
1275 7 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1276 0 : err=UNZ_ERRNO;
1277 7 : else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1278 : ((uFlags & 8)==0))
1279 0 : err=UNZ_BADZIPFILE;
1280 :
1281 7 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1282 0 : err=UNZ_ERRNO;
1283 7 : else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1284 : ((uFlags & 8)==0))
1285 0 : err=UNZ_BADZIPFILE;
1286 :
1287 7 : if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1288 0 : err=UNZ_ERRNO;
1289 7 : else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1290 : ((uFlags & 8)==0))
1291 0 : err=UNZ_BADZIPFILE;
1292 :
1293 :
1294 7 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1295 0 : err=UNZ_ERRNO;
1296 7 : else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1297 0 : err=UNZ_BADZIPFILE;
1298 :
1299 7 : *piSizeVar += (uInt)size_filename;
1300 :
1301 7 : if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1302 0 : err=UNZ_ERRNO;
1303 : *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1304 7 : SIZEZIPLOCALHEADER + size_filename;
1305 7 : *psize_local_extrafield = (uInt)size_extra_field;
1306 :
1307 7 : *piSizeVar += (uInt)size_extra_field;
1308 :
1309 7 : return err;
1310 : }
1311 :
1312 : /*
1313 : Open for reading data the current file in the zipfile.
1314 : If there is no error and the file is opened, the return value is UNZ_OK.
1315 : */
1316 7 : extern int ZEXPORT cpl_unzOpenCurrentFile3 (unzFile file, int* method,
1317 : int* level, int raw, const char* password)
1318 : {
1319 7 : int err=UNZ_OK;
1320 : uInt iSizeVar;
1321 : unz_s* s;
1322 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1323 : uLong64 offset_local_extrafield; /* offset of the local extra field */
1324 : uInt size_local_extrafield; /* size of the local extra field */
1325 : # ifndef NOUNCRYPT
1326 : char source[12];
1327 : # else
1328 7 : if (password != NULL)
1329 0 : return UNZ_PARAMERROR;
1330 : # endif
1331 :
1332 7 : if (file==NULL)
1333 0 : return UNZ_PARAMERROR;
1334 7 : s=(unz_s*)file;
1335 7 : if (!s->current_file_ok)
1336 0 : return UNZ_PARAMERROR;
1337 :
1338 7 : if (s->pfile_in_zip_read != NULL)
1339 0 : cpl_unzCloseCurrentFile(file);
1340 :
1341 7 : if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1342 : &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1343 0 : return UNZ_BADZIPFILE;
1344 :
1345 : pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1346 7 : ALLOC(sizeof(file_in_zip_read_info_s));
1347 7 : if (pfile_in_zip_read_info==NULL)
1348 0 : return UNZ_INTERNALERROR;
1349 :
1350 7 : pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1351 7 : pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1352 7 : pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1353 7 : pfile_in_zip_read_info->pos_local_extrafield=0;
1354 7 : pfile_in_zip_read_info->raw=raw;
1355 :
1356 7 : if (pfile_in_zip_read_info->read_buffer==NULL)
1357 : {
1358 0 : TRYFREE(pfile_in_zip_read_info);
1359 0 : return UNZ_INTERNALERROR;
1360 : }
1361 :
1362 7 : pfile_in_zip_read_info->stream_initialised=0;
1363 :
1364 7 : if (method!=NULL)
1365 0 : *method = (int)s->cur_file_info.compression_method;
1366 :
1367 7 : if (level!=NULL)
1368 : {
1369 0 : *level = 6;
1370 0 : switch (s->cur_file_info.flag & 0x06)
1371 : {
1372 0 : case 6 : *level = 1; break;
1373 0 : case 4 : *level = 2; break;
1374 0 : case 2 : *level = 9; break;
1375 : }
1376 : }
1377 :
1378 7 : if ((s->cur_file_info.compression_method!=0) &&
1379 : (s->cur_file_info.compression_method!=Z_DEFLATED))
1380 0 : err=UNZ_BADZIPFILE;
1381 :
1382 7 : pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1383 7 : pfile_in_zip_read_info->crc32=0;
1384 : pfile_in_zip_read_info->compression_method =
1385 7 : s->cur_file_info.compression_method;
1386 7 : pfile_in_zip_read_info->filestream=s->filestream;
1387 7 : pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1388 7 : pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1389 :
1390 7 : pfile_in_zip_read_info->stream.total_out = 0;
1391 :
1392 7 : if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1393 : (!raw))
1394 : {
1395 7 : pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1396 7 : pfile_in_zip_read_info->stream.zfree = (free_func)0;
1397 7 : pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1398 7 : pfile_in_zip_read_info->stream.next_in = 0;
1399 7 : pfile_in_zip_read_info->stream.avail_in = 0;
1400 :
1401 7 : err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1402 7 : if (err == Z_OK)
1403 7 : pfile_in_zip_read_info->stream_initialised=1;
1404 : else
1405 : {
1406 0 : TRYFREE(pfile_in_zip_read_info);
1407 0 : return err;
1408 : }
1409 : /* windowBits is passed < 0 to tell that there is no zlib header.
1410 : * Note that in this case inflate *requires* an extra "dummy" byte
1411 : * after the compressed stream in order to complete decompression and
1412 : * return Z_STREAM_END.
1413 : * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1414 : * size of both compressed and uncompressed data
1415 : */
1416 : }
1417 : pfile_in_zip_read_info->rest_read_compressed =
1418 7 : s->cur_file_info.compressed_size ;
1419 : pfile_in_zip_read_info->rest_read_uncompressed =
1420 7 : s->cur_file_info.uncompressed_size ;
1421 :
1422 :
1423 : pfile_in_zip_read_info->pos_in_zipfile =
1424 : s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1425 7 : iSizeVar;
1426 :
1427 7 : pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1428 :
1429 7 : s->pfile_in_zip_read = pfile_in_zip_read_info;
1430 :
1431 : # ifndef NOUNCRYPT
1432 : if (password != NULL)
1433 : {
1434 : int i;
1435 : s->pcrc_32_tab = get_crc_table();
1436 : init_keys(password,s->keys,s->pcrc_32_tab);
1437 : if (ZSEEK(s->z_filefunc, s->filestream,
1438 : s->pfile_in_zip_read->pos_in_zipfile +
1439 : s->pfile_in_zip_read->byte_before_the_zipfile,
1440 : SEEK_SET)!=0)
1441 : return UNZ_INTERNALERROR;
1442 : if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1443 : return UNZ_INTERNALERROR;
1444 :
1445 : for (i = 0; i<12; i++)
1446 : zdecode(s->keys,s->pcrc_32_tab,source[i]);
1447 :
1448 : s->pfile_in_zip_read->pos_in_zipfile+=12;
1449 : s->encrypted=1;
1450 : }
1451 : # endif
1452 :
1453 :
1454 7 : return UNZ_OK;
1455 : }
1456 :
1457 7 : extern int ZEXPORT cpl_unzOpenCurrentFile (unzFile file)
1458 : {
1459 7 : return cpl_unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1460 : }
1461 :
1462 0 : extern int ZEXPORT cpl_unzOpenCurrentFilePassword (unzFile file, const char* password)
1463 : {
1464 0 : return cpl_unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1465 : }
1466 :
1467 0 : extern int ZEXPORT cpl_unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1468 : {
1469 0 : return cpl_unzOpenCurrentFile3(file, method, level, raw, NULL);
1470 : }
1471 :
1472 : /** Addition for GDAL : START */
1473 :
1474 6 : extern uLong64 ZEXPORT cpl_unzGetCurrentFileZStreamPos( unzFile file)
1475 : {
1476 : unz_s* s;
1477 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1478 6 : s=(unz_s*)file;
1479 6 : if (file==NULL)
1480 0 : return 0; //UNZ_PARAMERROR;
1481 6 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1482 6 : if (pfile_in_zip_read_info==NULL)
1483 0 : return 0; //UNZ_PARAMERROR;
1484 : return pfile_in_zip_read_info->pos_in_zipfile +
1485 6 : pfile_in_zip_read_info->byte_before_the_zipfile;
1486 : }
1487 :
1488 : /** Addition for GDAL : END */
1489 :
1490 : /*
1491 : Read bytes from the current file.
1492 : buf contain buffer where data must be copied
1493 : len the size of buf.
1494 :
1495 : return the number of byte copied if somes bytes are copied
1496 : return 0 if the end of file was reached
1497 : return <0 with error code if there is an error
1498 : (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1499 : */
1500 0 : extern int ZEXPORT cpl_unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1501 : {
1502 0 : int err=UNZ_OK;
1503 0 : uInt iRead = 0;
1504 : unz_s* s;
1505 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1506 0 : if (file==NULL)
1507 0 : return UNZ_PARAMERROR;
1508 0 : s=(unz_s*)file;
1509 0 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1510 :
1511 0 : if (pfile_in_zip_read_info==NULL)
1512 0 : return UNZ_PARAMERROR;
1513 :
1514 :
1515 0 : if ((pfile_in_zip_read_info->read_buffer == NULL))
1516 0 : return UNZ_END_OF_LIST_OF_FILE;
1517 0 : if (len==0)
1518 0 : return 0;
1519 :
1520 0 : pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1521 :
1522 0 : pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1523 :
1524 0 : if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1525 : (!(pfile_in_zip_read_info->raw)))
1526 : pfile_in_zip_read_info->stream.avail_out =
1527 0 : (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1528 :
1529 0 : if ((len>pfile_in_zip_read_info->rest_read_compressed+
1530 : pfile_in_zip_read_info->stream.avail_in) &&
1531 : (pfile_in_zip_read_info->raw))
1532 : pfile_in_zip_read_info->stream.avail_out =
1533 : (uInt)pfile_in_zip_read_info->rest_read_compressed+
1534 0 : pfile_in_zip_read_info->stream.avail_in;
1535 :
1536 0 : while (pfile_in_zip_read_info->stream.avail_out>0)
1537 : {
1538 0 : if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1539 : (pfile_in_zip_read_info->rest_read_compressed>0))
1540 : {
1541 0 : uInt uReadThis = UNZ_BUFSIZE;
1542 0 : if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1543 0 : uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1544 0 : if (uReadThis == 0)
1545 0 : return UNZ_EOF;
1546 0 : if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1547 : pfile_in_zip_read_info->filestream,
1548 : pfile_in_zip_read_info->pos_in_zipfile +
1549 : pfile_in_zip_read_info->byte_before_the_zipfile,
1550 : ZLIB_FILEFUNC_SEEK_SET)!=0)
1551 0 : return UNZ_ERRNO;
1552 0 : if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1553 : pfile_in_zip_read_info->filestream,
1554 : pfile_in_zip_read_info->read_buffer,
1555 : uReadThis)!=uReadThis)
1556 0 : return UNZ_ERRNO;
1557 :
1558 :
1559 : # ifndef NOUNCRYPT
1560 : if(s->encrypted)
1561 : {
1562 : uInt i;
1563 : for(i=0;i<uReadThis;i++)
1564 : pfile_in_zip_read_info->read_buffer[i] =
1565 : zdecode(s->keys,s->pcrc_32_tab,
1566 : pfile_in_zip_read_info->read_buffer[i]);
1567 : }
1568 : # endif
1569 :
1570 :
1571 0 : pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1572 :
1573 0 : pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1574 :
1575 : pfile_in_zip_read_info->stream.next_in =
1576 0 : (Bytef*)pfile_in_zip_read_info->read_buffer;
1577 0 : pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1578 : }
1579 :
1580 0 : if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1581 : {
1582 : uInt uDoCopy,i ;
1583 :
1584 0 : if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1585 : (pfile_in_zip_read_info->rest_read_compressed == 0))
1586 0 : return (iRead==0) ? UNZ_EOF : iRead;
1587 :
1588 0 : if (pfile_in_zip_read_info->stream.avail_out <
1589 : pfile_in_zip_read_info->stream.avail_in)
1590 0 : uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1591 : else
1592 0 : uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1593 :
1594 0 : for (i=0;i<uDoCopy;i++)
1595 : *(pfile_in_zip_read_info->stream.next_out+i) =
1596 0 : *(pfile_in_zip_read_info->stream.next_in+i);
1597 :
1598 : pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1599 : pfile_in_zip_read_info->stream.next_out,
1600 0 : uDoCopy);
1601 0 : pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1602 0 : pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1603 0 : pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1604 0 : pfile_in_zip_read_info->stream.next_out += uDoCopy;
1605 0 : pfile_in_zip_read_info->stream.next_in += uDoCopy;
1606 0 : pfile_in_zip_read_info->stream.total_out += uDoCopy;
1607 0 : iRead += uDoCopy;
1608 : }
1609 : else
1610 : {
1611 : uLong64 uTotalOutBefore,uTotalOutAfter;
1612 : const Bytef *bufBefore;
1613 : uLong64 uOutThis;
1614 0 : int flush=Z_SYNC_FLUSH;
1615 :
1616 0 : uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1617 0 : bufBefore = pfile_in_zip_read_info->stream.next_out;
1618 :
1619 : /*
1620 : if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1621 : pfile_in_zip_read_info->stream.avail_out) &&
1622 : (pfile_in_zip_read_info->rest_read_compressed == 0))
1623 : flush = Z_FINISH;
1624 : */
1625 0 : err=inflate(&pfile_in_zip_read_info->stream,flush);
1626 :
1627 0 : if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1628 0 : err = Z_DATA_ERROR;
1629 :
1630 0 : uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1631 0 : uOutThis = uTotalOutAfter-uTotalOutBefore;
1632 :
1633 : pfile_in_zip_read_info->crc32 =
1634 : crc32(pfile_in_zip_read_info->crc32,bufBefore,
1635 0 : (uInt)(uOutThis));
1636 :
1637 : pfile_in_zip_read_info->rest_read_uncompressed -=
1638 0 : uOutThis;
1639 :
1640 0 : iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1641 :
1642 0 : if (err==Z_STREAM_END)
1643 0 : return (iRead==0) ? UNZ_EOF : iRead;
1644 0 : if (err!=Z_OK)
1645 0 : break;
1646 : }
1647 : }
1648 :
1649 0 : if (err==Z_OK)
1650 0 : return iRead;
1651 0 : return err;
1652 : }
1653 :
1654 :
1655 : /*
1656 : Give the current position in uncompressed data
1657 : */
1658 0 : extern z_off_t ZEXPORT cpl_unztell (unzFile file)
1659 : {
1660 : unz_s* s;
1661 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1662 0 : if (file==NULL)
1663 0 : return UNZ_PARAMERROR;
1664 0 : s=(unz_s*)file;
1665 0 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1666 :
1667 0 : if (pfile_in_zip_read_info==NULL)
1668 0 : return UNZ_PARAMERROR;
1669 :
1670 0 : return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1671 : }
1672 :
1673 :
1674 : /*
1675 : return 1 if the end of file was reached, 0 elsewhere
1676 : */
1677 0 : extern int ZEXPORT cpl_unzeof (unzFile file)
1678 : {
1679 : unz_s* s;
1680 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1681 0 : if (file==NULL)
1682 0 : return UNZ_PARAMERROR;
1683 0 : s=(unz_s*)file;
1684 0 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1685 :
1686 0 : if (pfile_in_zip_read_info==NULL)
1687 0 : return UNZ_PARAMERROR;
1688 :
1689 0 : if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1690 0 : return 1;
1691 : else
1692 0 : return 0;
1693 : }
1694 :
1695 :
1696 :
1697 : /*
1698 : Read extra field from the current file (opened by unzOpenCurrentFile)
1699 : This is the local-header version of the extra field (sometimes, there is
1700 : more info in the local-header version than in the central-header)
1701 :
1702 : if buf==NULL, it return the size of the local extra field that can be read
1703 :
1704 : if buf!=NULL, len is the size of the buffer, the extra header is copied in
1705 : buf.
1706 : the return value is the number of bytes copied in buf, or (if <0)
1707 : the error code
1708 : */
1709 0 : extern int ZEXPORT cpl_unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1710 : {
1711 : unz_s* s;
1712 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1713 : uInt read_now;
1714 : uLong64 size_to_read;
1715 :
1716 0 : if (file==NULL)
1717 0 : return UNZ_PARAMERROR;
1718 0 : s=(unz_s*)file;
1719 0 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1720 :
1721 0 : if (pfile_in_zip_read_info==NULL)
1722 0 : return UNZ_PARAMERROR;
1723 :
1724 : size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1725 0 : pfile_in_zip_read_info->pos_local_extrafield);
1726 :
1727 0 : if (buf==NULL)
1728 0 : return (int)size_to_read;
1729 :
1730 0 : if (len>size_to_read)
1731 0 : read_now = (uInt)size_to_read;
1732 : else
1733 0 : read_now = (uInt)len ;
1734 :
1735 0 : if (read_now==0)
1736 0 : return 0;
1737 :
1738 0 : if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1739 : pfile_in_zip_read_info->filestream,
1740 : pfile_in_zip_read_info->offset_local_extrafield +
1741 : pfile_in_zip_read_info->pos_local_extrafield,
1742 : ZLIB_FILEFUNC_SEEK_SET)!=0)
1743 0 : return UNZ_ERRNO;
1744 :
1745 0 : if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1746 : pfile_in_zip_read_info->filestream,
1747 : buf,read_now)!=read_now)
1748 0 : return UNZ_ERRNO;
1749 :
1750 0 : return (int)read_now;
1751 : }
1752 :
1753 : /*
1754 : Close the file in zip opened with unzipOpenCurrentFile
1755 : Return UNZ_CRCERROR if all the file was read but the CRC is not good
1756 : */
1757 7 : extern int ZEXPORT cpl_unzCloseCurrentFile (unzFile file)
1758 : {
1759 7 : int err=UNZ_OK;
1760 :
1761 : unz_s* s;
1762 : file_in_zip_read_info_s* pfile_in_zip_read_info;
1763 7 : if (file==NULL)
1764 0 : return UNZ_PARAMERROR;
1765 7 : s=(unz_s*)file;
1766 7 : pfile_in_zip_read_info=s->pfile_in_zip_read;
1767 :
1768 7 : if (pfile_in_zip_read_info==NULL)
1769 0 : return UNZ_PARAMERROR;
1770 :
1771 :
1772 7 : if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1773 : (!pfile_in_zip_read_info->raw))
1774 : {
1775 0 : if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1776 0 : err=UNZ_CRCERROR;
1777 : }
1778 :
1779 :
1780 7 : TRYFREE(pfile_in_zip_read_info->read_buffer);
1781 7 : pfile_in_zip_read_info->read_buffer = NULL;
1782 7 : if (pfile_in_zip_read_info->stream_initialised)
1783 7 : inflateEnd(&pfile_in_zip_read_info->stream);
1784 :
1785 7 : pfile_in_zip_read_info->stream_initialised = 0;
1786 7 : TRYFREE(pfile_in_zip_read_info);
1787 :
1788 7 : s->pfile_in_zip_read=NULL;
1789 :
1790 7 : return err;
1791 : }
1792 :
1793 :
1794 : /*
1795 : Get the global comment string of the ZipFile, in the szComment buffer.
1796 : uSizeBuf is the size of the szComment buffer.
1797 : return the number of byte copied or an error code <0
1798 : */
1799 0 : extern int ZEXPORT cpl_unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
1800 : {
1801 : /* int err=UNZ_OK; */
1802 : unz_s* s;
1803 : uLong uReadThis ;
1804 0 : if (file==NULL)
1805 0 : return UNZ_PARAMERROR;
1806 0 : s=(unz_s*)file;
1807 :
1808 0 : uReadThis = uSizeBuf;
1809 0 : if (uReadThis>s->gi.size_comment)
1810 0 : uReadThis = s->gi.size_comment;
1811 :
1812 0 : if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1813 0 : return UNZ_ERRNO;
1814 :
1815 0 : if (uReadThis>0)
1816 : {
1817 0 : *szComment='\0';
1818 0 : if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1819 0 : return UNZ_ERRNO;
1820 : }
1821 :
1822 0 : if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1823 0 : *(szComment+s->gi.size_comment)='\0';
1824 0 : return (int)uReadThis;
1825 : }
1826 :
1827 : /* Additions by RX '2004 */
1828 0 : extern uLong64 ZEXPORT cpl_unzGetOffset (unzFile file)
1829 : {
1830 : unz_s* s;
1831 :
1832 0 : if (file==NULL)
1833 0 : return 0; //UNZ_PARAMERROR;
1834 0 : s=(unz_s*)file;
1835 0 : if (!s->current_file_ok)
1836 0 : return 0;
1837 0 : if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1838 0 : if (s->num_file==s->gi.number_entry)
1839 0 : return 0;
1840 0 : return s->pos_in_central_dir;
1841 : }
1842 :
1843 0 : extern int ZEXPORT cpl_unzSetOffset (unzFile file, uLong64 pos)
1844 : {
1845 : unz_s* s;
1846 : int err;
1847 :
1848 0 : if (file==NULL)
1849 0 : return UNZ_PARAMERROR;
1850 0 : s=(unz_s*)file;
1851 :
1852 0 : s->pos_in_central_dir = pos;
1853 0 : s->num_file = s->gi.number_entry; /* hack */
1854 : err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1855 : &s->cur_file_info_internal,
1856 0 : NULL,0,NULL,0,NULL,0);
1857 0 : s->current_file_ok = (err == UNZ_OK);
1858 0 : return err;
1859 : }
1860 :
|