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