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).
59
/* compile with -Dlocal if your debugger can't find static symbols */
62
#ifndef CASESENSITIVITYDEFAULT_NO
63
# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
64
# define CASESENSITIVITYDEFAULT_NO
70
#define UNZ_BUFSIZE (16384)
73
#ifndef UNZ_MAXFILENAMEINZIP
74
#define UNZ_MAXFILENAMEINZIP (256)
78
# define ALLOC(size) (malloc(size))
81
# define TRYFREE(p) {if (p) free(p);}
84
#define SIZECENTRALDIRITEM (0x2e)
85
#define SIZEZIPLOCALHEADER (0x1e)
90
const char unz_copyright[] =
91
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
93
/* unz_file_info_interntal contain internal info about a file in zipfile*/
94
typedef struct unz_file_info_internal_s
96
uLong offset_curfile;/* relative offset of local header 4 bytes */
97
} unz_file_info_internal;
100
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
101
when reading and decompress it */
104
char *read_buffer; /* internal buffer for compressed data */
105
z_stream stream; /* zLib stream structure for inflate */
107
uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
108
uLong stream_initialised; /* flag set if stream structure is initialised*/
110
uLong offset_local_extrafield;/* offset of the local extra field */
111
uInt size_local_extrafield;/* size of the local extra field */
112
uLong pos_local_extrafield; /* position in the local extra field in read*/
114
uLong crc32; /* crc32 of all data uncompressed */
115
uLong crc32_wait; /* crc32 we must obtain after decompress all */
116
uLong rest_read_compressed; /* number of byte to be decompressed */
117
uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
118
zlib_filefunc_def z_filefunc;
119
voidpf filestream; /* io structore of the zipfile */
120
uLong compression_method; /* compression method (0==store) */
121
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
123
} file_in_zip_read_info_s;
126
/* unz_s contain internal information about the zipfile
130
zlib_filefunc_def z_filefunc;
131
voidpf filestream; /* io structore of the zipfile */
132
unz_global_info gi; /* public global information */
133
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
134
uLong num_file; /* number of the current file in the zipfile*/
135
uLong pos_in_central_dir; /* pos of the current file in the central dir*/
136
uLong current_file_ok; /* flag about the usability of the current file*/
137
uLong central_pos; /* position of the beginning of the central dir*/
139
uLong size_central_dir; /* size of the central directory */
140
uLong offset_central_dir; /* offset of start of central directory with
141
respect to the starting disk number */
143
unz_file_info cur_file_info; /* public info about the current file in zip*/
144
unz_file_info_internal cur_file_info_internal; /* private info about it*/
145
file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
146
file if we are decompressing it */
149
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
150
const unsigned long* pcrc_32_tab;
159
/* ===========================================================================
160
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
162
IN assertion: the stream s has been sucessfully opened for reading.
166
local int unzlocal_getByte OF((
167
const zlib_filefunc_def* pzlib_filefunc_def,
171
local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
172
const zlib_filefunc_def* pzlib_filefunc_def;
177
int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
185
if (ZERROR(*pzlib_filefunc_def,filestream))
193
/* ===========================================================================
194
Reads a long in LSB order from the given gz_stream. Sets
196
local int unzlocal_getShort OF((
197
const zlib_filefunc_def* pzlib_filefunc_def,
201
local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
202
const zlib_filefunc_def* pzlib_filefunc_def;
210
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
214
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
224
local int unzlocal_getLong OF((
225
const zlib_filefunc_def* pzlib_filefunc_def,
229
local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
230
const zlib_filefunc_def* pzlib_filefunc_def;
238
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
242
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
246
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
250
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
261
/* My own strcmpi / strcasecmp */
262
local int strcmpcasenosensitive_internal (fileName1,fileName2)
263
const char* fileName1;
264
const char* fileName2;
268
char c1=*(fileName1++);
269
char c2=*(fileName2++);
270
if ((c1>='a') && (c1<='z'))
272
if ((c2>='a') && (c2<='z'))
275
return ((c2=='\0') ? 0 : -1);
286
#ifdef CASESENSITIVITYDEFAULT_NO
287
#define CASESENSITIVITYDEFAULTVALUE 2
289
#define CASESENSITIVITYDEFAULTVALUE 1
292
#ifndef STRCMPCASENOSENTIVEFUNCTION
293
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
297
Compare two filename (fileName1,fileName2).
298
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
299
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
301
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
302
(like 1 on Unix, 2 on Windows)
305
extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
306
const char* fileName1;
307
const char* fileName2;
308
int iCaseSensitivity;
310
if (iCaseSensitivity==0)
311
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
313
if (iCaseSensitivity==1)
314
return strcmp(fileName1,fileName2);
316
return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
319
#ifndef BUFREADCOMMENT
320
#define BUFREADCOMMENT (0x400)
324
Locate the Central directory of a zipfile (at the end, just before
327
local uLong unzlocal_SearchCentralDir OF((
328
const zlib_filefunc_def* pzlib_filefunc_def,
331
local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
332
const zlib_filefunc_def* pzlib_filefunc_def;
338
uLong uMaxBack=0xffff; /* maximum size of global comment */
341
if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
345
uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
347
if (uMaxBack>uSizeFile)
348
uMaxBack = uSizeFile;
350
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
355
while (uBackRead<uMaxBack)
357
uLong uReadSize,uReadPos ;
359
if (uBackRead+BUFREADCOMMENT>uMaxBack)
360
uBackRead = uMaxBack;
362
uBackRead+=BUFREADCOMMENT;
363
uReadPos = uSizeFile-uBackRead ;
365
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
366
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
367
if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
370
if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
373
for (i=(int)uReadSize-3; (i--)>0;)
374
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
375
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
377
uPosFound = uReadPos+i;
389
Open a Zip file. path contain the full pathname (by example,
390
on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
392
If the zipfile cannot be opened (file doesn't exist or in not valid), the
393
return value is NULL.
394
Else, the return value is a unzFile Handle, usable with other function
395
of this unzip package.
397
extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
399
zlib_filefunc_def* pzlib_filefunc_def;
403
uLong central_pos,uL;
405
uLong number_disk; /* number of the current dist, used for
406
spaning ZIP, unsupported, always 0*/
407
uLong number_disk_with_CD; /* number the the disk with central dir, used
408
for spaning ZIP, unsupported, always 0*/
409
uLong number_entry_CD; /* total number of entries in
411
(same than number_entry on nospan) */
415
if (unz_copyright[0]!=' ')
418
if (pzlib_filefunc_def==NULL)
419
fill_fopen_filefunc(&us.z_filefunc);
421
us.z_filefunc = *pzlib_filefunc_def;
423
us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
425
ZLIB_FILEFUNC_MODE_READ |
426
ZLIB_FILEFUNC_MODE_EXISTING);
427
if (us.filestream==NULL)
430
central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
434
if (ZSEEK(us.z_filefunc, us.filestream,
435
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
438
/* the signature, already checked */
439
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
442
/* number of this disk */
443
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
446
/* number of the disk with the start of the central directory */
447
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
450
/* total number of entries in the central dir on this disk */
451
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
454
/* total number of entries in the central dir */
455
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
458
if ((number_entry_CD!=us.gi.number_entry) ||
459
(number_disk_with_CD!=0) ||
463
/* size of the central directory */
464
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
467
/* offset of start of central directory with respect to the
468
starting disk number */
469
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
472
/* zipfile comment length */
473
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
476
if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
482
ZCLOSE(us.z_filefunc, us.filestream);
486
us.byte_before_the_zipfile = central_pos -
487
(us.offset_central_dir+us.size_central_dir);
488
us.central_pos = central_pos;
489
us.pfile_in_zip_read = NULL;
493
s=(unz_s*)ALLOC(sizeof(unz_s));
495
unzGoToFirstFile((unzFile)s);
500
extern unzFile ZEXPORT unzOpen (path)
503
return unzOpen2(path, NULL);
507
Close a ZipFile opened with unzipOpen.
508
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510
return UNZ_OK if there is no problem. */
511
extern int ZEXPORT unzClose (file)
516
return UNZ_PARAMERROR;
519
if (s->pfile_in_zip_read!=NULL)
520
unzCloseCurrentFile(file);
522
ZCLOSE(s->z_filefunc, s->filestream);
529
Write info about the ZipFile in the *pglobal_info structure.
530
No preparation of the structure is needed
531
return UNZ_OK if there is no problem. */
532
extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
534
unz_global_info *pglobal_info;
538
return UNZ_PARAMERROR;
546
Translate date/time from Dos format to tm_unz (readable more easilty)
548
local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
553
uDate = (uLong)(ulDosDate>>16);
554
ptm->tm_mday = (uInt)(uDate&0x1f) ;
555
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
556
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
558
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
559
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
560
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
564
Get Info about the current file in the zipfile, with internal only info
566
local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
567
unz_file_info *pfile_info,
568
unz_file_info_internal
569
*pfile_info_internal,
571
uLong fileNameBufferSize,
573
uLong extraFieldBufferSize,
575
uLong commentBufferSize));
577
local int unzlocal_GetCurrentFileInfoInternal (file,
580
szFileName, fileNameBufferSize,
581
extraField, extraFieldBufferSize,
582
szComment, commentBufferSize)
584
unz_file_info *pfile_info;
585
unz_file_info_internal *pfile_info_internal;
587
uLong fileNameBufferSize;
589
uLong extraFieldBufferSize;
591
uLong commentBufferSize;
594
unz_file_info file_info;
595
unz_file_info_internal file_info_internal;
601
return UNZ_PARAMERROR;
603
if (ZSEEK(s->z_filefunc, s->filestream,
604
s->pos_in_central_dir+s->byte_before_the_zipfile,
605
ZLIB_FILEFUNC_SEEK_SET)!=0)
609
/* we check the magic */
611
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
613
else if (uMagic!=0x02014b50)
617
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
620
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
623
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
626
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
629
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
632
unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
634
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
637
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
640
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
643
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
646
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
649
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
652
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
655
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
658
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
661
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
664
lSeek+=file_info.size_filename;
665
if ((err==UNZ_OK) && (szFileName!=NULL))
668
if (file_info.size_filename<fileNameBufferSize)
670
*(szFileName+file_info.size_filename)='\0';
671
uSizeRead = file_info.size_filename;
674
uSizeRead = fileNameBufferSize;
676
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
677
if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
683
if ((err==UNZ_OK) && (extraField!=NULL))
686
if (file_info.size_file_extra<extraFieldBufferSize)
687
uSizeRead = file_info.size_file_extra;
689
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;
718
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
723
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
724
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
726
lSeek+=file_info.size_file_comment - uSizeRead;
729
lSeek+=file_info.size_file_comment;
731
if ((err==UNZ_OK) && (pfile_info!=NULL))
732
*pfile_info=file_info;
734
if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
735
*pfile_info_internal=file_info_internal;
743
Write info about the ZipFile in the *pglobal_info structure.
744
No preparation of the structure is needed
745
return UNZ_OK if there is no problem.
747
extern int ZEXPORT unzGetCurrentFileInfo (file,
749
szFileName, fileNameBufferSize,
750
extraField, extraFieldBufferSize,
751
szComment, commentBufferSize)
753
unz_file_info *pfile_info;
755
uLong fileNameBufferSize;
757
uLong extraFieldBufferSize;
759
uLong commentBufferSize;
761
return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
762
szFileName,fileNameBufferSize,
763
extraField,extraFieldBufferSize,
764
szComment,commentBufferSize);
768
Set the current file of the zipfile to the first file.
769
return UNZ_OK if there is no problem
771
extern int ZEXPORT unzGoToFirstFile (file)
777
return UNZ_PARAMERROR;
779
s->pos_in_central_dir=s->offset_central_dir;
781
err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
782
&s->cur_file_info_internal,
783
NULL,0,NULL,0,NULL,0);
784
s->current_file_ok = (err == UNZ_OK);
789
Set the current file of the zipfile to the next file.
790
return UNZ_OK if there is no problem
791
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
793
extern int ZEXPORT unzGoToNextFile (file)
800
return UNZ_PARAMERROR;
802
if (!s->current_file_ok)
803
return UNZ_END_OF_LIST_OF_FILE;
804
if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
805
if (s->num_file+1==s->gi.number_entry)
806
return UNZ_END_OF_LIST_OF_FILE;
808
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
809
s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
811
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
812
&s->cur_file_info_internal,
813
NULL,0,NULL,0,NULL,0);
814
s->current_file_ok = (err == UNZ_OK);
820
Try locate the file szFileName in the zipfile.
821
For the iCaseSensitivity signification, see unzipStringFileNameCompare
824
UNZ_OK if the file is found. It becomes the current file.
825
UNZ_END_OF_LIST_OF_FILE if the file is not found
827
extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
829
const char *szFileName;
830
int iCaseSensitivity;
835
/* We remember the 'current' position in the file so that we can jump
836
* back there if we fail.
838
unz_file_info cur_file_infoSaved;
839
unz_file_info_internal cur_file_info_internalSaved;
841
uLong pos_in_central_dirSaved;
845
return UNZ_PARAMERROR;
847
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
848
return UNZ_PARAMERROR;
851
if (!s->current_file_ok)
852
return UNZ_END_OF_LIST_OF_FILE;
854
/* Save the current state */
855
num_fileSaved = s->num_file;
856
pos_in_central_dirSaved = s->pos_in_central_dir;
857
cur_file_infoSaved = s->cur_file_info;
858
cur_file_info_internalSaved = s->cur_file_info_internal;
860
err = unzGoToFirstFile(file);
862
while (err == UNZ_OK)
864
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
865
err = unzGetCurrentFileInfo(file,NULL,
866
szCurrentFileName,sizeof(szCurrentFileName)-1,
870
if (unzStringFileNameCompare(szCurrentFileName,
871
szFileName,iCaseSensitivity)==0)
873
err = unzGoToNextFile(file);
877
/* We failed, so restore the state of the 'current file' to where we
880
s->num_file = num_fileSaved ;
881
s->pos_in_central_dir = pos_in_central_dirSaved ;
882
s->cur_file_info = cur_file_infoSaved;
883
s->cur_file_info_internal = cur_file_info_internalSaved;
889
///////////////////////////////////////////
890
// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
891
// I need random access
893
// Further optimization could be realized by adding an ability
894
// to cache the directory in memory. The goal being a single
895
// comprehensive file read to put the file I need in a memory.
899
typedef struct unz_file_pos_s
901
uLong pos_in_zip_directory; // offset in file
902
uLong num_of_file; // # of file
906
extern int ZEXPORT unzGetFilePos(file, file_pos)
908
unz_file_pos* file_pos;
912
if (file==NULL || file_pos==NULL)
913
return UNZ_PARAMERROR;
915
if (!s->current_file_ok)
916
return UNZ_END_OF_LIST_OF_FILE;
918
file_pos->pos_in_zip_directory = s->pos_in_central_dir;
919
file_pos->num_of_file = s->num_file;
924
extern int ZEXPORT unzGoToFilePos(file, file_pos)
926
unz_file_pos* file_pos;
931
if (file==NULL || file_pos==NULL)
932
return UNZ_PARAMERROR;
935
/* jump to the right spot */
936
s->pos_in_central_dir = file_pos->pos_in_zip_directory;
937
s->num_file = file_pos->num_of_file;
939
/* set the current file */
940
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
941
&s->cur_file_info_internal,
942
NULL,0,NULL,0,NULL,0);
944
s->current_file_ok = (err == UNZ_OK);
949
// Unzip Helper Functions - should be here?
950
///////////////////////////////////////////
954
Read the local header of the current zipfile
955
Check the coherency of the local header and info in the end of central
956
directory about this file
957
store in *piSizeVar the size of extra info in local header
958
(filename and size of extra field data)
960
local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
961
poffset_local_extrafield,
962
psize_local_extrafield)
965
uLong *poffset_local_extrafield;
966
uInt *psize_local_extrafield;
968
uLong uMagic,uData,uFlags;
970
uLong size_extra_field;
974
*poffset_local_extrafield = 0;
975
*psize_local_extrafield = 0;
977
if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
978
s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
983
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
985
else if (uMagic!=0x04034b50)
989
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
992
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
995
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
998
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1000
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1003
if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1004
(s->cur_file_info.compression_method!=Z_DEFLATED))
1007
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1010
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1012
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1016
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1018
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1022
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1024
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1029
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1031
else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1034
*piSizeVar += (uInt)size_filename;
1036
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1038
*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1039
SIZEZIPLOCALHEADER + size_filename;
1040
*psize_local_extrafield = (uInt)size_extra_field;
1042
*piSizeVar += (uInt)size_extra_field;
1048
Open for reading data the current file in the zipfile.
1049
If there is no error and the file is opened, the return value is UNZ_OK.
1051
extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1056
const char* password;
1061
file_in_zip_read_info_s* pfile_in_zip_read_info;
1062
uLong offset_local_extrafield; /* offset of the local extra field */
1063
uInt size_local_extrafield; /* size of the local extra field */
1067
if (password != NULL)
1068
return UNZ_PARAMERROR;
1072
return UNZ_PARAMERROR;
1074
if (!s->current_file_ok)
1075
return UNZ_PARAMERROR;
1077
if (s->pfile_in_zip_read != NULL)
1078
unzCloseCurrentFile(file);
1080
if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1081
&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1082
return UNZ_BADZIPFILE;
1084
pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1085
ALLOC(sizeof(file_in_zip_read_info_s));
1086
if (pfile_in_zip_read_info==NULL)
1087
return UNZ_INTERNALERROR;
1089
pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1090
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1091
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1092
pfile_in_zip_read_info->pos_local_extrafield=0;
1093
pfile_in_zip_read_info->raw=raw;
1095
if (pfile_in_zip_read_info->read_buffer==NULL)
1097
TRYFREE(pfile_in_zip_read_info);
1098
return UNZ_INTERNALERROR;
1101
pfile_in_zip_read_info->stream_initialised=0;
1104
*method = (int)s->cur_file_info.compression_method;
1109
switch (s->cur_file_info.flag & 0x06)
1111
case 6 : *level = 1; break;
1112
case 4 : *level = 2; break;
1113
case 2 : *level = 9; break;
1117
if ((s->cur_file_info.compression_method!=0) &&
1118
(s->cur_file_info.compression_method!=Z_DEFLATED))
1121
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1122
pfile_in_zip_read_info->crc32=0;
1123
pfile_in_zip_read_info->compression_method =
1124
s->cur_file_info.compression_method;
1125
pfile_in_zip_read_info->filestream=s->filestream;
1126
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1127
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1129
pfile_in_zip_read_info->stream.total_out = 0;
1131
if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1134
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1135
pfile_in_zip_read_info->stream.zfree = (free_func)0;
1136
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1137
pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1138
pfile_in_zip_read_info->stream.avail_in = 0;
1140
err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1142
pfile_in_zip_read_info->stream_initialised=1;
1145
TRYFREE(pfile_in_zip_read_info);
1148
/* windowBits is passed < 0 to tell that there is no zlib header.
1149
* Note that in this case inflate *requires* an extra "dummy" byte
1150
* after the compressed stream in order to complete decompression and
1151
* return Z_STREAM_END.
1152
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
1153
* size of both compressed and uncompressed data
1156
pfile_in_zip_read_info->rest_read_compressed =
1157
s->cur_file_info.compressed_size ;
1158
pfile_in_zip_read_info->rest_read_uncompressed =
1159
s->cur_file_info.uncompressed_size ;
1162
pfile_in_zip_read_info->pos_in_zipfile =
1163
s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1166
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1168
s->pfile_in_zip_read = pfile_in_zip_read_info;
1171
if (password != NULL)
1174
s->pcrc_32_tab = get_crc_table();
1175
init_keys(password,s->keys,s->pcrc_32_tab);
1176
if (ZSEEK(s->z_filefunc, s->filestream,
1177
s->pfile_in_zip_read->pos_in_zipfile +
1178
s->pfile_in_zip_read->byte_before_the_zipfile,
1180
return UNZ_INTERNALERROR;
1181
if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1182
return UNZ_INTERNALERROR;
1184
for (i = 0; i<12; i++)
1185
zdecode(s->keys,s->pcrc_32_tab,source[i]);
1187
s->pfile_in_zip_read->pos_in_zipfile+=12;
1196
extern int ZEXPORT unzOpenCurrentFile (file)
1199
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1202
extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1204
const char* password;
1206
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1209
extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1215
return unzOpenCurrentFile3(file, method, level, raw, NULL);
1219
Read bytes from the current file.
1220
buf contain buffer where data must be copied
1221
len the size of buf.
1223
return the number of byte copied if somes bytes are copied
1224
return 0 if the end of file was reached
1225
return <0 with error code if there is an error
1226
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
1228
extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1236
file_in_zip_read_info_s* pfile_in_zip_read_info;
1238
return UNZ_PARAMERROR;
1240
pfile_in_zip_read_info=s->pfile_in_zip_read;
1242
if (pfile_in_zip_read_info==NULL)
1243
return UNZ_PARAMERROR;
1246
if ((pfile_in_zip_read_info->read_buffer == NULL))
1247
return UNZ_END_OF_LIST_OF_FILE;
1251
pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1253
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1255
if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1256
(!(pfile_in_zip_read_info->raw)))
1257
pfile_in_zip_read_info->stream.avail_out =
1258
(uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1260
if ((len>pfile_in_zip_read_info->rest_read_compressed+
1261
pfile_in_zip_read_info->stream.avail_in) &&
1262
(pfile_in_zip_read_info->raw))
1263
pfile_in_zip_read_info->stream.avail_out =
1264
(uInt)pfile_in_zip_read_info->rest_read_compressed+
1265
pfile_in_zip_read_info->stream.avail_in;
1267
while (pfile_in_zip_read_info->stream.avail_out>0)
1269
if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1270
(pfile_in_zip_read_info->rest_read_compressed>0))
1272
uInt uReadThis = UNZ_BUFSIZE;
1273
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1274
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1277
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1278
pfile_in_zip_read_info->filestream,
1279
pfile_in_zip_read_info->pos_in_zipfile +
1280
pfile_in_zip_read_info->byte_before_the_zipfile,
1281
ZLIB_FILEFUNC_SEEK_SET)!=0)
1283
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1284
pfile_in_zip_read_info->filestream,
1285
pfile_in_zip_read_info->read_buffer,
1286
uReadThis)!=uReadThis)
1294
for(i=0;i<uReadThis;i++)
1295
pfile_in_zip_read_info->read_buffer[i] =
1296
zdecode(s->keys,s->pcrc_32_tab,
1297
pfile_in_zip_read_info->read_buffer[i]);
1302
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1304
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1306
pfile_in_zip_read_info->stream.next_in =
1307
(Bytef*)pfile_in_zip_read_info->read_buffer;
1308
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1311
if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1315
if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1316
(pfile_in_zip_read_info->rest_read_compressed == 0))
1317
return (iRead==0) ? UNZ_EOF : iRead;
1319
if (pfile_in_zip_read_info->stream.avail_out <
1320
pfile_in_zip_read_info->stream.avail_in)
1321
uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1323
uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1325
for (i=0;i<uDoCopy;i++)
1326
*(pfile_in_zip_read_info->stream.next_out+i) =
1327
*(pfile_in_zip_read_info->stream.next_in+i);
1329
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1330
pfile_in_zip_read_info->stream.next_out,
1332
pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1333
pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1334
pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1335
pfile_in_zip_read_info->stream.next_out += uDoCopy;
1336
pfile_in_zip_read_info->stream.next_in += uDoCopy;
1337
pfile_in_zip_read_info->stream.total_out += uDoCopy;
1342
uLong uTotalOutBefore,uTotalOutAfter;
1343
const Bytef *bufBefore;
1345
int flush=Z_SYNC_FLUSH;
1347
uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1348
bufBefore = pfile_in_zip_read_info->stream.next_out;
1351
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1352
pfile_in_zip_read_info->stream.avail_out) &&
1353
(pfile_in_zip_read_info->rest_read_compressed == 0))
1356
err=inflate(&pfile_in_zip_read_info->stream,flush);
1358
if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1361
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1362
uOutThis = uTotalOutAfter-uTotalOutBefore;
1364
pfile_in_zip_read_info->crc32 =
1365
crc32(pfile_in_zip_read_info->crc32,bufBefore,
1368
pfile_in_zip_read_info->rest_read_uncompressed -=
1371
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1373
if (err==Z_STREAM_END)
1374
return (iRead==0) ? UNZ_EOF : iRead;
1387
Give the current position in uncompressed data
1389
extern z_off_t ZEXPORT unztell (file)
1393
file_in_zip_read_info_s* pfile_in_zip_read_info;
1395
return UNZ_PARAMERROR;
1397
pfile_in_zip_read_info=s->pfile_in_zip_read;
1399
if (pfile_in_zip_read_info==NULL)
1400
return UNZ_PARAMERROR;
1402
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1407
return 1 if the end of file was reached, 0 elsewhere
1409
extern int ZEXPORT unzeof (file)
1413
file_in_zip_read_info_s* pfile_in_zip_read_info;
1415
return UNZ_PARAMERROR;
1417
pfile_in_zip_read_info=s->pfile_in_zip_read;
1419
if (pfile_in_zip_read_info==NULL)
1420
return UNZ_PARAMERROR;
1422
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1431
Read extra field from the current file (opened by unzOpenCurrentFile)
1432
This is the local-header version of the extra field (sometimes, there is
1433
more info in the local-header version than in the central-header)
1435
if buf==NULL, it return the size of the local extra field that can be read
1437
if buf!=NULL, len is the size of the buffer, the extra header is copied in
1439
the return value is the number of bytes copied in buf, or (if <0)
1442
extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1448
file_in_zip_read_info_s* pfile_in_zip_read_info;
1453
return UNZ_PARAMERROR;
1455
pfile_in_zip_read_info=s->pfile_in_zip_read;
1457
if (pfile_in_zip_read_info==NULL)
1458
return UNZ_PARAMERROR;
1460
size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1461
pfile_in_zip_read_info->pos_local_extrafield);
1464
return (int)size_to_read;
1466
if (len>size_to_read)
1467
read_now = (uInt)size_to_read;
1469
read_now = (uInt)len ;
1474
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1475
pfile_in_zip_read_info->filestream,
1476
pfile_in_zip_read_info->offset_local_extrafield +
1477
pfile_in_zip_read_info->pos_local_extrafield,
1478
ZLIB_FILEFUNC_SEEK_SET)!=0)
1481
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1482
pfile_in_zip_read_info->filestream,
1483
buf,read_now)!=read_now)
1486
return (int)read_now;
1490
Close the file in zip opened with unzipOpenCurrentFile
1491
Return UNZ_CRCERROR if all the file was read but the CRC is not good
1493
extern int ZEXPORT unzCloseCurrentFile (file)
1499
file_in_zip_read_info_s* pfile_in_zip_read_info;
1501
return UNZ_PARAMERROR;
1503
pfile_in_zip_read_info=s->pfile_in_zip_read;
1505
if (pfile_in_zip_read_info==NULL)
1506
return UNZ_PARAMERROR;
1509
if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1510
(!pfile_in_zip_read_info->raw))
1512
if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1517
TRYFREE(pfile_in_zip_read_info->read_buffer);
1518
pfile_in_zip_read_info->read_buffer = NULL;
1519
if (pfile_in_zip_read_info->stream_initialised)
1520
inflateEnd(&pfile_in_zip_read_info->stream);
1522
pfile_in_zip_read_info->stream_initialised = 0;
1523
TRYFREE(pfile_in_zip_read_info);
1525
s->pfile_in_zip_read=NULL;
1532
Get the global comment string of the ZipFile, in the szComment buffer.
1533
uSizeBuf is the size of the szComment buffer.
1534
return the number of byte copied or an error code <0
1536
extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1544
return UNZ_PARAMERROR;
1547
uReadThis = uSizeBuf;
1548
if (uReadThis>s->gi.size_comment)
1549
uReadThis = s->gi.size_comment;
1551
if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1557
if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1561
if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1562
*(szComment+s->gi.size_comment)='\0';
1563
return (int)uReadThis;
1566
/* Additions by RX '2004 */
1567
extern uLong ZEXPORT unzGetOffset (file)
1573
return UNZ_PARAMERROR;
1575
if (!s->current_file_ok)
1577
if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1578
if (s->num_file==s->gi.number_entry)
1580
return s->pos_in_central_dir;
1583
extern int ZEXPORT unzSetOffset (file, pos)
1591
return UNZ_PARAMERROR;
1594
s->pos_in_central_dir = pos;
1595
s->num_file = s->gi.number_entry; /* hack */
1596
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1597
&s->cur_file_info_internal,
1598
NULL,0,NULL,0,NULL,0);
1599
s->current_file_ok = (err == UNZ_OK);