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