diff src/common/unzip.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/common/unzip.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,1208 @@
     1.4 +/* unzip.c -- IO on .zip files using zlib
     1.5 +   Version 0.15 beta, Mar 19th, 1998,
     1.6 +
     1.7 +   Read unzip.h for more info
     1.8 + */
     1.9 +
    1.10 +#include <cstdio>
    1.11 +#include <cstdlib>
    1.12 +#include <cstring>
    1.13 +#include "zlib.h"
    1.14 +#include "unzip.h"
    1.15 +
    1.16 +#ifdef NO_ERRNO_H
    1.17 +extern int errno;
    1.18 +#else
    1.19 +#   include <cerrno>
    1.20 +#endif
    1.21 +
    1.22 +#ifndef local
    1.23 +#  define local static
    1.24 +#endif
    1.25 +/* compile with -Dlocal if your debugger can't find static symbols */
    1.26 +
    1.27 +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
    1.28 +    !defined(CASESENSITIVITYDEFAULT_NO)
    1.29 +#define CASESENSITIVITYDEFAULT_NO
    1.30 +#endif
    1.31 +
    1.32 +#ifndef UNZ_BUFSIZE
    1.33 +#define UNZ_BUFSIZE (16384)
    1.34 +#endif
    1.35 +
    1.36 +#ifndef UNZ_MAXFILENAMEINZIP
    1.37 +#define UNZ_MAXFILENAMEINZIP (256)
    1.38 +#endif
    1.39 +
    1.40 +#ifndef ALLOC
    1.41 +# define ALLOC(size) (malloc(size))
    1.42 +#endif
    1.43 +#ifndef TRYFREE
    1.44 +# define TRYFREE(p) {if (p) \
    1.45 +						 free(p);}
    1.46 +#endif
    1.47 +
    1.48 +#define SIZECENTRALDIRITEM (0x2e)
    1.49 +#define SIZEZIPLOCALHEADER (0x1e)
    1.50 +
    1.51 +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
    1.52 +
    1.53 +#ifndef SEEK_CUR
    1.54 +#define SEEK_CUR    1
    1.55 +#endif
    1.56 +
    1.57 +#ifndef SEEK_END
    1.58 +#define SEEK_END    2
    1.59 +#endif
    1.60 +
    1.61 +#ifndef SEEK_SET
    1.62 +#define SEEK_SET    0
    1.63 +#endif
    1.64 +
    1.65 +const char unz_copyright[] =
    1.66 +    " unzip 0.15 Copyright 1998 Gilles Vollant ";
    1.67 +
    1.68 +/* unz_file_info_interntal contain internal info about a file in zipfile*/
    1.69 +typedef struct unz_file_info_internal_s
    1.70 +{
    1.71 +	uLong offset_curfile; /* relative offset of local header 4 bytes */
    1.72 +} unz_file_info_internal;
    1.73 +
    1.74 +/* file_in_zip_read_info_s contain internal information about a file in zipfile,
    1.75 +    when reading and decompress it */
    1.76 +typedef struct
    1.77 +{
    1.78 +	char *   read_buffer;           /* internal buffer for compressed data */
    1.79 +	z_stream stream;                /* zLib stream structure for inflate */
    1.80 +
    1.81 +	uLong pos_in_zipfile;           /* position in byte on the zipfile, for fseek*/
    1.82 +	uLong stream_initialised;       /* flag set if stream structure is initialised*/
    1.83 +
    1.84 +	uLong offset_local_extrafield;    /* offset of the local extra field */
    1.85 +	uInt  size_local_extrafield;    /* size of the local extra field */
    1.86 +	uLong pos_local_extrafield;       /* position in the local extra field in read*/
    1.87 +
    1.88 +	uLong crc32;                    /* crc32 of all data uncompressed */
    1.89 +	uLong crc32_wait;               /* crc32 we must obtain after decompress all */
    1.90 +	uLong rest_read_compressed;     /* number of byte to be decompressed */
    1.91 +	uLong rest_read_uncompressed;    /*number of byte to be obtained after decomp*/
    1.92 +	FILE* file;                     /* io structore of the zipfile */
    1.93 +	uLong compression_method;       /* compression method (0==store) */
    1.94 +	uLong byte_before_the_zipfile;    /* byte before the zipfile, (>0 for sfx)*/
    1.95 +} file_in_zip_read_info_s;
    1.96 +
    1.97 +/* unz_s contain internal information about the zipfile
    1.98 + */
    1.99 +typedef struct
   1.100 +{
   1.101 +	FILE*file;                      /* io structore of the zipfile */
   1.102 +	unz_global_info gi;           /* public global information */
   1.103 +	uLong byte_before_the_zipfile;    /* byte before the zipfile, (>0 for sfx)*/
   1.104 +	uLong num_file;                 /* number of the current file in the zipfile*/
   1.105 +	uLong pos_in_central_dir;       /* pos of the current file in the central dir*/
   1.106 +	uLong current_file_ok;          /* flag about the usability of the current file*/
   1.107 +	uLong central_pos;              /* position of the beginning of the central dir*/
   1.108 +
   1.109 +	uLong size_central_dir;         /* size of the central directory  */
   1.110 +	uLong offset_central_dir;       /* offset of start of central directory with
   1.111 +									                               respect to the starting disk number */
   1.112 +
   1.113 +	unz_file_info cur_file_info;     /* public info about the current file in zip*/
   1.114 +	unz_file_info_internal  cur_file_info_internal;    /* private info about it*/
   1.115 +	file_in_zip_read_info_s*pfile_in_zip_read;  /* structure about the current
   1.116 +												   file if we are decompressing it */
   1.117 +} unz_s;
   1.118 +
   1.119 +/* ===========================================================================
   1.120 +     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
   1.121 +   for end of file.
   1.122 +   IN assertion: the stream s has been sucessfully opened for reading.
   1.123 + */
   1.124 +
   1.125 +local int unzlocal_getByte(FILE *fin, int *pi)
   1.126 +{
   1.127 +	unsigned char c;
   1.128 +	int err = fread(&c, 1, 1, fin);
   1.129 +	if (err == 1)
   1.130 +	{
   1.131 +		*pi = (int)c;
   1.132 +		return UNZ_OK;
   1.133 +	}
   1.134 +	else
   1.135 +	{
   1.136 +		if (ferror(fin))
   1.137 +			return UNZ_ERRNO;
   1.138 +		else
   1.139 +			return UNZ_EOF;
   1.140 +	}
   1.141 +}
   1.142 +
   1.143 +/* ===========================================================================
   1.144 +   Reads a long in LSB order from the given gz_stream. Sets
   1.145 + */
   1.146 +local int unzlocal_getShort(FILE *fin, uLong *pX)
   1.147 +{
   1.148 +	uLong x ;
   1.149 +	int   i;
   1.150 +	int   err;
   1.151 +
   1.152 +	err = unzlocal_getByte(fin, &i);
   1.153 +	x   = (uLong)i;
   1.154 +
   1.155 +	if (err == UNZ_OK)
   1.156 +		err = unzlocal_getByte(fin, &i);
   1.157 +	x += ((uLong)i)<<8;
   1.158 +
   1.159 +	if (err == UNZ_OK)
   1.160 +		*pX = x;
   1.161 +	else
   1.162 +		*pX = 0;
   1.163 +	return err;
   1.164 +}
   1.165 +
   1.166 +local int unzlocal_getLong(FILE *fin, uLong *pX)
   1.167 +{
   1.168 +	uLong x ;
   1.169 +	int   i;
   1.170 +	int   err;
   1.171 +
   1.172 +	err = unzlocal_getByte(fin, &i);
   1.173 +	x   = (uLong)i;
   1.174 +
   1.175 +	if (err == UNZ_OK)
   1.176 +		err = unzlocal_getByte(fin, &i);
   1.177 +	x += ((uLong)i)<<8;
   1.178 +
   1.179 +	if (err == UNZ_OK)
   1.180 +		err = unzlocal_getByte(fin, &i);
   1.181 +	x += ((uLong)i)<<16;
   1.182 +
   1.183 +	if (err == UNZ_OK)
   1.184 +		err = unzlocal_getByte(fin, &i);
   1.185 +	x += ((uLong)i)<<24;
   1.186 +
   1.187 +	if (err == UNZ_OK)
   1.188 +		*pX = x;
   1.189 +	else
   1.190 +		*pX = 0;
   1.191 +	return err;
   1.192 +}
   1.193 +
   1.194 +/* My own strcmpi / strcasecmp */
   1.195 +local int strcmpcasenosensitive_internal(const char *fileName1,
   1.196 +                                         const char *fileName2)
   1.197 +{
   1.198 +	for (;;)
   1.199 +	{
   1.200 +		char c1 = *(fileName1++);
   1.201 +		char c2 = *(fileName2++);
   1.202 +		if ((c1 >= 'a') && (c1 <= 'z'))
   1.203 +			c1 -= 0x20;
   1.204 +		if ((c2 >= 'a') && (c2 <= 'z'))
   1.205 +			c2 -= 0x20;
   1.206 +		if (c1 == '\0')
   1.207 +			return ((c2 == '\0') ? 0 : -1);
   1.208 +		if (c2 == '\0')
   1.209 +			return 1;
   1.210 +		if (c1 < c2)
   1.211 +			return -1;
   1.212 +		if (c1 > c2)
   1.213 +			return 1;
   1.214 +	}
   1.215 +}
   1.216 +
   1.217 +#ifdef  CASESENSITIVITYDEFAULT_NO
   1.218 +#define CASESENSITIVITYDEFAULTVALUE 2
   1.219 +#else
   1.220 +#define CASESENSITIVITYDEFAULTVALUE 1
   1.221 +#endif
   1.222 +
   1.223 +#ifndef STRCMPCASENOSENTIVEFUNCTION
   1.224 +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
   1.225 +#endif
   1.226 +
   1.227 +/*
   1.228 +   Compare two filename (fileName1,fileName2).
   1.229 +   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
   1.230 +   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
   1.231 +                                                                or strcasecmp)
   1.232 +   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
   1.233 +        (like 1 on Unix, 2 on Windows)
   1.234 +
   1.235 + */
   1.236 +extern int ZEXPORT unzStringFileNameCompare(const char *fileName1,
   1.237 +                                            const char *fileName2,
   1.238 +                                            int iCaseSensitivity)
   1.239 +{
   1.240 +	if (iCaseSensitivity == 0)
   1.241 +		iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE;
   1.242 +
   1.243 +	if (iCaseSensitivity == 1)
   1.244 +		return strcmp(fileName1, fileName2);
   1.245 +
   1.246 +	return STRCMPCASENOSENTIVEFUNCTION(fileName1, fileName2);
   1.247 +}
   1.248 +
   1.249 +#define BUFREADCOMMENT (0x400)
   1.250 +
   1.251 +/*
   1.252 +   Locate the Central directory of a zipfile (at the end, just before
   1.253 +    the global comment)
   1.254 + */
   1.255 +local uLong unzlocal_SearchCentralDir(FILE *fin)
   1.256 +{
   1.257 +	unsigned char*buf;
   1.258 +	uLong         uSizeFile;
   1.259 +	uLong         uBackRead;
   1.260 +	uLong         uMaxBack  = 0xffff; /* maximum size of global comment */
   1.261 +	uLong         uPosFound = 0;
   1.262 +
   1.263 +	if (fseek(fin, 0, SEEK_END) != 0)
   1.264 +		return 0;
   1.265 +
   1.266 +	uSizeFile = ftell(fin);
   1.267 +
   1.268 +	if (uMaxBack > uSizeFile)
   1.269 +		uMaxBack = uSizeFile;
   1.270 +
   1.271 +	buf = (unsigned char *)ALLOC(BUFREADCOMMENT+4);
   1.272 +	if (buf == NULL)
   1.273 +		return 0;
   1.274 +
   1.275 +	uBackRead = 4;
   1.276 +	while (uBackRead < uMaxBack)
   1.277 +	{
   1.278 +		uLong uReadSize, uReadPos ;
   1.279 +		int   i;
   1.280 +		if (uBackRead+BUFREADCOMMENT > uMaxBack)
   1.281 +			uBackRead = uMaxBack;
   1.282 +		else
   1.283 +			uBackRead += BUFREADCOMMENT;
   1.284 +		uReadPos = uSizeFile-uBackRead ;
   1.285 +
   1.286 +		uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
   1.287 +		            (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
   1.288 +		if (fseek(fin, uReadPos, SEEK_SET) != 0)
   1.289 +			break;
   1.290 +
   1.291 +		if (fread(buf, (uInt)uReadSize, 1, fin) != 1)
   1.292 +			break;
   1.293 +
   1.294 +		for (i = (int)uReadSize-3; (i--) > 0;)
   1.295 +			if (((*(buf+i)) == 0x50) && ((*(buf+i+1)) == 0x4b) &&
   1.296 +			    ((*(buf+i+2)) == 0x05) && ((*(buf+i+3)) == 0x06))
   1.297 +			{
   1.298 +				uPosFound = uReadPos+i;
   1.299 +				break;
   1.300 +			}
   1.301 +
   1.302 +		if (uPosFound != 0)
   1.303 +			break;
   1.304 +	}
   1.305 +	TRYFREE(buf);
   1.306 +	return uPosFound;
   1.307 +}
   1.308 +
   1.309 +/*
   1.310 +   Open a Zip file. path contain the full pathname (by example,
   1.311 +     on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
   1.312 +         "zlib/zlib109.zip".
   1.313 +         If the zipfile cannot be opened (file don't exist or in not valid), the
   1.314 +           return value is NULL.
   1.315 +     Else, the return value is a unzFile Handle, usable with other function
   1.316 +           of this unzip package.
   1.317 + */
   1.318 +extern unzFile ZEXPORT unzOpen(const char *path)
   1.319 +{
   1.320 +	unz_s  us;
   1.321 +	unz_s *s;
   1.322 +	uLong  central_pos, uL;
   1.323 +	FILE * fin ;
   1.324 +
   1.325 +	uLong number_disk;              /* number of the current dist, used for
   1.326 +									                               spaning ZIP, unsupported, always 0*/
   1.327 +	uLong number_disk_with_CD;      /* number the the disk with central dir, used
   1.328 +									                               for spaning ZIP, unsupported, always 0*/
   1.329 +	uLong number_entry_CD;          /* total number of entries in
   1.330 +									   the central dir
   1.331 +									   (same than number_entry on nospan) */
   1.332 +
   1.333 +	int err = UNZ_OK;
   1.334 +
   1.335 +	if (unz_copyright[0] != ' ')
   1.336 +		return NULL;
   1.337 +
   1.338 +	fin = fopen(path, "rb");
   1.339 +	if (fin == NULL)
   1.340 +		return NULL;
   1.341 +
   1.342 +	central_pos = unzlocal_SearchCentralDir(fin);
   1.343 +	if (central_pos == 0)
   1.344 +		err = UNZ_ERRNO;
   1.345 +
   1.346 +	if (fseek(fin, central_pos, SEEK_SET) != 0)
   1.347 +		err = UNZ_ERRNO;
   1.348 +
   1.349 +	/* the signature, already checked */
   1.350 +	if (unzlocal_getLong(fin, &uL) != UNZ_OK)
   1.351 +		err = UNZ_ERRNO;
   1.352 +
   1.353 +	/* number of this disk */
   1.354 +	if (unzlocal_getShort(fin, &number_disk) != UNZ_OK)
   1.355 +		err = UNZ_ERRNO;
   1.356 +
   1.357 +	/* number of the disk with the start of the central directory */
   1.358 +	if (unzlocal_getShort(fin, &number_disk_with_CD) != UNZ_OK)
   1.359 +		err = UNZ_ERRNO;
   1.360 +
   1.361 +	/* total number of entries in the central dir on this disk */
   1.362 +	if (unzlocal_getShort(fin, &us.gi.number_entry) != UNZ_OK)
   1.363 +		err = UNZ_ERRNO;
   1.364 +
   1.365 +	/* total number of entries in the central dir */
   1.366 +	if (unzlocal_getShort(fin, &number_entry_CD) != UNZ_OK)
   1.367 +		err = UNZ_ERRNO;
   1.368 +
   1.369 +	if ((number_entry_CD != us.gi.number_entry) ||
   1.370 +	    (number_disk_with_CD != 0) ||
   1.371 +	    (number_disk != 0))
   1.372 +		err = UNZ_BADZIPFILE;
   1.373 +
   1.374 +	/* size of the central directory */
   1.375 +	if (unzlocal_getLong(fin, &us.size_central_dir) != UNZ_OK)
   1.376 +		err = UNZ_ERRNO;
   1.377 +
   1.378 +	/* offset of start of central directory with respect to the
   1.379 +	      starting disk number */
   1.380 +	if (unzlocal_getLong(fin, &us.offset_central_dir) != UNZ_OK)
   1.381 +		err = UNZ_ERRNO;
   1.382 +
   1.383 +	/* zipfile comment length */
   1.384 +	if (unzlocal_getShort(fin, &us.gi.size_comment) != UNZ_OK)
   1.385 +		err = UNZ_ERRNO;
   1.386 +
   1.387 +	if ((central_pos < us.offset_central_dir+us.size_central_dir) &&
   1.388 +	    (err == UNZ_OK))
   1.389 +		err = UNZ_BADZIPFILE;
   1.390 +
   1.391 +	if (err != UNZ_OK)
   1.392 +	{
   1.393 +		fclose(fin);
   1.394 +		return NULL;
   1.395 +	}
   1.396 +
   1.397 +	us.file = fin;
   1.398 +	us.byte_before_the_zipfile = central_pos -
   1.399 +	                             (us.offset_central_dir+us.size_central_dir);
   1.400 +	us.central_pos       = central_pos;
   1.401 +	us.pfile_in_zip_read = NULL;
   1.402 +
   1.403 +	s  = (unz_s *)ALLOC(sizeof(unz_s));
   1.404 +	*s = us;
   1.405 +	unzGoToFirstFile((unzFile)s);
   1.406 +	return (unzFile)s;
   1.407 +}
   1.408 +
   1.409 +/*
   1.410 +   Close a ZipFile opened with unzipOpen.
   1.411 +   If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
   1.412 +    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
   1.413 +   return UNZ_OK if there is no problem. */
   1.414 +extern int ZEXPORT unzClose(unzFile file)
   1.415 +{
   1.416 +	unz_s*s;
   1.417 +	if (file == NULL)
   1.418 +		return UNZ_PARAMERROR;
   1.419 +	s = (unz_s *)file;
   1.420 +
   1.421 +	if (s->pfile_in_zip_read != NULL)
   1.422 +		unzCloseCurrentFile(file);
   1.423 +
   1.424 +	fclose(s->file);
   1.425 +	TRYFREE(s);
   1.426 +	return UNZ_OK;
   1.427 +}
   1.428 +
   1.429 +/*
   1.430 +   Write info about the ZipFile in the *pglobal_info structure.
   1.431 +   No preparation of the structure is needed
   1.432 +   return UNZ_OK if there is no problem. */
   1.433 +extern int ZEXPORT unzGetGlobalInfo(unzFile file,
   1.434 +                                    unz_global_info *pglobal_info)
   1.435 +{
   1.436 +	unz_s*s;
   1.437 +	if (file == NULL)
   1.438 +		return UNZ_PARAMERROR;
   1.439 +	s = (unz_s *)file;
   1.440 +	*pglobal_info = s->gi;
   1.441 +	return UNZ_OK;
   1.442 +}
   1.443 +
   1.444 +/*
   1.445 +   Translate date/time from Dos format to tm_unz (readable more easilty)
   1.446 + */
   1.447 +local void unzlocal_DosDateToTmuDate(uLong ulDosDate, tm_unz *ptm)
   1.448 +{
   1.449 +	uLong uDate;
   1.450 +	uDate        = (uLong)(ulDosDate>>16);
   1.451 +	ptm->tm_mday = (uInt)(uDate&0x1f) ;
   1.452 +	ptm->tm_mon  =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
   1.453 +	ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
   1.454 +
   1.455 +	ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
   1.456 +	ptm->tm_min  =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
   1.457 +	ptm->tm_sec  =  (uInt) (2*(ulDosDate&0x1f)) ;
   1.458 +}
   1.459 +
   1.460 +/*
   1.461 +   Get Info about the current file in the zipfile, with internal only info
   1.462 + */
   1.463 +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
   1.464 +                                                  unz_file_info *pfile_info,
   1.465 +                                                  unz_file_info_internal
   1.466 +                                                  *pfile_info_internal,
   1.467 +                                                  char *szFileName,
   1.468 +                                                  uLong fileNameBufferSize,
   1.469 +                                                  void *extraField,
   1.470 +                                                  uLong extraFieldBufferSize,
   1.471 +                                                  char *szComment,
   1.472 +                                                  uLong commentBufferSize));
   1.473 +
   1.474 +local int unzlocal_GetCurrentFileInfoInternal(unzFile file,
   1.475 +                                              unz_file_info *pfile_info,
   1.476 +                                              unz_file_info_internal *pfile_info_internal,
   1.477 +                                              char *szFileName,
   1.478 +                                              uLong fileNameBufferSize,
   1.479 +                                              void *extraField,
   1.480 +                                              uLong extraFieldBufferSize,
   1.481 +                                              char *szComment,
   1.482 +                                              uLong commentBufferSize)
   1.483 +{
   1.484 +	unz_s*        s;
   1.485 +	unz_file_info file_info;
   1.486 +	unz_file_info_internal file_info_internal;
   1.487 +	int   err = UNZ_OK;
   1.488 +	uLong uMagic;
   1.489 +	long  lSeek = 0;
   1.490 +
   1.491 +	if (file == NULL)
   1.492 +		return UNZ_PARAMERROR;
   1.493 +	s = (unz_s *)file;
   1.494 +	if (fseek(s->file, s->pos_in_central_dir+s->byte_before_the_zipfile, SEEK_SET) != 0)
   1.495 +		err = UNZ_ERRNO;
   1.496 +
   1.497 +	/* we check the magic */
   1.498 +	if (err == UNZ_OK)
   1.499 +		if (unzlocal_getLong(s->file, &uMagic) != UNZ_OK)
   1.500 +			err = UNZ_ERRNO;
   1.501 +		else if (uMagic != 0x02014b50)
   1.502 +			err = UNZ_BADZIPFILE;
   1.503 +
   1.504 +	if (unzlocal_getShort(s->file, &file_info.version) != UNZ_OK)
   1.505 +		err = UNZ_ERRNO;
   1.506 +
   1.507 +	if (unzlocal_getShort(s->file, &file_info.version_needed) != UNZ_OK)
   1.508 +		err = UNZ_ERRNO;
   1.509 +
   1.510 +	if (unzlocal_getShort(s->file, &file_info.flag) != UNZ_OK)
   1.511 +		err = UNZ_ERRNO;
   1.512 +
   1.513 +	if (unzlocal_getShort(s->file, &file_info.compression_method) != UNZ_OK)
   1.514 +		err = UNZ_ERRNO;
   1.515 +
   1.516 +	if (unzlocal_getLong(s->file, &file_info.dosDate) != UNZ_OK)
   1.517 +		err = UNZ_ERRNO;
   1.518 +
   1.519 +	unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date);
   1.520 +
   1.521 +	if (unzlocal_getLong(s->file, &file_info.crc) != UNZ_OK)
   1.522 +		err = UNZ_ERRNO;
   1.523 +
   1.524 +	if (unzlocal_getLong(s->file, &file_info.compressed_size) != UNZ_OK)
   1.525 +		err = UNZ_ERRNO;
   1.526 +
   1.527 +	if (unzlocal_getLong(s->file, &file_info.uncompressed_size) != UNZ_OK)
   1.528 +		err = UNZ_ERRNO;
   1.529 +
   1.530 +	if (unzlocal_getShort(s->file, &file_info.size_filename) != UNZ_OK)
   1.531 +		err = UNZ_ERRNO;
   1.532 +
   1.533 +	if (unzlocal_getShort(s->file, &file_info.size_file_extra) != UNZ_OK)
   1.534 +		err = UNZ_ERRNO;
   1.535 +
   1.536 +	if (unzlocal_getShort(s->file, &file_info.size_file_comment) != UNZ_OK)
   1.537 +		err = UNZ_ERRNO;
   1.538 +
   1.539 +	if (unzlocal_getShort(s->file, &file_info.disk_num_start) != UNZ_OK)
   1.540 +		err = UNZ_ERRNO;
   1.541 +
   1.542 +	if (unzlocal_getShort(s->file, &file_info.internal_fa) != UNZ_OK)
   1.543 +		err = UNZ_ERRNO;
   1.544 +
   1.545 +	if (unzlocal_getLong(s->file, &file_info.external_fa) != UNZ_OK)
   1.546 +		err = UNZ_ERRNO;
   1.547 +
   1.548 +	if (unzlocal_getLong(s->file, &file_info_internal.offset_curfile) != UNZ_OK)
   1.549 +		err = UNZ_ERRNO;
   1.550 +
   1.551 +	lSeek += file_info.size_filename;
   1.552 +	if ((err == UNZ_OK) && (szFileName != NULL))
   1.553 +	{
   1.554 +		uLong uSizeRead ;
   1.555 +		if (file_info.size_filename < fileNameBufferSize)
   1.556 +		{
   1.557 +			*(szFileName+file_info.size_filename) = '\0';
   1.558 +			uSizeRead = file_info.size_filename;
   1.559 +		}
   1.560 +		else
   1.561 +			uSizeRead = fileNameBufferSize;
   1.562 +
   1.563 +		if ((file_info.size_filename > 0) && (fileNameBufferSize > 0))
   1.564 +			if (fread(szFileName, (uInt)uSizeRead, 1, s->file) != 1)
   1.565 +				err = UNZ_ERRNO;
   1.566 +		lSeek -= uSizeRead;
   1.567 +	}
   1.568 +
   1.569 +	if ((err == UNZ_OK) && (extraField != NULL))
   1.570 +	{
   1.571 +		uLong uSizeRead ;
   1.572 +		if (file_info.size_file_extra < extraFieldBufferSize)
   1.573 +			uSizeRead = file_info.size_file_extra;
   1.574 +		else
   1.575 +			uSizeRead = extraFieldBufferSize;
   1.576 +
   1.577 +		if (lSeek != 0)
   1.578 +			if (fseek(s->file, lSeek, SEEK_CUR) == 0)
   1.579 +				lSeek = 0;
   1.580 +			else
   1.581 +				err = UNZ_ERRNO;
   1.582 +		if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0))
   1.583 +			if (fread(extraField, (uInt)uSizeRead, 1, s->file) != 1)
   1.584 +				err = UNZ_ERRNO;
   1.585 +		lSeek += file_info.size_file_extra - uSizeRead;
   1.586 +	}
   1.587 +	else
   1.588 +		lSeek += file_info.size_file_extra;
   1.589 +
   1.590 +	if ((err == UNZ_OK) && (szComment != NULL))
   1.591 +	{
   1.592 +		uLong uSizeRead ;
   1.593 +		if (file_info.size_file_comment < commentBufferSize)
   1.594 +		{
   1.595 +			*(szComment+file_info.size_file_comment) = '\0';
   1.596 +			uSizeRead = file_info.size_file_comment;
   1.597 +		}
   1.598 +		else
   1.599 +			uSizeRead = commentBufferSize;
   1.600 +
   1.601 +		if (lSeek != 0)
   1.602 +			if (fseek(s->file, lSeek, SEEK_CUR) == 0)
   1.603 +				lSeek = 0;
   1.604 +			else
   1.605 +				err = UNZ_ERRNO;
   1.606 +		if ((file_info.size_file_comment > 0) && (commentBufferSize > 0))
   1.607 +			if (fread(szComment, (uInt)uSizeRead, 1, s->file) != 1)
   1.608 +				err = UNZ_ERRNO;
   1.609 +		lSeek += file_info.size_file_comment - uSizeRead;
   1.610 +	}
   1.611 +	else
   1.612 +		lSeek += file_info.size_file_comment;
   1.613 +
   1.614 +	if ((err == UNZ_OK) && (pfile_info != NULL))
   1.615 +		*pfile_info = file_info;
   1.616 +
   1.617 +	if ((err == UNZ_OK) && (pfile_info_internal != NULL))
   1.618 +		*pfile_info_internal = file_info_internal;
   1.619 +
   1.620 +	return err;
   1.621 +}
   1.622 +
   1.623 +/*
   1.624 +   Write info about the ZipFile in the *pglobal_info structure.
   1.625 +   No preparation of the structure is needed
   1.626 +   return UNZ_OK if there is no problem.
   1.627 + */
   1.628 +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
   1.629 +                                         unz_file_info *pfile_info,
   1.630 +                                         char *szFileName,
   1.631 +                                         uLong fileNameBufferSize,
   1.632 +                                         void *extraField,
   1.633 +                                         uLong extraFieldBufferSize,
   1.634 +                                         char *szComment,
   1.635 +                                         uLong commentBufferSize)
   1.636 +{
   1.637 +	return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL,
   1.638 +	                                           szFileName, fileNameBufferSize,
   1.639 +	                                           extraField, extraFieldBufferSize,
   1.640 +	                                           szComment, commentBufferSize);
   1.641 +}
   1.642 +
   1.643 +/*
   1.644 +   Set the current file of the zipfile to the first file.
   1.645 +   return UNZ_OK if there is no problem
   1.646 + */
   1.647 +extern int ZEXPORT unzGoToFirstFile(unzFile file)
   1.648 +{
   1.649 +	int   err = UNZ_OK;
   1.650 +	unz_s*s;
   1.651 +	if (file == NULL)
   1.652 +		return UNZ_PARAMERROR;
   1.653 +	s = (unz_s *)file;
   1.654 +	s->pos_in_central_dir = s->offset_central_dir;
   1.655 +	s->num_file = 0;
   1.656 +	err         = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info,
   1.657 +	                                                  &s->cur_file_info_internal,
   1.658 +	                                                  NULL, 0, NULL, 0, NULL, 0);
   1.659 +	s->current_file_ok = (err == UNZ_OK);
   1.660 +	return err;
   1.661 +}
   1.662 +
   1.663 +/*
   1.664 +   Set the current file of the zipfile to the next file.
   1.665 +   return UNZ_OK if there is no problem
   1.666 +   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
   1.667 + */
   1.668 +extern int ZEXPORT unzGoToNextFile(unzFile file)
   1.669 +{
   1.670 +	unz_s*s;
   1.671 +	int   err;
   1.672 +
   1.673 +	if (file == NULL)
   1.674 +		return UNZ_PARAMERROR;
   1.675 +	s = (unz_s *)file;
   1.676 +	if (!s->current_file_ok)
   1.677 +		return UNZ_END_OF_LIST_OF_FILE;
   1.678 +	if (s->num_file+1 == s->gi.number_entry)
   1.679 +		return UNZ_END_OF_LIST_OF_FILE;
   1.680 +
   1.681 +	s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
   1.682 +	                         s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
   1.683 +	s->num_file++;
   1.684 +	err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info,
   1.685 +	                                          &s->cur_file_info_internal,
   1.686 +	                                          NULL, 0, NULL, 0, NULL, 0);
   1.687 +	s->current_file_ok = (err == UNZ_OK);
   1.688 +	return err;
   1.689 +}
   1.690 +
   1.691 +/*
   1.692 +   Try locate the file szFileName in the zipfile.
   1.693 +   For the iCaseSensitivity signification, see unzipStringFileNameCompare
   1.694 +
   1.695 +   return value :
   1.696 +   UNZ_OK if the file is found. It becomes the current file.
   1.697 +   UNZ_END_OF_LIST_OF_FILE if the file is not found
   1.698 + */
   1.699 +extern int ZEXPORT unzLocateFile(unzFile file,
   1.700 +                                 const char *szFileName,
   1.701 +                                 int iCaseSensitivity)
   1.702 +{
   1.703 +	unz_s*s;
   1.704 +	int   err;
   1.705 +
   1.706 +	uLong num_fileSaved;
   1.707 +	uLong pos_in_central_dirSaved;
   1.708 +
   1.709 +	if (file == NULL)
   1.710 +		return UNZ_PARAMERROR;
   1.711 +
   1.712 +	if (strlen(szFileName) >= UNZ_MAXFILENAMEINZIP)
   1.713 +		return UNZ_PARAMERROR;
   1.714 +
   1.715 +	s = (unz_s *)file;
   1.716 +	if (!s->current_file_ok)
   1.717 +		return UNZ_END_OF_LIST_OF_FILE;
   1.718 +
   1.719 +	num_fileSaved = s->num_file;
   1.720 +	pos_in_central_dirSaved = s->pos_in_central_dir;
   1.721 +
   1.722 +	err = unzGoToFirstFile(file);
   1.723 +
   1.724 +	while (err == UNZ_OK)
   1.725 +	{
   1.726 +		char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
   1.727 +		unzGetCurrentFileInfo(file, NULL,
   1.728 +		                      szCurrentFileName, sizeof(szCurrentFileName)-1,
   1.729 +		                      NULL, 0, NULL, 0);
   1.730 +		if (unzStringFileNameCompare(szCurrentFileName,
   1.731 +		                             szFileName, iCaseSensitivity) == 0)
   1.732 +			return UNZ_OK;
   1.733 +		err = unzGoToNextFile(file);
   1.734 +	}
   1.735 +
   1.736 +	s->num_file = num_fileSaved ;
   1.737 +	s->pos_in_central_dir = pos_in_central_dirSaved ;
   1.738 +	return err;
   1.739 +}
   1.740 +
   1.741 +/*
   1.742 +   Read the local header of the current zipfile
   1.743 +   Check the coherency of the local header and info in the end of central
   1.744 +        directory about this file
   1.745 +   store in *piSizeVar the size of extra info in local header
   1.746 +        (filename and size of extra field data)
   1.747 + */
   1.748 +local int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s,
   1.749 +                                                   uInt *piSizeVar,
   1.750 +                                                   uLong *poffset_local_extrafield,
   1.751 +                                                   uInt *psize_local_extrafield)
   1.752 +{
   1.753 +	uLong uMagic, uData, uFlags;
   1.754 +	uLong size_filename;
   1.755 +	uLong size_extra_field;
   1.756 +	int   err = UNZ_OK;
   1.757 +
   1.758 +	*piSizeVar = 0;
   1.759 +	*poffset_local_extrafield = 0;
   1.760 +	*psize_local_extrafield   = 0;
   1.761 +
   1.762 +	if (fseek(s->file, s->cur_file_info_internal.offset_curfile +
   1.763 +	          s->byte_before_the_zipfile, SEEK_SET) != 0)
   1.764 +		return UNZ_ERRNO;
   1.765 +
   1.766 +	if (err == UNZ_OK)
   1.767 +		if (unzlocal_getLong(s->file, &uMagic) != UNZ_OK)
   1.768 +			err = UNZ_ERRNO;
   1.769 +		else if (uMagic != 0x04034b50)
   1.770 +			err = UNZ_BADZIPFILE;
   1.771 +
   1.772 +	if (unzlocal_getShort(s->file, &uData) != UNZ_OK)
   1.773 +		err = UNZ_ERRNO;
   1.774 +/*
   1.775 +        else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
   1.776 +                err=UNZ_BADZIPFILE;
   1.777 + */
   1.778 +	if (unzlocal_getShort(s->file, &uFlags) != UNZ_OK)
   1.779 +		err = UNZ_ERRNO;
   1.780 +
   1.781 +	if (unzlocal_getShort(s->file, &uData) != UNZ_OK)
   1.782 +		err = UNZ_ERRNO;
   1.783 +	else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method))
   1.784 +		err = UNZ_BADZIPFILE;
   1.785 +
   1.786 +	if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) &&
   1.787 +	    (s->cur_file_info.compression_method != Z_DEFLATED))
   1.788 +		err = UNZ_BADZIPFILE;
   1.789 +
   1.790 +	if (unzlocal_getLong(s->file, &uData) != UNZ_OK)    /* date/time */
   1.791 +		err = UNZ_ERRNO;
   1.792 +
   1.793 +	if (unzlocal_getLong(s->file, &uData) != UNZ_OK)    /* crc */
   1.794 +		err = UNZ_ERRNO;
   1.795 +	else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) &&
   1.796 +	         ((uFlags & 8) == 0))
   1.797 +		err = UNZ_BADZIPFILE;
   1.798 +
   1.799 +	if (unzlocal_getLong(s->file, &uData) != UNZ_OK)    /* size compr */
   1.800 +		err = UNZ_ERRNO;
   1.801 +	else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) &&
   1.802 +	         ((uFlags & 8) == 0))
   1.803 +		err = UNZ_BADZIPFILE;
   1.804 +
   1.805 +	if (unzlocal_getLong(s->file, &uData) != UNZ_OK)    /* size uncompr */
   1.806 +		err = UNZ_ERRNO;
   1.807 +	else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) &&
   1.808 +	         ((uFlags & 8) == 0))
   1.809 +		err = UNZ_BADZIPFILE;
   1.810 +
   1.811 +	if (unzlocal_getShort(s->file, &size_filename) != UNZ_OK)
   1.812 +		err = UNZ_ERRNO;
   1.813 +	else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename))
   1.814 +		err = UNZ_BADZIPFILE;
   1.815 +
   1.816 +	*piSizeVar += (uInt)size_filename;
   1.817 +
   1.818 +	if (unzlocal_getShort(s->file, &size_extra_field) != UNZ_OK)
   1.819 +		err = UNZ_ERRNO;
   1.820 +	*poffset_local_extrafield = s->cur_file_info_internal.offset_curfile +
   1.821 +	                            SIZEZIPLOCALHEADER + size_filename;
   1.822 +	*psize_local_extrafield = (uInt)size_extra_field;
   1.823 +
   1.824 +	*piSizeVar += (uInt)size_extra_field;
   1.825 +
   1.826 +	return err;
   1.827 +}
   1.828 +
   1.829 +/*
   1.830 +   Open for reading data the current file in the zipfile.
   1.831 +   If there is no error and the file is opened, the return value is UNZ_OK.
   1.832 + */
   1.833 +extern int ZEXPORT unzOpenCurrentFile(unzFile file)
   1.834 +{
   1.835 +	int   err = UNZ_OK;
   1.836 +	int   Store;
   1.837 +	uInt  iSizeVar;
   1.838 +	unz_s*s;
   1.839 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
   1.840 +	uLong offset_local_extrafield;      /* offset of the local extra field */
   1.841 +	uInt  size_local_extrafield;        /* size of the local extra field */
   1.842 +
   1.843 +	if (file == NULL)
   1.844 +		return UNZ_PARAMERROR;
   1.845 +	s = (unz_s *)file;
   1.846 +	if (!s->current_file_ok)
   1.847 +		return UNZ_PARAMERROR;
   1.848 +
   1.849 +	if (s->pfile_in_zip_read != NULL)
   1.850 +		unzCloseCurrentFile(file);
   1.851 +
   1.852 +	if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar,
   1.853 +	                                             &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
   1.854 +		return UNZ_BADZIPFILE;
   1.855 +
   1.856 +	pfile_in_zip_read_info = (file_in_zip_read_info_s *)
   1.857 +	                         ALLOC(sizeof(file_in_zip_read_info_s));
   1.858 +	if (pfile_in_zip_read_info == NULL)
   1.859 +		return UNZ_INTERNALERROR;
   1.860 +
   1.861 +	pfile_in_zip_read_info->read_buffer = (char *)ALLOC(UNZ_BUFSIZE);
   1.862 +	pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
   1.863 +	pfile_in_zip_read_info->size_local_extrafield   = size_local_extrafield;
   1.864 +	pfile_in_zip_read_info->pos_local_extrafield    = 0;
   1.865 +
   1.866 +	if (pfile_in_zip_read_info->read_buffer == NULL)
   1.867 +	{
   1.868 +		TRYFREE(pfile_in_zip_read_info);
   1.869 +		return UNZ_INTERNALERROR;
   1.870 +	}
   1.871 +
   1.872 +	pfile_in_zip_read_info->stream_initialised = 0;
   1.873 +
   1.874 +	if ((s->cur_file_info.compression_method != 0) &&
   1.875 +	    (s->cur_file_info.compression_method != Z_DEFLATED))
   1.876 +		err = UNZ_BADZIPFILE;
   1.877 +	Store = s->cur_file_info.compression_method == 0;
   1.878 +
   1.879 +	pfile_in_zip_read_info->crc32_wait         = s->cur_file_info.crc;
   1.880 +	pfile_in_zip_read_info->crc32              = 0;
   1.881 +	pfile_in_zip_read_info->compression_method =
   1.882 +	    s->cur_file_info.compression_method;
   1.883 +	pfile_in_zip_read_info->file = s->file;
   1.884 +	pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;
   1.885 +
   1.886 +	pfile_in_zip_read_info->stream.total_out = 0;
   1.887 +
   1.888 +	if (!Store)
   1.889 +	{
   1.890 +		pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
   1.891 +		pfile_in_zip_read_info->stream.zfree  = (free_func)0;
   1.892 +		pfile_in_zip_read_info->stream.opaque = (voidpf)0;
   1.893 +
   1.894 +		err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
   1.895 +		if (err == Z_OK)
   1.896 +			pfile_in_zip_read_info->stream_initialised = 1;
   1.897 +		/* windowBits is passed < 0 to tell that there is no zlib header.
   1.898 +		 * Note that in this case inflate *requires* an extra "dummy" byte
   1.899 +		 * after the compressed stream in order to complete decompression and
   1.900 +		 * return Z_STREAM_END.
   1.901 +		 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
   1.902 +		 * size of both compressed and uncompressed data
   1.903 +		 */
   1.904 +	}
   1.905 +	pfile_in_zip_read_info->rest_read_compressed =
   1.906 +	    s->cur_file_info.compressed_size ;
   1.907 +	pfile_in_zip_read_info->rest_read_uncompressed =
   1.908 +	    s->cur_file_info.uncompressed_size ;
   1.909 +
   1.910 +	pfile_in_zip_read_info->pos_in_zipfile =
   1.911 +	    s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
   1.912 +	    iSizeVar;
   1.913 +
   1.914 +	pfile_in_zip_read_info->stream.avail_in = (uInt)0;
   1.915 +
   1.916 +	s->pfile_in_zip_read = pfile_in_zip_read_info;
   1.917 +	return UNZ_OK;
   1.918 +}
   1.919 +
   1.920 +/*
   1.921 +   Read bytes from the current file.
   1.922 +   buf contain buffer where data must be copied
   1.923 +   len the size of buf.
   1.924 +
   1.925 +   return the number of byte copied if somes bytes are copied
   1.926 +   return 0 if the end of file was reached
   1.927 +   return <0 with error code if there is an error
   1.928 +    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
   1.929 + */
   1.930 +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len)
   1.931 +{
   1.932 +	int   err   = UNZ_OK;
   1.933 +	uInt  iRead = 0;
   1.934 +	unz_s*s;
   1.935 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
   1.936 +	if (file == NULL)
   1.937 +		return UNZ_PARAMERROR;
   1.938 +	s = (unz_s *)file;
   1.939 +	pfile_in_zip_read_info = s->pfile_in_zip_read;
   1.940 +
   1.941 +	if (pfile_in_zip_read_info == NULL)
   1.942 +		return UNZ_PARAMERROR;
   1.943 +
   1.944 +	if ((pfile_in_zip_read_info->read_buffer == NULL))
   1.945 +		return UNZ_END_OF_LIST_OF_FILE;
   1.946 +	if (len == 0)
   1.947 +		return 0;
   1.948 +
   1.949 +	pfile_in_zip_read_info->stream.next_out = (Bytef *)buf;
   1.950 +
   1.951 +	pfile_in_zip_read_info->stream.avail_out = (uInt)len;
   1.952 +
   1.953 +	if (len > pfile_in_zip_read_info->rest_read_uncompressed)
   1.954 +		pfile_in_zip_read_info->stream.avail_out =
   1.955 +		    (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
   1.956 +
   1.957 +	while (pfile_in_zip_read_info->stream.avail_out > 0)
   1.958 +	{
   1.959 +		if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
   1.960 +		    (pfile_in_zip_read_info->rest_read_compressed > 0))
   1.961 +		{
   1.962 +			uInt uReadThis = UNZ_BUFSIZE;
   1.963 +			if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
   1.964 +				uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
   1.965 +			if (uReadThis == 0)
   1.966 +				return UNZ_EOF;
   1.967 +			if (fseek(pfile_in_zip_read_info->file,
   1.968 +			          pfile_in_zip_read_info->pos_in_zipfile +
   1.969 +			          pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0)
   1.970 +				return UNZ_ERRNO;
   1.971 +			if (fread(pfile_in_zip_read_info->read_buffer, uReadThis, 1,
   1.972 +			          pfile_in_zip_read_info->file) != 1)
   1.973 +				return UNZ_ERRNO;
   1.974 +			pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
   1.975 +
   1.976 +			pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
   1.977 +
   1.978 +			pfile_in_zip_read_info->stream.next_in =
   1.979 +			    (Bytef *)pfile_in_zip_read_info->read_buffer;
   1.980 +			pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
   1.981 +		}
   1.982 +
   1.983 +		if (pfile_in_zip_read_info->compression_method == 0)
   1.984 +		{
   1.985 +			uInt uDoCopy, i ;
   1.986 +			if (pfile_in_zip_read_info->stream.avail_out <
   1.987 +			    pfile_in_zip_read_info->stream.avail_in)
   1.988 +				uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
   1.989 +			else
   1.990 +				uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
   1.991 +
   1.992 +			for (i = 0; i < uDoCopy; i++)
   1.993 +				*(pfile_in_zip_read_info->stream.next_out+i) =
   1.994 +				    *(pfile_in_zip_read_info->stream.next_in+i);
   1.995 +
   1.996 +			pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
   1.997 +			                                      pfile_in_zip_read_info->stream.next_out,
   1.998 +			                                      uDoCopy);
   1.999 +			pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
  1.1000 +			pfile_in_zip_read_info->stream.avail_in        -= uDoCopy;
  1.1001 +			pfile_in_zip_read_info->stream.avail_out       -= uDoCopy;
  1.1002 +			pfile_in_zip_read_info->stream.next_out        += uDoCopy;
  1.1003 +			pfile_in_zip_read_info->stream.next_in         += uDoCopy;
  1.1004 +			pfile_in_zip_read_info->stream.total_out       += uDoCopy;
  1.1005 +			iRead += uDoCopy;
  1.1006 +		}
  1.1007 +		else
  1.1008 +		{
  1.1009 +			uLong        uTotalOutBefore, uTotalOutAfter;
  1.1010 +			const Bytef *bufBefore;
  1.1011 +			uLong        uOutThis;
  1.1012 +			int flush = Z_SYNC_FLUSH;
  1.1013 +
  1.1014 +			uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
  1.1015 +			bufBefore       = pfile_in_zip_read_info->stream.next_out;
  1.1016 +
  1.1017 +			/*
  1.1018 +			   if ((pfile_in_zip_read_info->rest_read_uncompressed ==
  1.1019 +			         pfile_in_zip_read_info->stream.avail_out) &&
  1.1020 +			        (pfile_in_zip_read_info->rest_read_compressed == 0))
  1.1021 +			        flush = Z_FINISH;
  1.1022 +			 */
  1.1023 +			err = inflate(&pfile_in_zip_read_info->stream, flush);
  1.1024 +
  1.1025 +			uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
  1.1026 +			uOutThis       = uTotalOutAfter-uTotalOutBefore;
  1.1027 +
  1.1028 +			pfile_in_zip_read_info->crc32 =
  1.1029 +			    crc32(pfile_in_zip_read_info->crc32, bufBefore,
  1.1030 +			          (uInt)(uOutThis));
  1.1031 +
  1.1032 +			pfile_in_zip_read_info->rest_read_uncompressed -=
  1.1033 +			    uOutThis;
  1.1034 +
  1.1035 +			iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
  1.1036 +
  1.1037 +			if (err == Z_STREAM_END)
  1.1038 +				return (iRead == 0) ? UNZ_EOF : iRead;
  1.1039 +			if (err != Z_OK)
  1.1040 +				break;
  1.1041 +		}
  1.1042 +	}
  1.1043 +
  1.1044 +	if (err == Z_OK)
  1.1045 +		return iRead;
  1.1046 +	return err;
  1.1047 +}
  1.1048 +
  1.1049 +/*
  1.1050 +   Give the current position in uncompressed data
  1.1051 + */
  1.1052 +extern z_off_t ZEXPORT unztell(unzFile file)
  1.1053 +{
  1.1054 +	unz_s*s;
  1.1055 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
  1.1056 +	if (file == NULL)
  1.1057 +		return UNZ_PARAMERROR;
  1.1058 +	s = (unz_s *)file;
  1.1059 +	pfile_in_zip_read_info = s->pfile_in_zip_read;
  1.1060 +
  1.1061 +	if (pfile_in_zip_read_info == NULL)
  1.1062 +		return UNZ_PARAMERROR;
  1.1063 +
  1.1064 +	return (z_off_t)pfile_in_zip_read_info->stream.total_out;
  1.1065 +}
  1.1066 +
  1.1067 +/*
  1.1068 +   return 1 if the end of file was reached, 0 elsewhere
  1.1069 + */
  1.1070 +extern int ZEXPORT unzeof(unzFile file)
  1.1071 +{
  1.1072 +	unz_s*s;
  1.1073 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
  1.1074 +	if (file == NULL)
  1.1075 +		return UNZ_PARAMERROR;
  1.1076 +	s = (unz_s *)file;
  1.1077 +	pfile_in_zip_read_info = s->pfile_in_zip_read;
  1.1078 +
  1.1079 +	if (pfile_in_zip_read_info == NULL)
  1.1080 +		return UNZ_PARAMERROR;
  1.1081 +
  1.1082 +	if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
  1.1083 +		return 1;
  1.1084 +	else
  1.1085 +		return 0;
  1.1086 +}
  1.1087 +
  1.1088 +/*
  1.1089 +   Read extra field from the current file (opened by unzOpenCurrentFile)
  1.1090 +   This is the local-header version of the extra field (sometimes, there is
  1.1091 +    more info in the local-header version than in the central-header)
  1.1092 +
  1.1093 +   if buf==NULL, it return the size of the local extra field that can be read
  1.1094 +
  1.1095 +   if buf!=NULL, len is the size of the buffer, the extra header is copied in
  1.1096 +        buf.
  1.1097 +   the return value is the number of bytes copied in buf, or (if <0)
  1.1098 +        the error code
  1.1099 + */
  1.1100 +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len)
  1.1101 +{
  1.1102 +	unz_s*s;
  1.1103 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
  1.1104 +	uInt  read_now;
  1.1105 +	uLong size_to_read;
  1.1106 +
  1.1107 +	if (file == NULL)
  1.1108 +		return UNZ_PARAMERROR;
  1.1109 +	s = (unz_s *)file;
  1.1110 +	pfile_in_zip_read_info = s->pfile_in_zip_read;
  1.1111 +
  1.1112 +	if (pfile_in_zip_read_info == NULL)
  1.1113 +		return UNZ_PARAMERROR;
  1.1114 +
  1.1115 +	size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
  1.1116 +	                pfile_in_zip_read_info->pos_local_extrafield);
  1.1117 +
  1.1118 +	if (buf == NULL)
  1.1119 +		return (int)size_to_read;
  1.1120 +
  1.1121 +	if (len > size_to_read)
  1.1122 +		read_now = (uInt)size_to_read;
  1.1123 +	else
  1.1124 +		read_now = (uInt)len ;
  1.1125 +
  1.1126 +	if (read_now == 0)
  1.1127 +		return 0;
  1.1128 +
  1.1129 +	if (fseek(pfile_in_zip_read_info->file,
  1.1130 +	          pfile_in_zip_read_info->offset_local_extrafield +
  1.1131 +	          pfile_in_zip_read_info->pos_local_extrafield, SEEK_SET) != 0)
  1.1132 +		return UNZ_ERRNO;
  1.1133 +
  1.1134 +	if (fread(buf, (uInt)size_to_read, 1, pfile_in_zip_read_info->file) != 1)
  1.1135 +		return UNZ_ERRNO;
  1.1136 +
  1.1137 +	return (int)read_now;
  1.1138 +}
  1.1139 +
  1.1140 +/*
  1.1141 +   Close the file in zip opened with unzipOpenCurrentFile
  1.1142 +   Return UNZ_CRCERROR if all the file was read but the CRC is not good
  1.1143 + */
  1.1144 +extern int ZEXPORT unzCloseCurrentFile(unzFile file)
  1.1145 +{
  1.1146 +	int err = UNZ_OK;
  1.1147 +
  1.1148 +	unz_s*s;
  1.1149 +	file_in_zip_read_info_s*pfile_in_zip_read_info;
  1.1150 +	if (file == NULL)
  1.1151 +		return UNZ_PARAMERROR;
  1.1152 +	s = (unz_s *)file;
  1.1153 +	pfile_in_zip_read_info = s->pfile_in_zip_read;
  1.1154 +
  1.1155 +	if (pfile_in_zip_read_info == NULL)
  1.1156 +		return UNZ_PARAMERROR;
  1.1157 +
  1.1158 +	if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
  1.1159 +	{
  1.1160 +		if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
  1.1161 +			err = UNZ_CRCERROR;
  1.1162 +	}
  1.1163 +
  1.1164 +	TRYFREE(pfile_in_zip_read_info->read_buffer);
  1.1165 +	pfile_in_zip_read_info->read_buffer = NULL;
  1.1166 +	if (pfile_in_zip_read_info->stream_initialised)
  1.1167 +		inflateEnd(&pfile_in_zip_read_info->stream);
  1.1168 +
  1.1169 +	pfile_in_zip_read_info->stream_initialised = 0;
  1.1170 +	TRYFREE(pfile_in_zip_read_info);
  1.1171 +
  1.1172 +	s->pfile_in_zip_read = NULL;
  1.1173 +
  1.1174 +	return err;
  1.1175 +}
  1.1176 +
  1.1177 +/*
  1.1178 +   Get the global comment string of the ZipFile, in the szComment buffer.
  1.1179 +   uSizeBuf is the size of the szComment buffer.
  1.1180 +   return the number of byte copied or an error code <0
  1.1181 + */
  1.1182 +extern int ZEXPORT unzGetGlobalComment(unzFile file,
  1.1183 +                                       char *szComment,
  1.1184 +                                       uLong uSizeBuf)
  1.1185 +{
  1.1186 +	//int err=UNZ_OK;
  1.1187 +	unz_s*s;
  1.1188 +	uLong uReadThis ;
  1.1189 +	if (file == NULL)
  1.1190 +		return UNZ_PARAMERROR;
  1.1191 +	s = (unz_s *)file;
  1.1192 +
  1.1193 +	uReadThis = uSizeBuf;
  1.1194 +	if (uReadThis > s->gi.size_comment)
  1.1195 +		uReadThis = s->gi.size_comment;
  1.1196 +
  1.1197 +	if (fseek(s->file, s->central_pos+22, SEEK_SET) != 0)
  1.1198 +		return UNZ_ERRNO;
  1.1199 +
  1.1200 +	if (uReadThis > 0)
  1.1201 +	{
  1.1202 +		*szComment = '\0';
  1.1203 +		if (fread(szComment, (uInt)uReadThis, 1, s->file) != 1)
  1.1204 +			return UNZ_ERRNO;
  1.1205 +	}
  1.1206 +
  1.1207 +	if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
  1.1208 +		*(szComment+s->gi.size_comment) = '\0';
  1.1209 +	return (int)uReadThis;
  1.1210 +}
  1.1211 +