~ubuntu-branches/ubuntu/natty/libextractor/natty

« back to all changes in this revision

Viewing changes to src/common/unzip.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-17 20:27:32 UTC
  • mfrom: (1.10.4 upstream) (5.2.5 sid)
  • Revision ID: james.westby@ubuntu.com-20091117202732-ipm2h3gks5bdw2vx
Tags: 0.5.23+dfsg-3
* Building against libltdl7.
* Updating to standards version 3.8.3.
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Simplifying autotools handling in rules.
* Updating README.source.
* Moving maintainer homepage field from control to copyright.
* Dropping la files.
* Simplyfing debhelper install files.
* Bumping versioned build-depends on debhelper.
* Adding depends to dpkg install info.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */
 
54
typedef 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
 
 
100
const 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*/
 
104
typedef 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 */
 
112
typedef 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
*/
 
138
typedef 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
 
 
169
static int unzlocal_getByte OF((
 
170
    const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
 
171
    voidpf filestream,
 
172
    int *pi));
 
173
 
 
174
static 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
*/
 
199
static int unzlocal_getShort OF((
 
200
    const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
 
201
    voidpf filestream,
 
202
    uLong *pX));
 
203
 
 
204
static 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
 
 
227
static int unzlocal_getLong OF((
 
228
    const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
 
229
    voidpf filestream,
 
230
    uLong *pX));
 
231
 
 
232
static 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 */
 
265
static 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
*/
 
308
int 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
*/
 
330
static uLong unzlocal_SearchCentralDir OF((
 
331
    const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def,
 
332
    voidpf filestream));
 
333
 
 
334
static 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
*/
 
394
static 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
 
 
411
static 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
*/
 
577
int 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
*/
 
604
EXTRACTOR_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
*/
 
707
int 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. */
 
749
int 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
*/
 
771
int 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
*/
 
796
int 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
*/
 
831
int 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
*/
 
902
int 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
*/
 
1043
static 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
*/
 
1135
int 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
 
 
1246
typedef struct Ecls {
 
1247
  char * data;
 
1248
  size_t size;
 
1249
  size_t pos;
 
1250
} Ecls;
 
1251
 
 
1252
voidpf 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
 
 
1262
uLong 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
 
 
1279
long EXTRACTOR_common_unzip_zlib_tell_file_func(voidpf opaque,
 
1280
                            voidpf stream) {
 
1281
  Ecls * e = opaque;
 
1282
  return e->pos;
 
1283
}
 
1284
 
 
1285
long 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
 
 
1316
int EXTRACTOR_common_unzip_zlib_close_file_func(voidpf opaque,
 
1317
                            voidpf stream) {
 
1318
  return 0;
 
1319
}
 
1320
 
 
1321
int EXTRACTOR_common_unzip_zlib_testerror_file_func(voidpf opaque,
 
1322
                                voidpf stream) {
 
1323
  return 0;
 
1324
}