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 <plugin/z/lib/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
unzlocal_getByte(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream,int * pi)186 local int unzlocal_getByte(const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, int *pi)
187 {
188 unsigned char c;
189 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
190 if (err==1)
191 {
192 *pi = (int)c;
193 return UNZ_OK;
194 }
195 else
196 {
197 if (ZERROR(*pzlib_filefunc_def,filestream))
198 return UNZ_ERRNO;
199 else
200 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
unzlocal_getShort(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)213 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 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
222 x = (uLong)i;
223
224 if (err==UNZ_OK)
225 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
226 x += ((uLong)i)<<8;
227
228 if (err==UNZ_OK)
229 *pX = x;
230 else
231 *pX = 0;
232 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
unzlocal_getLong(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)240 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 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
249 x = (uLong)i;
250
251 if (err==UNZ_OK)
252 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
253 x += ((uLong)i)<<8;
254
255 if (err==UNZ_OK)
256 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
257 x += ((uLong)i)<<16;
258
259 if (err==UNZ_OK)
260 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
261 x += ((uLong)i)<<24;
262
263 if (err==UNZ_OK)
264 *pX = x;
265 else
266 *pX = 0;
267 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
unzlocal_getLong64(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream,uLong64 * pX)276 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 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
285 x = (uLong64)i;
286
287 if (err==UNZ_OK)
288 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
289 x += ((uLong64)i)<<8;
290
291 if (err==UNZ_OK)
292 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
293 x += ((uLong64)i)<<16;
294
295 if (err==UNZ_OK)
296 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
297 x += ((uLong64)i)<<24;
298
299 if (err==UNZ_OK)
300 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
301 x += ((uLong64)i)<<32;
302
303 if (err==UNZ_OK)
304 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
305 x += ((uLong64)i)<<40;
306
307 if (err==UNZ_OK)
308 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
309 x += ((uLong64)i)<<48;
310
311 if (err==UNZ_OK)
312 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
313 x += ((uLong64)i)<<56;
314
315 if (err==UNZ_OK)
316 *pX = x;
317 else
318 *pX = 0;
319 return err;
320 }
321
322 /* My own strcmpi / strcasecmp */
strcmpcasenosensitive_internal(const char * fileName1,const char * fileName2)323 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
324 {
325 for (;;)
326 {
327 char c1=*(fileName1++);
328 char c2=*(fileName2++);
329 if ((c1>='a') && (c1<='z'))
330 c1 -= 0x20;
331 if ((c2>='a') && (c2<='z'))
332 c2 -= 0x20;
333 if (c1=='\0')
334 return ((c2=='\0') ? 0 : -1);
335 if (c2=='\0')
336 return 1;
337 if (c1<c2)
338 return -1;
339 if (c1>c2)
340 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 */
cpl_unzStringFileNameCompare(const char * fileName1,const char * fileName2,int iCaseSensitivity)364 extern int ZEXPORT cpl_unzStringFileNameCompare (const char* fileName1,
365 const char* fileName2,
366 int iCaseSensitivity)
367
368 {
369 if (iCaseSensitivity==0)
370 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
371
372 if (iCaseSensitivity==1)
373 return strcmp(fileName1,fileName2);
374
375 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
unzlocal_SearchCentralDir(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream)390 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 uLong64 uMaxBack=0xffff; /* maximum size of global comment */
397 uLong64 uPosFound=0;
398
399 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
400 return 0;
401
402
403 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
404
405 if (uMaxBack>uSizeFile)
406 uMaxBack = uSizeFile;
407
408 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
409 if (buf==NULL)
410 return 0;
411
412 uBackRead = 4;
413 while (uBackRead<uMaxBack)
414 {
415 uLong uReadSize;
416 uLong64 uReadPos ;
417 int i;
418 if (uBackRead+BUFREADCOMMENT>uMaxBack)
419 uBackRead = uMaxBack;
420 else
421 uBackRead+=BUFREADCOMMENT;
422 uReadPos = uSizeFile-uBackRead ;
423
424 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
425 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
426 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
427 break;
428
429 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
430 break;
431
432 for (i=(int)uReadSize-3; (i--)>0;)
433 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
434 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
435 {
436 uPosFound = uReadPos+i;
437 break;
438 }
439
440 if (uPosFound!=0)
441 break;
442 }
443 TRYFREE(buf);
444 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
unzlocal_SearchCentralDir64(const zlib_filefunc_def * pzlib_filefunc_def,voidpf filestream)456 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 uLong64 uMaxBack=0xffff; /* maximum size of global comment */
463 uLong64 uPosFound=0;
464 uLong uL;
465
466 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
467 return 0;
468
469
470 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
471
472 if (uMaxBack>uSizeFile)
473 uMaxBack = uSizeFile;
474
475 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
476 if (buf==NULL)
477 return 0;
478
479 uBackRead = 4;
480 while (uBackRead<uMaxBack)
481 {
482 uLong uReadSize;
483 uLong64 uReadPos;
484 int i;
485 if (uBackRead+BUFREADCOMMENT>uMaxBack)
486 uBackRead = uMaxBack;
487 else
488 uBackRead+=BUFREADCOMMENT;
489 uReadPos = uSizeFile-uBackRead ;
490
491 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
492 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
493 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
494 break;
495
496 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
497 break;
498
499 for (i=(int)uReadSize-3; (i--)>0;)
500 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
501 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
502 {
503 uPosFound = uReadPos+i;
504 break;
505 }
506
507 if (uPosFound!=0)
508 break;
509 }
510 TRYFREE(buf);
511 if (uPosFound == 0)
512 return 0;
513
514 /* Zip64 end of central directory locator */
515 if (ZSEEK(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
516 return 0;
517
518 /* the signature, already checked */
519 if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
520 return 0;
521
522 /* number of the disk with the start of the zip64 end of central directory */
523 if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
524 return 0;
525 if (uL != 0)
526 return 0;
527
528 /* relative offset of the zip64 end of central directory record */
529 uLong64 relativeOffset;
530 if (unzlocal_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
531 return 0;
532
533 /* total number of disks */
534 if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
535 return 0;
536 if (uL != 1)
537 return 0;
538
539 /* Goto end of central directory record */
540 if (ZSEEK(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
541 return 0;
542
543 /* the signature */
544 if (unzlocal_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
545 return 0;
546
547 if (uL != 0x06064b50)
548 return 0;
549
550 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 */
cpl_unzOpen2(const char * path,zlib_filefunc_def * pzlib_filefunc_def)562 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 int err=UNZ_OK;
579
580 if (unz_copyright[0]!=' ')
581 return NULL;
582
583 if (pzlib_filefunc_def==NULL)
584 cpl_fill_fopen_filefunc(&us.z_filefunc);
585 else
586 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 ZLIB_FILEFUNC_MODE_EXISTING);
592 if (us.filestream==NULL)
593 return NULL;
594
595 central_pos = unzlocal_SearchCentralDir64(&us.z_filefunc,us.filestream);
596 if (central_pos)
597 {
598 uLong uS;
599 uLong64 uL64;
600
601 us.isZip64 = 1;
602
603 //printf("ZIP64 file !\n");
604
605 if (ZSEEK(us.z_filefunc, us.filestream,
606 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
607 err=UNZ_ERRNO;
608
609 /* the signature, already checked */
610 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
611 err=UNZ_ERRNO;
612
613 /* size of zip64 end of central directory record */
614 if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
615 err=UNZ_ERRNO;
616
617 /* version made by */
618 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
619 err=UNZ_ERRNO;
620
621 /* version needed to extract */
622 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
623 err=UNZ_ERRNO;
624
625 /* number of this disk */
626 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
627 err=UNZ_ERRNO;
628
629 /* number of the disk with the start of the central directory */
630 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
631 err=UNZ_ERRNO;
632
633 /* total number of entries in the central directory on this disk */
634 if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
635 err=UNZ_ERRNO;
636
637 /* total number of entries in the central directory */
638 if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
639 err=UNZ_ERRNO;
640
641 if ((number_entry_CD!=us.gi.number_entry) ||
642 (number_disk_with_CD!=0) ||
643 (number_disk!=0))
644 err=UNZ_BADZIPFILE;
645
646 /* size of the central directory */
647 if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
648 err=UNZ_ERRNO;
649
650 /* offset of start of central directory with respect to the
651 starting disk number */
652 if (unzlocal_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
653 err=UNZ_ERRNO;
654
655 us.gi.size_comment = 0;
656 }
657 else
658 {
659 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
660 if (central_pos==0)
661 err=UNZ_ERRNO;
662
663 us.isZip64 = 0;
664
665 if (ZSEEK(us.z_filefunc, us.filestream,
666 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
667 err=UNZ_ERRNO;
668
669 /* the signature, already checked */
670 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
671 err=UNZ_ERRNO;
672
673 /* number of this disk */
674 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
675 err=UNZ_ERRNO;
676
677 /* number of the disk with the start of the central directory */
678 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
679 err=UNZ_ERRNO;
680
681 /* total number of entries in the central dir on this disk */
682 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
683 err=UNZ_ERRNO;
684 us.gi.number_entry = uL;
685
686 /* total number of entries in the central dir */
687 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
688 err=UNZ_ERRNO;
689 number_entry_CD = uL;
690
691 if ((number_entry_CD!=us.gi.number_entry) ||
692 (number_disk_with_CD!=0) ||
693 (number_disk!=0))
694 err=UNZ_BADZIPFILE;
695
696 /* size of the central directory */
697 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
698 err=UNZ_ERRNO;
699 us.size_central_dir = uL;
700
701 /* offset of start of central directory with respect to the
702 starting disk number */
703 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
704 err=UNZ_ERRNO;
705 us.offset_central_dir = uL;
706
707 /* zipfile comment length */
708 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
709 err=UNZ_ERRNO;
710 }
711
712 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
713 (err==UNZ_OK))
714 err=UNZ_BADZIPFILE;
715
716 if (err!=UNZ_OK)
717 {
718 ZCLOSE(us.z_filefunc, us.filestream);
719 return NULL;
720 }
721
722 us.byte_before_the_zipfile = central_pos -
723 (us.offset_central_dir+us.size_central_dir);
724 us.central_pos = central_pos;
725 us.pfile_in_zip_read = NULL;
726 us.encrypted = 0;
727
728
729 s=(unz_s*)ALLOC(sizeof(unz_s));
730 *s=us;
731 cpl_unzGoToFirstFile((unzFile)s);
732 return (unzFile)s;
733 }
734
735
cpl_unzOpen(const char * path)736 extern unzFile ZEXPORT cpl_unzOpen (const char *path)
737 {
738 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. */
cpl_unzClose(unzFile file)746 extern int ZEXPORT cpl_unzClose (unzFile file)
747 {
748 unz_s* s;
749 if (file==NULL)
750 return UNZ_PARAMERROR;
751 s=(unz_s*)file;
752
753 if (s->pfile_in_zip_read!=NULL)
754 cpl_unzCloseCurrentFile(file);
755
756 ZCLOSE(s->z_filefunc, s->filestream);
757 TRYFREE(s);
758 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. */
cpl_unzGetGlobalInfo(unzFile file,unz_global_info * pglobal_info)766 extern int ZEXPORT cpl_unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info)
767 {
768 unz_s* s;
769 if (file==NULL)
770 return UNZ_PARAMERROR;
771 s=(unz_s*)file;
772 *pglobal_info=s->gi;
773 return UNZ_OK;
774 }
775
776
777 /*
778 Translate date/time from Dos format to tm_unz (readable more easilty)
779 */
unzlocal_DosDateToTmuDate(uLong64 ulDosDate,tm_unz * ptm)780 local void unzlocal_DosDateToTmuDate (uLong64 ulDosDate, tm_unz* ptm)
781 {
782 uLong64 uDate;
783 uDate = (uLong64)(ulDosDate>>16);
784 ptm->tm_mday = (uInt)(uDate&0x1f) ;
785 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
786 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
787
788 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
789 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
790 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
791 }
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
unzlocal_GetCurrentFileInfoInternal(unzFile file,unz_file_info * pfile_info,unz_file_info_internal * pfile_info_internal,char * szFileName,uLong fileNameBufferSize,void * extraField,uLong extraFieldBufferSize,char * szComment,uLong commentBufferSize)807 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 int err=UNZ_OK;
822 uLong uMagic;
823 long lSeek=0;
824 uLong uL;
825
826 if (file==NULL)
827 return UNZ_PARAMERROR;
828 s=(unz_s*)file;
829 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 err=UNZ_ERRNO;
833
834
835 /* we check the magic */
836 if (err==UNZ_OK)
837 {
838 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
839 err=UNZ_ERRNO;
840 else if (uMagic!=0x02014b50)
841 err=UNZ_BADZIPFILE;
842 }
843
844 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
845 err=UNZ_ERRNO;
846
847 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
848 err=UNZ_ERRNO;
849
850 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
851 err=UNZ_ERRNO;
852
853 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
854 err=UNZ_ERRNO;
855
856 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
857 err=UNZ_ERRNO;
858
859 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
860
861 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
862 err=UNZ_ERRNO;
863
864 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
865 err=UNZ_ERRNO;
866 file_info.compressed_size = uL;
867
868 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
869 err=UNZ_ERRNO;
870 file_info.uncompressed_size = uL;
871
872 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
873 err=UNZ_ERRNO;
874
875 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
876 err=UNZ_ERRNO;
877
878 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
879 err=UNZ_ERRNO;
880
881 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
882 err=UNZ_ERRNO;
883
884 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
885 err=UNZ_ERRNO;
886
887 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
888 err=UNZ_ERRNO;
889
890 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
891 err=UNZ_ERRNO;
892 file_info_internal.offset_curfile = uL;
893
894 lSeek+=file_info.size_filename;
895 if ((err==UNZ_OK) && (szFileName!=NULL))
896 {
897 uLong uSizeRead ;
898 if (file_info.size_filename<fileNameBufferSize)
899 {
900 *(szFileName+file_info.size_filename)='\0';
901 uSizeRead = file_info.size_filename;
902 }
903 else
904 uSizeRead = fileNameBufferSize;
905
906 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
907 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
908 err=UNZ_ERRNO;
909 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 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
938 {
939 if (lSeek!=0)
940 {
941 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
942 lSeek=0;
943 else
944 err=UNZ_ERRNO;
945 }
946
947 uLong acc = 0;
948 while(acc < file_info.size_file_extra)
949 {
950 uLong headerId;
951 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
952 err=UNZ_ERRNO;
953
954 uLong dataSize;
955 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
956 err=UNZ_ERRNO;
957
958 /* ZIP64 extra fields */
959 if (headerId == 0x0001)
960 {
961 if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
962 err=UNZ_ERRNO;
963
964 if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
965 err=UNZ_ERRNO;
966
967 /* Relative Header offset */
968 uLong64 u64;
969 if (unzlocal_getLong64(&s->z_filefunc, s->filestream,&u64) != UNZ_OK)
970 err=UNZ_ERRNO;
971
972 /* Disk Start Number */
973 uLong uL;
974 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
975 err=UNZ_ERRNO;
976 }
977 else
978 {
979 if (ZSEEK(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
980 err=UNZ_ERRNO;
981 }
982
983 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 if ((err==UNZ_OK) && (pfile_info!=NULL))
1017 *pfile_info=file_info;
1018
1019 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1020 *pfile_info_internal=file_info_internal;
1021
1022 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 */
cpl_unzGetCurrentFileInfo(unzFile file,unz_file_info * pfile_info,char * szFileName,uLong fileNameBufferSize,void * extraField,uLong extraFieldBufferSize,char * szComment,uLong commentBufferSize)1032 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 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 */
cpl_unzGoToFirstFile(unzFile file)1048 extern int ZEXPORT cpl_unzGoToFirstFile (unzFile file)
1049 {
1050 int err=UNZ_OK;
1051 unz_s* s;
1052 if (file==NULL)
1053 return UNZ_PARAMERROR;
1054 s=(unz_s*)file;
1055 s->pos_in_central_dir=s->offset_central_dir;
1056 s->num_file=0;
1057 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1058 &s->cur_file_info_internal,
1059 NULL,0,NULL,0,NULL,0);
1060 s->current_file_ok = (err == UNZ_OK);
1061 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 */
cpl_unzGoToNextFile(unzFile file)1069 extern int ZEXPORT cpl_unzGoToNextFile (unzFile file)
1070 {
1071 unz_s* s;
1072 int err;
1073
1074 if (file==NULL)
1075 return UNZ_PARAMERROR;
1076 s=(unz_s*)file;
1077 if (!s->current_file_ok)
1078 return UNZ_END_OF_LIST_OF_FILE;
1079 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1080 if (s->num_file+1==s->gi.number_entry)
1081 return UNZ_END_OF_LIST_OF_FILE;
1082
1083 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1084 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1085 s->num_file++;
1086 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1087 &s->cur_file_info_internal,
1088 NULL,0,NULL,0,NULL,0);
1089 s->current_file_ok = (err == UNZ_OK);
1090 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 */
cpl_unzLocateFile(unzFile file,const char * szFileName,int iCaseSensitivity)1102 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 if (file==NULL)
1117 return UNZ_PARAMERROR;
1118
1119 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1120 return UNZ_PARAMERROR;
1121
1122 s=(unz_s*)file;
1123 if (!s->current_file_ok)
1124 return UNZ_END_OF_LIST_OF_FILE;
1125
1126 /* Save the current state */
1127 num_fileSaved = s->num_file;
1128 pos_in_central_dirSaved = s->pos_in_central_dir;
1129 cur_file_infoSaved = s->cur_file_info;
1130 cur_file_info_internalSaved = s->cur_file_info_internal;
1131
1132 err = cpl_unzGoToFirstFile(file);
1133
1134 while (err == UNZ_OK)
1135 {
1136 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1137 err = cpl_unzGetCurrentFileInfo(file,NULL,
1138 szCurrentFileName,sizeof(szCurrentFileName)-1,
1139 NULL,0,NULL,0);
1140 if (err == UNZ_OK)
1141 {
1142 if (cpl_unzStringFileNameCompare(szCurrentFileName,
1143 szFileName,iCaseSensitivity)==0)
1144 return UNZ_OK;
1145 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 s->num_file = num_fileSaved ;
1153 s->pos_in_central_dir = pos_in_central_dirSaved ;
1154 s->cur_file_info = cur_file_infoSaved;
1155 s->cur_file_info_internal = cur_file_info_internalSaved;
1156 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
cpl_unzGetFilePos(unzFile file,unz_file_pos * file_pos)1178 extern int ZEXPORT cpl_unzGetFilePos(unzFile file, unz_file_pos* file_pos)
1179 {
1180 unz_s* s;
1181
1182 if (file==NULL || file_pos==NULL)
1183 return UNZ_PARAMERROR;
1184 s=(unz_s*)file;
1185 if (!s->current_file_ok)
1186 return UNZ_END_OF_LIST_OF_FILE;
1187
1188 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1189 file_pos->num_of_file = s->num_file;
1190
1191 return UNZ_OK;
1192 }
1193
cpl_unzGoToFilePos(unzFile file,unz_file_pos * file_pos)1194 extern int ZEXPORT cpl_unzGoToFilePos(unzFile file, unz_file_pos* file_pos)
1195 {
1196 unz_s* s;
1197 int err;
1198
1199 if (file==NULL || file_pos==NULL)
1200 return UNZ_PARAMERROR;
1201 s=(unz_s*)file;
1202
1203 /* jump to the right spot */
1204 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1205 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 NULL,0,NULL,0,NULL,0);
1211 /* return results */
1212 s->current_file_ok = (err == UNZ_OK);
1213 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 */
unzlocal_CheckCurrentFileCoherencyHeader(unz_s * s,uInt * piSizeVar,uLong64 * poffset_local_extrafield,uInt * psize_local_extrafield)1228 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 int err=UNZ_OK;
1236
1237 *piSizeVar = 0;
1238 *poffset_local_extrafield = 0;
1239 *psize_local_extrafield = 0;
1240
1241 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 return UNZ_ERRNO;
1244
1245
1246 if (err==UNZ_OK)
1247 {
1248 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1249 err=UNZ_ERRNO;
1250 else if (uMagic!=0x04034b50)
1251 err=UNZ_BADZIPFILE;
1252 }
1253
1254 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1255 err=UNZ_ERRNO;
1256 /*
1257 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1258 err=UNZ_BADZIPFILE;
1259 */
1260 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1261 err=UNZ_ERRNO;
1262
1263 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1264 err=UNZ_ERRNO;
1265 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1266 err=UNZ_BADZIPFILE;
1267
1268 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1269 (s->cur_file_info.compression_method!=Z_DEFLATED))
1270 err=UNZ_BADZIPFILE;
1271
1272 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1273 err=UNZ_ERRNO;
1274
1275 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1276 err=UNZ_ERRNO;
1277 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1278 ((uFlags & 8)==0))
1279 err=UNZ_BADZIPFILE;
1280
1281 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1282 err=UNZ_ERRNO;
1283 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1284 ((uFlags & 8)==0))
1285 err=UNZ_BADZIPFILE;
1286
1287 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1288 err=UNZ_ERRNO;
1289 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1290 ((uFlags & 8)==0))
1291 err=UNZ_BADZIPFILE;
1292
1293
1294 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1295 err=UNZ_ERRNO;
1296 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1297 err=UNZ_BADZIPFILE;
1298
1299 *piSizeVar += (uInt)size_filename;
1300
1301 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1302 err=UNZ_ERRNO;
1303 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1304 SIZEZIPLOCALHEADER + size_filename;
1305 *psize_local_extrafield = (uInt)size_extra_field;
1306
1307 *piSizeVar += (uInt)size_extra_field;
1308
1309 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 */
cpl_unzOpenCurrentFile3(unzFile file,int * method,int * level,int raw,const char * password)1316 extern int ZEXPORT cpl_unzOpenCurrentFile3 (unzFile file, int* method,
1317 int* level, int raw, const char* password)
1318 {
1319 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 if (password != NULL)
1329 return UNZ_PARAMERROR;
1330 # endif
1331
1332 if (file==NULL)
1333 return UNZ_PARAMERROR;
1334 s=(unz_s*)file;
1335 if (!s->current_file_ok)
1336 return UNZ_PARAMERROR;
1337
1338 if (s->pfile_in_zip_read != NULL)
1339 cpl_unzCloseCurrentFile(file);
1340
1341 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1342 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1343 return UNZ_BADZIPFILE;
1344
1345 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1346 ALLOC(sizeof(file_in_zip_read_info_s));
1347 if (pfile_in_zip_read_info==NULL)
1348 return UNZ_INTERNALERROR;
1349
1350 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1351 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1352 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1353 pfile_in_zip_read_info->pos_local_extrafield=0;
1354 pfile_in_zip_read_info->raw=raw;
1355
1356 if (pfile_in_zip_read_info->read_buffer==NULL)
1357 {
1358 TRYFREE(pfile_in_zip_read_info);
1359 return UNZ_INTERNALERROR;
1360 }
1361
1362 pfile_in_zip_read_info->stream_initialised=0;
1363
1364 if (method!=NULL)
1365 *method = (int)s->cur_file_info.compression_method;
1366
1367 if (level!=NULL)
1368 {
1369 *level = 6;
1370 switch (s->cur_file_info.flag & 0x06)
1371 {
1372 case 6 : *level = 1; break;
1373 case 4 : *level = 2; break;
1374 case 2 : *level = 9; break;
1375 }
1376 }
1377
1378 if ((s->cur_file_info.compression_method!=0) &&
1379 (s->cur_file_info.compression_method!=Z_DEFLATED))
1380 err=UNZ_BADZIPFILE;
1381
1382 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1383 pfile_in_zip_read_info->crc32=0;
1384 pfile_in_zip_read_info->compression_method =
1385 s->cur_file_info.compression_method;
1386 pfile_in_zip_read_info->filestream=s->filestream;
1387 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1388 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1389
1390 pfile_in_zip_read_info->stream.total_out = 0;
1391
1392 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1393 (!raw))
1394 {
1395 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1396 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1397 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1398 pfile_in_zip_read_info->stream.next_in = 0;
1399 pfile_in_zip_read_info->stream.avail_in = 0;
1400
1401 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1402 if (err == Z_OK)
1403 pfile_in_zip_read_info->stream_initialised=1;
1404 else
1405 {
1406 TRYFREE(pfile_in_zip_read_info);
1407 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 s->cur_file_info.compressed_size ;
1419 pfile_in_zip_read_info->rest_read_uncompressed =
1420 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 iSizeVar;
1426
1427 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1428
1429 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 return UNZ_OK;
1455 }
1456
cpl_unzOpenCurrentFile(unzFile file)1457 extern int ZEXPORT cpl_unzOpenCurrentFile (unzFile file)
1458 {
1459 return cpl_unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1460 }
1461
cpl_unzOpenCurrentFilePassword(unzFile file,const char * password)1462 extern int ZEXPORT cpl_unzOpenCurrentFilePassword (unzFile file, const char* password)
1463 {
1464 return cpl_unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1465 }
1466
cpl_unzOpenCurrentFile2(unzFile file,int * method,int * level,int raw)1467 extern int ZEXPORT cpl_unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1468 {
1469 return cpl_unzOpenCurrentFile3(file, method, level, raw, NULL);
1470 }
1471
1472 /** Addition for GDAL : START */
1473
cpl_unzGetCurrentFileZStreamPos(unzFile file)1474 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 s=(unz_s*)file;
1479 if (file==NULL)
1480 return 0; //UNZ_PARAMERROR;
1481 pfile_in_zip_read_info=s->pfile_in_zip_read;
1482 if (pfile_in_zip_read_info==NULL)
1483 return 0; //UNZ_PARAMERROR;
1484 return pfile_in_zip_read_info->pos_in_zipfile +
1485 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 */
cpl_unzReadCurrentFile(unzFile file,voidp buf,unsigned len)1500 extern int ZEXPORT cpl_unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1501 {
1502 int err=UNZ_OK;
1503 uInt iRead = 0;
1504 unz_s* s;
1505 file_in_zip_read_info_s* pfile_in_zip_read_info;
1506 if (file==NULL)
1507 return UNZ_PARAMERROR;
1508 s=(unz_s*)file;
1509 pfile_in_zip_read_info=s->pfile_in_zip_read;
1510
1511 if (pfile_in_zip_read_info==NULL)
1512 return UNZ_PARAMERROR;
1513
1514
1515 if ((pfile_in_zip_read_info->read_buffer == NULL))
1516 return UNZ_END_OF_LIST_OF_FILE;
1517 if (len==0)
1518 return 0;
1519
1520 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1521
1522 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1523
1524 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 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1528
1529 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 pfile_in_zip_read_info->stream.avail_in;
1535
1536 while (pfile_in_zip_read_info->stream.avail_out>0)
1537 {
1538 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1539 (pfile_in_zip_read_info->rest_read_compressed>0))
1540 {
1541 uInt uReadThis = UNZ_BUFSIZE;
1542 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1543 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1544 if (uReadThis == 0)
1545 return UNZ_EOF;
1546 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 return UNZ_ERRNO;
1552 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 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 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1572
1573 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1574
1575 pfile_in_zip_read_info->stream.next_in =
1576 (Bytef*)pfile_in_zip_read_info->read_buffer;
1577 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1578 }
1579
1580 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1581 {
1582 uInt uDoCopy,i ;
1583
1584 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1585 (pfile_in_zip_read_info->rest_read_compressed == 0))
1586 return (iRead==0) ? UNZ_EOF : iRead;
1587
1588 if (pfile_in_zip_read_info->stream.avail_out <
1589 pfile_in_zip_read_info->stream.avail_in)
1590 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1591 else
1592 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1593
1594 for (i=0;i<uDoCopy;i++)
1595 *(pfile_in_zip_read_info->stream.next_out+i) =
1596 *(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 uDoCopy);
1601 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1602 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1603 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1604 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1605 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1606 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1607 iRead += uDoCopy;
1608 }
1609 else
1610 {
1611 uLong64 uTotalOutBefore,uTotalOutAfter;
1612 const Bytef *bufBefore;
1613 uLong64 uOutThis;
1614 int flush=Z_SYNC_FLUSH;
1615
1616 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1617 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 err=inflate(&pfile_in_zip_read_info->stream,flush);
1626
1627 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1628 err = Z_DATA_ERROR;
1629
1630 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1631 uOutThis = uTotalOutAfter-uTotalOutBefore;
1632
1633 pfile_in_zip_read_info->crc32 =
1634 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1635 (uInt)(uOutThis));
1636
1637 pfile_in_zip_read_info->rest_read_uncompressed -=
1638 uOutThis;
1639
1640 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1641
1642 if (err==Z_STREAM_END)
1643 return (iRead==0) ? UNZ_EOF : iRead;
1644 if (err!=Z_OK)
1645 break;
1646 }
1647 }
1648
1649 if (err==Z_OK)
1650 return iRead;
1651 return err;
1652 }
1653
1654
1655 /*
1656 Give the current position in uncompressed data
1657 */
cpl_unztell(unzFile file)1658 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 if (file==NULL)
1663 return UNZ_PARAMERROR;
1664 s=(unz_s*)file;
1665 pfile_in_zip_read_info=s->pfile_in_zip_read;
1666
1667 if (pfile_in_zip_read_info==NULL)
1668 return UNZ_PARAMERROR;
1669
1670 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 */
cpl_unzeof(unzFile file)1677 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 if (file==NULL)
1682 return UNZ_PARAMERROR;
1683 s=(unz_s*)file;
1684 pfile_in_zip_read_info=s->pfile_in_zip_read;
1685
1686 if (pfile_in_zip_read_info==NULL)
1687 return UNZ_PARAMERROR;
1688
1689 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1690 return 1;
1691 else
1692 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 */
cpl_unzGetLocalExtrafield(unzFile file,voidp buf,unsigned len)1709 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 if (file==NULL)
1717 return UNZ_PARAMERROR;
1718 s=(unz_s*)file;
1719 pfile_in_zip_read_info=s->pfile_in_zip_read;
1720
1721 if (pfile_in_zip_read_info==NULL)
1722 return UNZ_PARAMERROR;
1723
1724 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1725 pfile_in_zip_read_info->pos_local_extrafield);
1726
1727 if (buf==NULL)
1728 return (int)size_to_read;
1729
1730 if (len>size_to_read)
1731 read_now = (uInt)size_to_read;
1732 else
1733 read_now = (uInt)len ;
1734
1735 if (read_now==0)
1736 return 0;
1737
1738 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 return UNZ_ERRNO;
1744
1745 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1746 pfile_in_zip_read_info->filestream,
1747 buf,read_now)!=read_now)
1748 return UNZ_ERRNO;
1749
1750 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 */
cpl_unzCloseCurrentFile(unzFile file)1757 extern int ZEXPORT cpl_unzCloseCurrentFile (unzFile file)
1758 {
1759 int err=UNZ_OK;
1760
1761 unz_s* s;
1762 file_in_zip_read_info_s* pfile_in_zip_read_info;
1763 if (file==NULL)
1764 return UNZ_PARAMERROR;
1765 s=(unz_s*)file;
1766 pfile_in_zip_read_info=s->pfile_in_zip_read;
1767
1768 if (pfile_in_zip_read_info==NULL)
1769 return UNZ_PARAMERROR;
1770
1771
1772 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1773 (!pfile_in_zip_read_info->raw))
1774 {
1775 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1776 err=UNZ_CRCERROR;
1777 }
1778
1779
1780 TRYFREE(pfile_in_zip_read_info->read_buffer);
1781 pfile_in_zip_read_info->read_buffer = NULL;
1782 if (pfile_in_zip_read_info->stream_initialised)
1783 inflateEnd(&pfile_in_zip_read_info->stream);
1784
1785 pfile_in_zip_read_info->stream_initialised = 0;
1786 TRYFREE(pfile_in_zip_read_info);
1787
1788 s->pfile_in_zip_read=NULL;
1789
1790 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 */
cpl_unzGetGlobalComment(unzFile file,char * szComment,uLong uSizeBuf)1799 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 if (file==NULL)
1805 return UNZ_PARAMERROR;
1806 s=(unz_s*)file;
1807
1808 uReadThis = uSizeBuf;
1809 if (uReadThis>s->gi.size_comment)
1810 uReadThis = s->gi.size_comment;
1811
1812 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1813 return UNZ_ERRNO;
1814
1815 if (uReadThis>0)
1816 {
1817 *szComment='\0';
1818 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1819 return UNZ_ERRNO;
1820 }
1821
1822 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1823 *(szComment+s->gi.size_comment)='\0';
1824 return (int)uReadThis;
1825 }
1826
1827 /* Additions by RX '2004 */
cpl_unzGetOffset(unzFile file)1828 extern uLong64 ZEXPORT cpl_unzGetOffset (unzFile file)
1829 {
1830 unz_s* s;
1831
1832 if (file==NULL)
1833 return 0; //UNZ_PARAMERROR;
1834 s=(unz_s*)file;
1835 if (!s->current_file_ok)
1836 return 0;
1837 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1838 if (s->num_file==s->gi.number_entry)
1839 return 0;
1840 return s->pos_in_central_dir;
1841 }
1842
cpl_unzSetOffset(unzFile file,uLong64 pos)1843 extern int ZEXPORT cpl_unzSetOffset (unzFile file, uLong64 pos)
1844 {
1845 unz_s* s;
1846 int err;
1847
1848 if (file==NULL)
1849 return UNZ_PARAMERROR;
1850 s=(unz_s*)file;
1851
1852 s->pos_in_central_dir = pos;
1853 s->num_file = s->gi.number_entry; /* hack */
1854 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1855 &s->cur_file_info_internal,
1856 NULL,0,NULL,0,NULL,0);
1857 s->current_file_ok = (err == UNZ_OK);
1858 return err;
1859 }
1860
1861