1 /* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.01e, February 12th, 2005
4 Copyright (C) 1998-2005 Gilles Vollant
6 Read unzip.h for more info
9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
10 compatibility with older software. The following is from the original crypt.c. Code
11 woven in by Terry Thorsen 1/2003.
14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
16 See the accompanying file LICENSE, version 2000-Apr-09 or later
17 (the contents of which are also included in zip.h) for terms of use.
18 If, for some reason, all these files are missing, the Info-ZIP license
19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
24 The encryption/decryption parts of this source code (as opposed to the
25 non-echoing password parts) were originally written in Europe. The
26 whole source package can be freely distributed, including from the USA.
27 (Prior to January 2000, re-export from the US was a violation of US law.)
31 This encryption code is a direct transcription of the algorithm from
32 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
33 file (appnote.txt) is distributed with the PKZIP program (even in the
34 version without encryption capabilities).
57 /* compile with -Dlocal if your debugger can't find static symbols */
60 #ifndef CASESENSITIVITYDEFAULT_NO
61 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
62 # define CASESENSITIVITYDEFAULT_NO
68 #define UNZ_BUFSIZE (16384)
71 #ifndef UNZ_MAXFILENAMEINZIP
72 #define UNZ_MAXFILENAMEINZIP (256)
76 # define ALLOC(size) (malloc(size))
79 # define TRYFREE(p) {free(p);}
82 #define SIZECENTRALDIRITEM (0x2e)
83 #define SIZEZIPLOCALHEADER (0x1e)
88 const char unz_copyright
[] =
89 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
91 /* unz_file_info_interntal contain internal info about a file in zipfile*/
92 typedef struct unz_file_info_internal_s
94 uLong offset_curfile
;/* relative offset of local header 4 bytes */
95 } unz_file_info_internal
;
98 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
99 when reading and decompress it */
102 char *read_buffer
; /* internal buffer for compressed data */
103 z_stream stream
; /* zLib stream structure for inflate */
105 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
106 uLong stream_initialised
; /* flag set if stream structure is initialised*/
108 uLong offset_local_extrafield
;/* offset of the local extra field */
109 uInt size_local_extrafield
;/* size of the local extra field */
110 uLong pos_local_extrafield
; /* position in the local extra field in read*/
112 uLong crc32
; /* crc32 of all data uncompressed */
113 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
114 uLong rest_read_compressed
; /* number of byte to be decompressed */
115 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
116 zlib_filefunc_def z_filefunc
;
117 voidpf filestream
; /* io structore of the zipfile */
118 uLong compression_method
; /* compression method (0==store) */
119 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
121 } file_in_zip_read_info_s
;
124 /* unz_s contain internal information about the zipfile
128 zlib_filefunc_def z_filefunc
;
129 voidpf filestream
; /* io structore of the zipfile */
130 unz_global_info gi
; /* public global information */
131 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
132 uLong num_file
; /* number of the current file in the zipfile*/
133 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
134 uLong current_file_ok
; /* flag about the usability of the current file*/
135 uLong central_pos
; /* position of the beginning of the central dir*/
137 uLong size_central_dir
; /* size of the central directory */
138 uLong offset_central_dir
; /* offset of start of central directory with
139 respect to the starting disk number */
141 unz_file_info cur_file_info
; /* public info about the current file in zip*/
142 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
143 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
144 file if we are decompressing it */
147 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
148 const unsigned long* pcrc_32_tab
;
157 /* ===========================================================================
158 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
160 IN assertion: the stream s has been sucessfully opened for reading.
164 local
int unzlocal_getByte
OF((
165 const zlib_filefunc_def
* pzlib_filefunc_def
,
169 local
int unzlocal_getByte(pzlib_filefunc_def
,filestream
,pi
)
170 const zlib_filefunc_def
* pzlib_filefunc_def
;
175 int err
= (int)ZREAD(*pzlib_filefunc_def
,filestream
,&c
,1);
183 if (ZERROR(*pzlib_filefunc_def
,filestream
))
191 /* ===========================================================================
192 Reads a long in LSB order from the given gz_stream. Sets
194 local
int unzlocal_getShort
OF((
195 const zlib_filefunc_def
* pzlib_filefunc_def
,
199 local
int unzlocal_getShort (pzlib_filefunc_def
,filestream
,pX
)
200 const zlib_filefunc_def
* pzlib_filefunc_def
;
208 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
212 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
222 local
int unzlocal_getLong
OF((
223 const zlib_filefunc_def
* pzlib_filefunc_def
,
227 local
int unzlocal_getLong (pzlib_filefunc_def
,filestream
,pX
)
228 const zlib_filefunc_def
* pzlib_filefunc_def
;
236 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
240 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
244 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
248 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
259 /* My own strcmpi / strcasecmp */
260 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
261 const char* fileName1
;
262 const char* fileName2
;
266 char c1
=*(fileName1
++);
267 char c2
=*(fileName2
++);
268 if ((c1
>='a') && (c1
<='z'))
270 if ((c2
>='a') && (c2
<='z'))
273 return ((c2
=='\0') ? 0 : -1);
284 #ifdef CASESENSITIVITYDEFAULT_NO
285 #define CASESENSITIVITYDEFAULTVALUE 2
287 #define CASESENSITIVITYDEFAULTVALUE 1
290 #ifndef STRCMPCASENOSENTIVEFUNCTION
291 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
295 Compare two filename (fileName1,fileName2).
296 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
297 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
299 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
300 (like 1 on Unix, 2 on Windows)
303 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
304 const char* fileName1
;
305 const char* fileName2
;
306 int iCaseSensitivity
;
308 if (iCaseSensitivity
==0)
309 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
311 if (iCaseSensitivity
==1)
312 return strcmp(fileName1
,fileName2
);
314 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
317 #ifndef BUFREADCOMMENT
318 #define BUFREADCOMMENT (0x400)
322 Locate the Central directory of a zipfile (at the end, just before
325 local uLong unzlocal_SearchCentralDir
OF((
326 const zlib_filefunc_def
* pzlib_filefunc_def
,
329 local uLong
unzlocal_SearchCentralDir(pzlib_filefunc_def
,filestream
)
330 const zlib_filefunc_def
* pzlib_filefunc_def
;
336 uLong uMaxBack
=0xffff; /* maximum size of global comment */
339 if (ZSEEK(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
343 uSizeFile
= ZTELL(*pzlib_filefunc_def
,filestream
);
345 if (uMaxBack
>uSizeFile
)
346 uMaxBack
= uSizeFile
;
348 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
353 while (uBackRead
<uMaxBack
)
355 uLong uReadSize
,uReadPos
;
357 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
358 uBackRead
= uMaxBack
;
360 uBackRead
+=BUFREADCOMMENT
;
361 uReadPos
= uSizeFile
-uBackRead
;
363 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
364 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
365 if (ZSEEK(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
368 if (ZREAD(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
371 for (i
=(int)uReadSize
-3; (i
--)>0;)
372 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
373 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
375 uPosFound
= uReadPos
+i
;
387 Open a Zip file. path contain the full pathname (by example,
388 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
390 If the zipfile cannot be opened (file doesn't exist or in not valid), the
391 return value is NULL.
392 Else, the return value is a unzFile Handle, usable with other function
393 of this unzip package.
395 extern unzFile ZEXPORT
unzOpen2 (path
, pzlib_filefunc_def
)
397 zlib_filefunc_def
* pzlib_filefunc_def
;
401 uLong central_pos
,uL
;
403 uLong number_disk
; /* number of the current dist, used for
404 spaning ZIP, unsupported, always 0*/
405 uLong number_disk_with_CD
; /* number the the disk with central dir, used
406 for spaning ZIP, unsupported, always 0*/
407 uLong number_entry_CD
; /* total number of entries in
409 (same than number_entry on nospan) */
413 if (unz_copyright
[0]!=' ')
416 if (pzlib_filefunc_def
==NULL
)
417 fill_fopen_filefunc(&us
.z_filefunc
);
419 us
.z_filefunc
= *pzlib_filefunc_def
;
421 us
.filestream
= (*(us
.z_filefunc
.zopen_file
))(us
.z_filefunc
.opaque
,
423 ZLIB_FILEFUNC_MODE_READ
|
424 ZLIB_FILEFUNC_MODE_EXISTING
);
425 if (us
.filestream
==NULL
)
428 central_pos
= unzlocal_SearchCentralDir(&us
.z_filefunc
,us
.filestream
);
432 if (ZSEEK(us
.z_filefunc
, us
.filestream
,
433 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
436 /* the signature, already checked */
437 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
440 /* number of this disk */
441 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk
)!=UNZ_OK
)
444 /* number of the disk with the start of the central directory */
445 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk_with_CD
)!=UNZ_OK
)
448 /* total number of entries in the central dir on this disk */
449 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.number_entry
)!=UNZ_OK
)
452 /* total number of entries in the central dir */
453 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_entry_CD
)!=UNZ_OK
)
456 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
457 (number_disk_with_CD
!=0) ||
461 /* size of the central directory */
462 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.size_central_dir
)!=UNZ_OK
)
465 /* offset of start of central directory with respect to the
466 starting disk number */
467 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.offset_central_dir
)!=UNZ_OK
)
470 /* zipfile comment length */
471 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.size_comment
)!=UNZ_OK
)
474 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
480 ZCLOSE(us
.z_filefunc
, us
.filestream
);
484 us
.byte_before_the_zipfile
= central_pos
-
485 (us
.offset_central_dir
+us
.size_central_dir
);
486 us
.central_pos
= central_pos
;
487 us
.pfile_in_zip_read
= NULL
;
491 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
493 unzGoToFirstFile((unzFile
)s
);
498 extern unzFile ZEXPORT
unzOpen (path
)
501 return unzOpen2(path
, NULL
);
505 Close a ZipFile opened with unzipOpen.
506 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
507 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
508 return UNZ_OK if there is no problem. */
509 extern int ZEXPORT
unzClose (file
)
514 return UNZ_PARAMERROR
;
517 if (s
->pfile_in_zip_read
!=NULL
)
518 unzCloseCurrentFile(file
);
520 ZCLOSE(s
->z_filefunc
, s
->filestream
);
527 Write info about the ZipFile in the *pglobal_info structure.
528 No preparation of the structure is needed
529 return UNZ_OK if there is no problem. */
530 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
532 unz_global_info
*pglobal_info
;
536 return UNZ_PARAMERROR
;
544 Translate date/time from Dos format to tm_unz (readable more easilty)
546 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
551 uDate
= (uLong
)(ulDosDate
>>16);
552 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
553 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
554 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
556 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
557 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
558 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
562 Get Info about the current file in the zipfile, with internal only info
564 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
565 unz_file_info
*pfile_info
,
566 unz_file_info_internal
567 *pfile_info_internal
,
569 uLong fileNameBufferSize
,
571 uLong extraFieldBufferSize
,
573 uLong commentBufferSize
));
575 local
int unzlocal_GetCurrentFileInfoInternal (file
,
578 szFileName
, fileNameBufferSize
,
579 extraField
, extraFieldBufferSize
,
580 szComment
, commentBufferSize
)
582 unz_file_info
*pfile_info
;
583 unz_file_info_internal
*pfile_info_internal
;
585 uLong fileNameBufferSize
;
587 uLong extraFieldBufferSize
;
589 uLong commentBufferSize
;
592 unz_file_info file_info
;
593 unz_file_info_internal file_info_internal
;
599 return UNZ_PARAMERROR
;
601 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
602 s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,
603 ZLIB_FILEFUNC_SEEK_SET
)!=0)
607 /* we check the magic */
610 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
612 else if (uMagic
!=0x02014b50)
616 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version
) != UNZ_OK
)
619 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version_needed
) != UNZ_OK
)
622 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.flag
) != UNZ_OK
)
625 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.compression_method
) != UNZ_OK
)
628 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.dosDate
) != UNZ_OK
)
631 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
633 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.crc
) != UNZ_OK
)
636 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.compressed_size
) != UNZ_OK
)
639 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.uncompressed_size
) != UNZ_OK
)
642 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_filename
) != UNZ_OK
)
645 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_extra
) != UNZ_OK
)
648 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_comment
) != UNZ_OK
)
651 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.disk_num_start
) != UNZ_OK
)
654 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.internal_fa
) != UNZ_OK
)
657 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.external_fa
) != UNZ_OK
)
660 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
663 lSeek
+=file_info
.size_filename
;
664 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
667 if (file_info
.size_filename
<fileNameBufferSize
)
669 *(szFileName
+file_info
.size_filename
)='\0';
670 uSizeRead
= file_info
.size_filename
;
673 uSizeRead
= fileNameBufferSize
;
675 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
676 if (ZREAD(s
->z_filefunc
, s
->filestream
,szFileName
,uSizeRead
)!=uSizeRead
)
682 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
685 if (file_info
.size_file_extra
<extraFieldBufferSize
)
686 uSizeRead
= file_info
.size_file_extra
;
688 uSizeRead
= extraFieldBufferSize
;
692 if (ZSEEK(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
697 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
698 if (ZREAD(s
->z_filefunc
, s
->filestream
,extraField
,uSizeRead
)!=uSizeRead
)
700 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
703 lSeek
+=file_info
.size_file_extra
;
706 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
709 if (file_info
.size_file_comment
<commentBufferSize
)
711 *(szComment
+file_info
.size_file_comment
)='\0';
712 uSizeRead
= file_info
.size_file_comment
;
715 uSizeRead
= commentBufferSize
;
719 if (ZSEEK(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
724 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
725 if (ZREAD(s
->z_filefunc
, s
->filestream
,szComment
,uSizeRead
)!=uSizeRead
)
727 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
730 lSeek
+=file_info
.size_file_comment
;
732 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
733 *pfile_info
=file_info
;
735 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
736 *pfile_info_internal
=file_info_internal
;
744 Write info about the ZipFile in the *pglobal_info structure.
745 No preparation of the structure is needed
746 return UNZ_OK if there is no problem.
748 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
750 szFileName
, fileNameBufferSize
,
751 extraField
, extraFieldBufferSize
,
752 szComment
, commentBufferSize
)
754 unz_file_info
*pfile_info
;
756 uLong fileNameBufferSize
;
758 uLong extraFieldBufferSize
;
760 uLong commentBufferSize
;
762 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
763 szFileName
,fileNameBufferSize
,
764 extraField
,extraFieldBufferSize
,
765 szComment
,commentBufferSize
);
769 Set the current file of the zipfile to the first file.
770 return UNZ_OK if there is no problem
772 extern int ZEXPORT
unzGoToFirstFile (file
)
778 return UNZ_PARAMERROR
;
780 s
->pos_in_central_dir
=s
->offset_central_dir
;
782 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
783 &s
->cur_file_info_internal
,
784 NULL
,0,NULL
,0,NULL
,0);
785 s
->current_file_ok
= (err
== UNZ_OK
);
790 Set the current file of the zipfile to the next file.
791 return UNZ_OK if there is no problem
792 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
794 extern int ZEXPORT
unzGoToNextFile (file
)
801 return UNZ_PARAMERROR
;
803 if (!s
->current_file_ok
)
804 return UNZ_END_OF_LIST_OF_FILE
;
805 if (s
->gi
.number_entry
!= 0xffff) /* 2^16 files overflow hack */
806 if (s
->num_file
+1==s
->gi
.number_entry
)
807 return UNZ_END_OF_LIST_OF_FILE
;
809 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
810 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
812 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
813 &s
->cur_file_info_internal
,
814 NULL
,0,NULL
,0,NULL
,0);
815 s
->current_file_ok
= (err
== UNZ_OK
);
821 Try locate the file szFileName in the zipfile.
822 For the iCaseSensitivity signification, see unzipStringFileNameCompare
825 UNZ_OK if the file is found. It becomes the current file.
826 UNZ_END_OF_LIST_OF_FILE if the file is not found
828 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
830 const char *szFileName
;
831 int iCaseSensitivity
;
836 /* We remember the 'current' position in the file so that we can jump
837 * back there if we fail.
839 unz_file_info cur_file_infoSaved
;
840 unz_file_info_internal cur_file_info_internalSaved
;
842 uLong pos_in_central_dirSaved
;
846 return UNZ_PARAMERROR
;
848 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
849 return UNZ_PARAMERROR
;
852 if (!s
->current_file_ok
)
853 return UNZ_END_OF_LIST_OF_FILE
;
855 /* Save the current state */
856 num_fileSaved
= s
->num_file
;
857 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
858 cur_file_infoSaved
= s
->cur_file_info
;
859 cur_file_info_internalSaved
= s
->cur_file_info_internal
;
861 err
= unzGoToFirstFile(file
);
863 while (err
== UNZ_OK
)
865 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
866 err
= unzGetCurrentFileInfo(file
,NULL
,
867 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
871 if (unzStringFileNameCompare(szCurrentFileName
,
872 szFileName
,iCaseSensitivity
)==0)
874 err
= unzGoToNextFile(file
);
878 /* We failed, so restore the state of the 'current file' to where we
881 s
->num_file
= num_fileSaved
;
882 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
883 s
->cur_file_info
= cur_file_infoSaved
;
884 s
->cur_file_info_internal
= cur_file_info_internalSaved
;
890 ///////////////////////////////////////////
891 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
892 // I need random access
894 // Further optimization could be realized by adding an ability
895 // to cache the directory in memory. The goal being a single
896 // comprehensive file read to put the file I need in a memory.
900 typedef struct unz_file_pos_s
902 uLong pos_in_zip_directory; // offset in file
903 uLong num_of_file; // # of file
907 extern int ZEXPORT
unzGetFilePos(file
, file_pos
)
909 unz_file_pos
* file_pos
;
913 if (file
==NULL
|| file_pos
==NULL
)
914 return UNZ_PARAMERROR
;
916 if (!s
->current_file_ok
)
917 return UNZ_END_OF_LIST_OF_FILE
;
919 file_pos
->pos_in_zip_directory
= s
->pos_in_central_dir
;
920 file_pos
->num_of_file
= s
->num_file
;
925 extern int ZEXPORT
unzGoToFilePos(file
, file_pos
)
927 unz_file_pos
* file_pos
;
932 if (file
==NULL
|| file_pos
==NULL
)
933 return UNZ_PARAMERROR
;
936 /* jump to the right spot */
937 s
->pos_in_central_dir
= file_pos
->pos_in_zip_directory
;
938 s
->num_file
= file_pos
->num_of_file
;
940 /* set the current file */
941 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
942 &s
->cur_file_info_internal
,
943 NULL
,0,NULL
,0,NULL
,0);
945 s
->current_file_ok
= (err
== UNZ_OK
);
950 // Unzip Helper Functions - should be here?
951 ///////////////////////////////////////////
955 Read the local header of the current zipfile
956 Check the coherency of the local header and info in the end of central
957 directory about this file
958 store in *piSizeVar the size of extra info in local header
959 (filename and size of extra field data)
961 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
962 poffset_local_extrafield
,
963 psize_local_extrafield
)
966 uLong
*poffset_local_extrafield
;
967 uInt
*psize_local_extrafield
;
969 uLong uMagic
,uData
,uFlags
;
971 uLong size_extra_field
;
975 *poffset_local_extrafield
= 0;
976 *psize_local_extrafield
= 0;
978 if (ZSEEK(s
->z_filefunc
, s
->filestream
,s
->cur_file_info_internal
.offset_curfile
+
979 s
->byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
985 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
987 else if (uMagic
!=0x04034b50)
990 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
993 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
996 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uFlags
) != UNZ_OK
)
999 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
1001 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
1004 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
1005 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1008 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* date/time */
1011 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* crc */
1013 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
1017 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size compr */
1019 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
1023 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size uncompr */
1025 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
1030 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_filename
) != UNZ_OK
)
1032 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
1035 *piSizeVar
+= (uInt
)size_filename
;
1037 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_extra_field
) != UNZ_OK
)
1039 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
1040 SIZEZIPLOCALHEADER
+ size_filename
;
1041 *psize_local_extrafield
= (uInt
)size_extra_field
;
1043 *piSizeVar
+= (uInt
)size_extra_field
;
1049 Open for reading data the current file in the zipfile.
1050 If there is no error and the file is opened, the return value is UNZ_OK.
1052 extern int ZEXPORT
unzOpenCurrentFile3 (file
, method
, level
, raw
, password
)
1057 const char* password
;
1062 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1063 uLong offset_local_extrafield
; /* offset of the local extra field */
1064 uInt size_local_extrafield
; /* size of the local extra field */
1068 if (password
!= NULL
)
1069 return UNZ_PARAMERROR
;
1073 return UNZ_PARAMERROR
;
1075 if (!s
->current_file_ok
)
1076 return UNZ_PARAMERROR
;
1078 if (s
->pfile_in_zip_read
!= NULL
)
1079 unzCloseCurrentFile(file
);
1081 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1082 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1083 return UNZ_BADZIPFILE
;
1085 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1086 ALLOC(sizeof(file_in_zip_read_info_s
));
1087 if (pfile_in_zip_read_info
==NULL
)
1088 return UNZ_INTERNALERROR
;
1090 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1091 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1092 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1093 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1094 pfile_in_zip_read_info
->raw
=raw
;
1096 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1098 TRYFREE(pfile_in_zip_read_info
);
1099 return UNZ_INTERNALERROR
;
1102 pfile_in_zip_read_info
->stream_initialised
=0;
1105 *method
= (int)s
->cur_file_info
.compression_method
;
1110 switch (s
->cur_file_info
.flag
& 0x06)
1112 case 6 : *level
= 1; break;
1113 case 4 : *level
= 2; break;
1114 case 2 : *level
= 9; break;
1118 if ((s
->cur_file_info
.compression_method
!=0) &&
1119 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1122 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1123 pfile_in_zip_read_info
->crc32
=0;
1124 pfile_in_zip_read_info
->compression_method
=
1125 s
->cur_file_info
.compression_method
;
1126 pfile_in_zip_read_info
->filestream
=s
->filestream
;
1127 pfile_in_zip_read_info
->z_filefunc
=s
->z_filefunc
;
1128 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1130 pfile_in_zip_read_info
->stream
.total_out
= 0;
1132 if ((s
->cur_file_info
.compression_method
==Z_DEFLATED
) &&
1135 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1136 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1137 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1138 pfile_in_zip_read_info
->stream
.next_in
= (voidpf
)0;
1139 pfile_in_zip_read_info
->stream
.avail_in
= 0;
1141 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1143 pfile_in_zip_read_info
->stream_initialised
=1;
1146 TRYFREE(pfile_in_zip_read_info
);
1149 /* windowBits is passed < 0 to tell that there is no zlib header.
1150 * Note that in this case inflate *requires* an extra "dummy" byte
1151 * after the compressed stream in order to complete decompression and
1152 * return Z_STREAM_END.
1153 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1154 * size of both compressed and uncompressed data
1157 pfile_in_zip_read_info
->rest_read_compressed
=
1158 s
->cur_file_info
.compressed_size
;
1159 pfile_in_zip_read_info
->rest_read_uncompressed
=
1160 s
->cur_file_info
.uncompressed_size
;
1163 pfile_in_zip_read_info
->pos_in_zipfile
=
1164 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1167 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1169 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1172 if (password
!= NULL
)
1175 s
->pcrc_32_tab
= get_crc_table();
1176 init_keys(password
,s
->keys
,s
->pcrc_32_tab
);
1177 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
1178 s
->pfile_in_zip_read
->pos_in_zipfile
+
1179 s
->pfile_in_zip_read
->byte_before_the_zipfile
,
1181 return UNZ_INTERNALERROR
;
1182 if(ZREAD(s
->z_filefunc
, s
->filestream
,source
, 12)<12)
1183 return UNZ_INTERNALERROR
;
1185 for (i
= 0; i
<12; i
++)
1186 zdecode(s
->keys
,s
->pcrc_32_tab
,source
[i
]);
1188 s
->pfile_in_zip_read
->pos_in_zipfile
+=12;
1197 extern int ZEXPORT
unzOpenCurrentFile (file
)
1200 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, NULL
);
1203 extern int ZEXPORT
unzOpenCurrentFilePassword (file
, password
)
1205 const char* password
;
1207 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, password
);
1210 extern int ZEXPORT
unzOpenCurrentFile2 (file
,method
,level
,raw
)
1216 return unzOpenCurrentFile3(file
, method
, level
, raw
, NULL
);
1220 Read bytes from the current file.
1221 buf contain buffer where data must be copied
1222 len the size of buf.
1224 return the number of byte copied if somes bytes are copied
1225 return 0 if the end of file was reached
1226 return <0 with error code if there is an error
1227 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1229 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1237 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1239 return UNZ_PARAMERROR
;
1241 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1243 if (pfile_in_zip_read_info
==NULL
)
1244 return UNZ_PARAMERROR
;
1247 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1248 return UNZ_END_OF_LIST_OF_FILE
;
1252 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1254 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1256 if ((len
>pfile_in_zip_read_info
->rest_read_uncompressed
) &&
1257 (!(pfile_in_zip_read_info
->raw
)))
1258 pfile_in_zip_read_info
->stream
.avail_out
=
1259 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1261 if ((len
>pfile_in_zip_read_info
->rest_read_compressed
+
1262 pfile_in_zip_read_info
->stream
.avail_in
) &&
1263 (pfile_in_zip_read_info
->raw
))
1264 pfile_in_zip_read_info
->stream
.avail_out
=
1265 (uInt
)pfile_in_zip_read_info
->rest_read_compressed
+
1266 pfile_in_zip_read_info
->stream
.avail_in
;
1268 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1270 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1271 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1273 uInt uReadThis
= UNZ_BUFSIZE
;
1274 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1275 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1278 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1279 pfile_in_zip_read_info
->filestream
,
1280 pfile_in_zip_read_info
->pos_in_zipfile
+
1281 pfile_in_zip_read_info
->byte_before_the_zipfile
,
1282 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1284 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1285 pfile_in_zip_read_info
->filestream
,
1286 pfile_in_zip_read_info
->read_buffer
,
1287 uReadThis
)!=uReadThis
)
1295 for(i
=0;i
<uReadThis
;i
++)
1296 pfile_in_zip_read_info
->read_buffer
[i
] =
1297 zdecode(s
->keys
,s
->pcrc_32_tab
,
1298 pfile_in_zip_read_info
->read_buffer
[i
]);
1303 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1305 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1307 pfile_in_zip_read_info
->stream
.next_in
=
1308 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1309 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1312 if ((pfile_in_zip_read_info
->compression_method
==0) || (pfile_in_zip_read_info
->raw
))
1316 if ((pfile_in_zip_read_info
->stream
.avail_in
== 0) &&
1317 (pfile_in_zip_read_info
->rest_read_compressed
== 0))
1318 return (iRead
==0) ? UNZ_EOF
: iRead
;
1320 if (pfile_in_zip_read_info
->stream
.avail_out
<
1321 pfile_in_zip_read_info
->stream
.avail_in
)
1322 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1324 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1326 for (i
=0;i
<uDoCopy
;i
++)
1327 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1328 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1330 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1331 pfile_in_zip_read_info
->stream
.next_out
,
1333 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1334 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1335 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1336 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1337 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1338 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1343 uLong uTotalOutBefore
,uTotalOutAfter
;
1344 const Bytef
*bufBefore
;
1346 int flush
=Z_SYNC_FLUSH
;
1348 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1349 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1352 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1353 pfile_in_zip_read_info->stream.avail_out) &&
1354 (pfile_in_zip_read_info->rest_read_compressed == 0))
1357 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1359 if ((err
>=0) && (pfile_in_zip_read_info
->stream
.msg
!=NULL
))
1362 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1363 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1365 pfile_in_zip_read_info
->crc32
=
1366 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1369 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1372 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1374 if (err
==Z_STREAM_END
)
1375 return (iRead
==0) ? UNZ_EOF
: iRead
;
1388 Give the current position in uncompressed data
1390 extern z_off_t ZEXPORT
unztell (file
)
1394 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1396 return UNZ_PARAMERROR
;
1398 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1400 if (pfile_in_zip_read_info
==NULL
)
1401 return UNZ_PARAMERROR
;
1403 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1408 return 1 if the end of file was reached, 0 elsewhere
1410 extern int ZEXPORT
unzeof (file
)
1414 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1416 return UNZ_PARAMERROR
;
1418 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1420 if (pfile_in_zip_read_info
==NULL
)
1421 return UNZ_PARAMERROR
;
1423 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1432 Read extra field from the current file (opened by unzOpenCurrentFile)
1433 This is the local-header version of the extra field (sometimes, there is
1434 more info in the local-header version than in the central-header)
1436 if buf==NULL, it return the size of the local extra field that can be read
1438 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1440 the return value is the number of bytes copied in buf, or (if <0)
1443 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1449 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1454 return UNZ_PARAMERROR
;
1456 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1458 if (pfile_in_zip_read_info
==NULL
)
1459 return UNZ_PARAMERROR
;
1461 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1462 pfile_in_zip_read_info
->pos_local_extrafield
);
1465 return (int)size_to_read
;
1467 if (len
>size_to_read
)
1468 read_now
= (uInt
)size_to_read
;
1470 read_now
= (uInt
)len
;
1475 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1476 pfile_in_zip_read_info
->filestream
,
1477 pfile_in_zip_read_info
->offset_local_extrafield
+
1478 pfile_in_zip_read_info
->pos_local_extrafield
,
1479 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1482 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1483 pfile_in_zip_read_info
->filestream
,
1484 buf
,read_now
)!=read_now
)
1487 return (int)read_now
;
1491 Close the file in zip opened with unzipOpenCurrentFile
1492 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1494 extern int ZEXPORT
unzCloseCurrentFile (file
)
1500 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1502 return UNZ_PARAMERROR
;
1504 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1506 if (pfile_in_zip_read_info
==NULL
)
1507 return UNZ_PARAMERROR
;
1510 if ((pfile_in_zip_read_info
->rest_read_uncompressed
== 0) &&
1511 (!pfile_in_zip_read_info
->raw
))
1513 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1518 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1519 pfile_in_zip_read_info
->read_buffer
= NULL
;
1520 if (pfile_in_zip_read_info
->stream_initialised
)
1521 inflateEnd(&pfile_in_zip_read_info
->stream
);
1523 pfile_in_zip_read_info
->stream_initialised
= 0;
1524 TRYFREE(pfile_in_zip_read_info
);
1526 s
->pfile_in_zip_read
=NULL
;
1533 Get the global comment string of the ZipFile, in the szComment buffer.
1534 uSizeBuf is the size of the szComment buffer.
1535 return the number of byte copied or an error code <0
1537 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1545 return UNZ_PARAMERROR
;
1548 uReadThis
= uSizeBuf
;
1549 if (uReadThis
>s
->gi
.size_comment
)
1550 uReadThis
= s
->gi
.size_comment
;
1552 if (ZSEEK(s
->z_filefunc
,s
->filestream
,s
->central_pos
+22,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1558 if (ZREAD(s
->z_filefunc
,s
->filestream
,szComment
,uReadThis
)!=uReadThis
)
1562 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1563 *(szComment
+s
->gi
.size_comment
)='\0';
1564 return (int)uReadThis
;
1567 /* Additions by RX '2004 */
1568 extern uLong ZEXPORT
unzGetOffset (file
)
1574 return UNZ_PARAMERROR
;
1576 if (!s
->current_file_ok
)
1578 if (s
->gi
.number_entry
!= 0 && s
->gi
.number_entry
!= 0xffff)
1579 if (s
->num_file
==s
->gi
.number_entry
)
1581 return s
->pos_in_central_dir
;
1584 extern int ZEXPORT
unzSetOffset (file
, pos
)
1592 return UNZ_PARAMERROR
;
1595 s
->pos_in_central_dir
= pos
;
1596 s
->num_file
= s
->gi
.number_entry
; /* hack */
1597 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1598 &s
->cur_file_info_internal
,
1599 NULL
,0,NULL
,0,NULL
,0);
1600 s
->current_file_ok
= (err
== UNZ_OK
);