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