3 /* unzip.c -- IO for uncompress .zip files using zlib
4 Version 1.01e, February 12th, 2005
6 Copyright (C) 1998-2005 Gilles Vollant
8 Read unzip.h for more info
11 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
12 compatibility with older software. The following is from the original crypt.c. Code
13 woven in by Terry Thorsen 1/2003.
16 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
18 See the accompanying file LICENSE, version 2000-Apr-09 or later
19 (the contents of which are also included in zip.h) for terms of use.
20 If, for some reason, all these files are missing, the Info-ZIP license
21 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
24 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
26 The encryption/decryption parts of this source code (as opposed to the
27 non-echoing password parts) were originally written in Europe. The
28 whole source package can be freely distributed, including from the USA.
29 (Prior to January 2000, re-export from the US was a violation of US law.)
33 This encryption code is a direct transcription of the algorithm from
34 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
35 file (appnote.txt) is distributed with the PKZIP program (even in the
36 version without encryption capabilities).
61 /* compile with -Dlocal if your debugger can't find static symbols */
64 #ifndef CASESENSITIVITYDEFAULT_NO
65 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
66 # define CASESENSITIVITYDEFAULT_NO
72 #define UNZ_BUFSIZE (16384)
75 #ifndef UNZ_MAXFILENAMEINZIP
76 #define UNZ_MAXFILENAMEINZIP (256)
80 # define ALLOC(size) (malloc(size))
83 # define TRYFREE(p) {if (p) free(p);}
86 #define SIZECENTRALDIRITEM (0x2e)
87 #define SIZEZIPLOCALHEADER (0x1e)
92 const char unz_copyright
[] =
93 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
95 /* unz_file_info_interntal contain internal info about a file in zipfile*/
96 typedef struct unz_file_info_internal_s
98 uLong offset_curfile
;/* relative offset of local header 4 bytes */
99 } unz_file_info_internal
;
102 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
103 when reading and decompress it */
106 char *read_buffer
; /* internal buffer for compressed data */
107 z_stream stream
; /* zLib stream structure for inflate */
109 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
110 uLong stream_initialised
; /* flag set if stream structure is initialised*/
112 uLong offset_local_extrafield
;/* offset of the local extra field */
113 uInt size_local_extrafield
;/* size of the local extra field */
114 uLong pos_local_extrafield
; /* position in the local extra field in read*/
116 uLong crc32
; /* crc32 of all data uncompressed */
117 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
118 uLong rest_read_compressed
; /* number of byte to be decompressed */
119 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
120 zlib_filefunc_def z_filefunc
;
121 voidpf filestream
; /* io structore of the zipfile */
122 uLong compression_method
; /* compression method (0==store) */
123 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
125 } file_in_zip_read_info_s
;
128 /* unz_s contain internal information about the zipfile
132 zlib_filefunc_def z_filefunc
;
133 voidpf filestream
; /* io structore of the zipfile */
134 unz_global_info gi
; /* public global information */
135 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
136 uLong num_file
; /* number of the current file in the zipfile*/
137 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
138 uLong current_file_ok
; /* flag about the usability of the current file*/
139 uLong central_pos
; /* position of the beginning of the central dir*/
141 uLong size_central_dir
; /* size of the central directory */
142 uLong offset_central_dir
; /* offset of start of central directory with
143 respect to the starting disk number */
145 unz_file_info cur_file_info
; /* public info about the current file in zip*/
146 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
147 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
148 file if we are decompressing it */
151 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
152 const unsigned long* pcrc_32_tab
;
161 /* ===========================================================================
162 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
164 IN assertion: the stream s has been sucessfully opened for reading.
168 local
int unzlocal_getByte
OF((
169 const zlib_filefunc_def
* pzlib_filefunc_def
,
173 local
int unzlocal_getByte(pzlib_filefunc_def
,filestream
,pi
)
174 const zlib_filefunc_def
* pzlib_filefunc_def
;
179 int err
= (int)ZREAD(*pzlib_filefunc_def
,filestream
,&c
,1);
187 if (ZERROR(*pzlib_filefunc_def
,filestream
))
195 /* ===========================================================================
196 Reads a long in LSB order from the given gz_stream. Sets
198 local
int unzlocal_getShort
OF((
199 const zlib_filefunc_def
* pzlib_filefunc_def
,
203 local
int unzlocal_getShort (pzlib_filefunc_def
,filestream
,pX
)
204 const zlib_filefunc_def
* pzlib_filefunc_def
;
212 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
216 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
226 local
int unzlocal_getLong
OF((
227 const zlib_filefunc_def
* pzlib_filefunc_def
,
231 local
int unzlocal_getLong (pzlib_filefunc_def
,filestream
,pX
)
232 const zlib_filefunc_def
* pzlib_filefunc_def
;
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
);
252 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
263 /* My own strcmpi / strcasecmp */
264 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
265 const char* fileName1
;
266 const char* fileName2
;
270 char c1
=*(fileName1
++);
271 char c2
=*(fileName2
++);
272 if ((c1
>='a') && (c1
<='z'))
274 if ((c2
>='a') && (c2
<='z'))
277 return ((c2
=='\0') ? 0 : -1);
288 #ifdef CASESENSITIVITYDEFAULT_NO
289 #define CASESENSITIVITYDEFAULTVALUE 2
291 #define CASESENSITIVITYDEFAULTVALUE 1
294 #ifndef STRCMPCASENOSENTIVEFUNCTION
295 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
299 Compare two filename (fileName1,fileName2).
300 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
301 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
303 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
304 (like 1 on Unix, 2 on Windows)
307 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
308 const char* fileName1
;
309 const char* fileName2
;
310 int iCaseSensitivity
;
312 if (iCaseSensitivity
==0)
313 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
315 if (iCaseSensitivity
==1)
316 return strcmp(fileName1
,fileName2
);
318 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
321 #ifndef BUFREADCOMMENT
322 #define BUFREADCOMMENT (0x400)
326 Locate the Central directory of a zipfile (at the end, just before
329 local uLong unzlocal_SearchCentralDir
OF((
330 const zlib_filefunc_def
* pzlib_filefunc_def
,
333 local uLong
unzlocal_SearchCentralDir(pzlib_filefunc_def
,filestream
)
334 const zlib_filefunc_def
* pzlib_filefunc_def
;
340 uLong uMaxBack
=0xffff; /* maximum size of global comment */
343 if (ZSEEK(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
347 uSizeFile
= ZTELL(*pzlib_filefunc_def
,filestream
);
349 if (uMaxBack
>uSizeFile
)
350 uMaxBack
= uSizeFile
;
352 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
357 while (uBackRead
<uMaxBack
)
359 uLong uReadSize
,uReadPos
;
361 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
362 uBackRead
= uMaxBack
;
364 uBackRead
+=BUFREADCOMMENT
;
365 uReadPos
= uSizeFile
-uBackRead
;
367 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
368 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
369 if (ZSEEK(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
372 if (ZREAD(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
375 for (i
=(int)uReadSize
-3; (i
--)>0;)
376 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
377 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
379 uPosFound
= uReadPos
+i
;
391 Open a Zip file. path contain the full pathname (by example,
392 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
394 If the zipfile cannot be opened (file doesn't exist or in not valid), the
395 return value is NULL.
396 Else, the return value is a unzFile Handle, usable with other function
397 of this unzip package.
399 extern unzFile ZEXPORT
unzOpen2 (path
, pzlib_filefunc_def
)
401 zlib_filefunc_def
* pzlib_filefunc_def
;
405 uLong central_pos
,uL
;
407 uLong number_disk
; /* number of the current dist, used for
408 spaning ZIP, unsupported, always 0*/
409 uLong number_disk_with_CD
; /* number the the disk with central dir, used
410 for spaning ZIP, unsupported, always 0*/
411 uLong number_entry_CD
; /* total number of entries in
413 (same than number_entry on nospan) */
417 if (unz_copyright
[0]!=' ')
420 if (pzlib_filefunc_def
==NULL
)
421 fill_fopen_filefunc(&us
.z_filefunc
);
423 us
.z_filefunc
= *pzlib_filefunc_def
;
425 us
.filestream
= (*(us
.z_filefunc
.zopen_file
))(us
.z_filefunc
.opaque
,
427 ZLIB_FILEFUNC_MODE_READ
|
428 ZLIB_FILEFUNC_MODE_EXISTING
);
429 if (us
.filestream
==NULL
)
432 central_pos
= unzlocal_SearchCentralDir(&us
.z_filefunc
,us
.filestream
);
436 if (ZSEEK(us
.z_filefunc
, us
.filestream
,
437 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
440 /* the signature, already checked */
441 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
444 /* number of this disk */
445 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk
)!=UNZ_OK
)
448 /* number of the disk with the start of the central directory */
449 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk_with_CD
)!=UNZ_OK
)
452 /* total number of entries in the central dir on this disk */
453 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.number_entry
)!=UNZ_OK
)
456 /* total number of entries in the central dir */
457 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_entry_CD
)!=UNZ_OK
)
460 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
461 (number_disk_with_CD
!=0) ||
465 /* size of the central directory */
466 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.size_central_dir
)!=UNZ_OK
)
469 /* offset of start of central directory with respect to the
470 starting disk number */
471 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.offset_central_dir
)!=UNZ_OK
)
474 /* zipfile comment length */
475 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.size_comment
)!=UNZ_OK
)
478 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
484 ZCLOSE(us
.z_filefunc
, us
.filestream
);
488 us
.byte_before_the_zipfile
= central_pos
-
489 (us
.offset_central_dir
+us
.size_central_dir
);
490 us
.central_pos
= central_pos
;
491 us
.pfile_in_zip_read
= NULL
;
495 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
497 unzGoToFirstFile((unzFile
)s
);
502 extern unzFile ZEXPORT
unzOpen (path
)
505 return unzOpen2(path
, NULL
);
509 Close a ZipFile opened with unzipOpen.
510 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
511 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
512 return UNZ_OK if there is no problem. */
513 extern int ZEXPORT
unzClose (file
)
518 return UNZ_PARAMERROR
;
521 if (s
->pfile_in_zip_read
!=NULL
)
522 unzCloseCurrentFile(file
);
524 ZCLOSE(s
->z_filefunc
, s
->filestream
);
531 Write info about the ZipFile in the *pglobal_info structure.
532 No preparation of the structure is needed
533 return UNZ_OK if there is no problem. */
534 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
536 unz_global_info
*pglobal_info
;
540 return UNZ_PARAMERROR
;
548 Translate date/time from Dos format to tm_unz (readable more easilty)
550 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
555 uDate
= (uLong
)(ulDosDate
>>16);
556 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
557 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
558 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
560 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
561 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
562 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
566 Get Info about the current file in the zipfile, with internal only info
568 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
569 unz_file_info
*pfile_info
,
570 unz_file_info_internal
571 *pfile_info_internal
,
573 uLong fileNameBufferSize
,
575 uLong extraFieldBufferSize
,
577 uLong commentBufferSize
));
579 local
int unzlocal_GetCurrentFileInfoInternal (file
,
582 szFileName
, fileNameBufferSize
,
583 extraField
, extraFieldBufferSize
,
584 szComment
, commentBufferSize
)
586 unz_file_info
*pfile_info
;
587 unz_file_info_internal
*pfile_info_internal
;
589 uLong fileNameBufferSize
;
591 uLong extraFieldBufferSize
;
593 uLong commentBufferSize
;
596 unz_file_info file_info
;
597 unz_file_info_internal file_info_internal
;
603 return UNZ_PARAMERROR
;
605 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
606 s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,
607 ZLIB_FILEFUNC_SEEK_SET
)!=0)
611 /* we check the magic */
613 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
615 else if (uMagic
!=0x02014b50)
618 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version
) != UNZ_OK
)
621 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version_needed
) != UNZ_OK
)
624 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.flag
) != UNZ_OK
)
627 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.compression_method
) != UNZ_OK
)
630 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.dosDate
) != UNZ_OK
)
633 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
635 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.crc
) != UNZ_OK
)
638 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.compressed_size
) != UNZ_OK
)
641 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.uncompressed_size
) != UNZ_OK
)
644 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_filename
) != UNZ_OK
)
647 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_extra
) != UNZ_OK
)
650 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_comment
) != UNZ_OK
)
653 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.disk_num_start
) != UNZ_OK
)
656 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.internal_fa
) != UNZ_OK
)
659 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.external_fa
) != UNZ_OK
)
662 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
665 lSeek
+=file_info
.size_filename
;
666 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
669 if (file_info
.size_filename
<fileNameBufferSize
)
671 *(szFileName
+file_info
.size_filename
)='\0';
672 uSizeRead
= file_info
.size_filename
;
675 uSizeRead
= fileNameBufferSize
;
677 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
678 if (ZREAD(s
->z_filefunc
, s
->filestream
,szFileName
,uSizeRead
)!=uSizeRead
)
684 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
687 if (file_info
.size_file_extra
<extraFieldBufferSize
)
688 uSizeRead
= file_info
.size_file_extra
;
690 uSizeRead
= extraFieldBufferSize
;
693 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
;
718 if (ZSEEK(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
722 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
723 if (ZREAD(s
->z_filefunc
, s
->filestream
,szComment
,uSizeRead
)!=uSizeRead
)
725 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
728 lSeek
+=file_info
.size_file_comment
;
730 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
731 *pfile_info
=file_info
;
733 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
734 *pfile_info_internal
=file_info_internal
;
742 Write info about the ZipFile in the *pglobal_info structure.
743 No preparation of the structure is needed
744 return UNZ_OK if there is no problem.
746 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
748 szFileName
, fileNameBufferSize
,
749 extraField
, extraFieldBufferSize
,
750 szComment
, commentBufferSize
)
752 unz_file_info
*pfile_info
;
754 uLong fileNameBufferSize
;
756 uLong extraFieldBufferSize
;
758 uLong commentBufferSize
;
760 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
761 szFileName
,fileNameBufferSize
,
762 extraField
,extraFieldBufferSize
,
763 szComment
,commentBufferSize
);
767 Set the current file of the zipfile to the first file.
768 return UNZ_OK if there is no problem
770 extern int ZEXPORT
unzGoToFirstFile (file
)
776 return UNZ_PARAMERROR
;
778 s
->pos_in_central_dir
=s
->offset_central_dir
;
780 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
781 &s
->cur_file_info_internal
,
782 NULL
,0,NULL
,0,NULL
,0);
783 s
->current_file_ok
= (err
== UNZ_OK
);
788 Set the current file of the zipfile to the next file.
789 return UNZ_OK if there is no problem
790 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
792 extern int ZEXPORT
unzGoToNextFile (file
)
799 return UNZ_PARAMERROR
;
801 if (!s
->current_file_ok
)
802 return UNZ_END_OF_LIST_OF_FILE
;
803 if (s
->gi
.number_entry
!= 0xffff) /* 2^16 files overflow hack */
804 if (s
->num_file
+1==s
->gi
.number_entry
)
805 return UNZ_END_OF_LIST_OF_FILE
;
807 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
808 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
810 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
811 &s
->cur_file_info_internal
,
812 NULL
,0,NULL
,0,NULL
,0);
813 s
->current_file_ok
= (err
== UNZ_OK
);
819 Try locate the file szFileName in the zipfile.
820 For the iCaseSensitivity signification, see unzipStringFileNameCompare
823 UNZ_OK if the file is found. It becomes the current file.
824 UNZ_END_OF_LIST_OF_FILE if the file is not found
826 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
828 const char *szFileName
;
829 int iCaseSensitivity
;
834 /* We remember the 'current' position in the file so that we can jump
835 * back there if we fail.
837 unz_file_info cur_file_infoSaved
;
838 unz_file_info_internal cur_file_info_internalSaved
;
840 uLong pos_in_central_dirSaved
;
844 return UNZ_PARAMERROR
;
846 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
847 return UNZ_PARAMERROR
;
850 if (!s
->current_file_ok
)
851 return UNZ_END_OF_LIST_OF_FILE
;
853 /* Save the current state */
854 num_fileSaved
= s
->num_file
;
855 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
856 cur_file_infoSaved
= s
->cur_file_info
;
857 cur_file_info_internalSaved
= s
->cur_file_info_internal
;
859 err
= unzGoToFirstFile(file
);
861 while (err
== UNZ_OK
)
863 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
864 err
= unzGetCurrentFileInfo(file
,NULL
,
865 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
869 if (unzStringFileNameCompare(szCurrentFileName
,
870 szFileName
,iCaseSensitivity
)==0)
872 err
= unzGoToNextFile(file
);
876 /* We failed, so restore the state of the 'current file' to where we
879 s
->num_file
= num_fileSaved
;
880 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
881 s
->cur_file_info
= cur_file_infoSaved
;
882 s
->cur_file_info_internal
= cur_file_info_internalSaved
;
888 ///////////////////////////////////////////
889 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
890 // I need random access
892 // Further optimization could be realized by adding an ability
893 // to cache the directory in memory. The goal being a single
894 // comprehensive file read to put the file I need in a memory.
898 typedef struct unz_file_pos_s
900 uLong pos_in_zip_directory; // offset in file
901 uLong num_of_file; // # of file
905 extern int ZEXPORT
unzGetFilePos(file
, file_pos
)
907 unz_file_pos
* file_pos
;
911 if (file
==NULL
|| file_pos
==NULL
)
912 return UNZ_PARAMERROR
;
914 if (!s
->current_file_ok
)
915 return UNZ_END_OF_LIST_OF_FILE
;
917 file_pos
->pos_in_zip_directory
= s
->pos_in_central_dir
;
918 file_pos
->num_of_file
= s
->num_file
;
923 extern int ZEXPORT
unzGoToFilePos(file
, file_pos
)
925 unz_file_pos
* file_pos
;
930 if (file
==NULL
|| file_pos
==NULL
)
931 return UNZ_PARAMERROR
;
934 /* jump to the right spot */
935 s
->pos_in_central_dir
= file_pos
->pos_in_zip_directory
;
936 s
->num_file
= file_pos
->num_of_file
;
938 /* set the current file */
939 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
940 &s
->cur_file_info_internal
,
941 NULL
,0,NULL
,0,NULL
,0);
943 s
->current_file_ok
= (err
== UNZ_OK
);
948 // Unzip Helper Functions - should be here?
949 ///////////////////////////////////////////
953 Read the local header of the current zipfile
954 Check the coherency of the local header and info in the end of central
955 directory about this file
956 store in *piSizeVar the size of extra info in local header
957 (filename and size of extra field data)
959 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
960 poffset_local_extrafield
,
961 psize_local_extrafield
)
964 uLong
*poffset_local_extrafield
;
965 uInt
*psize_local_extrafield
;
967 uLong uMagic
,uData
,uFlags
;
969 uLong size_extra_field
;
973 *poffset_local_extrafield
= 0;
974 *psize_local_extrafield
= 0;
976 if (ZSEEK(s
->z_filefunc
, s
->filestream
,s
->cur_file_info_internal
.offset_curfile
+
977 s
->byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
982 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
984 else if (uMagic
!=0x04034b50)
987 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
990 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
993 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uFlags
) != UNZ_OK
)
996 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
998 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
1001 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
1002 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1005 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* date/time */
1008 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* crc */
1010 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
1014 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size compr */
1016 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
1020 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size uncompr */
1022 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
1027 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_filename
) != UNZ_OK
)
1029 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
1032 *piSizeVar
+= (uInt
)size_filename
;
1034 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_extra_field
) != UNZ_OK
)
1036 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
1037 SIZEZIPLOCALHEADER
+ size_filename
;
1038 *psize_local_extrafield
= (uInt
)size_extra_field
;
1040 *piSizeVar
+= (uInt
)size_extra_field
;
1046 Open for reading data the current file in the zipfile.
1047 If there is no error and the file is opened, the return value is UNZ_OK.
1049 extern int ZEXPORT
unzOpenCurrentFile3 (file
, method
, level
, raw
, password
)
1054 const char* password
;
1059 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1060 uLong offset_local_extrafield
; /* offset of the local extra field */
1061 uInt size_local_extrafield
; /* size of the local extra field */
1065 if (password
!= NULL
)
1066 return UNZ_PARAMERROR
;
1070 return UNZ_PARAMERROR
;
1072 if (!s
->current_file_ok
)
1073 return UNZ_PARAMERROR
;
1075 if (s
->pfile_in_zip_read
!= NULL
)
1076 unzCloseCurrentFile(file
);
1078 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1079 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1080 return UNZ_BADZIPFILE
;
1082 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1083 ALLOC(sizeof(file_in_zip_read_info_s
));
1084 if (pfile_in_zip_read_info
==NULL
)
1085 return UNZ_INTERNALERROR
;
1087 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1088 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1089 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1090 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1091 pfile_in_zip_read_info
->raw
=raw
;
1093 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1095 TRYFREE(pfile_in_zip_read_info
);
1096 return UNZ_INTERNALERROR
;
1099 pfile_in_zip_read_info
->stream_initialised
=0;
1102 *method
= (int)s
->cur_file_info
.compression_method
;
1107 switch (s
->cur_file_info
.flag
& 0x06)
1109 case 6 : *level
= 1; break;
1110 case 4 : *level
= 2; break;
1111 case 2 : *level
= 9; break;
1115 if ((s
->cur_file_info
.compression_method
!=0) &&
1116 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1119 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1120 pfile_in_zip_read_info
->crc32
=0;
1121 pfile_in_zip_read_info
->compression_method
=
1122 s
->cur_file_info
.compression_method
;
1123 pfile_in_zip_read_info
->filestream
=s
->filestream
;
1124 pfile_in_zip_read_info
->z_filefunc
=s
->z_filefunc
;
1125 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1127 pfile_in_zip_read_info
->stream
.total_out
= 0;
1129 if ((s
->cur_file_info
.compression_method
==Z_DEFLATED
) &&
1132 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1133 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1134 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1135 pfile_in_zip_read_info
->stream
.next_in
= (voidpf
)0;
1136 pfile_in_zip_read_info
->stream
.avail_in
= 0;
1138 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1140 pfile_in_zip_read_info
->stream_initialised
=1;
1143 TRYFREE(pfile_in_zip_read_info
);
1146 /* windowBits is passed < 0 to tell that there is no zlib header.
1147 * Note that in this case inflate *requires* an extra "dummy" byte
1148 * after the compressed stream in order to complete decompression and
1149 * return Z_STREAM_END.
1150 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1151 * size of both compressed and uncompressed data
1154 pfile_in_zip_read_info
->rest_read_compressed
=
1155 s
->cur_file_info
.compressed_size
;
1156 pfile_in_zip_read_info
->rest_read_uncompressed
=
1157 s
->cur_file_info
.uncompressed_size
;
1160 pfile_in_zip_read_info
->pos_in_zipfile
=
1161 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1164 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1166 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1169 if (password
!= NULL
)
1172 s
->pcrc_32_tab
= get_crc_table();
1173 init_keys(password
,s
->keys
,s
->pcrc_32_tab
);
1174 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
1175 s
->pfile_in_zip_read
->pos_in_zipfile
+
1176 s
->pfile_in_zip_read
->byte_before_the_zipfile
,
1178 return UNZ_INTERNALERROR
;
1179 if(ZREAD(s
->z_filefunc
, s
->filestream
,source
, 12)<12)
1180 return UNZ_INTERNALERROR
;
1182 for (i
= 0; i
<12; i
++)
1183 zdecode(s
->keys
,s
->pcrc_32_tab
,source
[i
]);
1185 s
->pfile_in_zip_read
->pos_in_zipfile
+=12;
1194 extern int ZEXPORT
unzOpenCurrentFile (file
)
1197 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, NULL
);
1200 extern int ZEXPORT
unzOpenCurrentFilePassword (file
, password
)
1202 const char* password
;
1204 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, password
);
1207 extern int ZEXPORT
unzOpenCurrentFile2 (file
,method
,level
,raw
)
1213 return unzOpenCurrentFile3(file
, method
, level
, raw
, NULL
);
1217 Read bytes from the current file.
1218 buf contain buffer where data must be copied
1219 len the size of buf.
1221 return the number of byte copied if somes bytes are copied
1222 return 0 if the end of file was reached
1223 return <0 with error code if there is an error
1224 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1226 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1234 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1236 return UNZ_PARAMERROR
;
1238 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1240 if (pfile_in_zip_read_info
==NULL
)
1241 return UNZ_PARAMERROR
;
1244 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1245 return UNZ_END_OF_LIST_OF_FILE
;
1249 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1251 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1253 if ((len
>pfile_in_zip_read_info
->rest_read_uncompressed
) &&
1254 (!(pfile_in_zip_read_info
->raw
)))
1255 pfile_in_zip_read_info
->stream
.avail_out
=
1256 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1258 if ((len
>pfile_in_zip_read_info
->rest_read_compressed
+
1259 pfile_in_zip_read_info
->stream
.avail_in
) &&
1260 (pfile_in_zip_read_info
->raw
))
1261 pfile_in_zip_read_info
->stream
.avail_out
=
1262 (uInt
)pfile_in_zip_read_info
->rest_read_compressed
+
1263 pfile_in_zip_read_info
->stream
.avail_in
;
1265 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1267 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1268 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1270 uInt uReadThis
= UNZ_BUFSIZE
;
1271 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1272 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1275 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1276 pfile_in_zip_read_info
->filestream
,
1277 pfile_in_zip_read_info
->pos_in_zipfile
+
1278 pfile_in_zip_read_info
->byte_before_the_zipfile
,
1279 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1281 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1282 pfile_in_zip_read_info
->filestream
,
1283 pfile_in_zip_read_info
->read_buffer
,
1284 uReadThis
)!=uReadThis
)
1292 for(i
=0;i
<uReadThis
;i
++)
1293 pfile_in_zip_read_info
->read_buffer
[i
] =
1294 zdecode(s
->keys
,s
->pcrc_32_tab
,
1295 pfile_in_zip_read_info
->read_buffer
[i
]);
1300 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1302 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1304 pfile_in_zip_read_info
->stream
.next_in
=
1305 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1306 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1309 if ((pfile_in_zip_read_info
->compression_method
==0) || (pfile_in_zip_read_info
->raw
))
1313 if ((pfile_in_zip_read_info
->stream
.avail_in
== 0) &&
1314 (pfile_in_zip_read_info
->rest_read_compressed
== 0))
1315 return (iRead
==0) ? UNZ_EOF
: iRead
;
1317 if (pfile_in_zip_read_info
->stream
.avail_out
<
1318 pfile_in_zip_read_info
->stream
.avail_in
)
1319 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1321 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1323 for (i
=0;i
<uDoCopy
;i
++)
1324 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1325 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1327 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1328 pfile_in_zip_read_info
->stream
.next_out
,
1330 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1331 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1332 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1333 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1334 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1335 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1340 uLong uTotalOutBefore
,uTotalOutAfter
;
1341 const Bytef
*bufBefore
;
1343 int flush
=Z_SYNC_FLUSH
;
1345 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1346 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1349 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1350 pfile_in_zip_read_info->stream.avail_out) &&
1351 (pfile_in_zip_read_info->rest_read_compressed == 0))
1354 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1356 if ((err
>=0) && (pfile_in_zip_read_info
->stream
.msg
!=NULL
))
1359 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1360 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1362 pfile_in_zip_read_info
->crc32
=
1363 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1366 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1369 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1371 if (err
==Z_STREAM_END
)
1372 return (iRead
==0) ? UNZ_EOF
: iRead
;
1385 Give the current position in uncompressed data
1387 extern z_off_t ZEXPORT
unztell (file
)
1391 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1393 return UNZ_PARAMERROR
;
1395 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1397 if (pfile_in_zip_read_info
==NULL
)
1398 return UNZ_PARAMERROR
;
1400 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1405 return 1 if the end of file was reached, 0 elsewhere
1407 extern int ZEXPORT
unzeof (file
)
1411 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1413 return UNZ_PARAMERROR
;
1415 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1417 if (pfile_in_zip_read_info
==NULL
)
1418 return UNZ_PARAMERROR
;
1420 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1429 Read extra field from the current file (opened by unzOpenCurrentFile)
1430 This is the local-header version of the extra field (sometimes, there is
1431 more info in the local-header version than in the central-header)
1433 if buf==NULL, it return the size of the local extra field that can be read
1435 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1437 the return value is the number of bytes copied in buf, or (if <0)
1440 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1446 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1451 return UNZ_PARAMERROR
;
1453 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1455 if (pfile_in_zip_read_info
==NULL
)
1456 return UNZ_PARAMERROR
;
1458 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1459 pfile_in_zip_read_info
->pos_local_extrafield
);
1462 return (int)size_to_read
;
1464 if (len
>size_to_read
)
1465 read_now
= (uInt
)size_to_read
;
1467 read_now
= (uInt
)len
;
1472 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1473 pfile_in_zip_read_info
->filestream
,
1474 pfile_in_zip_read_info
->offset_local_extrafield
+
1475 pfile_in_zip_read_info
->pos_local_extrafield
,
1476 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1479 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1480 pfile_in_zip_read_info
->filestream
,
1481 buf
,read_now
)!=read_now
)
1484 return (int)read_now
;
1488 Close the file in zip opened with unzipOpenCurrentFile
1489 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1491 extern int ZEXPORT
unzCloseCurrentFile (file
)
1497 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1499 return UNZ_PARAMERROR
;
1501 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1503 if (pfile_in_zip_read_info
==NULL
)
1504 return UNZ_PARAMERROR
;
1507 if ((pfile_in_zip_read_info
->rest_read_uncompressed
== 0) &&
1508 (!pfile_in_zip_read_info
->raw
))
1510 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1515 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1516 pfile_in_zip_read_info
->read_buffer
= NULL
;
1517 if (pfile_in_zip_read_info
->stream_initialised
)
1518 inflateEnd(&pfile_in_zip_read_info
->stream
);
1520 pfile_in_zip_read_info
->stream_initialised
= 0;
1521 TRYFREE(pfile_in_zip_read_info
);
1523 s
->pfile_in_zip_read
=NULL
;
1530 Get the global comment string of the ZipFile, in the szComment buffer.
1531 uSizeBuf is the size of the szComment buffer.
1532 return the number of byte copied or an error code <0
1534 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1543 return UNZ_PARAMERROR
;
1546 uReadThis
= uSizeBuf
;
1547 if (uReadThis
>s
->gi
.size_comment
)
1548 uReadThis
= s
->gi
.size_comment
;
1550 if (ZSEEK(s
->z_filefunc
,s
->filestream
,s
->central_pos
+22,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1556 if (ZREAD(s
->z_filefunc
,s
->filestream
,szComment
,uReadThis
)!=uReadThis
)
1560 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1561 *(szComment
+s
->gi
.size_comment
)='\0';
1562 return (int)uReadThis
;
1565 /* Additions by RX '2004 */
1566 extern uLong ZEXPORT
unzGetOffset (file
)
1572 return UNZ_PARAMERROR
;
1574 if (!s
->current_file_ok
)
1576 if (s
->gi
.number_entry
!= 0 && s
->gi
.number_entry
!= 0xffff)
1577 if (s
->num_file
==s
->gi
.number_entry
)
1579 return s
->pos_in_central_dir
;
1582 extern int ZEXPORT
unzSetOffset (file
, pos
)
1590 return UNZ_PARAMERROR
;
1593 s
->pos_in_central_dir
= pos
;
1594 s
->num_file
= s
->gi
.number_entry
; /* hack */
1595 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1596 &s
->cur_file_info_internal
,
1597 NULL
,0,NULL
,0,NULL
,0);
1598 s
->current_file_ok
= (err
== UNZ_OK
);