aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2008-11-16 22:00:21 +0000
committerNils Durner <durner@gnunet.org>2008-11-16 22:00:21 +0000
commit64c63da758619d3a1896c4dcaafd4bf689ab830f (patch)
tree0c81a5754d6d0aad96f2c8abc2ca060b59d9f7d8 /src/common
parente54cd0ec18b824ad63a85412edb49fb5bc2fdd41 (diff)
downloadlibextractor-64c63da758619d3a1896c4dcaafd4bf689ab830f.tar.gz
libextractor-64c63da758619d3a1896c4dcaafd4bf689ab830f.zip
move unzip code to libextractor_common
Diffstat (limited to 'src/common')
-rw-r--r--src/common/ChangeLogUnzip93
-rw-r--r--src/common/Makefile.am4
-rw-r--r--src/common/unzip.c1324
-rw-r--r--src/common/unzip.h126
4 files changed, 1546 insertions, 1 deletions
diff --git a/src/common/ChangeLogUnzip b/src/common/ChangeLogUnzip
new file mode 100644
index 0000000..06c70d9
--- /dev/null
+++ b/src/common/ChangeLogUnzip
@@ -0,0 +1,93 @@
1The files crypt.h, ioapi.c, ioapi.h, miniunz, unzip.c and unzip.h are
2from contrib/ in zlib (copyright below). The code was adapted for
3libextractor and extended to support OpenOffice meta-data extraction
4by Christian Grothoff.
5
6 Copyright (C) 1998-2003 Gilles Vollant
7
8 This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
9 WinZip, InfoZip tools and compatible.
10 Encryption and multi volume ZipFile (span) are not supported.
11 Old compressions used by old PKZip 1.x are not supported
12
13
14 I WAIT FEEDBACK at mail info@winimage.com
15 Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
16
17 Condition of use and distribution are the same than zlib :
18
19 This software is provided 'as-is', without any express or implied
20 warranty. In no event will the authors be held liable for any damages
21 arising from the use of this software.
22
23 Permission is granted to anyone to use this software for any purpose,
24 including commercial applications, and to alter it and redistribute it
25 freely, subject to the following restrictions:
26
27 1. The origin of this software must not be misrepresented; you must not
28 claim that you wrote the original software. If you use this software
29 in a product, an acknowledgment in the product documentation would be
30 appreciated but is not required.
31 2. Altered source versions must be plainly marked as such, and must not be
32 misrepresented as being the original software.
33 3. This notice may not be removed or altered from any source distribution.
34
35
36Original ChangeLog (from before LE integration):
37
38
39Change in 1.00: (10 sept 03)
40- rename to 1.00
41- cosmetic code change
42
43Change in 0.22: (19 May 03)
44- crypting support (unless you define NOCRYPT)
45- append file in existing zipfile
46
47Change in 0.21: (10 Mar 03)
48- bug fixes
49
50Change in 0.17: (27 Jan 02)
51- bug fixes
52
53Change in 0.16: (19 Jan 02)
54- Support of ioapi for virtualize zip file access
55
56Change in 0.15: (19 Mar 98)
57- fix memory leak in minizip.c
58
59Change in 0.14: (10 Mar 98)
60- fix bugs in minizip.c sample for zipping big file
61- fix problem in month in date handling
62- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
63 comment handling
64
65Change in 0.13: (6 Mar 98)
66- fix bugs in zip.c
67- add real minizip sample
68
69Change in 0.12: (4 Mar 98)
70- add zip.c and zip.h for creates .zip file
71- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
72- fix miniunz.c for file without specific record for directory
73
74Change in 0.11: (3 Mar 98)
75- fix bug in unzGetCurrentFileInfo for get extra field and comment
76- enhance miniunz sample, remove the bad unztst.c sample
77
78Change in 0.10: (2 Mar 98)
79- fix bug in unzReadCurrentFile
80- rename unzip* to unz* function and structure
81- remove Windows-like hungary notation variable name
82- modify some structure in unzip.h
83- add somes comment in source
84- remove unzipGetcCurrentFile function
85- replace ZUNZEXPORT by ZEXPORT
86- add unzGetLocalExtrafield for get the local extrafield info
87- add a new sample, miniunz.c
88
89Change in 0.4: (25 Feb 98)
90- suppress the type unzipFileInZip.
91 Only on file in the zipfile can be open at the same time
92- fix somes typo in code
93- added tm_unz structure in unzip_file_info (date/time in readable format)
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 4ffd5bd..6d2ff77 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -19,9 +19,11 @@ libextractor_common_la_LDFLAGS = \
19 $(exportflag) $(winexportflag) -version-info @LIB_VERSION_CURRENT@:@LIB_VERSION_REVISION@:@LIB_VERSION_AGE@ $(LIBICONV) 19 $(exportflag) $(winexportflag) -version-info @LIB_VERSION_CURRENT@:@LIB_VERSION_REVISION@:@LIB_VERSION_AGE@ $(LIBICONV)
20 20
21libextractor_common_la_LIBADD = \ 21libextractor_common_la_LIBADD = \
22 $(LIBLTDL) $(dlflag) 22 $(LIBLTDL) $(dlflag) -lz
23 23
24libextractor_common_la_SOURCES = \ 24libextractor_common_la_SOURCES = \
25 unzip.c \
26 unzip.h \
25 pack.c \ 27 pack.c \
26 pack.h \ 28 pack.h \
27 convert.c \ 29 convert.c \
diff --git a/src/common/unzip.c b/src/common/unzip.c
new file mode 100644
index 0000000..60c97b1
--- /dev/null
+++ b/src/common/unzip.c
@@ -0,0 +1,1324 @@
1/*
2 This file is part of libextractor.
3 (C) 2004, 2008 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include "platform.h"
22#include <ctype.h>
23#include "extractor.h"
24#include "unzip.h"
25
26#define CASESENSITIVITY (0)
27#define MAXFILENAME (256)
28
29/* *********************** IOAPI ***************** */
30
31#define ZLIB_FILEFUNC_SEEK_CUR (1)
32#define ZLIB_FILEFUNC_SEEK_END (2)
33#define ZLIB_FILEFUNC_SEEK_SET (0)
34
35#define ZLIB_FILEFUNC_MODE_READ (1)
36#define ZLIB_FILEFUNC_MODE_WRITE (2)
37#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
38#define ZLIB_FILEFUNC_MODE_EXISTING (4)
39#define ZLIB_FILEFUNC_MODE_CREATE (8)
40
41
42#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
43#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
44#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
45#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
46#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
47#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
48
49
50/* ******************* former crypt.h ********************* */
51
52/* unz_global_info structure contain global data about the ZIPfile
53 These data comes from the end of central dir */
54typedef struct unz_global_info_s
55{
56 uLong number_entry; /* total number of entries in
57 the central dir on this disk */
58 uLong size_comment; /* size of the global comment of the zipfile */
59} unz_global_info;
60
61/*
62 Read extra field from the current file (opened by unzOpenCurrentFile)
63 This is the local-header version of the extra field (sometimes, there is
64 more info in the local-header version than in the central-header)
65
66 if buf==NULL, it return the size of the local extra field
67
68 if buf!=NULL, len is the size of the buffer, the extra header is copied in
69 buf.
70 the return value is the number of bytes copied in buf, or (if <0)
71 the error code
72*/
73
74#ifndef CASESENSITIVITYDEFAULT_NO
75# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
76# define CASESENSITIVITYDEFAULT_NO
77# endif
78#endif
79
80
81#ifndef UNZ_BUFSIZE
82#define UNZ_BUFSIZE (16384)
83#endif
84
85#ifndef UNZ_MAXFILENAMEINZIP
86#define UNZ_MAXFILENAMEINZIP (256)
87#endif
88
89#ifndef ALLOC
90# define ALLOC(size) (malloc(size))
91#endif
92#ifndef TRYFREE
93# define TRYFREE(p) {if (p) free(p);}
94#endif
95
96#define SIZECENTRALDIRITEM (0x2e)
97#define SIZEZIPLOCALHEADER (0x1e)
98
99
100const char unz_copyright[] =
101 " unzip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll";
102
103/* EXTRACTOR_unzip_file_info_interntal contain internal info about a file in zipfile*/
104typedef struct unz_file_info_internal_s
105{
106 uLong offset_curfile;/* relative offset of local header 4 bytes */
107} unz_file_info_internal;
108
109
110/* file_in_zip_read_info_s contain internal information about a file in zipfile,
111 when reading and decompress it */
112typedef struct
113{
114 char *read_buffer; /* internal buffer for compressed data */
115 z_stream stream; /* zLib stream structure for inflate */
116
117 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
118 uLong stream_initialised; /* flag set if stream structure is initialised*/
119
120 uLong offset_local_extrafield;/* offset of the local extra field */
121 uInt size_local_extrafield;/* size of the local extra field */
122 uLong pos_local_extrafield; /* position in the local extra field in read*/
123
124 uLong crc32; /* crc32 of all data uncompressed */
125 uLong crc32_wait; /* crc32 we must obtain after decompress all */
126 uLong rest_read_compressed; /* number of byte to be decompressed */
127 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
128 EXTRACTOR_unzip_filefunc_def z_filefunc;
129 voidpf filestream; /* io structore of the zipfile */
130 uLong compression_method; /* compression method (0==store) */
131 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
132 int raw;
133} file_in_zip_read_info_s;
134
135
136/* unz_s contain internal information about the zipfile
137*/
138typedef struct
139{
140 EXTRACTOR_unzip_filefunc_def z_filefunc;
141 voidpf filestream; /* io structore of the zipfile */
142 unz_global_info gi; /* public global information */
143 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
144 uLong num_file; /* number of the current file in the zipfile*/
145 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
146 uLong current_file_ok; /* flag about the usability of the current file*/
147 uLong central_pos; /* position of the beginning of the central dir*/
148
149 uLong size_central_dir; /* size of the central directory */
150 uLong offset_central_dir; /* offset of start of central directory with
151 respect to the starting disk number */
152
153 EXTRACTOR_unzip_file_info cur_file_info; /* public info about the current file in zip*/
154 unz_file_info_internal cur_file_info_internal; /* private info about it*/
155 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
156 file if we are decompressing it */
157 int encrypted;
158} unz_s;
159
160
161
162/* ===========================================================================
163 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
164 for end of file.
165 IN assertion: the stream s has been sucessfully opened for reading.
166*/
167
168
169static int unzlocal_getByte OF((
170 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
171 voidpf filestream,
172 int *pi));
173
174static int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
175 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def;
176 voidpf filestream;
177 int *pi;
178{
179 unsigned char c;
180 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
181 if (err==1)
182 {
183 *pi = (int)c;
184 return EXTRACTOR_UNZIP_OK;
185 }
186 else
187 {
188 if (ZERROR(*pzlib_filefunc_def,filestream))
189 return EXTRACTOR_UNZIP_ERRNO;
190 else
191 return EXTRACTOR_UNZIP_EOF;
192 }
193}
194
195
196/* ===========================================================================
197 Reads a long in LSB order from the given gz_stream. Sets
198*/
199static int unzlocal_getShort OF((
200 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
201 voidpf filestream,
202 uLong *pX));
203
204static int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
205 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def;
206 voidpf filestream;
207 uLong *pX;
208{
209 uLong x ;
210 int i;
211 int err;
212
213 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
214 x = (uLong)i;
215
216 if (err==EXTRACTOR_UNZIP_OK)
217 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
218 x += ((uLong)i)<<8;
219
220 if (err==EXTRACTOR_UNZIP_OK)
221 *pX = x;
222 else
223 *pX = 0;
224 return err;
225}
226
227static int unzlocal_getLong OF((
228 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
229 voidpf filestream,
230 uLong *pX));
231
232static int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
233 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def;
234 voidpf filestream;
235 uLong *pX;
236{
237 uLong x ;
238 int i;
239 int err;
240
241 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
242 x = (uLong)i;
243
244 if (err==EXTRACTOR_UNZIP_OK)
245 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
246 x += ((uLong)i)<<8;
247
248 if (err==EXTRACTOR_UNZIP_OK)
249 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
250 x += ((uLong)i)<<16;
251
252 if (err==EXTRACTOR_UNZIP_OK)
253 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
254 x += ((uLong)i)<<24;
255
256 if (err==EXTRACTOR_UNZIP_OK)
257 *pX = x;
258 else
259 *pX = 0;
260 return err;
261}
262
263
264/* My own strcmpi / strcasecmp */
265static int strcmpcasenosensitive_internal (fileName1,fileName2)
266 const char* fileName1;
267 const char* fileName2;
268{
269 for (;;)
270 {
271 char c1=*(fileName1++);
272 char c2=*(fileName2++);
273 if ((c1>='a') && (c1<='z'))
274 c1 -= 0x20;
275 if ((c2>='a') && (c2<='z'))
276 c2 -= 0x20;
277 if (c1=='\0')
278 return ((c2=='\0') ? 0 : -1);
279 if (c2=='\0')
280 return 1;
281 if (c1<c2)
282 return -1;
283 if (c1>c2)
284 return 1;
285 }
286}
287
288
289#ifdef CASESENSITIVITYDEFAULT_NO
290#define CASESENSITIVITYDEFAULTVALUE 2
291#else
292#define CASESENSITIVITYDEFAULTVALUE 1
293#endif
294
295#ifndef STRCMPCASENOSENTIVEFUNCTION
296#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
297#endif
298
299/*
300 Compare two filename (fileName1,fileName2).
301 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
302 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
303 or strcasecmp)
304 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
305 (like 1 on Unix, 2 on Windows)
306
307*/
308int EXTRACTOR_common_unzip_string_file_name_compare (fileName1,fileName2,iCaseSensitivity)
309 const char* fileName1;
310 const char* fileName2;
311 int iCaseSensitivity;
312{
313 if (iCaseSensitivity==0)
314 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
315
316 if (iCaseSensitivity==1)
317 return strcmp(fileName1,fileName2);
318
319 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
320}
321
322#ifndef BUFREADCOMMENT
323#define BUFREADCOMMENT (0x400)
324#endif
325
326/*
327 Locate the Central directory of a zipfile (at the end, just before
328 the global comment)
329*/
330static uLong unzlocal_SearchCentralDir OF((
331 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
332 voidpf filestream));
333
334static uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
335 const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def;
336 voidpf filestream;
337{
338 unsigned char* buf;
339 uLong uSizeFile;
340 uLong uBackRead;
341 uLong uMaxBack=0xffff; /* maximum size of global comment */
342 uLong uPosFound=0;
343
344 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
345 return 0;
346
347
348 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
349
350 if (uMaxBack>uSizeFile)
351 uMaxBack = uSizeFile;
352
353 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
354 if (buf==NULL)
355 return 0;
356
357 uBackRead = 4;
358 while (uBackRead<uMaxBack)
359 {
360 uLong uReadSize,uReadPos ;
361 int i;
362 if (uBackRead+BUFREADCOMMENT>uMaxBack)
363 uBackRead = uMaxBack;
364 else
365 uBackRead+=BUFREADCOMMENT;
366 uReadPos = uSizeFile-uBackRead ;
367
368 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
369 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
370 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
371 break;
372
373 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
374 break;
375
376 for (i=(int)uReadSize-3; (i--)>0;)
377 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
378 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
379 {
380 uPosFound = uReadPos+i;
381 break;
382 }
383
384 if (uPosFound!=0)
385 break;
386 }
387 TRYFREE(buf);
388 return uPosFound;
389}
390
391/*
392 Translate date/time from Dos format to EXTRACTOR_unzip_tm_unz (readable more easilty)
393*/
394static void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
395 uLong ulDosDate;
396 EXTRACTOR_unzip_tm_unz* ptm;
397{
398 uLong uDate;
399 uDate = (uLong)(ulDosDate>>16);
400 ptm->tm_mday = (uInt)(uDate&0x1f) ;
401 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
402 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
403
404 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
405 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
406 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
407}
408
409
410
411static int unzlocal_GetCurrentFileInfoInternal (file,
412 pfile_info,
413 pfile_info_internal,
414 szFileName, fileNameBufferSize,
415 extraField, extraFieldBufferSize,
416 szComment, commentBufferSize)
417 EXTRACTOR_unzip_file file;
418 EXTRACTOR_unzip_file_info *pfile_info;
419 unz_file_info_internal *pfile_info_internal;
420 char *szFileName;
421 uLong fileNameBufferSize;
422 void *extraField;
423 uLong extraFieldBufferSize;
424 char *szComment;
425 uLong commentBufferSize;
426{
427 unz_s* s;
428 EXTRACTOR_unzip_file_info file_info;
429 unz_file_info_internal file_info_internal;
430 int err=EXTRACTOR_UNZIP_OK;
431 uLong uMagic;
432 long lSeek=0;
433
434 if (file==NULL)
435 return EXTRACTOR_UNZIP_PARAMERROR;
436 s=(unz_s*)file;
437 if (ZSEEK(s->z_filefunc, s->filestream,
438 s->pos_in_central_dir+s->byte_before_the_zipfile,
439 ZLIB_FILEFUNC_SEEK_SET)!=0)
440 err=EXTRACTOR_UNZIP_ERRNO;
441
442
443 /* we check the magic */
444 if (err==EXTRACTOR_UNZIP_OK) {
445 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != EXTRACTOR_UNZIP_OK)
446 err=EXTRACTOR_UNZIP_ERRNO;
447 else if (uMagic!=0x02014b50)
448 err=EXTRACTOR_UNZIP_BADZIPFILE;
449 }
450 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != EXTRACTOR_UNZIP_OK)
451 err=EXTRACTOR_UNZIP_ERRNO;
452
453 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != EXTRACTOR_UNZIP_OK)
454 err=EXTRACTOR_UNZIP_ERRNO;
455
456 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != EXTRACTOR_UNZIP_OK)
457 err=EXTRACTOR_UNZIP_ERRNO;
458
459 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != EXTRACTOR_UNZIP_OK)
460 err=EXTRACTOR_UNZIP_ERRNO;
461
462 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != EXTRACTOR_UNZIP_OK)
463 err=EXTRACTOR_UNZIP_ERRNO;
464
465 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
466
467 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != EXTRACTOR_UNZIP_OK)
468 err=EXTRACTOR_UNZIP_ERRNO;
469
470 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != EXTRACTOR_UNZIP_OK)
471 err=EXTRACTOR_UNZIP_ERRNO;
472
473 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != EXTRACTOR_UNZIP_OK)
474 err=EXTRACTOR_UNZIP_ERRNO;
475
476 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != EXTRACTOR_UNZIP_OK)
477 err=EXTRACTOR_UNZIP_ERRNO;
478
479 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != EXTRACTOR_UNZIP_OK)
480 err=EXTRACTOR_UNZIP_ERRNO;
481
482 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != EXTRACTOR_UNZIP_OK)
483 err=EXTRACTOR_UNZIP_ERRNO;
484
485 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != EXTRACTOR_UNZIP_OK)
486 err=EXTRACTOR_UNZIP_ERRNO;
487
488 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != EXTRACTOR_UNZIP_OK)
489 err=EXTRACTOR_UNZIP_ERRNO;
490
491 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != EXTRACTOR_UNZIP_OK)
492 err=EXTRACTOR_UNZIP_ERRNO;
493
494 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != EXTRACTOR_UNZIP_OK)
495 err=EXTRACTOR_UNZIP_ERRNO;
496
497 lSeek+=file_info.size_filename;
498 if ((err==EXTRACTOR_UNZIP_OK) && (szFileName!=NULL))
499 {
500 uLong uSizeRead ;
501 if (file_info.size_filename<fileNameBufferSize)
502 {
503 *(szFileName+file_info.size_filename)='\0';
504 uSizeRead = file_info.size_filename;
505 }
506 else
507 uSizeRead = fileNameBufferSize;
508
509 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
510 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
511 err=EXTRACTOR_UNZIP_ERRNO;
512 lSeek -= uSizeRead;
513 }
514
515
516 if ((err==EXTRACTOR_UNZIP_OK) && (extraField!=NULL))
517 {
518 uLong uSizeRead ;
519 if (file_info.size_file_extra<extraFieldBufferSize)
520 uSizeRead = file_info.size_file_extra;
521 else
522 uSizeRead = extraFieldBufferSize;
523
524 if (lSeek!=0) {
525 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
526 lSeek=0;
527 else
528 err=EXTRACTOR_UNZIP_ERRNO;
529 }
530 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
531 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
532 err=EXTRACTOR_UNZIP_ERRNO;
533 lSeek += file_info.size_file_extra - uSizeRead;
534 }
535 else
536 lSeek+=file_info.size_file_extra;
537
538
539 if ((err==EXTRACTOR_UNZIP_OK) && (szComment!=NULL))
540 {
541 uLong uSizeRead ;
542 if (file_info.size_file_comment<commentBufferSize)
543 {
544 *(szComment+file_info.size_file_comment)='\0';
545 uSizeRead = file_info.size_file_comment;
546 }
547 else
548 uSizeRead = commentBufferSize;
549
550 if (lSeek!=0) {
551 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
552 lSeek=0;
553 else
554 err=EXTRACTOR_UNZIP_ERRNO;
555 }
556 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
557 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
558 err=EXTRACTOR_UNZIP_ERRNO;
559 lSeek+=file_info.size_file_comment - uSizeRead;
560 }
561 else
562 lSeek+=file_info.size_file_comment;
563
564 if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info!=NULL))
565 *pfile_info=file_info;
566
567 if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info_internal!=NULL))
568 *pfile_info_internal=file_info_internal;
569
570 return err;
571}
572
573/*
574 Set the current file of the zipfile to the first file.
575 return UNZ_OK if there is no problem
576*/
577int EXTRACTOR_common_unzip_go_to_first_file (file)
578 EXTRACTOR_unzip_file file;
579{
580 int err=EXTRACTOR_UNZIP_OK;
581 unz_s* s;
582 if (file==NULL)
583 return EXTRACTOR_UNZIP_PARAMERROR;
584 s=(unz_s*)file;
585 s->pos_in_central_dir=s->offset_central_dir;
586 s->num_file=0;
587 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
588 &s->cur_file_info_internal,
589 NULL,0,NULL,0,NULL,0);
590 s->current_file_ok = (err == EXTRACTOR_UNZIP_OK);
591 return err;
592}
593
594
595/*
596 Open a Zip file. path contain the full pathname (by example,
597 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
598 "zlib/zlib114.zip".
599 If the zipfile cannot be opened (file doesn't exist or in not valid), the
600 return value is NULL.
601 Else, the return value is a EXTRACTOR_unzip_file Handle, usable with other function
602 of this unzip package.
603*/
604EXTRACTOR_unzip_file EXTRACTOR_common_unzip_open2 (path, pzlib_filefunc_def)
605 const char *path;
606 EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def;
607{
608 unz_s us;
609 unz_s *s;
610 uLong central_pos,uL;
611
612 uLong number_disk; /* number of the current dist, used for
613 spaning ZIP, unsupported, always 0*/
614 uLong number_disk_with_CD; /* number the the disk with central dir, used
615 for spaning ZIP, unsupported, always 0*/
616 uLong number_entry_CD; /* total number of entries in
617 the central dir
618 (same than number_entry on nospan) */
619
620 int err=EXTRACTOR_UNZIP_OK;
621
622 if (unz_copyright[0]!=' ')
623 return NULL;
624
625 us.z_filefunc = *pzlib_filefunc_def;
626
627 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
628 path,
629 ZLIB_FILEFUNC_MODE_READ |
630 ZLIB_FILEFUNC_MODE_EXISTING);
631 if (us.filestream==NULL)
632 return NULL;
633
634 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
635 if (central_pos==0)
636 err=EXTRACTOR_UNZIP_ERRNO;
637
638 if (ZSEEK(us.z_filefunc, us.filestream,
639 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
640 err=EXTRACTOR_UNZIP_ERRNO;
641
642 /* the signature, already checked */
643 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=EXTRACTOR_UNZIP_OK)
644 err=EXTRACTOR_UNZIP_ERRNO;
645
646 /* number of this disk */
647 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=EXTRACTOR_UNZIP_OK)
648 err=EXTRACTOR_UNZIP_ERRNO;
649
650 /* number of the disk with the start of the central directory */
651 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=EXTRACTOR_UNZIP_OK)
652 err=EXTRACTOR_UNZIP_ERRNO;
653
654 /* total number of entries in the central dir on this disk */
655 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=EXTRACTOR_UNZIP_OK)
656 err=EXTRACTOR_UNZIP_ERRNO;
657
658 /* total number of entries in the central dir */
659 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=EXTRACTOR_UNZIP_OK)
660 err=EXTRACTOR_UNZIP_ERRNO;
661
662 if ((number_entry_CD!=us.gi.number_entry) ||
663 (number_disk_with_CD!=0) ||
664 (number_disk!=0))
665 err=EXTRACTOR_UNZIP_BADZIPFILE;
666
667 /* size of the central directory */
668 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=EXTRACTOR_UNZIP_OK)
669 err=EXTRACTOR_UNZIP_ERRNO;
670
671 /* offset of start of central directory with respect to the
672 starting disk number */
673 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=EXTRACTOR_UNZIP_OK)
674 err=EXTRACTOR_UNZIP_ERRNO;
675
676 /* zipfile comment length */
677 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=EXTRACTOR_UNZIP_OK)
678 err=EXTRACTOR_UNZIP_ERRNO;
679
680 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
681 (err==EXTRACTOR_UNZIP_OK))
682 err=EXTRACTOR_UNZIP_BADZIPFILE;
683
684 if (err!=EXTRACTOR_UNZIP_OK)
685 {
686 ZCLOSE(us.z_filefunc, us.filestream);
687 return NULL;
688 }
689
690 us.byte_before_the_zipfile = central_pos -
691 (us.offset_central_dir+us.size_central_dir);
692 us.central_pos = central_pos;
693 us.pfile_in_zip_read = NULL;
694 us.encrypted = 0;
695
696
697 s=(unz_s*)ALLOC(sizeof(unz_s));
698 *s=us;
699 EXTRACTOR_common_unzip_go_to_first_file((EXTRACTOR_unzip_file)s);
700 return (EXTRACTOR_unzip_file)s;
701}
702
703/*
704 Close the file in zip opened with unzipOpenCurrentFile
705 Return EXTRACTOR_UNZIP_CRCERROR if all the file was read but the CRC is not good
706*/
707int EXTRACTOR_common_unzip_close_current_file (file)
708 EXTRACTOR_unzip_file file;
709{
710 int err=EXTRACTOR_UNZIP_OK;
711
712 unz_s* s;
713 file_in_zip_read_info_s* pfile_in_zip_read_info;
714 if (file==NULL)
715 return EXTRACTOR_UNZIP_PARAMERROR;
716 s=(unz_s*)file;
717 pfile_in_zip_read_info=s->pfile_in_zip_read;
718
719 if (pfile_in_zip_read_info==NULL)
720 return EXTRACTOR_UNZIP_PARAMERROR;
721
722
723 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
724 (!pfile_in_zip_read_info->raw))
725 {
726 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
727 err=EXTRACTOR_UNZIP_CRCERROR;
728 }
729
730
731 TRYFREE(pfile_in_zip_read_info->read_buffer);
732 pfile_in_zip_read_info->read_buffer = NULL;
733 if (pfile_in_zip_read_info->stream_initialised)
734 inflateEnd(&pfile_in_zip_read_info->stream);
735
736 pfile_in_zip_read_info->stream_initialised = 0;
737 TRYFREE(pfile_in_zip_read_info);
738
739 s->pfile_in_zip_read=NULL;
740
741 return err;
742}
743
744/*
745 Close a ZipFile opened with unzipOpen.
746 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
747 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
748 return EXTRACTOR_UNZIP_OK if there is no problem. */
749int EXTRACTOR_common_unzip_close (file)
750 EXTRACTOR_unzip_file file;
751{
752 unz_s* s;
753 if (file==NULL)
754 return EXTRACTOR_UNZIP_PARAMERROR;
755 s=(unz_s*)file;
756
757 if (s->pfile_in_zip_read!=NULL)
758 EXTRACTOR_common_unzip_close_current_file(file);
759
760 ZCLOSE(s->z_filefunc, s->filestream);
761 TRYFREE(s);
762 return EXTRACTOR_UNZIP_OK;
763}
764
765
766/*
767 Write info about the ZipFile in the *pglobal_info structure.
768 No preparation of the structure is needed
769 return EXTRACTOR_UNZIP_OK if there is no problem.
770*/
771int EXTRACTOR_common_unzip_get_current_file_info (file,
772 pfile_info,
773 szFileName, fileNameBufferSize,
774 extraField, extraFieldBufferSize,
775 szComment, commentBufferSize)
776 EXTRACTOR_unzip_file file;
777 EXTRACTOR_unzip_file_info *pfile_info;
778 char *szFileName;
779 uLong fileNameBufferSize;
780 void *extraField;
781 uLong extraFieldBufferSize;
782 char *szComment;
783 uLong commentBufferSize;
784{
785 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
786 szFileName,fileNameBufferSize,
787 extraField,extraFieldBufferSize,
788 szComment,commentBufferSize);
789}
790
791/*
792 Set the current file of the zipfile to the next file.
793 return EXTRACTOR_UNZIP_OK if there is no problem
794 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the actual file was the latest.
795*/
796int EXTRACTOR_common_unzip_go_to_next_file (file)
797 EXTRACTOR_unzip_file file;
798{
799 unz_s* s;
800 int err;
801
802 if (file==NULL)
803 return EXTRACTOR_UNZIP_PARAMERROR;
804 s=(unz_s*)file;
805 if (!s->current_file_ok)
806 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
807 if (s->num_file+1==s->gi.number_entry)
808 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
809
810 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
811 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
812 s->num_file++;
813 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
814 &s->cur_file_info_internal,
815 NULL,0,NULL,0,NULL,0);
816 s->current_file_ok = (err == EXTRACTOR_UNZIP_OK);
817 return err;
818}
819
820
821
822
823/*
824 Try locate the file szFileName in the zipfile.
825 For the iCaseSensitivity signification, see unzipStringFileNameCompare
826
827 return value :
828 EXTRACTOR_UNZIP_OK if the file is found. It becomes the current file.
829 EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the file is not found
830*/
831int EXTRACTOR_common_unzip_local_file (file, szFileName, iCaseSensitivity)
832 EXTRACTOR_unzip_file file;
833 const char *szFileName;
834 int iCaseSensitivity;
835{
836 unz_s* s;
837 int err;
838
839 /* We remember the 'current' position in the file so that we can jump
840 * back there if we fail.
841 */
842 EXTRACTOR_unzip_file_info cur_file_infoSaved;
843 unz_file_info_internal cur_file_info_internalSaved;
844 uLong num_fileSaved;
845 uLong pos_in_central_dirSaved;
846
847
848 if (file==NULL)
849 return EXTRACTOR_UNZIP_PARAMERROR;
850
851 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
852 return EXTRACTOR_UNZIP_PARAMERROR;
853
854 s=(unz_s*)file;
855 if (!s->current_file_ok)
856 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
857
858 /* Save the current state */
859 num_fileSaved = s->num_file;
860 pos_in_central_dirSaved = s->pos_in_central_dir;
861 cur_file_infoSaved = s->cur_file_info;
862 cur_file_info_internalSaved = s->cur_file_info_internal;
863
864 err = EXTRACTOR_common_unzip_go_to_first_file(file);
865
866 while (err == EXTRACTOR_UNZIP_OK)
867 {
868 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
869 err = EXTRACTOR_common_unzip_get_current_file_info(file,NULL,
870 szCurrentFileName,sizeof(szCurrentFileName)-1,
871 NULL,0,NULL,0);
872 if (err == EXTRACTOR_UNZIP_OK)
873 {
874 if (EXTRACTOR_common_unzip_string_file_name_compare(szCurrentFileName,
875 szFileName,iCaseSensitivity)==0)
876 return EXTRACTOR_UNZIP_OK;
877 err = EXTRACTOR_common_unzip_go_to_next_file(file);
878 }
879 }
880
881 /* We failed, so restore the state of the 'current file' to where we
882 * were.
883 */
884 s->num_file = num_fileSaved ;
885 s->pos_in_central_dir = pos_in_central_dirSaved ;
886 s->cur_file_info = cur_file_infoSaved;
887 s->cur_file_info_internal = cur_file_info_internalSaved;
888 return err;
889}
890
891
892/*
893 Read bytes from the current file.
894 buf contain buffer where data must be copied
895 len the size of buf.
896
897 return the number of byte copied if somes bytes are copied
898 return 0 if the end of file was reached
899 return <0 with error code if there is an error
900 (EXTRACTOR_UNZIP_ERRNO for IO error, or zLib error for uncompress error)
901*/
902int EXTRACTOR_common_unzip_read_current_file (file, buf, len)
903 EXTRACTOR_unzip_file file;
904 voidp buf;
905 unsigned len;
906{
907 int err=EXTRACTOR_UNZIP_OK;
908 uInt iRead = 0;
909 unz_s* s;
910 file_in_zip_read_info_s* pfile_in_zip_read_info;
911 if (file==NULL)
912 return EXTRACTOR_UNZIP_PARAMERROR;
913 s=(unz_s*)file;
914 pfile_in_zip_read_info=s->pfile_in_zip_read;
915
916 if (pfile_in_zip_read_info==NULL)
917 return EXTRACTOR_UNZIP_PARAMERROR;
918
919
920 if ((pfile_in_zip_read_info->read_buffer == NULL))
921 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
922 if (len==0)
923 return 0;
924
925 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
926
927 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
928
929 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
930 pfile_in_zip_read_info->stream.avail_out =
931 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
932
933 while (pfile_in_zip_read_info->stream.avail_out>0)
934 {
935 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
936 (pfile_in_zip_read_info->rest_read_compressed>0))
937 {
938 uInt uReadThis = UNZ_BUFSIZE;
939 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
940 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
941 if (uReadThis == 0)
942 return EXTRACTOR_UNZIP_EOF;
943 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
944 pfile_in_zip_read_info->filestream,
945 pfile_in_zip_read_info->pos_in_zipfile +
946 pfile_in_zip_read_info->byte_before_the_zipfile,
947 ZLIB_FILEFUNC_SEEK_SET)!=0)
948 return EXTRACTOR_UNZIP_ERRNO;
949 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
950 pfile_in_zip_read_info->filestream,
951 pfile_in_zip_read_info->read_buffer,
952 uReadThis)!=uReadThis)
953 return EXTRACTOR_UNZIP_ERRNO;
954
955
956 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
957
958 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
959
960 pfile_in_zip_read_info->stream.next_in =
961 (Bytef*)pfile_in_zip_read_info->read_buffer;
962 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
963 }
964
965 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
966 {
967 uInt uDoCopy,i ;
968
969 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
970 (pfile_in_zip_read_info->rest_read_compressed == 0))
971 return (iRead==0) ? EXTRACTOR_UNZIP_EOF : iRead;
972
973 if (pfile_in_zip_read_info->stream.avail_out <
974 pfile_in_zip_read_info->stream.avail_in)
975 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
976 else
977 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
978
979 for (i=0;i<uDoCopy;i++)
980 *(pfile_in_zip_read_info->stream.next_out+i) =
981 *(pfile_in_zip_read_info->stream.next_in+i);
982
983 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
984 pfile_in_zip_read_info->stream.next_out,
985 uDoCopy);
986 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
987 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
988 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
989 pfile_in_zip_read_info->stream.next_out += uDoCopy;
990 pfile_in_zip_read_info->stream.next_in += uDoCopy;
991 pfile_in_zip_read_info->stream.total_out += uDoCopy;
992 iRead += uDoCopy;
993 }
994 else
995 {
996 uLong uTotalOutBefore,uTotalOutAfter;
997 const Bytef *bufBefore;
998 uLong uOutThis;
999 int flush=Z_SYNC_FLUSH;
1000
1001 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1002 bufBefore = pfile_in_zip_read_info->stream.next_out;
1003
1004 /*
1005 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1006 pfile_in_zip_read_info->stream.avail_out) &&
1007 (pfile_in_zip_read_info->rest_read_compressed == 0))
1008 flush = Z_FINISH;
1009 */
1010 err=inflate(&pfile_in_zip_read_info->stream,flush);
1011
1012 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1013 uOutThis = uTotalOutAfter-uTotalOutBefore;
1014
1015 pfile_in_zip_read_info->crc32 =
1016 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1017 (uInt)(uOutThis));
1018
1019 pfile_in_zip_read_info->rest_read_uncompressed -=
1020 uOutThis;
1021
1022 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1023
1024 if (err==Z_STREAM_END)
1025 return (iRead==0) ? EXTRACTOR_UNZIP_EOF : iRead;
1026 if (err!=Z_OK)
1027 break;
1028 }
1029 }
1030
1031 if (err==Z_OK)
1032 return iRead;
1033 return err;
1034}
1035
1036/*
1037 Read the local header of the current zipfile
1038 Check the coherency of the local header and info in the end of central
1039 directory about this file
1040 store in *piSizeVar the size of extra info in local header
1041 (filename and size of extra field data)
1042*/
1043static int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
1044 poffset_local_extrafield,
1045 psize_local_extrafield)
1046 unz_s* s;
1047 uInt* piSizeVar;
1048 uLong *poffset_local_extrafield;
1049 uInt *psize_local_extrafield;
1050{
1051 uLong uMagic,uData,uFlags;
1052 uLong size_filename;
1053 uLong size_extra_field;
1054 int err=EXTRACTOR_UNZIP_OK;
1055
1056 *piSizeVar = 0;
1057 *poffset_local_extrafield = 0;
1058 *psize_local_extrafield = 0;
1059
1060 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1061 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1062 return EXTRACTOR_UNZIP_ERRNO;
1063
1064
1065 if (err==EXTRACTOR_UNZIP_OK) {
1066 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != EXTRACTOR_UNZIP_OK)
1067 err=EXTRACTOR_UNZIP_ERRNO;
1068 else if (uMagic!=0x04034b50)
1069 err=EXTRACTOR_UNZIP_BADZIPFILE;
1070 }
1071 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK)
1072 err=EXTRACTOR_UNZIP_ERRNO;
1073/*
1074 else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.wVersion))
1075 err=EXTRACTOR_UNZIP_BADZIPFILE;
1076*/
1077 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != EXTRACTOR_UNZIP_OK)
1078 err=EXTRACTOR_UNZIP_ERRNO;
1079
1080 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK)
1081 err=EXTRACTOR_UNZIP_ERRNO;
1082 else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.compression_method))
1083 err=EXTRACTOR_UNZIP_BADZIPFILE;
1084
1085 if ((err==EXTRACTOR_UNZIP_OK) && (s->cur_file_info.compression_method!=0) &&
1086 (s->cur_file_info.compression_method!=Z_DEFLATED))
1087 err=EXTRACTOR_UNZIP_BADZIPFILE;
1088
1089 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* date/time */
1090 err=EXTRACTOR_UNZIP_ERRNO;
1091
1092 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* crc */
1093 err=EXTRACTOR_UNZIP_ERRNO;
1094 else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.crc) &&
1095 ((uFlags & 8)==0))
1096 err=EXTRACTOR_UNZIP_BADZIPFILE;
1097
1098 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* size compr */
1099 err=EXTRACTOR_UNZIP_ERRNO;
1100 else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.compressed_size) &&
1101 ((uFlags & 8)==0))
1102 err=EXTRACTOR_UNZIP_BADZIPFILE;
1103
1104 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* size uncompr */
1105 err=EXTRACTOR_UNZIP_ERRNO;
1106 else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1107 ((uFlags & 8)==0))
1108 err=EXTRACTOR_UNZIP_BADZIPFILE;
1109
1110
1111 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != EXTRACTOR_UNZIP_OK)
1112 err=EXTRACTOR_UNZIP_ERRNO;
1113 else if ((err==EXTRACTOR_UNZIP_OK) && (size_filename!=s->cur_file_info.size_filename))
1114 err=EXTRACTOR_UNZIP_BADZIPFILE;
1115
1116 *piSizeVar += (uInt)size_filename;
1117
1118 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != EXTRACTOR_UNZIP_OK)
1119 err=EXTRACTOR_UNZIP_ERRNO;
1120 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1121 SIZEZIPLOCALHEADER + size_filename;
1122 *psize_local_extrafield = (uInt)size_extra_field;
1123
1124 *piSizeVar += (uInt)size_extra_field;
1125
1126 return err;
1127}
1128
1129
1130
1131/*
1132 Open for reading data the current file in the zipfile.
1133 If there is no error and the file is opened, the return value is EXTRACTOR_UNZIP_OK.
1134*/
1135int EXTRACTOR_common_unzip_open_current_file3 (file, method, level, raw)
1136 EXTRACTOR_unzip_file file;
1137 int* method;
1138 int* level;
1139 int raw;
1140{
1141 int err=EXTRACTOR_UNZIP_OK;
1142 uInt iSizeVar;
1143 unz_s* s;
1144 file_in_zip_read_info_s* pfile_in_zip_read_info;
1145 uLong offset_local_extrafield; /* offset of the local extra field */
1146 uInt size_local_extrafield; /* size of the local extra field */
1147
1148 if (file==NULL)
1149 return EXTRACTOR_UNZIP_PARAMERROR;
1150 s=(unz_s*)file;
1151 if (!s->current_file_ok)
1152 return EXTRACTOR_UNZIP_PARAMERROR;
1153
1154 if (s->pfile_in_zip_read != NULL)
1155 EXTRACTOR_common_unzip_close_current_file(file);
1156 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1157 &offset_local_extrafield,&size_local_extrafield)!=EXTRACTOR_UNZIP_OK)
1158 return EXTRACTOR_UNZIP_BADZIPFILE;
1159
1160 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1161 ALLOC(sizeof(file_in_zip_read_info_s));
1162 if (pfile_in_zip_read_info==NULL)
1163 return EXTRACTOR_UNZIP_INTERNALERROR;
1164
1165 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1166 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1167 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1168 pfile_in_zip_read_info->pos_local_extrafield=0;
1169 pfile_in_zip_read_info->raw=raw;
1170
1171 if (pfile_in_zip_read_info->read_buffer==NULL)
1172 {
1173 TRYFREE(pfile_in_zip_read_info);
1174 return EXTRACTOR_UNZIP_INTERNALERROR;
1175 }
1176
1177 pfile_in_zip_read_info->stream_initialised=0;
1178
1179 if (method!=NULL)
1180 *method = (int)s->cur_file_info.compression_method;
1181
1182 if (level!=NULL)
1183 {
1184 *level = 6;
1185 switch (s->cur_file_info.flag & 0x06)
1186 {
1187 case 6 : *level = 1; break;
1188 case 4 : *level = 2; break;
1189 case 2 : *level = 9; break;
1190 }
1191 }
1192
1193 if ((s->cur_file_info.compression_method!=0) &&
1194 (s->cur_file_info.compression_method!=Z_DEFLATED))
1195 err=EXTRACTOR_UNZIP_BADZIPFILE;
1196
1197 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1198 pfile_in_zip_read_info->crc32=0;
1199 pfile_in_zip_read_info->compression_method =
1200 s->cur_file_info.compression_method;
1201 pfile_in_zip_read_info->filestream=s->filestream;
1202 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1203 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1204
1205 pfile_in_zip_read_info->stream.total_out = 0;
1206
1207 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1208 (!raw))
1209 {
1210 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1211 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1212 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1213 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1214 pfile_in_zip_read_info->stream.avail_in = 0;
1215
1216 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1217 if (err == Z_OK)
1218 pfile_in_zip_read_info->stream_initialised=1;
1219 else
1220 return err;
1221 /* windowBits is passed < 0 to tell that there is no zlib header.
1222 * Note that in this case inflate *requires* an extra "dummy" byte
1223 * after the compressed stream in order to complete decompression and
1224 * return Z_STREAM_END.
1225 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1226 * size of both compressed and uncompressed data
1227 */
1228 }
1229 pfile_in_zip_read_info->rest_read_compressed =
1230 s->cur_file_info.compressed_size ;
1231 pfile_in_zip_read_info->rest_read_uncompressed =
1232 s->cur_file_info.uncompressed_size ;
1233
1234
1235 pfile_in_zip_read_info->pos_in_zipfile =
1236 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1237 iSizeVar;
1238
1239 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1240
1241 s->pfile_in_zip_read = pfile_in_zip_read_info;
1242
1243 return EXTRACTOR_UNZIP_OK;
1244}
1245
1246typedef struct Ecls {
1247 char * data;
1248 size_t size;
1249 size_t pos;
1250} Ecls;
1251
1252voidpf EXTRACTOR_common_unzip_zlib_open_file_func (voidpf opaque,
1253 const char* filename,
1254 int mode) {
1255 if (0 == strcmp(filename,
1256 "ERROR"))
1257 return opaque;
1258 else
1259 return NULL;
1260}
1261
1262uLong EXTRACTOR_common_unzip_zlib_read_file_func(voidpf opaque,
1263 voidpf stream,
1264 void* buf,
1265 uLong size) {
1266 Ecls * e = opaque;
1267 uLong ret;
1268
1269 ret = e->size - e->pos;
1270 if (ret > size)
1271 ret = size;
1272 memcpy(buf,
1273 &e->data[e->pos],
1274 ret);
1275 e->pos += ret;
1276 return ret;
1277}
1278
1279long EXTRACTOR_common_unzip_zlib_tell_file_func(voidpf opaque,
1280 voidpf stream) {
1281 Ecls * e = opaque;
1282 return e->pos;
1283}
1284
1285long EXTRACTOR_common_unzip_zlib_seek_file_func(voidpf opaque,
1286 voidpf stream,
1287 uLong offset,
1288 int origin) {
1289 Ecls * e = opaque;
1290
1291 switch (origin) {
1292 case ZLIB_FILEFUNC_SEEK_SET:
1293 if ( (offset > e->size) ||
1294 (offset < 0) )
1295 return -1;
1296 e->pos = offset;
1297 break;
1298 case ZLIB_FILEFUNC_SEEK_END:
1299 if ( (offset > e->size) ||
1300 (offset < 0) )
1301 return -1;
1302 e->pos = e->size - offset;
1303 break;
1304 case ZLIB_FILEFUNC_SEEK_CUR:
1305 if ( (offset < - e->pos) ||
1306 (offset > e->size - e->pos) )
1307 return -1;
1308 e->pos += offset;
1309 break;
1310 default:
1311 return -1;
1312 }
1313 return 0;
1314}
1315
1316int EXTRACTOR_common_unzip_zlib_close_file_func(voidpf opaque,
1317 voidpf stream) {
1318 return 0;
1319}
1320
1321int EXTRACTOR_common_unzip_zlib_testerror_file_func(voidpf opaque,
1322 voidpf stream) {
1323 return 0;
1324}
diff --git a/src/common/unzip.h b/src/common/unzip.h
new file mode 100644
index 0000000..f0c2c4e
--- /dev/null
+++ b/src/common/unzip.h
@@ -0,0 +1,126 @@
1/*
2 This file is part of libextractor.
3 (C) 2008 Christian Grothoff (and other contributing authors)
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#ifndef UNZIP_H_
22#define UNZIP_H_
23
24#include <zlib.h>
25
26#define EXTRACTOR_UNZIP_OK (0)
27#define EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE (-100)
28#define EXTRACTOR_UNZIP_ERRNO (Z_ERRNO)
29#define EXTRACTOR_UNZIP_EOF (0)
30#define EXTRACTOR_UNZIP_PARAMERROR (-102)
31#define EXTRACTOR_UNZIP_BADZIPFILE (-103)
32#define EXTRACTOR_UNZIP_INTERNALERROR (-104)
33#define EXTRACTOR_UNZIP_CRCERROR (-105)
34
35typedef voidp EXTRACTOR_unzip_file;
36
37typedef struct EXTRACTOR_unzip_filefunc_def_s
38{
39 voidpf ( *zopen_file) (voidpf opaque, const char* filename, int mode);
40 uLong ( *zread_file) (voidpf opaque, voidpf stream, void* buf, uLong size);
41 uLong ( *zwrite_file) (voidpf opaque, voidpf stream, const void* buf, uLong size);
42 long ( *ztell_file) (voidpf opaque, voidpf stream);
43 long ( *zseek_file) (voidpf opaque, voidpf stream, uLong offset, int origin);
44 int ( *zclose_file) (voidpf opaque, voidpf stream);
45 int ( *zerror_file) (voidpf opaque, voidpf stream);
46 voidpf opaque;
47} EXTRACTOR_unzip_filefunc_def;
48
49/* tm_unz contain date/time info */
50typedef struct EXTRACTOR_unzip_tm_unz_s
51{
52 uInt tm_sec; /* seconds after the minute - [0,59] */
53 uInt tm_min; /* minutes after the hour - [0,59] */
54 uInt tm_hour; /* hours since midnight - [0,23] */
55 uInt tm_mday; /* day of the month - [1,31] */
56 uInt tm_mon; /* months since January - [0,11] */
57 uInt tm_year; /* years - [1980..2044] */
58} EXTRACTOR_unzip_tm_unz;
59
60/* unz_file_info contain information about a file in the zipfile */
61typedef struct EXTRACTOR_unzip_file_info_s
62{
63 uLong version; /* version made by 2 bytes */
64 uLong version_needed; /* version needed to extract 2 bytes */
65 uLong flag; /* general purpose bit flag 2 bytes */
66 uLong compression_method; /* compression method 2 bytes */
67 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
68 uLong crc; /* crc-32 4 bytes */
69 uLong compressed_size; /* compressed size 4 bytes */
70 uLong uncompressed_size; /* uncompressed size 4 bytes */
71 uLong size_filename; /* filename length 2 bytes */
72 uLong size_file_extra; /* extra field length 2 bytes */
73 uLong size_file_comment; /* file comment length 2 bytes */
74
75 uLong disk_num_start; /* disk number start 2 bytes */
76 uLong internal_fa; /* internal file attributes 2 bytes */
77 uLong external_fa; /* external file attributes 4 bytes */
78
79 EXTRACTOR_unzip_tm_unz tmu_date;
80} EXTRACTOR_unzip_file_info;
81
82int EXTRACTOR_common_unzip_string_file_name_compare(const char* fileName1,
83 const char* fileName2, int iCaseSensitivity);
84
85int EXTRACTOR_common_unzip_go_to_first_file(EXTRACTOR_unzip_file file);
86
87EXTRACTOR_unzip_file EXTRACTOR_common_unzip_open2(const char *path,
88 EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def);
89
90int EXTRACTOR_common_unzip_close_current_file(EXTRACTOR_unzip_file file);
91
92int EXTRACTOR_common_unzip_close(EXTRACTOR_unzip_file file);
93
94int EXTRACTOR_common_unzip_get_current_file_info(EXTRACTOR_unzip_file file,
95 EXTRACTOR_unzip_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize,
96 void *extraField, uLong extraFieldBufferSize, char *szComment,
97 uLong commentBufferSize);
98
99int EXTRACTOR_common_unzip_go_to_next_file(EXTRACTOR_unzip_file file);
100
101int EXTRACTOR_common_unzip_local_file(EXTRACTOR_unzip_file file, const char *szFileName,
102 int iCaseSensitivity);
103
104int EXTRACTOR_common_unzip_read_current_file(EXTRACTOR_unzip_file file, voidp buf,
105 unsigned len);
106
107int EXTRACTOR_common_unzip_open_current_file3(EXTRACTOR_unzip_file file, int* method,
108 int* level, int raw);
109
110voidpf EXTRACTOR_common_unzip_zlib_open_file_func(voidpf opaque,
111 const char* filename, int mode);
112
113uLong EXTRACTOR_common_unzip_zlib_read_file_func(voidpf opaque, voidpf stream,
114 void* buf, uLong size);
115
116long EXTRACTOR_common_unzip_zlib_tell_file_func(voidpf opaque, voidpf stream);
117
118long EXTRACTOR_common_unzip_zlib_seek_file_func(voidpf opaque, voidpf stream,
119 uLong offset, int origin);
120
121int EXTRACTOR_common_unzip_zlib_close_file_func(voidpf opaque, voidpf stream);
122
123int EXTRACTOR_common_unzip_zlib_testerror_file_func(voidpf opaque,
124 voidpf stream);
125
126#endif /* UNZIP_H_ */