~gma500/gma500/unstable

« back to all changes in this revision

Viewing changes to vlc/vlc-1.1.4/libs/unzip/unzip.c

  • Committer: Maarten Fonville
  • Date: 2010-10-05 19:30:44 UTC
  • Revision ID: maarten.fonville@gmail.com-20101005193044-ebziftknrpm55uyc
added ffmpeg (for our libva)
added vlc (optimized for va-api)
fixed gnome-mplayer

Show diffs side-by-side

added added

removed removed

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