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