1*44bedb31SLionel Sambuc /* $NetBSD: unzip.c,v 1.1.1.1 2006/01/14 20:10:59 christos Exp $ */
2*44bedb31SLionel Sambuc
3*44bedb31SLionel Sambuc /* unzip.c -- IO for uncompress .zip files using zlib
4*44bedb31SLionel Sambuc Version 1.01e, February 12th, 2005
5*44bedb31SLionel Sambuc
6*44bedb31SLionel Sambuc Copyright (C) 1998-2005 Gilles Vollant
7*44bedb31SLionel Sambuc
8*44bedb31SLionel Sambuc Read unzip.h for more info
9*44bedb31SLionel Sambuc */
10*44bedb31SLionel Sambuc
11*44bedb31SLionel Sambuc /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
12*44bedb31SLionel Sambuc compatibility with older software. The following is from the original crypt.c. Code
13*44bedb31SLionel Sambuc woven in by Terry Thorsen 1/2003.
14*44bedb31SLionel Sambuc */
15*44bedb31SLionel Sambuc /*
16*44bedb31SLionel Sambuc Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
17*44bedb31SLionel Sambuc
18*44bedb31SLionel Sambuc See the accompanying file LICENSE, version 2000-Apr-09 or later
19*44bedb31SLionel Sambuc (the contents of which are also included in zip.h) for terms of use.
20*44bedb31SLionel Sambuc If, for some reason, all these files are missing, the Info-ZIP license
21*44bedb31SLionel Sambuc also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22*44bedb31SLionel Sambuc */
23*44bedb31SLionel Sambuc /*
24*44bedb31SLionel Sambuc crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
25*44bedb31SLionel Sambuc
26*44bedb31SLionel Sambuc The encryption/decryption parts of this source code (as opposed to the
27*44bedb31SLionel Sambuc non-echoing password parts) were originally written in Europe. The
28*44bedb31SLionel Sambuc whole source package can be freely distributed, including from the USA.
29*44bedb31SLionel Sambuc (Prior to January 2000, re-export from the US was a violation of US law.)
30*44bedb31SLionel Sambuc */
31*44bedb31SLionel Sambuc
32*44bedb31SLionel Sambuc /*
33*44bedb31SLionel Sambuc This encryption code is a direct transcription of the algorithm from
34*44bedb31SLionel Sambuc Roger Schlafly, described by Phil Katz in the file appnote.txt. This
35*44bedb31SLionel Sambuc file (appnote.txt) is distributed with the PKZIP program (even in the
36*44bedb31SLionel Sambuc version without encryption capabilities).
37*44bedb31SLionel Sambuc */
38*44bedb31SLionel Sambuc
39*44bedb31SLionel Sambuc
40*44bedb31SLionel Sambuc #include <stdio.h>
41*44bedb31SLionel Sambuc #include <stdlib.h>
42*44bedb31SLionel Sambuc #include <string.h>
43*44bedb31SLionel Sambuc #include "zlib.h"
44*44bedb31SLionel Sambuc #include "unzip.h"
45*44bedb31SLionel Sambuc
46*44bedb31SLionel Sambuc #ifdef STDC
47*44bedb31SLionel Sambuc # include <stddef.h>
48*44bedb31SLionel Sambuc # include <string.h>
49*44bedb31SLionel Sambuc # include <stdlib.h>
50*44bedb31SLionel Sambuc #endif
51*44bedb31SLionel Sambuc #ifdef NO_ERRNO_H
52*44bedb31SLionel Sambuc extern int errno;
53*44bedb31SLionel Sambuc #else
54*44bedb31SLionel Sambuc # include <errno.h>
55*44bedb31SLionel Sambuc #endif
56*44bedb31SLionel Sambuc
57*44bedb31SLionel Sambuc
58*44bedb31SLionel Sambuc #ifndef local
59*44bedb31SLionel Sambuc # define local static
60*44bedb31SLionel Sambuc #endif
61*44bedb31SLionel Sambuc /* compile with -Dlocal if your debugger can't find static symbols */
62*44bedb31SLionel Sambuc
63*44bedb31SLionel Sambuc
64*44bedb31SLionel Sambuc #ifndef CASESENSITIVITYDEFAULT_NO
65*44bedb31SLionel Sambuc # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
66*44bedb31SLionel Sambuc # define CASESENSITIVITYDEFAULT_NO
67*44bedb31SLionel Sambuc # endif
68*44bedb31SLionel Sambuc #endif
69*44bedb31SLionel Sambuc
70*44bedb31SLionel Sambuc
71*44bedb31SLionel Sambuc #ifndef UNZ_BUFSIZE
72*44bedb31SLionel Sambuc #define UNZ_BUFSIZE (16384)
73*44bedb31SLionel Sambuc #endif
74*44bedb31SLionel Sambuc
75*44bedb31SLionel Sambuc #ifndef UNZ_MAXFILENAMEINZIP
76*44bedb31SLionel Sambuc #define UNZ_MAXFILENAMEINZIP (256)
77*44bedb31SLionel Sambuc #endif
78*44bedb31SLionel Sambuc
79*44bedb31SLionel Sambuc #ifndef ALLOC
80*44bedb31SLionel Sambuc # define ALLOC(size) (malloc(size))
81*44bedb31SLionel Sambuc #endif
82*44bedb31SLionel Sambuc #ifndef TRYFREE
83*44bedb31SLionel Sambuc # define TRYFREE(p) {if (p) free(p);}
84*44bedb31SLionel Sambuc #endif
85*44bedb31SLionel Sambuc
86*44bedb31SLionel Sambuc #define SIZECENTRALDIRITEM (0x2e)
87*44bedb31SLionel Sambuc #define SIZEZIPLOCALHEADER (0x1e)
88*44bedb31SLionel Sambuc
89*44bedb31SLionel Sambuc
90*44bedb31SLionel Sambuc
91*44bedb31SLionel Sambuc
92*44bedb31SLionel Sambuc const char unz_copyright[] =
93*44bedb31SLionel Sambuc " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
94*44bedb31SLionel Sambuc
95*44bedb31SLionel Sambuc /* unz_file_info_interntal contain internal info about a file in zipfile*/
96*44bedb31SLionel Sambuc typedef struct unz_file_info_internal_s
97*44bedb31SLionel Sambuc {
98*44bedb31SLionel Sambuc uLong offset_curfile;/* relative offset of local header 4 bytes */
99*44bedb31SLionel Sambuc } unz_file_info_internal;
100*44bedb31SLionel Sambuc
101*44bedb31SLionel Sambuc
102*44bedb31SLionel Sambuc /* file_in_zip_read_info_s contain internal information about a file in zipfile,
103*44bedb31SLionel Sambuc when reading and decompress it */
104*44bedb31SLionel Sambuc typedef struct
105*44bedb31SLionel Sambuc {
106*44bedb31SLionel Sambuc char *read_buffer; /* internal buffer for compressed data */
107*44bedb31SLionel Sambuc z_stream stream; /* zLib stream structure for inflate */
108*44bedb31SLionel Sambuc
109*44bedb31SLionel Sambuc uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
110*44bedb31SLionel Sambuc uLong stream_initialised; /* flag set if stream structure is initialised*/
111*44bedb31SLionel Sambuc
112*44bedb31SLionel Sambuc uLong offset_local_extrafield;/* offset of the local extra field */
113*44bedb31SLionel Sambuc uInt size_local_extrafield;/* size of the local extra field */
114*44bedb31SLionel Sambuc uLong pos_local_extrafield; /* position in the local extra field in read*/
115*44bedb31SLionel Sambuc
116*44bedb31SLionel Sambuc uLong crc32; /* crc32 of all data uncompressed */
117*44bedb31SLionel Sambuc uLong crc32_wait; /* crc32 we must obtain after decompress all */
118*44bedb31SLionel Sambuc uLong rest_read_compressed; /* number of byte to be decompressed */
119*44bedb31SLionel Sambuc uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
120*44bedb31SLionel Sambuc zlib_filefunc_def z_filefunc;
121*44bedb31SLionel Sambuc voidpf filestream; /* io structore of the zipfile */
122*44bedb31SLionel Sambuc uLong compression_method; /* compression method (0==store) */
123*44bedb31SLionel Sambuc uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
124*44bedb31SLionel Sambuc int raw;
125*44bedb31SLionel Sambuc } file_in_zip_read_info_s;
126*44bedb31SLionel Sambuc
127*44bedb31SLionel Sambuc
128*44bedb31SLionel Sambuc /* unz_s contain internal information about the zipfile
129*44bedb31SLionel Sambuc */
130*44bedb31SLionel Sambuc typedef struct
131*44bedb31SLionel Sambuc {
132*44bedb31SLionel Sambuc zlib_filefunc_def z_filefunc;
133*44bedb31SLionel Sambuc voidpf filestream; /* io structore of the zipfile */
134*44bedb31SLionel Sambuc unz_global_info gi; /* public global information */
135*44bedb31SLionel Sambuc uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
136*44bedb31SLionel Sambuc uLong num_file; /* number of the current file in the zipfile*/
137*44bedb31SLionel Sambuc uLong pos_in_central_dir; /* pos of the current file in the central dir*/
138*44bedb31SLionel Sambuc uLong current_file_ok; /* flag about the usability of the current file*/
139*44bedb31SLionel Sambuc uLong central_pos; /* position of the beginning of the central dir*/
140*44bedb31SLionel Sambuc
141*44bedb31SLionel Sambuc uLong size_central_dir; /* size of the central directory */
142*44bedb31SLionel Sambuc uLong offset_central_dir; /* offset of start of central directory with
143*44bedb31SLionel Sambuc respect to the starting disk number */
144*44bedb31SLionel Sambuc
145*44bedb31SLionel Sambuc unz_file_info cur_file_info; /* public info about the current file in zip*/
146*44bedb31SLionel Sambuc unz_file_info_internal cur_file_info_internal; /* private info about it*/
147*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
148*44bedb31SLionel Sambuc file if we are decompressing it */
149*44bedb31SLionel Sambuc int encrypted;
150*44bedb31SLionel Sambuc # ifndef NOUNCRYPT
151*44bedb31SLionel Sambuc unsigned long keys[3]; /* keys defining the pseudo-random sequence */
152*44bedb31SLionel Sambuc const unsigned long* pcrc_32_tab;
153*44bedb31SLionel Sambuc # endif
154*44bedb31SLionel Sambuc } unz_s;
155*44bedb31SLionel Sambuc
156*44bedb31SLionel Sambuc
157*44bedb31SLionel Sambuc #ifndef NOUNCRYPT
158*44bedb31SLionel Sambuc #include "crypt.h"
159*44bedb31SLionel Sambuc #endif
160*44bedb31SLionel Sambuc
161*44bedb31SLionel Sambuc /* ===========================================================================
162*44bedb31SLionel Sambuc Read a byte from a gz_stream; update next_in and avail_in. Return EOF
163*44bedb31SLionel Sambuc for end of file.
164*44bedb31SLionel Sambuc IN assertion: the stream s has been sucessfully opened for reading.
165*44bedb31SLionel Sambuc */
166*44bedb31SLionel Sambuc
167*44bedb31SLionel Sambuc
168*44bedb31SLionel Sambuc local int unzlocal_getByte OF((
169*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def,
170*44bedb31SLionel Sambuc voidpf filestream,
171*44bedb31SLionel Sambuc int *pi));
172*44bedb31SLionel Sambuc
unzlocal_getByte(pzlib_filefunc_def,filestream,pi)173*44bedb31SLionel Sambuc local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
174*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def;
175*44bedb31SLionel Sambuc voidpf filestream;
176*44bedb31SLionel Sambuc int *pi;
177*44bedb31SLionel Sambuc {
178*44bedb31SLionel Sambuc unsigned char c;
179*44bedb31SLionel Sambuc int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
180*44bedb31SLionel Sambuc if (err==1)
181*44bedb31SLionel Sambuc {
182*44bedb31SLionel Sambuc *pi = (int)c;
183*44bedb31SLionel Sambuc return UNZ_OK;
184*44bedb31SLionel Sambuc }
185*44bedb31SLionel Sambuc else
186*44bedb31SLionel Sambuc {
187*44bedb31SLionel Sambuc if (ZERROR(*pzlib_filefunc_def,filestream))
188*44bedb31SLionel Sambuc return UNZ_ERRNO;
189*44bedb31SLionel Sambuc else
190*44bedb31SLionel Sambuc return UNZ_EOF;
191*44bedb31SLionel Sambuc }
192*44bedb31SLionel Sambuc }
193*44bedb31SLionel Sambuc
194*44bedb31SLionel Sambuc
195*44bedb31SLionel Sambuc /* ===========================================================================
196*44bedb31SLionel Sambuc Reads a long in LSB order from the given gz_stream. Sets
197*44bedb31SLionel Sambuc */
198*44bedb31SLionel Sambuc local int unzlocal_getShort OF((
199*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def,
200*44bedb31SLionel Sambuc voidpf filestream,
201*44bedb31SLionel Sambuc uLong *pX));
202*44bedb31SLionel Sambuc
unzlocal_getShort(pzlib_filefunc_def,filestream,pX)203*44bedb31SLionel Sambuc local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
204*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def;
205*44bedb31SLionel Sambuc voidpf filestream;
206*44bedb31SLionel Sambuc uLong *pX;
207*44bedb31SLionel Sambuc {
208*44bedb31SLionel Sambuc uLong x ;
209*44bedb31SLionel Sambuc int i;
210*44bedb31SLionel Sambuc int err;
211*44bedb31SLionel Sambuc
212*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
213*44bedb31SLionel Sambuc x = (uLong)i;
214*44bedb31SLionel Sambuc
215*44bedb31SLionel Sambuc if (err==UNZ_OK)
216*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
217*44bedb31SLionel Sambuc x += ((uLong)i)<<8;
218*44bedb31SLionel Sambuc
219*44bedb31SLionel Sambuc if (err==UNZ_OK)
220*44bedb31SLionel Sambuc *pX = x;
221*44bedb31SLionel Sambuc else
222*44bedb31SLionel Sambuc *pX = 0;
223*44bedb31SLionel Sambuc return err;
224*44bedb31SLionel Sambuc }
225*44bedb31SLionel Sambuc
226*44bedb31SLionel Sambuc local int unzlocal_getLong OF((
227*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def,
228*44bedb31SLionel Sambuc voidpf filestream,
229*44bedb31SLionel Sambuc uLong *pX));
230*44bedb31SLionel Sambuc
unzlocal_getLong(pzlib_filefunc_def,filestream,pX)231*44bedb31SLionel Sambuc local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
232*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def;
233*44bedb31SLionel Sambuc voidpf filestream;
234*44bedb31SLionel Sambuc uLong *pX;
235*44bedb31SLionel Sambuc {
236*44bedb31SLionel Sambuc uLong x ;
237*44bedb31SLionel Sambuc int i;
238*44bedb31SLionel Sambuc int err;
239*44bedb31SLionel Sambuc
240*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
241*44bedb31SLionel Sambuc x = (uLong)i;
242*44bedb31SLionel Sambuc
243*44bedb31SLionel Sambuc if (err==UNZ_OK)
244*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
245*44bedb31SLionel Sambuc x += ((uLong)i)<<8;
246*44bedb31SLionel Sambuc
247*44bedb31SLionel Sambuc if (err==UNZ_OK)
248*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
249*44bedb31SLionel Sambuc x += ((uLong)i)<<16;
250*44bedb31SLionel Sambuc
251*44bedb31SLionel Sambuc if (err==UNZ_OK)
252*44bedb31SLionel Sambuc err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
253*44bedb31SLionel Sambuc x += ((uLong)i)<<24;
254*44bedb31SLionel Sambuc
255*44bedb31SLionel Sambuc if (err==UNZ_OK)
256*44bedb31SLionel Sambuc *pX = x;
257*44bedb31SLionel Sambuc else
258*44bedb31SLionel Sambuc *pX = 0;
259*44bedb31SLionel Sambuc return err;
260*44bedb31SLionel Sambuc }
261*44bedb31SLionel Sambuc
262*44bedb31SLionel Sambuc
263*44bedb31SLionel Sambuc /* My own strcmpi / strcasecmp */
strcmpcasenosensitive_internal(fileName1,fileName2)264*44bedb31SLionel Sambuc local int strcmpcasenosensitive_internal (fileName1,fileName2)
265*44bedb31SLionel Sambuc const char* fileName1;
266*44bedb31SLionel Sambuc const char* fileName2;
267*44bedb31SLionel Sambuc {
268*44bedb31SLionel Sambuc for (;;)
269*44bedb31SLionel Sambuc {
270*44bedb31SLionel Sambuc char c1=*(fileName1++);
271*44bedb31SLionel Sambuc char c2=*(fileName2++);
272*44bedb31SLionel Sambuc if ((c1>='a') && (c1<='z'))
273*44bedb31SLionel Sambuc c1 -= 0x20;
274*44bedb31SLionel Sambuc if ((c2>='a') && (c2<='z'))
275*44bedb31SLionel Sambuc c2 -= 0x20;
276*44bedb31SLionel Sambuc if (c1=='\0')
277*44bedb31SLionel Sambuc return ((c2=='\0') ? 0 : -1);
278*44bedb31SLionel Sambuc if (c2=='\0')
279*44bedb31SLionel Sambuc return 1;
280*44bedb31SLionel Sambuc if (c1<c2)
281*44bedb31SLionel Sambuc return -1;
282*44bedb31SLionel Sambuc if (c1>c2)
283*44bedb31SLionel Sambuc return 1;
284*44bedb31SLionel Sambuc }
285*44bedb31SLionel Sambuc }
286*44bedb31SLionel Sambuc
287*44bedb31SLionel Sambuc
288*44bedb31SLionel Sambuc #ifdef CASESENSITIVITYDEFAULT_NO
289*44bedb31SLionel Sambuc #define CASESENSITIVITYDEFAULTVALUE 2
290*44bedb31SLionel Sambuc #else
291*44bedb31SLionel Sambuc #define CASESENSITIVITYDEFAULTVALUE 1
292*44bedb31SLionel Sambuc #endif
293*44bedb31SLionel Sambuc
294*44bedb31SLionel Sambuc #ifndef STRCMPCASENOSENTIVEFUNCTION
295*44bedb31SLionel Sambuc #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
296*44bedb31SLionel Sambuc #endif
297*44bedb31SLionel Sambuc
298*44bedb31SLionel Sambuc /*
299*44bedb31SLionel Sambuc Compare two filename (fileName1,fileName2).
300*44bedb31SLionel Sambuc If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
301*44bedb31SLionel Sambuc If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
302*44bedb31SLionel Sambuc or strcasecmp)
303*44bedb31SLionel Sambuc If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
304*44bedb31SLionel Sambuc (like 1 on Unix, 2 on Windows)
305*44bedb31SLionel Sambuc
306*44bedb31SLionel Sambuc */
307*44bedb31SLionel Sambuc extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
308*44bedb31SLionel Sambuc const char* fileName1;
309*44bedb31SLionel Sambuc const char* fileName2;
310*44bedb31SLionel Sambuc int iCaseSensitivity;
311*44bedb31SLionel Sambuc {
312*44bedb31SLionel Sambuc if (iCaseSensitivity==0)
313*44bedb31SLionel Sambuc iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
314*44bedb31SLionel Sambuc
315*44bedb31SLionel Sambuc if (iCaseSensitivity==1)
316*44bedb31SLionel Sambuc return strcmp(fileName1,fileName2);
317*44bedb31SLionel Sambuc
318*44bedb31SLionel Sambuc return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
319*44bedb31SLionel Sambuc }
320*44bedb31SLionel Sambuc
321*44bedb31SLionel Sambuc #ifndef BUFREADCOMMENT
322*44bedb31SLionel Sambuc #define BUFREADCOMMENT (0x400)
323*44bedb31SLionel Sambuc #endif
324*44bedb31SLionel Sambuc
325*44bedb31SLionel Sambuc /*
326*44bedb31SLionel Sambuc Locate the Central directory of a zipfile (at the end, just before
327*44bedb31SLionel Sambuc the global comment)
328*44bedb31SLionel Sambuc */
329*44bedb31SLionel Sambuc local uLong unzlocal_SearchCentralDir OF((
330*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def,
331*44bedb31SLionel Sambuc voidpf filestream));
332*44bedb31SLionel Sambuc
unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)333*44bedb31SLionel Sambuc local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
334*44bedb31SLionel Sambuc const zlib_filefunc_def* pzlib_filefunc_def;
335*44bedb31SLionel Sambuc voidpf filestream;
336*44bedb31SLionel Sambuc {
337*44bedb31SLionel Sambuc unsigned char* buf;
338*44bedb31SLionel Sambuc uLong uSizeFile;
339*44bedb31SLionel Sambuc uLong uBackRead;
340*44bedb31SLionel Sambuc uLong uMaxBack=0xffff; /* maximum size of global comment */
341*44bedb31SLionel Sambuc uLong uPosFound=0;
342*44bedb31SLionel Sambuc
343*44bedb31SLionel Sambuc if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
344*44bedb31SLionel Sambuc return 0;
345*44bedb31SLionel Sambuc
346*44bedb31SLionel Sambuc
347*44bedb31SLionel Sambuc uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
348*44bedb31SLionel Sambuc
349*44bedb31SLionel Sambuc if (uMaxBack>uSizeFile)
350*44bedb31SLionel Sambuc uMaxBack = uSizeFile;
351*44bedb31SLionel Sambuc
352*44bedb31SLionel Sambuc buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
353*44bedb31SLionel Sambuc if (buf==NULL)
354*44bedb31SLionel Sambuc return 0;
355*44bedb31SLionel Sambuc
356*44bedb31SLionel Sambuc uBackRead = 4;
357*44bedb31SLionel Sambuc while (uBackRead<uMaxBack)
358*44bedb31SLionel Sambuc {
359*44bedb31SLionel Sambuc uLong uReadSize,uReadPos ;
360*44bedb31SLionel Sambuc int i;
361*44bedb31SLionel Sambuc if (uBackRead+BUFREADCOMMENT>uMaxBack)
362*44bedb31SLionel Sambuc uBackRead = uMaxBack;
363*44bedb31SLionel Sambuc else
364*44bedb31SLionel Sambuc uBackRead+=BUFREADCOMMENT;
365*44bedb31SLionel Sambuc uReadPos = uSizeFile-uBackRead ;
366*44bedb31SLionel Sambuc
367*44bedb31SLionel Sambuc uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
368*44bedb31SLionel Sambuc (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
369*44bedb31SLionel Sambuc if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
370*44bedb31SLionel Sambuc break;
371*44bedb31SLionel Sambuc
372*44bedb31SLionel Sambuc if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
373*44bedb31SLionel Sambuc break;
374*44bedb31SLionel Sambuc
375*44bedb31SLionel Sambuc for (i=(int)uReadSize-3; (i--)>0;)
376*44bedb31SLionel Sambuc if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
377*44bedb31SLionel Sambuc ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
378*44bedb31SLionel Sambuc {
379*44bedb31SLionel Sambuc uPosFound = uReadPos+i;
380*44bedb31SLionel Sambuc break;
381*44bedb31SLionel Sambuc }
382*44bedb31SLionel Sambuc
383*44bedb31SLionel Sambuc if (uPosFound!=0)
384*44bedb31SLionel Sambuc break;
385*44bedb31SLionel Sambuc }
386*44bedb31SLionel Sambuc TRYFREE(buf);
387*44bedb31SLionel Sambuc return uPosFound;
388*44bedb31SLionel Sambuc }
389*44bedb31SLionel Sambuc
390*44bedb31SLionel Sambuc /*
391*44bedb31SLionel Sambuc Open a Zip file. path contain the full pathname (by example,
392*44bedb31SLionel Sambuc on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
393*44bedb31SLionel Sambuc "zlib/zlib114.zip".
394*44bedb31SLionel Sambuc If the zipfile cannot be opened (file doesn't exist or in not valid), the
395*44bedb31SLionel Sambuc return value is NULL.
396*44bedb31SLionel Sambuc Else, the return value is a unzFile Handle, usable with other function
397*44bedb31SLionel Sambuc of this unzip package.
398*44bedb31SLionel Sambuc */
399*44bedb31SLionel Sambuc extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
400*44bedb31SLionel Sambuc const char *path;
401*44bedb31SLionel Sambuc zlib_filefunc_def* pzlib_filefunc_def;
402*44bedb31SLionel Sambuc {
403*44bedb31SLionel Sambuc unz_s us;
404*44bedb31SLionel Sambuc unz_s *s;
405*44bedb31SLionel Sambuc uLong central_pos,uL;
406*44bedb31SLionel Sambuc
407*44bedb31SLionel Sambuc uLong number_disk; /* number of the current dist, used for
408*44bedb31SLionel Sambuc spaning ZIP, unsupported, always 0*/
409*44bedb31SLionel Sambuc uLong number_disk_with_CD; /* number the the disk with central dir, used
410*44bedb31SLionel Sambuc for spaning ZIP, unsupported, always 0*/
411*44bedb31SLionel Sambuc uLong number_entry_CD; /* total number of entries in
412*44bedb31SLionel Sambuc the central dir
413*44bedb31SLionel Sambuc (same than number_entry on nospan) */
414*44bedb31SLionel Sambuc
415*44bedb31SLionel Sambuc int err=UNZ_OK;
416*44bedb31SLionel Sambuc
417*44bedb31SLionel Sambuc if (unz_copyright[0]!=' ')
418*44bedb31SLionel Sambuc return NULL;
419*44bedb31SLionel Sambuc
420*44bedb31SLionel Sambuc if (pzlib_filefunc_def==NULL)
421*44bedb31SLionel Sambuc fill_fopen_filefunc(&us.z_filefunc);
422*44bedb31SLionel Sambuc else
423*44bedb31SLionel Sambuc us.z_filefunc = *pzlib_filefunc_def;
424*44bedb31SLionel Sambuc
425*44bedb31SLionel Sambuc us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
426*44bedb31SLionel Sambuc path,
427*44bedb31SLionel Sambuc ZLIB_FILEFUNC_MODE_READ |
428*44bedb31SLionel Sambuc ZLIB_FILEFUNC_MODE_EXISTING);
429*44bedb31SLionel Sambuc if (us.filestream==NULL)
430*44bedb31SLionel Sambuc return NULL;
431*44bedb31SLionel Sambuc
432*44bedb31SLionel Sambuc central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
433*44bedb31SLionel Sambuc if (central_pos==0)
434*44bedb31SLionel Sambuc err=UNZ_ERRNO;
435*44bedb31SLionel Sambuc
436*44bedb31SLionel Sambuc if (ZSEEK(us.z_filefunc, us.filestream,
437*44bedb31SLionel Sambuc central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
438*44bedb31SLionel Sambuc err=UNZ_ERRNO;
439*44bedb31SLionel Sambuc
440*44bedb31SLionel Sambuc /* the signature, already checked */
441*44bedb31SLionel Sambuc if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
442*44bedb31SLionel Sambuc err=UNZ_ERRNO;
443*44bedb31SLionel Sambuc
444*44bedb31SLionel Sambuc /* number of this disk */
445*44bedb31SLionel Sambuc if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
446*44bedb31SLionel Sambuc err=UNZ_ERRNO;
447*44bedb31SLionel Sambuc
448*44bedb31SLionel Sambuc /* number of the disk with the start of the central directory */
449*44bedb31SLionel Sambuc if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
450*44bedb31SLionel Sambuc err=UNZ_ERRNO;
451*44bedb31SLionel Sambuc
452*44bedb31SLionel Sambuc /* total number of entries in the central dir on this disk */
453*44bedb31SLionel Sambuc if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
454*44bedb31SLionel Sambuc err=UNZ_ERRNO;
455*44bedb31SLionel Sambuc
456*44bedb31SLionel Sambuc /* total number of entries in the central dir */
457*44bedb31SLionel Sambuc if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
458*44bedb31SLionel Sambuc err=UNZ_ERRNO;
459*44bedb31SLionel Sambuc
460*44bedb31SLionel Sambuc if ((number_entry_CD!=us.gi.number_entry) ||
461*44bedb31SLionel Sambuc (number_disk_with_CD!=0) ||
462*44bedb31SLionel Sambuc (number_disk!=0))
463*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
464*44bedb31SLionel Sambuc
465*44bedb31SLionel Sambuc /* size of the central directory */
466*44bedb31SLionel Sambuc if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
467*44bedb31SLionel Sambuc err=UNZ_ERRNO;
468*44bedb31SLionel Sambuc
469*44bedb31SLionel Sambuc /* offset of start of central directory with respect to the
470*44bedb31SLionel Sambuc starting disk number */
471*44bedb31SLionel Sambuc if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
472*44bedb31SLionel Sambuc err=UNZ_ERRNO;
473*44bedb31SLionel Sambuc
474*44bedb31SLionel Sambuc /* zipfile comment length */
475*44bedb31SLionel Sambuc if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
476*44bedb31SLionel Sambuc err=UNZ_ERRNO;
477*44bedb31SLionel Sambuc
478*44bedb31SLionel Sambuc if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
479*44bedb31SLionel Sambuc (err==UNZ_OK))
480*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
481*44bedb31SLionel Sambuc
482*44bedb31SLionel Sambuc if (err!=UNZ_OK)
483*44bedb31SLionel Sambuc {
484*44bedb31SLionel Sambuc ZCLOSE(us.z_filefunc, us.filestream);
485*44bedb31SLionel Sambuc return NULL;
486*44bedb31SLionel Sambuc }
487*44bedb31SLionel Sambuc
488*44bedb31SLionel Sambuc us.byte_before_the_zipfile = central_pos -
489*44bedb31SLionel Sambuc (us.offset_central_dir+us.size_central_dir);
490*44bedb31SLionel Sambuc us.central_pos = central_pos;
491*44bedb31SLionel Sambuc us.pfile_in_zip_read = NULL;
492*44bedb31SLionel Sambuc us.encrypted = 0;
493*44bedb31SLionel Sambuc
494*44bedb31SLionel Sambuc
495*44bedb31SLionel Sambuc s=(unz_s*)ALLOC(sizeof(unz_s));
496*44bedb31SLionel Sambuc *s=us;
497*44bedb31SLionel Sambuc unzGoToFirstFile((unzFile)s);
498*44bedb31SLionel Sambuc return (unzFile)s;
499*44bedb31SLionel Sambuc }
500*44bedb31SLionel Sambuc
501*44bedb31SLionel Sambuc
502*44bedb31SLionel Sambuc extern unzFile ZEXPORT unzOpen (path)
503*44bedb31SLionel Sambuc const char *path;
504*44bedb31SLionel Sambuc {
505*44bedb31SLionel Sambuc return unzOpen2(path, NULL);
506*44bedb31SLionel Sambuc }
507*44bedb31SLionel Sambuc
508*44bedb31SLionel Sambuc /*
509*44bedb31SLionel Sambuc Close a ZipFile opened with unzipOpen.
510*44bedb31SLionel Sambuc If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
511*44bedb31SLionel Sambuc these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
512*44bedb31SLionel Sambuc return UNZ_OK if there is no problem. */
513*44bedb31SLionel Sambuc extern int ZEXPORT unzClose (file)
514*44bedb31SLionel Sambuc unzFile file;
515*44bedb31SLionel Sambuc {
516*44bedb31SLionel Sambuc unz_s* s;
517*44bedb31SLionel Sambuc if (file==NULL)
518*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
519*44bedb31SLionel Sambuc s=(unz_s*)file;
520*44bedb31SLionel Sambuc
521*44bedb31SLionel Sambuc if (s->pfile_in_zip_read!=NULL)
522*44bedb31SLionel Sambuc unzCloseCurrentFile(file);
523*44bedb31SLionel Sambuc
524*44bedb31SLionel Sambuc ZCLOSE(s->z_filefunc, s->filestream);
525*44bedb31SLionel Sambuc TRYFREE(s);
526*44bedb31SLionel Sambuc return UNZ_OK;
527*44bedb31SLionel Sambuc }
528*44bedb31SLionel Sambuc
529*44bedb31SLionel Sambuc
530*44bedb31SLionel Sambuc /*
531*44bedb31SLionel Sambuc Write info about the ZipFile in the *pglobal_info structure.
532*44bedb31SLionel Sambuc No preparation of the structure is needed
533*44bedb31SLionel Sambuc return UNZ_OK if there is no problem. */
534*44bedb31SLionel Sambuc extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
535*44bedb31SLionel Sambuc unzFile file;
536*44bedb31SLionel Sambuc unz_global_info *pglobal_info;
537*44bedb31SLionel Sambuc {
538*44bedb31SLionel Sambuc unz_s* s;
539*44bedb31SLionel Sambuc if (file==NULL)
540*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
541*44bedb31SLionel Sambuc s=(unz_s*)file;
542*44bedb31SLionel Sambuc *pglobal_info=s->gi;
543*44bedb31SLionel Sambuc return UNZ_OK;
544*44bedb31SLionel Sambuc }
545*44bedb31SLionel Sambuc
546*44bedb31SLionel Sambuc
547*44bedb31SLionel Sambuc /*
548*44bedb31SLionel Sambuc Translate date/time from Dos format to tm_unz (readable more easilty)
549*44bedb31SLionel Sambuc */
unzlocal_DosDateToTmuDate(ulDosDate,ptm)550*44bedb31SLionel Sambuc local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
551*44bedb31SLionel Sambuc uLong ulDosDate;
552*44bedb31SLionel Sambuc tm_unz* ptm;
553*44bedb31SLionel Sambuc {
554*44bedb31SLionel Sambuc uLong uDate;
555*44bedb31SLionel Sambuc uDate = (uLong)(ulDosDate>>16);
556*44bedb31SLionel Sambuc ptm->tm_mday = (uInt)(uDate&0x1f) ;
557*44bedb31SLionel Sambuc ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
558*44bedb31SLionel Sambuc ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
559*44bedb31SLionel Sambuc
560*44bedb31SLionel Sambuc ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
561*44bedb31SLionel Sambuc ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
562*44bedb31SLionel Sambuc ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
563*44bedb31SLionel Sambuc }
564*44bedb31SLionel Sambuc
565*44bedb31SLionel Sambuc /*
566*44bedb31SLionel Sambuc Get Info about the current file in the zipfile, with internal only info
567*44bedb31SLionel Sambuc */
568*44bedb31SLionel Sambuc local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
569*44bedb31SLionel Sambuc unz_file_info *pfile_info,
570*44bedb31SLionel Sambuc unz_file_info_internal
571*44bedb31SLionel Sambuc *pfile_info_internal,
572*44bedb31SLionel Sambuc char *szFileName,
573*44bedb31SLionel Sambuc uLong fileNameBufferSize,
574*44bedb31SLionel Sambuc void *extraField,
575*44bedb31SLionel Sambuc uLong extraFieldBufferSize,
576*44bedb31SLionel Sambuc char *szComment,
577*44bedb31SLionel Sambuc uLong commentBufferSize));
578*44bedb31SLionel Sambuc
unzlocal_GetCurrentFileInfoInternal(file,pfile_info,pfile_info_internal,szFileName,fileNameBufferSize,extraField,extraFieldBufferSize,szComment,commentBufferSize)579*44bedb31SLionel Sambuc local int unzlocal_GetCurrentFileInfoInternal (file,
580*44bedb31SLionel Sambuc pfile_info,
581*44bedb31SLionel Sambuc pfile_info_internal,
582*44bedb31SLionel Sambuc szFileName, fileNameBufferSize,
583*44bedb31SLionel Sambuc extraField, extraFieldBufferSize,
584*44bedb31SLionel Sambuc szComment, commentBufferSize)
585*44bedb31SLionel Sambuc unzFile file;
586*44bedb31SLionel Sambuc unz_file_info *pfile_info;
587*44bedb31SLionel Sambuc unz_file_info_internal *pfile_info_internal;
588*44bedb31SLionel Sambuc char *szFileName;
589*44bedb31SLionel Sambuc uLong fileNameBufferSize;
590*44bedb31SLionel Sambuc void *extraField;
591*44bedb31SLionel Sambuc uLong extraFieldBufferSize;
592*44bedb31SLionel Sambuc char *szComment;
593*44bedb31SLionel Sambuc uLong commentBufferSize;
594*44bedb31SLionel Sambuc {
595*44bedb31SLionel Sambuc unz_s* s;
596*44bedb31SLionel Sambuc unz_file_info file_info;
597*44bedb31SLionel Sambuc unz_file_info_internal file_info_internal;
598*44bedb31SLionel Sambuc int err=UNZ_OK;
599*44bedb31SLionel Sambuc uLong uMagic;
600*44bedb31SLionel Sambuc long lSeek=0;
601*44bedb31SLionel Sambuc
602*44bedb31SLionel Sambuc if (file==NULL)
603*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
604*44bedb31SLionel Sambuc s=(unz_s*)file;
605*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc, s->filestream,
606*44bedb31SLionel Sambuc s->pos_in_central_dir+s->byte_before_the_zipfile,
607*44bedb31SLionel Sambuc ZLIB_FILEFUNC_SEEK_SET)!=0)
608*44bedb31SLionel Sambuc err=UNZ_ERRNO;
609*44bedb31SLionel Sambuc
610*44bedb31SLionel Sambuc
611*44bedb31SLionel Sambuc /* we check the magic */
612*44bedb31SLionel Sambuc if (err==UNZ_OK)
613*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
614*44bedb31SLionel Sambuc err=UNZ_ERRNO;
615*44bedb31SLionel Sambuc else if (uMagic!=0x02014b50)
616*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
617*44bedb31SLionel Sambuc
618*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
619*44bedb31SLionel Sambuc err=UNZ_ERRNO;
620*44bedb31SLionel Sambuc
621*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
622*44bedb31SLionel Sambuc err=UNZ_ERRNO;
623*44bedb31SLionel Sambuc
624*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
625*44bedb31SLionel Sambuc err=UNZ_ERRNO;
626*44bedb31SLionel Sambuc
627*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
628*44bedb31SLionel Sambuc err=UNZ_ERRNO;
629*44bedb31SLionel Sambuc
630*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
631*44bedb31SLionel Sambuc err=UNZ_ERRNO;
632*44bedb31SLionel Sambuc
633*44bedb31SLionel Sambuc unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
634*44bedb31SLionel Sambuc
635*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
636*44bedb31SLionel Sambuc err=UNZ_ERRNO;
637*44bedb31SLionel Sambuc
638*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
639*44bedb31SLionel Sambuc err=UNZ_ERRNO;
640*44bedb31SLionel Sambuc
641*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
642*44bedb31SLionel Sambuc err=UNZ_ERRNO;
643*44bedb31SLionel Sambuc
644*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
645*44bedb31SLionel Sambuc err=UNZ_ERRNO;
646*44bedb31SLionel Sambuc
647*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
648*44bedb31SLionel Sambuc err=UNZ_ERRNO;
649*44bedb31SLionel Sambuc
650*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
651*44bedb31SLionel Sambuc err=UNZ_ERRNO;
652*44bedb31SLionel Sambuc
653*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
654*44bedb31SLionel Sambuc err=UNZ_ERRNO;
655*44bedb31SLionel Sambuc
656*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
657*44bedb31SLionel Sambuc err=UNZ_ERRNO;
658*44bedb31SLionel Sambuc
659*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
660*44bedb31SLionel Sambuc err=UNZ_ERRNO;
661*44bedb31SLionel Sambuc
662*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
663*44bedb31SLionel Sambuc err=UNZ_ERRNO;
664*44bedb31SLionel Sambuc
665*44bedb31SLionel Sambuc lSeek+=file_info.size_filename;
666*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (szFileName!=NULL))
667*44bedb31SLionel Sambuc {
668*44bedb31SLionel Sambuc uLong uSizeRead ;
669*44bedb31SLionel Sambuc if (file_info.size_filename<fileNameBufferSize)
670*44bedb31SLionel Sambuc {
671*44bedb31SLionel Sambuc *(szFileName+file_info.size_filename)='\0';
672*44bedb31SLionel Sambuc uSizeRead = file_info.size_filename;
673*44bedb31SLionel Sambuc }
674*44bedb31SLionel Sambuc else
675*44bedb31SLionel Sambuc uSizeRead = fileNameBufferSize;
676*44bedb31SLionel Sambuc
677*44bedb31SLionel Sambuc if ((file_info.size_filename>0) && (fileNameBufferSize>0))
678*44bedb31SLionel Sambuc if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
679*44bedb31SLionel Sambuc err=UNZ_ERRNO;
680*44bedb31SLionel Sambuc lSeek -= uSizeRead;
681*44bedb31SLionel Sambuc }
682*44bedb31SLionel Sambuc
683*44bedb31SLionel Sambuc
684*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (extraField!=NULL))
685*44bedb31SLionel Sambuc {
686*44bedb31SLionel Sambuc uLong uSizeRead ;
687*44bedb31SLionel Sambuc if (file_info.size_file_extra<extraFieldBufferSize)
688*44bedb31SLionel Sambuc uSizeRead = file_info.size_file_extra;
689*44bedb31SLionel Sambuc else
690*44bedb31SLionel Sambuc uSizeRead = extraFieldBufferSize;
691*44bedb31SLionel Sambuc
692*44bedb31SLionel Sambuc if (lSeek!=0)
693*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
694*44bedb31SLionel Sambuc lSeek=0;
695*44bedb31SLionel Sambuc else
696*44bedb31SLionel Sambuc err=UNZ_ERRNO;
697*44bedb31SLionel Sambuc if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
698*44bedb31SLionel Sambuc if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
699*44bedb31SLionel Sambuc err=UNZ_ERRNO;
700*44bedb31SLionel Sambuc lSeek += file_info.size_file_extra - uSizeRead;
701*44bedb31SLionel Sambuc }
702*44bedb31SLionel Sambuc else
703*44bedb31SLionel Sambuc lSeek+=file_info.size_file_extra;
704*44bedb31SLionel Sambuc
705*44bedb31SLionel Sambuc
706*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (szComment!=NULL))
707*44bedb31SLionel Sambuc {
708*44bedb31SLionel Sambuc uLong uSizeRead ;
709*44bedb31SLionel Sambuc if (file_info.size_file_comment<commentBufferSize)
710*44bedb31SLionel Sambuc {
711*44bedb31SLionel Sambuc *(szComment+file_info.size_file_comment)='\0';
712*44bedb31SLionel Sambuc uSizeRead = file_info.size_file_comment;
713*44bedb31SLionel Sambuc }
714*44bedb31SLionel Sambuc else
715*44bedb31SLionel Sambuc uSizeRead = commentBufferSize;
716*44bedb31SLionel Sambuc
717*44bedb31SLionel Sambuc if (lSeek!=0)
718*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
719*44bedb31SLionel Sambuc lSeek=0;
720*44bedb31SLionel Sambuc else
721*44bedb31SLionel Sambuc err=UNZ_ERRNO;
722*44bedb31SLionel Sambuc if ((file_info.size_file_comment>0) && (commentBufferSize>0))
723*44bedb31SLionel Sambuc if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
724*44bedb31SLionel Sambuc err=UNZ_ERRNO;
725*44bedb31SLionel Sambuc lSeek+=file_info.size_file_comment - uSizeRead;
726*44bedb31SLionel Sambuc }
727*44bedb31SLionel Sambuc else
728*44bedb31SLionel Sambuc lSeek+=file_info.size_file_comment;
729*44bedb31SLionel Sambuc
730*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (pfile_info!=NULL))
731*44bedb31SLionel Sambuc *pfile_info=file_info;
732*44bedb31SLionel Sambuc
733*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
734*44bedb31SLionel Sambuc *pfile_info_internal=file_info_internal;
735*44bedb31SLionel Sambuc
736*44bedb31SLionel Sambuc return err;
737*44bedb31SLionel Sambuc }
738*44bedb31SLionel Sambuc
739*44bedb31SLionel Sambuc
740*44bedb31SLionel Sambuc
741*44bedb31SLionel Sambuc /*
742*44bedb31SLionel Sambuc Write info about the ZipFile in the *pglobal_info structure.
743*44bedb31SLionel Sambuc No preparation of the structure is needed
744*44bedb31SLionel Sambuc return UNZ_OK if there is no problem.
745*44bedb31SLionel Sambuc */
746*44bedb31SLionel Sambuc extern int ZEXPORT unzGetCurrentFileInfo (file,
747*44bedb31SLionel Sambuc pfile_info,
748*44bedb31SLionel Sambuc szFileName, fileNameBufferSize,
749*44bedb31SLionel Sambuc extraField, extraFieldBufferSize,
750*44bedb31SLionel Sambuc szComment, commentBufferSize)
751*44bedb31SLionel Sambuc unzFile file;
752*44bedb31SLionel Sambuc unz_file_info *pfile_info;
753*44bedb31SLionel Sambuc char *szFileName;
754*44bedb31SLionel Sambuc uLong fileNameBufferSize;
755*44bedb31SLionel Sambuc void *extraField;
756*44bedb31SLionel Sambuc uLong extraFieldBufferSize;
757*44bedb31SLionel Sambuc char *szComment;
758*44bedb31SLionel Sambuc uLong commentBufferSize;
759*44bedb31SLionel Sambuc {
760*44bedb31SLionel Sambuc return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
761*44bedb31SLionel Sambuc szFileName,fileNameBufferSize,
762*44bedb31SLionel Sambuc extraField,extraFieldBufferSize,
763*44bedb31SLionel Sambuc szComment,commentBufferSize);
764*44bedb31SLionel Sambuc }
765*44bedb31SLionel Sambuc
766*44bedb31SLionel Sambuc /*
767*44bedb31SLionel Sambuc Set the current file of the zipfile to the first file.
768*44bedb31SLionel Sambuc return UNZ_OK if there is no problem
769*44bedb31SLionel Sambuc */
770*44bedb31SLionel Sambuc extern int ZEXPORT unzGoToFirstFile (file)
771*44bedb31SLionel Sambuc unzFile file;
772*44bedb31SLionel Sambuc {
773*44bedb31SLionel Sambuc int err=UNZ_OK;
774*44bedb31SLionel Sambuc unz_s* s;
775*44bedb31SLionel Sambuc if (file==NULL)
776*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
777*44bedb31SLionel Sambuc s=(unz_s*)file;
778*44bedb31SLionel Sambuc s->pos_in_central_dir=s->offset_central_dir;
779*44bedb31SLionel Sambuc s->num_file=0;
780*44bedb31SLionel Sambuc err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
781*44bedb31SLionel Sambuc &s->cur_file_info_internal,
782*44bedb31SLionel Sambuc NULL,0,NULL,0,NULL,0);
783*44bedb31SLionel Sambuc s->current_file_ok = (err == UNZ_OK);
784*44bedb31SLionel Sambuc return err;
785*44bedb31SLionel Sambuc }
786*44bedb31SLionel Sambuc
787*44bedb31SLionel Sambuc /*
788*44bedb31SLionel Sambuc Set the current file of the zipfile to the next file.
789*44bedb31SLionel Sambuc return UNZ_OK if there is no problem
790*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
791*44bedb31SLionel Sambuc */
792*44bedb31SLionel Sambuc extern int ZEXPORT unzGoToNextFile (file)
793*44bedb31SLionel Sambuc unzFile file;
794*44bedb31SLionel Sambuc {
795*44bedb31SLionel Sambuc unz_s* s;
796*44bedb31SLionel Sambuc int err;
797*44bedb31SLionel Sambuc
798*44bedb31SLionel Sambuc if (file==NULL)
799*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
800*44bedb31SLionel Sambuc s=(unz_s*)file;
801*44bedb31SLionel Sambuc if (!s->current_file_ok)
802*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE;
803*44bedb31SLionel Sambuc if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
804*44bedb31SLionel Sambuc if (s->num_file+1==s->gi.number_entry)
805*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE;
806*44bedb31SLionel Sambuc
807*44bedb31SLionel Sambuc s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
808*44bedb31SLionel Sambuc s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
809*44bedb31SLionel Sambuc s->num_file++;
810*44bedb31SLionel Sambuc err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
811*44bedb31SLionel Sambuc &s->cur_file_info_internal,
812*44bedb31SLionel Sambuc NULL,0,NULL,0,NULL,0);
813*44bedb31SLionel Sambuc s->current_file_ok = (err == UNZ_OK);
814*44bedb31SLionel Sambuc return err;
815*44bedb31SLionel Sambuc }
816*44bedb31SLionel Sambuc
817*44bedb31SLionel Sambuc
818*44bedb31SLionel Sambuc /*
819*44bedb31SLionel Sambuc Try locate the file szFileName in the zipfile.
820*44bedb31SLionel Sambuc For the iCaseSensitivity signification, see unzipStringFileNameCompare
821*44bedb31SLionel Sambuc
822*44bedb31SLionel Sambuc return value :
823*44bedb31SLionel Sambuc UNZ_OK if the file is found. It becomes the current file.
824*44bedb31SLionel Sambuc UNZ_END_OF_LIST_OF_FILE if the file is not found
825*44bedb31SLionel Sambuc */
826*44bedb31SLionel Sambuc extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
827*44bedb31SLionel Sambuc unzFile file;
828*44bedb31SLionel Sambuc const char *szFileName;
829*44bedb31SLionel Sambuc int iCaseSensitivity;
830*44bedb31SLionel Sambuc {
831*44bedb31SLionel Sambuc unz_s* s;
832*44bedb31SLionel Sambuc int err;
833*44bedb31SLionel Sambuc
834*44bedb31SLionel Sambuc /* We remember the 'current' position in the file so that we can jump
835*44bedb31SLionel Sambuc * back there if we fail.
836*44bedb31SLionel Sambuc */
837*44bedb31SLionel Sambuc unz_file_info cur_file_infoSaved;
838*44bedb31SLionel Sambuc unz_file_info_internal cur_file_info_internalSaved;
839*44bedb31SLionel Sambuc uLong num_fileSaved;
840*44bedb31SLionel Sambuc uLong pos_in_central_dirSaved;
841*44bedb31SLionel Sambuc
842*44bedb31SLionel Sambuc
843*44bedb31SLionel Sambuc if (file==NULL)
844*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
845*44bedb31SLionel Sambuc
846*44bedb31SLionel Sambuc if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
847*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
848*44bedb31SLionel Sambuc
849*44bedb31SLionel Sambuc s=(unz_s*)file;
850*44bedb31SLionel Sambuc if (!s->current_file_ok)
851*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE;
852*44bedb31SLionel Sambuc
853*44bedb31SLionel Sambuc /* Save the current state */
854*44bedb31SLionel Sambuc num_fileSaved = s->num_file;
855*44bedb31SLionel Sambuc pos_in_central_dirSaved = s->pos_in_central_dir;
856*44bedb31SLionel Sambuc cur_file_infoSaved = s->cur_file_info;
857*44bedb31SLionel Sambuc cur_file_info_internalSaved = s->cur_file_info_internal;
858*44bedb31SLionel Sambuc
859*44bedb31SLionel Sambuc err = unzGoToFirstFile(file);
860*44bedb31SLionel Sambuc
861*44bedb31SLionel Sambuc while (err == UNZ_OK)
862*44bedb31SLionel Sambuc {
863*44bedb31SLionel Sambuc char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
864*44bedb31SLionel Sambuc err = unzGetCurrentFileInfo(file,NULL,
865*44bedb31SLionel Sambuc szCurrentFileName,sizeof(szCurrentFileName)-1,
866*44bedb31SLionel Sambuc NULL,0,NULL,0);
867*44bedb31SLionel Sambuc if (err == UNZ_OK)
868*44bedb31SLionel Sambuc {
869*44bedb31SLionel Sambuc if (unzStringFileNameCompare(szCurrentFileName,
870*44bedb31SLionel Sambuc szFileName,iCaseSensitivity)==0)
871*44bedb31SLionel Sambuc return UNZ_OK;
872*44bedb31SLionel Sambuc err = unzGoToNextFile(file);
873*44bedb31SLionel Sambuc }
874*44bedb31SLionel Sambuc }
875*44bedb31SLionel Sambuc
876*44bedb31SLionel Sambuc /* We failed, so restore the state of the 'current file' to where we
877*44bedb31SLionel Sambuc * were.
878*44bedb31SLionel Sambuc */
879*44bedb31SLionel Sambuc s->num_file = num_fileSaved ;
880*44bedb31SLionel Sambuc s->pos_in_central_dir = pos_in_central_dirSaved ;
881*44bedb31SLionel Sambuc s->cur_file_info = cur_file_infoSaved;
882*44bedb31SLionel Sambuc s->cur_file_info_internal = cur_file_info_internalSaved;
883*44bedb31SLionel Sambuc return err;
884*44bedb31SLionel Sambuc }
885*44bedb31SLionel Sambuc
886*44bedb31SLionel Sambuc
887*44bedb31SLionel Sambuc /*
888*44bedb31SLionel Sambuc ///////////////////////////////////////////
889*44bedb31SLionel Sambuc // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
890*44bedb31SLionel Sambuc // I need random access
891*44bedb31SLionel Sambuc //
892*44bedb31SLionel Sambuc // Further optimization could be realized by adding an ability
893*44bedb31SLionel Sambuc // to cache the directory in memory. The goal being a single
894*44bedb31SLionel Sambuc // comprehensive file read to put the file I need in a memory.
895*44bedb31SLionel Sambuc */
896*44bedb31SLionel Sambuc
897*44bedb31SLionel Sambuc /*
898*44bedb31SLionel Sambuc typedef struct unz_file_pos_s
899*44bedb31SLionel Sambuc {
900*44bedb31SLionel Sambuc uLong pos_in_zip_directory; // offset in file
901*44bedb31SLionel Sambuc uLong num_of_file; // # of file
902*44bedb31SLionel Sambuc } unz_file_pos;
903*44bedb31SLionel Sambuc */
904*44bedb31SLionel Sambuc
905*44bedb31SLionel Sambuc extern int ZEXPORT unzGetFilePos(file, file_pos)
906*44bedb31SLionel Sambuc unzFile file;
907*44bedb31SLionel Sambuc unz_file_pos* file_pos;
908*44bedb31SLionel Sambuc {
909*44bedb31SLionel Sambuc unz_s* s;
910*44bedb31SLionel Sambuc
911*44bedb31SLionel Sambuc if (file==NULL || file_pos==NULL)
912*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
913*44bedb31SLionel Sambuc s=(unz_s*)file;
914*44bedb31SLionel Sambuc if (!s->current_file_ok)
915*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE;
916*44bedb31SLionel Sambuc
917*44bedb31SLionel Sambuc file_pos->pos_in_zip_directory = s->pos_in_central_dir;
918*44bedb31SLionel Sambuc file_pos->num_of_file = s->num_file;
919*44bedb31SLionel Sambuc
920*44bedb31SLionel Sambuc return UNZ_OK;
921*44bedb31SLionel Sambuc }
922*44bedb31SLionel Sambuc
923*44bedb31SLionel Sambuc extern int ZEXPORT unzGoToFilePos(file, file_pos)
924*44bedb31SLionel Sambuc unzFile file;
925*44bedb31SLionel Sambuc unz_file_pos* file_pos;
926*44bedb31SLionel Sambuc {
927*44bedb31SLionel Sambuc unz_s* s;
928*44bedb31SLionel Sambuc int err;
929*44bedb31SLionel Sambuc
930*44bedb31SLionel Sambuc if (file==NULL || file_pos==NULL)
931*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
932*44bedb31SLionel Sambuc s=(unz_s*)file;
933*44bedb31SLionel Sambuc
934*44bedb31SLionel Sambuc /* jump to the right spot */
935*44bedb31SLionel Sambuc s->pos_in_central_dir = file_pos->pos_in_zip_directory;
936*44bedb31SLionel Sambuc s->num_file = file_pos->num_of_file;
937*44bedb31SLionel Sambuc
938*44bedb31SLionel Sambuc /* set the current file */
939*44bedb31SLionel Sambuc err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
940*44bedb31SLionel Sambuc &s->cur_file_info_internal,
941*44bedb31SLionel Sambuc NULL,0,NULL,0,NULL,0);
942*44bedb31SLionel Sambuc /* return results */
943*44bedb31SLionel Sambuc s->current_file_ok = (err == UNZ_OK);
944*44bedb31SLionel Sambuc return err;
945*44bedb31SLionel Sambuc }
946*44bedb31SLionel Sambuc
947*44bedb31SLionel Sambuc /*
948*44bedb31SLionel Sambuc // Unzip Helper Functions - should be here?
949*44bedb31SLionel Sambuc ///////////////////////////////////////////
950*44bedb31SLionel Sambuc */
951*44bedb31SLionel Sambuc
952*44bedb31SLionel Sambuc /*
953*44bedb31SLionel Sambuc Read the local header of the current zipfile
954*44bedb31SLionel Sambuc Check the coherency of the local header and info in the end of central
955*44bedb31SLionel Sambuc directory about this file
956*44bedb31SLionel Sambuc store in *piSizeVar the size of extra info in local header
957*44bedb31SLionel Sambuc (filename and size of extra field data)
958*44bedb31SLionel Sambuc */
unzlocal_CheckCurrentFileCoherencyHeader(s,piSizeVar,poffset_local_extrafield,psize_local_extrafield)959*44bedb31SLionel Sambuc local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
960*44bedb31SLionel Sambuc poffset_local_extrafield,
961*44bedb31SLionel Sambuc psize_local_extrafield)
962*44bedb31SLionel Sambuc unz_s* s;
963*44bedb31SLionel Sambuc uInt* piSizeVar;
964*44bedb31SLionel Sambuc uLong *poffset_local_extrafield;
965*44bedb31SLionel Sambuc uInt *psize_local_extrafield;
966*44bedb31SLionel Sambuc {
967*44bedb31SLionel Sambuc uLong uMagic,uData,uFlags;
968*44bedb31SLionel Sambuc uLong size_filename;
969*44bedb31SLionel Sambuc uLong size_extra_field;
970*44bedb31SLionel Sambuc int err=UNZ_OK;
971*44bedb31SLionel Sambuc
972*44bedb31SLionel Sambuc *piSizeVar = 0;
973*44bedb31SLionel Sambuc *poffset_local_extrafield = 0;
974*44bedb31SLionel Sambuc *psize_local_extrafield = 0;
975*44bedb31SLionel Sambuc
976*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
977*44bedb31SLionel Sambuc s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
978*44bedb31SLionel Sambuc return UNZ_ERRNO;
979*44bedb31SLionel Sambuc
980*44bedb31SLionel Sambuc
981*44bedb31SLionel Sambuc if (err==UNZ_OK)
982*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
983*44bedb31SLionel Sambuc err=UNZ_ERRNO;
984*44bedb31SLionel Sambuc else if (uMagic!=0x04034b50)
985*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
986*44bedb31SLionel Sambuc
987*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
988*44bedb31SLionel Sambuc err=UNZ_ERRNO;
989*44bedb31SLionel Sambuc /*
990*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
991*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
992*44bedb31SLionel Sambuc */
993*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
994*44bedb31SLionel Sambuc err=UNZ_ERRNO;
995*44bedb31SLionel Sambuc
996*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
997*44bedb31SLionel Sambuc err=UNZ_ERRNO;
998*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
999*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1000*44bedb31SLionel Sambuc
1001*44bedb31SLionel Sambuc if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1002*44bedb31SLionel Sambuc (s->cur_file_info.compression_method!=Z_DEFLATED))
1003*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1004*44bedb31SLionel Sambuc
1005*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1006*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1007*44bedb31SLionel Sambuc
1008*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1009*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1010*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1011*44bedb31SLionel Sambuc ((uFlags & 8)==0))
1012*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1013*44bedb31SLionel Sambuc
1014*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1015*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1016*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1017*44bedb31SLionel Sambuc ((uFlags & 8)==0))
1018*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1019*44bedb31SLionel Sambuc
1020*44bedb31SLionel Sambuc if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1021*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1022*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1023*44bedb31SLionel Sambuc ((uFlags & 8)==0))
1024*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1025*44bedb31SLionel Sambuc
1026*44bedb31SLionel Sambuc
1027*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1028*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1029*44bedb31SLionel Sambuc else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1030*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1031*44bedb31SLionel Sambuc
1032*44bedb31SLionel Sambuc *piSizeVar += (uInt)size_filename;
1033*44bedb31SLionel Sambuc
1034*44bedb31SLionel Sambuc if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1035*44bedb31SLionel Sambuc err=UNZ_ERRNO;
1036*44bedb31SLionel Sambuc *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1037*44bedb31SLionel Sambuc SIZEZIPLOCALHEADER + size_filename;
1038*44bedb31SLionel Sambuc *psize_local_extrafield = (uInt)size_extra_field;
1039*44bedb31SLionel Sambuc
1040*44bedb31SLionel Sambuc *piSizeVar += (uInt)size_extra_field;
1041*44bedb31SLionel Sambuc
1042*44bedb31SLionel Sambuc return err;
1043*44bedb31SLionel Sambuc }
1044*44bedb31SLionel Sambuc
1045*44bedb31SLionel Sambuc /*
1046*44bedb31SLionel Sambuc Open for reading data the current file in the zipfile.
1047*44bedb31SLionel Sambuc If there is no error and the file is opened, the return value is UNZ_OK.
1048*44bedb31SLionel Sambuc */
1049*44bedb31SLionel Sambuc extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1050*44bedb31SLionel Sambuc unzFile file;
1051*44bedb31SLionel Sambuc int* method;
1052*44bedb31SLionel Sambuc int* level;
1053*44bedb31SLionel Sambuc int raw;
1054*44bedb31SLionel Sambuc const char* password;
1055*44bedb31SLionel Sambuc {
1056*44bedb31SLionel Sambuc int err=UNZ_OK;
1057*44bedb31SLionel Sambuc uInt iSizeVar;
1058*44bedb31SLionel Sambuc unz_s* s;
1059*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1060*44bedb31SLionel Sambuc uLong offset_local_extrafield; /* offset of the local extra field */
1061*44bedb31SLionel Sambuc uInt size_local_extrafield; /* size of the local extra field */
1062*44bedb31SLionel Sambuc # ifndef NOUNCRYPT
1063*44bedb31SLionel Sambuc char source[12];
1064*44bedb31SLionel Sambuc # else
1065*44bedb31SLionel Sambuc if (password != NULL)
1066*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1067*44bedb31SLionel Sambuc # endif
1068*44bedb31SLionel Sambuc
1069*44bedb31SLionel Sambuc if (file==NULL)
1070*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1071*44bedb31SLionel Sambuc s=(unz_s*)file;
1072*44bedb31SLionel Sambuc if (!s->current_file_ok)
1073*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1074*44bedb31SLionel Sambuc
1075*44bedb31SLionel Sambuc if (s->pfile_in_zip_read != NULL)
1076*44bedb31SLionel Sambuc unzCloseCurrentFile(file);
1077*44bedb31SLionel Sambuc
1078*44bedb31SLionel Sambuc if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1079*44bedb31SLionel Sambuc &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1080*44bedb31SLionel Sambuc return UNZ_BADZIPFILE;
1081*44bedb31SLionel Sambuc
1082*44bedb31SLionel Sambuc pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1083*44bedb31SLionel Sambuc ALLOC(sizeof(file_in_zip_read_info_s));
1084*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1085*44bedb31SLionel Sambuc return UNZ_INTERNALERROR;
1086*44bedb31SLionel Sambuc
1087*44bedb31SLionel Sambuc pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1088*44bedb31SLionel Sambuc pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1089*44bedb31SLionel Sambuc pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1090*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_local_extrafield=0;
1091*44bedb31SLionel Sambuc pfile_in_zip_read_info->raw=raw;
1092*44bedb31SLionel Sambuc
1093*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->read_buffer==NULL)
1094*44bedb31SLionel Sambuc {
1095*44bedb31SLionel Sambuc TRYFREE(pfile_in_zip_read_info);
1096*44bedb31SLionel Sambuc return UNZ_INTERNALERROR;
1097*44bedb31SLionel Sambuc }
1098*44bedb31SLionel Sambuc
1099*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream_initialised=0;
1100*44bedb31SLionel Sambuc
1101*44bedb31SLionel Sambuc if (method!=NULL)
1102*44bedb31SLionel Sambuc *method = (int)s->cur_file_info.compression_method;
1103*44bedb31SLionel Sambuc
1104*44bedb31SLionel Sambuc if (level!=NULL)
1105*44bedb31SLionel Sambuc {
1106*44bedb31SLionel Sambuc *level = 6;
1107*44bedb31SLionel Sambuc switch (s->cur_file_info.flag & 0x06)
1108*44bedb31SLionel Sambuc {
1109*44bedb31SLionel Sambuc case 6 : *level = 1; break;
1110*44bedb31SLionel Sambuc case 4 : *level = 2; break;
1111*44bedb31SLionel Sambuc case 2 : *level = 9; break;
1112*44bedb31SLionel Sambuc }
1113*44bedb31SLionel Sambuc }
1114*44bedb31SLionel Sambuc
1115*44bedb31SLionel Sambuc if ((s->cur_file_info.compression_method!=0) &&
1116*44bedb31SLionel Sambuc (s->cur_file_info.compression_method!=Z_DEFLATED))
1117*44bedb31SLionel Sambuc err=UNZ_BADZIPFILE;
1118*44bedb31SLionel Sambuc
1119*44bedb31SLionel Sambuc pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1120*44bedb31SLionel Sambuc pfile_in_zip_read_info->crc32=0;
1121*44bedb31SLionel Sambuc pfile_in_zip_read_info->compression_method =
1122*44bedb31SLionel Sambuc s->cur_file_info.compression_method;
1123*44bedb31SLionel Sambuc pfile_in_zip_read_info->filestream=s->filestream;
1124*44bedb31SLionel Sambuc pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1125*44bedb31SLionel Sambuc pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1126*44bedb31SLionel Sambuc
1127*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.total_out = 0;
1128*44bedb31SLionel Sambuc
1129*44bedb31SLionel Sambuc if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1130*44bedb31SLionel Sambuc (!raw))
1131*44bedb31SLionel Sambuc {
1132*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1133*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.zfree = (free_func)0;
1134*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1135*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1136*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in = 0;
1137*44bedb31SLionel Sambuc
1138*44bedb31SLionel Sambuc err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1139*44bedb31SLionel Sambuc if (err == Z_OK)
1140*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream_initialised=1;
1141*44bedb31SLionel Sambuc else
1142*44bedb31SLionel Sambuc {
1143*44bedb31SLionel Sambuc TRYFREE(pfile_in_zip_read_info);
1144*44bedb31SLionel Sambuc return err;
1145*44bedb31SLionel Sambuc }
1146*44bedb31SLionel Sambuc /* windowBits is passed < 0 to tell that there is no zlib header.
1147*44bedb31SLionel Sambuc * Note that in this case inflate *requires* an extra "dummy" byte
1148*44bedb31SLionel Sambuc * after the compressed stream in order to complete decompression and
1149*44bedb31SLionel Sambuc * return Z_STREAM_END.
1150*44bedb31SLionel Sambuc * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1151*44bedb31SLionel Sambuc * size of both compressed and uncompressed data
1152*44bedb31SLionel Sambuc */
1153*44bedb31SLionel Sambuc }
1154*44bedb31SLionel Sambuc pfile_in_zip_read_info->rest_read_compressed =
1155*44bedb31SLionel Sambuc s->cur_file_info.compressed_size ;
1156*44bedb31SLionel Sambuc pfile_in_zip_read_info->rest_read_uncompressed =
1157*44bedb31SLionel Sambuc s->cur_file_info.uncompressed_size ;
1158*44bedb31SLionel Sambuc
1159*44bedb31SLionel Sambuc
1160*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_in_zipfile =
1161*44bedb31SLionel Sambuc s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1162*44bedb31SLionel Sambuc iSizeVar;
1163*44bedb31SLionel Sambuc
1164*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1165*44bedb31SLionel Sambuc
1166*44bedb31SLionel Sambuc s->pfile_in_zip_read = pfile_in_zip_read_info;
1167*44bedb31SLionel Sambuc
1168*44bedb31SLionel Sambuc # ifndef NOUNCRYPT
1169*44bedb31SLionel Sambuc if (password != NULL)
1170*44bedb31SLionel Sambuc {
1171*44bedb31SLionel Sambuc int i;
1172*44bedb31SLionel Sambuc s->pcrc_32_tab = get_crc_table();
1173*44bedb31SLionel Sambuc init_keys(password,s->keys,s->pcrc_32_tab);
1174*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc, s->filestream,
1175*44bedb31SLionel Sambuc s->pfile_in_zip_read->pos_in_zipfile +
1176*44bedb31SLionel Sambuc s->pfile_in_zip_read->byte_before_the_zipfile,
1177*44bedb31SLionel Sambuc SEEK_SET)!=0)
1178*44bedb31SLionel Sambuc return UNZ_INTERNALERROR;
1179*44bedb31SLionel Sambuc if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1180*44bedb31SLionel Sambuc return UNZ_INTERNALERROR;
1181*44bedb31SLionel Sambuc
1182*44bedb31SLionel Sambuc for (i = 0; i<12; i++)
1183*44bedb31SLionel Sambuc zdecode(s->keys,s->pcrc_32_tab,source[i]);
1184*44bedb31SLionel Sambuc
1185*44bedb31SLionel Sambuc s->pfile_in_zip_read->pos_in_zipfile+=12;
1186*44bedb31SLionel Sambuc s->encrypted=1;
1187*44bedb31SLionel Sambuc }
1188*44bedb31SLionel Sambuc # endif
1189*44bedb31SLionel Sambuc
1190*44bedb31SLionel Sambuc
1191*44bedb31SLionel Sambuc return UNZ_OK;
1192*44bedb31SLionel Sambuc }
1193*44bedb31SLionel Sambuc
1194*44bedb31SLionel Sambuc extern int ZEXPORT unzOpenCurrentFile (file)
1195*44bedb31SLionel Sambuc unzFile file;
1196*44bedb31SLionel Sambuc {
1197*44bedb31SLionel Sambuc return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1198*44bedb31SLionel Sambuc }
1199*44bedb31SLionel Sambuc
1200*44bedb31SLionel Sambuc extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1201*44bedb31SLionel Sambuc unzFile file;
1202*44bedb31SLionel Sambuc const char* password;
1203*44bedb31SLionel Sambuc {
1204*44bedb31SLionel Sambuc return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1205*44bedb31SLionel Sambuc }
1206*44bedb31SLionel Sambuc
1207*44bedb31SLionel Sambuc extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1208*44bedb31SLionel Sambuc unzFile file;
1209*44bedb31SLionel Sambuc int* method;
1210*44bedb31SLionel Sambuc int* level;
1211*44bedb31SLionel Sambuc int raw;
1212*44bedb31SLionel Sambuc {
1213*44bedb31SLionel Sambuc return unzOpenCurrentFile3(file, method, level, raw, NULL);
1214*44bedb31SLionel Sambuc }
1215*44bedb31SLionel Sambuc
1216*44bedb31SLionel Sambuc /*
1217*44bedb31SLionel Sambuc Read bytes from the current file.
1218*44bedb31SLionel Sambuc buf contain buffer where data must be copied
1219*44bedb31SLionel Sambuc len the size of buf.
1220*44bedb31SLionel Sambuc
1221*44bedb31SLionel Sambuc return the number of byte copied if somes bytes are copied
1222*44bedb31SLionel Sambuc return 0 if the end of file was reached
1223*44bedb31SLionel Sambuc return <0 with error code if there is an error
1224*44bedb31SLionel Sambuc (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1225*44bedb31SLionel Sambuc */
1226*44bedb31SLionel Sambuc extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1227*44bedb31SLionel Sambuc unzFile file;
1228*44bedb31SLionel Sambuc voidp buf;
1229*44bedb31SLionel Sambuc unsigned len;
1230*44bedb31SLionel Sambuc {
1231*44bedb31SLionel Sambuc int err=UNZ_OK;
1232*44bedb31SLionel Sambuc uInt iRead = 0;
1233*44bedb31SLionel Sambuc unz_s* s;
1234*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1235*44bedb31SLionel Sambuc if (file==NULL)
1236*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1237*44bedb31SLionel Sambuc s=(unz_s*)file;
1238*44bedb31SLionel Sambuc pfile_in_zip_read_info=s->pfile_in_zip_read;
1239*44bedb31SLionel Sambuc
1240*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1241*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1242*44bedb31SLionel Sambuc
1243*44bedb31SLionel Sambuc
1244*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->read_buffer == NULL))
1245*44bedb31SLionel Sambuc return UNZ_END_OF_LIST_OF_FILE;
1246*44bedb31SLionel Sambuc if (len==0)
1247*44bedb31SLionel Sambuc return 0;
1248*44bedb31SLionel Sambuc
1249*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1250*44bedb31SLionel Sambuc
1251*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1252*44bedb31SLionel Sambuc
1253*44bedb31SLionel Sambuc if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1254*44bedb31SLionel Sambuc (!(pfile_in_zip_read_info->raw)))
1255*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_out =
1256*44bedb31SLionel Sambuc (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1257*44bedb31SLionel Sambuc
1258*44bedb31SLionel Sambuc if ((len>pfile_in_zip_read_info->rest_read_compressed+
1259*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in) &&
1260*44bedb31SLionel Sambuc (pfile_in_zip_read_info->raw))
1261*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_out =
1262*44bedb31SLionel Sambuc (uInt)pfile_in_zip_read_info->rest_read_compressed+
1263*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in;
1264*44bedb31SLionel Sambuc
1265*44bedb31SLionel Sambuc while (pfile_in_zip_read_info->stream.avail_out>0)
1266*44bedb31SLionel Sambuc {
1267*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1268*44bedb31SLionel Sambuc (pfile_in_zip_read_info->rest_read_compressed>0))
1269*44bedb31SLionel Sambuc {
1270*44bedb31SLionel Sambuc uInt uReadThis = UNZ_BUFSIZE;
1271*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1272*44bedb31SLionel Sambuc uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1273*44bedb31SLionel Sambuc if (uReadThis == 0)
1274*44bedb31SLionel Sambuc return UNZ_EOF;
1275*44bedb31SLionel Sambuc if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1276*44bedb31SLionel Sambuc pfile_in_zip_read_info->filestream,
1277*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_in_zipfile +
1278*44bedb31SLionel Sambuc pfile_in_zip_read_info->byte_before_the_zipfile,
1279*44bedb31SLionel Sambuc ZLIB_FILEFUNC_SEEK_SET)!=0)
1280*44bedb31SLionel Sambuc return UNZ_ERRNO;
1281*44bedb31SLionel Sambuc if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1282*44bedb31SLionel Sambuc pfile_in_zip_read_info->filestream,
1283*44bedb31SLionel Sambuc pfile_in_zip_read_info->read_buffer,
1284*44bedb31SLionel Sambuc uReadThis)!=uReadThis)
1285*44bedb31SLionel Sambuc return UNZ_ERRNO;
1286*44bedb31SLionel Sambuc
1287*44bedb31SLionel Sambuc
1288*44bedb31SLionel Sambuc # ifndef NOUNCRYPT
1289*44bedb31SLionel Sambuc if(s->encrypted)
1290*44bedb31SLionel Sambuc {
1291*44bedb31SLionel Sambuc uInt i;
1292*44bedb31SLionel Sambuc for(i=0;i<uReadThis;i++)
1293*44bedb31SLionel Sambuc pfile_in_zip_read_info->read_buffer[i] =
1294*44bedb31SLionel Sambuc zdecode(s->keys,s->pcrc_32_tab,
1295*44bedb31SLionel Sambuc pfile_in_zip_read_info->read_buffer[i]);
1296*44bedb31SLionel Sambuc }
1297*44bedb31SLionel Sambuc # endif
1298*44bedb31SLionel Sambuc
1299*44bedb31SLionel Sambuc
1300*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1301*44bedb31SLionel Sambuc
1302*44bedb31SLionel Sambuc pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1303*44bedb31SLionel Sambuc
1304*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_in =
1305*44bedb31SLionel Sambuc (Bytef*)pfile_in_zip_read_info->read_buffer;
1306*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1307*44bedb31SLionel Sambuc }
1308*44bedb31SLionel Sambuc
1309*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1310*44bedb31SLionel Sambuc {
1311*44bedb31SLionel Sambuc uInt uDoCopy,i ;
1312*44bedb31SLionel Sambuc
1313*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1314*44bedb31SLionel Sambuc (pfile_in_zip_read_info->rest_read_compressed == 0))
1315*44bedb31SLionel Sambuc return (iRead==0) ? UNZ_EOF : iRead;
1316*44bedb31SLionel Sambuc
1317*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->stream.avail_out <
1318*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in)
1319*44bedb31SLionel Sambuc uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1320*44bedb31SLionel Sambuc else
1321*44bedb31SLionel Sambuc uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1322*44bedb31SLionel Sambuc
1323*44bedb31SLionel Sambuc for (i=0;i<uDoCopy;i++)
1324*44bedb31SLionel Sambuc *(pfile_in_zip_read_info->stream.next_out+i) =
1325*44bedb31SLionel Sambuc *(pfile_in_zip_read_info->stream.next_in+i);
1326*44bedb31SLionel Sambuc
1327*44bedb31SLionel Sambuc pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1328*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_out,
1329*44bedb31SLionel Sambuc uDoCopy);
1330*44bedb31SLionel Sambuc pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1331*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1332*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1333*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_out += uDoCopy;
1334*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.next_in += uDoCopy;
1335*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.total_out += uDoCopy;
1336*44bedb31SLionel Sambuc iRead += uDoCopy;
1337*44bedb31SLionel Sambuc }
1338*44bedb31SLionel Sambuc else
1339*44bedb31SLionel Sambuc {
1340*44bedb31SLionel Sambuc uLong uTotalOutBefore,uTotalOutAfter;
1341*44bedb31SLionel Sambuc const Bytef *bufBefore;
1342*44bedb31SLionel Sambuc uLong uOutThis;
1343*44bedb31SLionel Sambuc int flush=Z_SYNC_FLUSH;
1344*44bedb31SLionel Sambuc
1345*44bedb31SLionel Sambuc uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1346*44bedb31SLionel Sambuc bufBefore = pfile_in_zip_read_info->stream.next_out;
1347*44bedb31SLionel Sambuc
1348*44bedb31SLionel Sambuc /*
1349*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1350*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream.avail_out) &&
1351*44bedb31SLionel Sambuc (pfile_in_zip_read_info->rest_read_compressed == 0))
1352*44bedb31SLionel Sambuc flush = Z_FINISH;
1353*44bedb31SLionel Sambuc */
1354*44bedb31SLionel Sambuc err=inflate(&pfile_in_zip_read_info->stream,flush);
1355*44bedb31SLionel Sambuc
1356*44bedb31SLionel Sambuc if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1357*44bedb31SLionel Sambuc err = Z_DATA_ERROR;
1358*44bedb31SLionel Sambuc
1359*44bedb31SLionel Sambuc uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1360*44bedb31SLionel Sambuc uOutThis = uTotalOutAfter-uTotalOutBefore;
1361*44bedb31SLionel Sambuc
1362*44bedb31SLionel Sambuc pfile_in_zip_read_info->crc32 =
1363*44bedb31SLionel Sambuc crc32(pfile_in_zip_read_info->crc32,bufBefore,
1364*44bedb31SLionel Sambuc (uInt)(uOutThis));
1365*44bedb31SLionel Sambuc
1366*44bedb31SLionel Sambuc pfile_in_zip_read_info->rest_read_uncompressed -=
1367*44bedb31SLionel Sambuc uOutThis;
1368*44bedb31SLionel Sambuc
1369*44bedb31SLionel Sambuc iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1370*44bedb31SLionel Sambuc
1371*44bedb31SLionel Sambuc if (err==Z_STREAM_END)
1372*44bedb31SLionel Sambuc return (iRead==0) ? UNZ_EOF : iRead;
1373*44bedb31SLionel Sambuc if (err!=Z_OK)
1374*44bedb31SLionel Sambuc break;
1375*44bedb31SLionel Sambuc }
1376*44bedb31SLionel Sambuc }
1377*44bedb31SLionel Sambuc
1378*44bedb31SLionel Sambuc if (err==Z_OK)
1379*44bedb31SLionel Sambuc return iRead;
1380*44bedb31SLionel Sambuc return err;
1381*44bedb31SLionel Sambuc }
1382*44bedb31SLionel Sambuc
1383*44bedb31SLionel Sambuc
1384*44bedb31SLionel Sambuc /*
1385*44bedb31SLionel Sambuc Give the current position in uncompressed data
1386*44bedb31SLionel Sambuc */
1387*44bedb31SLionel Sambuc extern z_off_t ZEXPORT unztell (file)
1388*44bedb31SLionel Sambuc unzFile file;
1389*44bedb31SLionel Sambuc {
1390*44bedb31SLionel Sambuc unz_s* s;
1391*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1392*44bedb31SLionel Sambuc if (file==NULL)
1393*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1394*44bedb31SLionel Sambuc s=(unz_s*)file;
1395*44bedb31SLionel Sambuc pfile_in_zip_read_info=s->pfile_in_zip_read;
1396*44bedb31SLionel Sambuc
1397*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1398*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1399*44bedb31SLionel Sambuc
1400*44bedb31SLionel Sambuc return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1401*44bedb31SLionel Sambuc }
1402*44bedb31SLionel Sambuc
1403*44bedb31SLionel Sambuc
1404*44bedb31SLionel Sambuc /*
1405*44bedb31SLionel Sambuc return 1 if the end of file was reached, 0 elsewhere
1406*44bedb31SLionel Sambuc */
1407*44bedb31SLionel Sambuc extern int ZEXPORT unzeof (file)
1408*44bedb31SLionel Sambuc unzFile file;
1409*44bedb31SLionel Sambuc {
1410*44bedb31SLionel Sambuc unz_s* s;
1411*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1412*44bedb31SLionel Sambuc if (file==NULL)
1413*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1414*44bedb31SLionel Sambuc s=(unz_s*)file;
1415*44bedb31SLionel Sambuc pfile_in_zip_read_info=s->pfile_in_zip_read;
1416*44bedb31SLionel Sambuc
1417*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1418*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1419*44bedb31SLionel Sambuc
1420*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1421*44bedb31SLionel Sambuc return 1;
1422*44bedb31SLionel Sambuc else
1423*44bedb31SLionel Sambuc return 0;
1424*44bedb31SLionel Sambuc }
1425*44bedb31SLionel Sambuc
1426*44bedb31SLionel Sambuc
1427*44bedb31SLionel Sambuc
1428*44bedb31SLionel Sambuc /*
1429*44bedb31SLionel Sambuc Read extra field from the current file (opened by unzOpenCurrentFile)
1430*44bedb31SLionel Sambuc This is the local-header version of the extra field (sometimes, there is
1431*44bedb31SLionel Sambuc more info in the local-header version than in the central-header)
1432*44bedb31SLionel Sambuc
1433*44bedb31SLionel Sambuc if buf==NULL, it return the size of the local extra field that can be read
1434*44bedb31SLionel Sambuc
1435*44bedb31SLionel Sambuc if buf!=NULL, len is the size of the buffer, the extra header is copied in
1436*44bedb31SLionel Sambuc buf.
1437*44bedb31SLionel Sambuc the return value is the number of bytes copied in buf, or (if <0)
1438*44bedb31SLionel Sambuc the error code
1439*44bedb31SLionel Sambuc */
1440*44bedb31SLionel Sambuc extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1441*44bedb31SLionel Sambuc unzFile file;
1442*44bedb31SLionel Sambuc voidp buf;
1443*44bedb31SLionel Sambuc unsigned len;
1444*44bedb31SLionel Sambuc {
1445*44bedb31SLionel Sambuc unz_s* s;
1446*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1447*44bedb31SLionel Sambuc uInt read_now;
1448*44bedb31SLionel Sambuc uLong size_to_read;
1449*44bedb31SLionel Sambuc
1450*44bedb31SLionel Sambuc if (file==NULL)
1451*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1452*44bedb31SLionel Sambuc s=(unz_s*)file;
1453*44bedb31SLionel Sambuc pfile_in_zip_read_info=s->pfile_in_zip_read;
1454*44bedb31SLionel Sambuc
1455*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1456*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1457*44bedb31SLionel Sambuc
1458*44bedb31SLionel Sambuc size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1459*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_local_extrafield);
1460*44bedb31SLionel Sambuc
1461*44bedb31SLionel Sambuc if (buf==NULL)
1462*44bedb31SLionel Sambuc return (int)size_to_read;
1463*44bedb31SLionel Sambuc
1464*44bedb31SLionel Sambuc if (len>size_to_read)
1465*44bedb31SLionel Sambuc read_now = (uInt)size_to_read;
1466*44bedb31SLionel Sambuc else
1467*44bedb31SLionel Sambuc read_now = (uInt)len ;
1468*44bedb31SLionel Sambuc
1469*44bedb31SLionel Sambuc if (read_now==0)
1470*44bedb31SLionel Sambuc return 0;
1471*44bedb31SLionel Sambuc
1472*44bedb31SLionel Sambuc if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1473*44bedb31SLionel Sambuc pfile_in_zip_read_info->filestream,
1474*44bedb31SLionel Sambuc pfile_in_zip_read_info->offset_local_extrafield +
1475*44bedb31SLionel Sambuc pfile_in_zip_read_info->pos_local_extrafield,
1476*44bedb31SLionel Sambuc ZLIB_FILEFUNC_SEEK_SET)!=0)
1477*44bedb31SLionel Sambuc return UNZ_ERRNO;
1478*44bedb31SLionel Sambuc
1479*44bedb31SLionel Sambuc if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1480*44bedb31SLionel Sambuc pfile_in_zip_read_info->filestream,
1481*44bedb31SLionel Sambuc buf,read_now)!=read_now)
1482*44bedb31SLionel Sambuc return UNZ_ERRNO;
1483*44bedb31SLionel Sambuc
1484*44bedb31SLionel Sambuc return (int)read_now;
1485*44bedb31SLionel Sambuc }
1486*44bedb31SLionel Sambuc
1487*44bedb31SLionel Sambuc /*
1488*44bedb31SLionel Sambuc Close the file in zip opened with unzipOpenCurrentFile
1489*44bedb31SLionel Sambuc Return UNZ_CRCERROR if all the file was read but the CRC is not good
1490*44bedb31SLionel Sambuc */
1491*44bedb31SLionel Sambuc extern int ZEXPORT unzCloseCurrentFile (file)
1492*44bedb31SLionel Sambuc unzFile file;
1493*44bedb31SLionel Sambuc {
1494*44bedb31SLionel Sambuc int err=UNZ_OK;
1495*44bedb31SLionel Sambuc
1496*44bedb31SLionel Sambuc unz_s* s;
1497*44bedb31SLionel Sambuc file_in_zip_read_info_s* pfile_in_zip_read_info;
1498*44bedb31SLionel Sambuc if (file==NULL)
1499*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1500*44bedb31SLionel Sambuc s=(unz_s*)file;
1501*44bedb31SLionel Sambuc pfile_in_zip_read_info=s->pfile_in_zip_read;
1502*44bedb31SLionel Sambuc
1503*44bedb31SLionel Sambuc if (pfile_in_zip_read_info==NULL)
1504*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1505*44bedb31SLionel Sambuc
1506*44bedb31SLionel Sambuc
1507*44bedb31SLionel Sambuc if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1508*44bedb31SLionel Sambuc (!pfile_in_zip_read_info->raw))
1509*44bedb31SLionel Sambuc {
1510*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1511*44bedb31SLionel Sambuc err=UNZ_CRCERROR;
1512*44bedb31SLionel Sambuc }
1513*44bedb31SLionel Sambuc
1514*44bedb31SLionel Sambuc
1515*44bedb31SLionel Sambuc TRYFREE(pfile_in_zip_read_info->read_buffer);
1516*44bedb31SLionel Sambuc pfile_in_zip_read_info->read_buffer = NULL;
1517*44bedb31SLionel Sambuc if (pfile_in_zip_read_info->stream_initialised)
1518*44bedb31SLionel Sambuc inflateEnd(&pfile_in_zip_read_info->stream);
1519*44bedb31SLionel Sambuc
1520*44bedb31SLionel Sambuc pfile_in_zip_read_info->stream_initialised = 0;
1521*44bedb31SLionel Sambuc TRYFREE(pfile_in_zip_read_info);
1522*44bedb31SLionel Sambuc
1523*44bedb31SLionel Sambuc s->pfile_in_zip_read=NULL;
1524*44bedb31SLionel Sambuc
1525*44bedb31SLionel Sambuc return err;
1526*44bedb31SLionel Sambuc }
1527*44bedb31SLionel Sambuc
1528*44bedb31SLionel Sambuc
1529*44bedb31SLionel Sambuc /*
1530*44bedb31SLionel Sambuc Get the global comment string of the ZipFile, in the szComment buffer.
1531*44bedb31SLionel Sambuc uSizeBuf is the size of the szComment buffer.
1532*44bedb31SLionel Sambuc return the number of byte copied or an error code <0
1533*44bedb31SLionel Sambuc */
1534*44bedb31SLionel Sambuc extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1535*44bedb31SLionel Sambuc unzFile file;
1536*44bedb31SLionel Sambuc char *szComment;
1537*44bedb31SLionel Sambuc uLong uSizeBuf;
1538*44bedb31SLionel Sambuc {
1539*44bedb31SLionel Sambuc int err=UNZ_OK;
1540*44bedb31SLionel Sambuc unz_s* s;
1541*44bedb31SLionel Sambuc uLong uReadThis ;
1542*44bedb31SLionel Sambuc if (file==NULL)
1543*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1544*44bedb31SLionel Sambuc s=(unz_s*)file;
1545*44bedb31SLionel Sambuc
1546*44bedb31SLionel Sambuc uReadThis = uSizeBuf;
1547*44bedb31SLionel Sambuc if (uReadThis>s->gi.size_comment)
1548*44bedb31SLionel Sambuc uReadThis = s->gi.size_comment;
1549*44bedb31SLionel Sambuc
1550*44bedb31SLionel Sambuc if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1551*44bedb31SLionel Sambuc return UNZ_ERRNO;
1552*44bedb31SLionel Sambuc
1553*44bedb31SLionel Sambuc if (uReadThis>0)
1554*44bedb31SLionel Sambuc {
1555*44bedb31SLionel Sambuc *szComment='\0';
1556*44bedb31SLionel Sambuc if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1557*44bedb31SLionel Sambuc return UNZ_ERRNO;
1558*44bedb31SLionel Sambuc }
1559*44bedb31SLionel Sambuc
1560*44bedb31SLionel Sambuc if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1561*44bedb31SLionel Sambuc *(szComment+s->gi.size_comment)='\0';
1562*44bedb31SLionel Sambuc return (int)uReadThis;
1563*44bedb31SLionel Sambuc }
1564*44bedb31SLionel Sambuc
1565*44bedb31SLionel Sambuc /* Additions by RX '2004 */
1566*44bedb31SLionel Sambuc extern uLong ZEXPORT unzGetOffset (file)
1567*44bedb31SLionel Sambuc unzFile file;
1568*44bedb31SLionel Sambuc {
1569*44bedb31SLionel Sambuc unz_s* s;
1570*44bedb31SLionel Sambuc
1571*44bedb31SLionel Sambuc if (file==NULL)
1572*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1573*44bedb31SLionel Sambuc s=(unz_s*)file;
1574*44bedb31SLionel Sambuc if (!s->current_file_ok)
1575*44bedb31SLionel Sambuc return 0;
1576*44bedb31SLionel Sambuc if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1577*44bedb31SLionel Sambuc if (s->num_file==s->gi.number_entry)
1578*44bedb31SLionel Sambuc return 0;
1579*44bedb31SLionel Sambuc return s->pos_in_central_dir;
1580*44bedb31SLionel Sambuc }
1581*44bedb31SLionel Sambuc
1582*44bedb31SLionel Sambuc extern int ZEXPORT unzSetOffset (file, pos)
1583*44bedb31SLionel Sambuc unzFile file;
1584*44bedb31SLionel Sambuc uLong pos;
1585*44bedb31SLionel Sambuc {
1586*44bedb31SLionel Sambuc unz_s* s;
1587*44bedb31SLionel Sambuc int err;
1588*44bedb31SLionel Sambuc
1589*44bedb31SLionel Sambuc if (file==NULL)
1590*44bedb31SLionel Sambuc return UNZ_PARAMERROR;
1591*44bedb31SLionel Sambuc s=(unz_s*)file;
1592*44bedb31SLionel Sambuc
1593*44bedb31SLionel Sambuc s->pos_in_central_dir = pos;
1594*44bedb31SLionel Sambuc s->num_file = s->gi.number_entry; /* hack */
1595*44bedb31SLionel Sambuc err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1596*44bedb31SLionel Sambuc &s->cur_file_info_internal,
1597*44bedb31SLionel Sambuc NULL,0,NULL,0,NULL,0);
1598*44bedb31SLionel Sambuc s->current_file_ok = (err == UNZ_OK);
1599*44bedb31SLionel Sambuc return err;
1600*44bedb31SLionel Sambuc }
1601