annotate src/zlib-1.2.7/contrib/minizip/unzip.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents e13257ea84a4
children
rev   line source
Chris@4 1 /* unzip.c -- IO for uncompress .zip files using zlib
Chris@4 2 Version 1.1, February 14h, 2010
Chris@4 3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Chris@4 4
Chris@4 5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Chris@4 6
Chris@4 7 Modifications of Unzip for Zip64
Chris@4 8 Copyright (C) 2007-2008 Even Rouault
Chris@4 9
Chris@4 10 Modifications for Zip64 support on both zip and unzip
Chris@4 11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
Chris@4 12
Chris@4 13 For more info read MiniZip_info.txt
Chris@4 14
Chris@4 15
Chris@4 16 ------------------------------------------------------------------------------------
Chris@4 17 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
Chris@4 18 compatibility with older software. The following is from the original crypt.c.
Chris@4 19 Code woven in by Terry Thorsen 1/2003.
Chris@4 20
Chris@4 21 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
Chris@4 22
Chris@4 23 See the accompanying file LICENSE, version 2000-Apr-09 or later
Chris@4 24 (the contents of which are also included in zip.h) for terms of use.
Chris@4 25 If, for some reason, all these files are missing, the Info-ZIP license
Chris@4 26 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
Chris@4 27
Chris@4 28 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
Chris@4 29
Chris@4 30 The encryption/decryption parts of this source code (as opposed to the
Chris@4 31 non-echoing password parts) were originally written in Europe. The
Chris@4 32 whole source package can be freely distributed, including from the USA.
Chris@4 33 (Prior to January 2000, re-export from the US was a violation of US law.)
Chris@4 34
Chris@4 35 This encryption code is a direct transcription of the algorithm from
Chris@4 36 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
Chris@4 37 file (appnote.txt) is distributed with the PKZIP program (even in the
Chris@4 38 version without encryption capabilities).
Chris@4 39
Chris@4 40 ------------------------------------------------------------------------------------
Chris@4 41
Chris@4 42 Changes in unzip.c
Chris@4 43
Chris@4 44 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
Chris@4 45 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
Chris@4 46 2007-2008 - Even Rouault - Remove old C style function prototypes
Chris@4 47 2007-2008 - Even Rouault - Add unzip support for ZIP64
Chris@4 48
Chris@4 49 Copyright (C) 2007-2008 Even Rouault
Chris@4 50
Chris@4 51
Chris@4 52 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
Chris@4 53 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
Chris@4 54 should only read the compressed/uncompressed size from the Zip64 format if
Chris@4 55 the size from normal header was 0xFFFFFFFF
Chris@4 56 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
Chris@4 57 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
Chris@4 58 Patch created by Daniel Borca
Chris@4 59
Chris@4 60 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
Chris@4 61
Chris@4 62 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
Chris@4 63
Chris@4 64 */
Chris@4 65
Chris@4 66
Chris@4 67 #include <stdio.h>
Chris@4 68 #include <stdlib.h>
Chris@4 69 #include <string.h>
Chris@4 70
Chris@4 71 #ifndef NOUNCRYPT
Chris@4 72 #define NOUNCRYPT
Chris@4 73 #endif
Chris@4 74
Chris@4 75 #include "zlib.h"
Chris@4 76 #include "unzip.h"
Chris@4 77
Chris@4 78 #ifdef STDC
Chris@4 79 # include <stddef.h>
Chris@4 80 # include <string.h>
Chris@4 81 # include <stdlib.h>
Chris@4 82 #endif
Chris@4 83 #ifdef NO_ERRNO_H
Chris@4 84 extern int errno;
Chris@4 85 #else
Chris@4 86 # include <errno.h>
Chris@4 87 #endif
Chris@4 88
Chris@4 89
Chris@4 90 #ifndef local
Chris@4 91 # define local static
Chris@4 92 #endif
Chris@4 93 /* compile with -Dlocal if your debugger can't find static symbols */
Chris@4 94
Chris@4 95
Chris@4 96 #ifndef CASESENSITIVITYDEFAULT_NO
Chris@4 97 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
Chris@4 98 # define CASESENSITIVITYDEFAULT_NO
Chris@4 99 # endif
Chris@4 100 #endif
Chris@4 101
Chris@4 102
Chris@4 103 #ifndef UNZ_BUFSIZE
Chris@4 104 #define UNZ_BUFSIZE (16384)
Chris@4 105 #endif
Chris@4 106
Chris@4 107 #ifndef UNZ_MAXFILENAMEINZIP
Chris@4 108 #define UNZ_MAXFILENAMEINZIP (256)
Chris@4 109 #endif
Chris@4 110
Chris@4 111 #ifndef ALLOC
Chris@4 112 # define ALLOC(size) (malloc(size))
Chris@4 113 #endif
Chris@4 114 #ifndef TRYFREE
Chris@4 115 # define TRYFREE(p) {if (p) free(p);}
Chris@4 116 #endif
Chris@4 117
Chris@4 118 #define SIZECENTRALDIRITEM (0x2e)
Chris@4 119 #define SIZEZIPLOCALHEADER (0x1e)
Chris@4 120
Chris@4 121
Chris@4 122 const char unz_copyright[] =
Chris@4 123 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
Chris@4 124
Chris@4 125 /* unz_file_info_interntal contain internal info about a file in zipfile*/
Chris@4 126 typedef struct unz_file_info64_internal_s
Chris@4 127 {
Chris@4 128 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
Chris@4 129 } unz_file_info64_internal;
Chris@4 130
Chris@4 131
Chris@4 132 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
Chris@4 133 when reading and decompress it */
Chris@4 134 typedef struct
Chris@4 135 {
Chris@4 136 char *read_buffer; /* internal buffer for compressed data */
Chris@4 137 z_stream stream; /* zLib stream structure for inflate */
Chris@4 138
Chris@4 139 #ifdef HAVE_BZIP2
Chris@4 140 bz_stream bstream; /* bzLib stream structure for bziped */
Chris@4 141 #endif
Chris@4 142
Chris@4 143 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
Chris@4 144 uLong stream_initialised; /* flag set if stream structure is initialised*/
Chris@4 145
Chris@4 146 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
Chris@4 147 uInt size_local_extrafield;/* size of the local extra field */
Chris@4 148 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
Chris@4 149 ZPOS64_T total_out_64;
Chris@4 150
Chris@4 151 uLong crc32; /* crc32 of all data uncompressed */
Chris@4 152 uLong crc32_wait; /* crc32 we must obtain after decompress all */
Chris@4 153 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
Chris@4 154 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
Chris@4 155 zlib_filefunc64_32_def z_filefunc;
Chris@4 156 voidpf filestream; /* io structore of the zipfile */
Chris@4 157 uLong compression_method; /* compression method (0==store) */
Chris@4 158 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
Chris@4 159 int raw;
Chris@4 160 } file_in_zip64_read_info_s;
Chris@4 161
Chris@4 162
Chris@4 163 /* unz64_s contain internal information about the zipfile
Chris@4 164 */
Chris@4 165 typedef struct
Chris@4 166 {
Chris@4 167 zlib_filefunc64_32_def z_filefunc;
Chris@4 168 int is64bitOpenFunction;
Chris@4 169 voidpf filestream; /* io structore of the zipfile */
Chris@4 170 unz_global_info64 gi; /* public global information */
Chris@4 171 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
Chris@4 172 ZPOS64_T num_file; /* number of the current file in the zipfile*/
Chris@4 173 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
Chris@4 174 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
Chris@4 175 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
Chris@4 176
Chris@4 177 ZPOS64_T size_central_dir; /* size of the central directory */
Chris@4 178 ZPOS64_T offset_central_dir; /* offset of start of central directory with
Chris@4 179 respect to the starting disk number */
Chris@4 180
Chris@4 181 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
Chris@4 182 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
Chris@4 183 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
Chris@4 184 file if we are decompressing it */
Chris@4 185 int encrypted;
Chris@4 186
Chris@4 187 int isZip64;
Chris@4 188
Chris@4 189 # ifndef NOUNCRYPT
Chris@4 190 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
Chris@4 191 const unsigned long* pcrc_32_tab;
Chris@4 192 # endif
Chris@4 193 } unz64_s;
Chris@4 194
Chris@4 195
Chris@4 196 #ifndef NOUNCRYPT
Chris@4 197 #include "crypt.h"
Chris@4 198 #endif
Chris@4 199
Chris@4 200 /* ===========================================================================
Chris@4 201 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
Chris@4 202 for end of file.
Chris@4 203 IN assertion: the stream s has been sucessfully opened for reading.
Chris@4 204 */
Chris@4 205
Chris@4 206
Chris@4 207 local int unz64local_getByte OF((
Chris@4 208 const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 209 voidpf filestream,
Chris@4 210 int *pi));
Chris@4 211
Chris@4 212 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
Chris@4 213 {
Chris@4 214 unsigned char c;
Chris@4 215 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
Chris@4 216 if (err==1)
Chris@4 217 {
Chris@4 218 *pi = (int)c;
Chris@4 219 return UNZ_OK;
Chris@4 220 }
Chris@4 221 else
Chris@4 222 {
Chris@4 223 if (ZERROR64(*pzlib_filefunc_def,filestream))
Chris@4 224 return UNZ_ERRNO;
Chris@4 225 else
Chris@4 226 return UNZ_EOF;
Chris@4 227 }
Chris@4 228 }
Chris@4 229
Chris@4 230
Chris@4 231 /* ===========================================================================
Chris@4 232 Reads a long in LSB order from the given gz_stream. Sets
Chris@4 233 */
Chris@4 234 local int unz64local_getShort OF((
Chris@4 235 const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 236 voidpf filestream,
Chris@4 237 uLong *pX));
Chris@4 238
Chris@4 239 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 240 voidpf filestream,
Chris@4 241 uLong *pX)
Chris@4 242 {
Chris@4 243 uLong x ;
Chris@4 244 int i = 0;
Chris@4 245 int err;
Chris@4 246
Chris@4 247 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 248 x = (uLong)i;
Chris@4 249
Chris@4 250 if (err==UNZ_OK)
Chris@4 251 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 252 x |= ((uLong)i)<<8;
Chris@4 253
Chris@4 254 if (err==UNZ_OK)
Chris@4 255 *pX = x;
Chris@4 256 else
Chris@4 257 *pX = 0;
Chris@4 258 return err;
Chris@4 259 }
Chris@4 260
Chris@4 261 local int unz64local_getLong OF((
Chris@4 262 const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 263 voidpf filestream,
Chris@4 264 uLong *pX));
Chris@4 265
Chris@4 266 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 267 voidpf filestream,
Chris@4 268 uLong *pX)
Chris@4 269 {
Chris@4 270 uLong x ;
Chris@4 271 int i = 0;
Chris@4 272 int err;
Chris@4 273
Chris@4 274 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 275 x = (uLong)i;
Chris@4 276
Chris@4 277 if (err==UNZ_OK)
Chris@4 278 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 279 x |= ((uLong)i)<<8;
Chris@4 280
Chris@4 281 if (err==UNZ_OK)
Chris@4 282 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 283 x |= ((uLong)i)<<16;
Chris@4 284
Chris@4 285 if (err==UNZ_OK)
Chris@4 286 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 287 x += ((uLong)i)<<24;
Chris@4 288
Chris@4 289 if (err==UNZ_OK)
Chris@4 290 *pX = x;
Chris@4 291 else
Chris@4 292 *pX = 0;
Chris@4 293 return err;
Chris@4 294 }
Chris@4 295
Chris@4 296 local int unz64local_getLong64 OF((
Chris@4 297 const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 298 voidpf filestream,
Chris@4 299 ZPOS64_T *pX));
Chris@4 300
Chris@4 301
Chris@4 302 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 303 voidpf filestream,
Chris@4 304 ZPOS64_T *pX)
Chris@4 305 {
Chris@4 306 ZPOS64_T x ;
Chris@4 307 int i = 0;
Chris@4 308 int err;
Chris@4 309
Chris@4 310 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 311 x = (ZPOS64_T)i;
Chris@4 312
Chris@4 313 if (err==UNZ_OK)
Chris@4 314 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 315 x |= ((ZPOS64_T)i)<<8;
Chris@4 316
Chris@4 317 if (err==UNZ_OK)
Chris@4 318 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 319 x |= ((ZPOS64_T)i)<<16;
Chris@4 320
Chris@4 321 if (err==UNZ_OK)
Chris@4 322 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 323 x |= ((ZPOS64_T)i)<<24;
Chris@4 324
Chris@4 325 if (err==UNZ_OK)
Chris@4 326 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 327 x |= ((ZPOS64_T)i)<<32;
Chris@4 328
Chris@4 329 if (err==UNZ_OK)
Chris@4 330 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 331 x |= ((ZPOS64_T)i)<<40;
Chris@4 332
Chris@4 333 if (err==UNZ_OK)
Chris@4 334 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 335 x |= ((ZPOS64_T)i)<<48;
Chris@4 336
Chris@4 337 if (err==UNZ_OK)
Chris@4 338 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
Chris@4 339 x |= ((ZPOS64_T)i)<<56;
Chris@4 340
Chris@4 341 if (err==UNZ_OK)
Chris@4 342 *pX = x;
Chris@4 343 else
Chris@4 344 *pX = 0;
Chris@4 345 return err;
Chris@4 346 }
Chris@4 347
Chris@4 348 /* My own strcmpi / strcasecmp */
Chris@4 349 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
Chris@4 350 {
Chris@4 351 for (;;)
Chris@4 352 {
Chris@4 353 char c1=*(fileName1++);
Chris@4 354 char c2=*(fileName2++);
Chris@4 355 if ((c1>='a') && (c1<='z'))
Chris@4 356 c1 -= 0x20;
Chris@4 357 if ((c2>='a') && (c2<='z'))
Chris@4 358 c2 -= 0x20;
Chris@4 359 if (c1=='\0')
Chris@4 360 return ((c2=='\0') ? 0 : -1);
Chris@4 361 if (c2=='\0')
Chris@4 362 return 1;
Chris@4 363 if (c1<c2)
Chris@4 364 return -1;
Chris@4 365 if (c1>c2)
Chris@4 366 return 1;
Chris@4 367 }
Chris@4 368 }
Chris@4 369
Chris@4 370
Chris@4 371 #ifdef CASESENSITIVITYDEFAULT_NO
Chris@4 372 #define CASESENSITIVITYDEFAULTVALUE 2
Chris@4 373 #else
Chris@4 374 #define CASESENSITIVITYDEFAULTVALUE 1
Chris@4 375 #endif
Chris@4 376
Chris@4 377 #ifndef STRCMPCASENOSENTIVEFUNCTION
Chris@4 378 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
Chris@4 379 #endif
Chris@4 380
Chris@4 381 /*
Chris@4 382 Compare two filename (fileName1,fileName2).
Chris@4 383 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
Chris@4 384 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
Chris@4 385 or strcasecmp)
Chris@4 386 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
Chris@4 387 (like 1 on Unix, 2 on Windows)
Chris@4 388
Chris@4 389 */
Chris@4 390 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
Chris@4 391 const char* fileName2,
Chris@4 392 int iCaseSensitivity)
Chris@4 393
Chris@4 394 {
Chris@4 395 if (iCaseSensitivity==0)
Chris@4 396 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
Chris@4 397
Chris@4 398 if (iCaseSensitivity==1)
Chris@4 399 return strcmp(fileName1,fileName2);
Chris@4 400
Chris@4 401 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
Chris@4 402 }
Chris@4 403
Chris@4 404 #ifndef BUFREADCOMMENT
Chris@4 405 #define BUFREADCOMMENT (0x400)
Chris@4 406 #endif
Chris@4 407
Chris@4 408 /*
Chris@4 409 Locate the Central directory of a zipfile (at the end, just before
Chris@4 410 the global comment)
Chris@4 411 */
Chris@4 412 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
Chris@4 413 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
Chris@4 414 {
Chris@4 415 unsigned char* buf;
Chris@4 416 ZPOS64_T uSizeFile;
Chris@4 417 ZPOS64_T uBackRead;
Chris@4 418 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
Chris@4 419 ZPOS64_T uPosFound=0;
Chris@4 420
Chris@4 421 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
Chris@4 422 return 0;
Chris@4 423
Chris@4 424
Chris@4 425 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
Chris@4 426
Chris@4 427 if (uMaxBack>uSizeFile)
Chris@4 428 uMaxBack = uSizeFile;
Chris@4 429
Chris@4 430 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
Chris@4 431 if (buf==NULL)
Chris@4 432 return 0;
Chris@4 433
Chris@4 434 uBackRead = 4;
Chris@4 435 while (uBackRead<uMaxBack)
Chris@4 436 {
Chris@4 437 uLong uReadSize;
Chris@4 438 ZPOS64_T uReadPos ;
Chris@4 439 int i;
Chris@4 440 if (uBackRead+BUFREADCOMMENT>uMaxBack)
Chris@4 441 uBackRead = uMaxBack;
Chris@4 442 else
Chris@4 443 uBackRead+=BUFREADCOMMENT;
Chris@4 444 uReadPos = uSizeFile-uBackRead ;
Chris@4 445
Chris@4 446 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
Chris@4 447 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
Chris@4 448 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 449 break;
Chris@4 450
Chris@4 451 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
Chris@4 452 break;
Chris@4 453
Chris@4 454 for (i=(int)uReadSize-3; (i--)>0;)
Chris@4 455 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
Chris@4 456 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
Chris@4 457 {
Chris@4 458 uPosFound = uReadPos+i;
Chris@4 459 break;
Chris@4 460 }
Chris@4 461
Chris@4 462 if (uPosFound!=0)
Chris@4 463 break;
Chris@4 464 }
Chris@4 465 TRYFREE(buf);
Chris@4 466 return uPosFound;
Chris@4 467 }
Chris@4 468
Chris@4 469
Chris@4 470 /*
Chris@4 471 Locate the Central directory 64 of a zipfile (at the end, just before
Chris@4 472 the global comment)
Chris@4 473 */
Chris@4 474 local ZPOS64_T unz64local_SearchCentralDir64 OF((
Chris@4 475 const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 476 voidpf filestream));
Chris@4 477
Chris@4 478 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
Chris@4 479 voidpf filestream)
Chris@4 480 {
Chris@4 481 unsigned char* buf;
Chris@4 482 ZPOS64_T uSizeFile;
Chris@4 483 ZPOS64_T uBackRead;
Chris@4 484 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
Chris@4 485 ZPOS64_T uPosFound=0;
Chris@4 486 uLong uL;
Chris@4 487 ZPOS64_T relativeOffset;
Chris@4 488
Chris@4 489 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
Chris@4 490 return 0;
Chris@4 491
Chris@4 492
Chris@4 493 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
Chris@4 494
Chris@4 495 if (uMaxBack>uSizeFile)
Chris@4 496 uMaxBack = uSizeFile;
Chris@4 497
Chris@4 498 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
Chris@4 499 if (buf==NULL)
Chris@4 500 return 0;
Chris@4 501
Chris@4 502 uBackRead = 4;
Chris@4 503 while (uBackRead<uMaxBack)
Chris@4 504 {
Chris@4 505 uLong uReadSize;
Chris@4 506 ZPOS64_T uReadPos;
Chris@4 507 int i;
Chris@4 508 if (uBackRead+BUFREADCOMMENT>uMaxBack)
Chris@4 509 uBackRead = uMaxBack;
Chris@4 510 else
Chris@4 511 uBackRead+=BUFREADCOMMENT;
Chris@4 512 uReadPos = uSizeFile-uBackRead ;
Chris@4 513
Chris@4 514 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
Chris@4 515 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
Chris@4 516 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 517 break;
Chris@4 518
Chris@4 519 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
Chris@4 520 break;
Chris@4 521
Chris@4 522 for (i=(int)uReadSize-3; (i--)>0;)
Chris@4 523 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
Chris@4 524 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
Chris@4 525 {
Chris@4 526 uPosFound = uReadPos+i;
Chris@4 527 break;
Chris@4 528 }
Chris@4 529
Chris@4 530 if (uPosFound!=0)
Chris@4 531 break;
Chris@4 532 }
Chris@4 533 TRYFREE(buf);
Chris@4 534 if (uPosFound == 0)
Chris@4 535 return 0;
Chris@4 536
Chris@4 537 /* Zip64 end of central directory locator */
Chris@4 538 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 539 return 0;
Chris@4 540
Chris@4 541 /* the signature, already checked */
Chris@4 542 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
Chris@4 543 return 0;
Chris@4 544
Chris@4 545 /* number of the disk with the start of the zip64 end of central directory */
Chris@4 546 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
Chris@4 547 return 0;
Chris@4 548 if (uL != 0)
Chris@4 549 return 0;
Chris@4 550
Chris@4 551 /* relative offset of the zip64 end of central directory record */
Chris@4 552 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
Chris@4 553 return 0;
Chris@4 554
Chris@4 555 /* total number of disks */
Chris@4 556 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
Chris@4 557 return 0;
Chris@4 558 if (uL != 1)
Chris@4 559 return 0;
Chris@4 560
Chris@4 561 /* Goto end of central directory record */
Chris@4 562 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 563 return 0;
Chris@4 564
Chris@4 565 /* the signature */
Chris@4 566 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
Chris@4 567 return 0;
Chris@4 568
Chris@4 569 if (uL != 0x06064b50)
Chris@4 570 return 0;
Chris@4 571
Chris@4 572 return relativeOffset;
Chris@4 573 }
Chris@4 574
Chris@4 575 /*
Chris@4 576 Open a Zip file. path contain the full pathname (by example,
Chris@4 577 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
Chris@4 578 "zlib/zlib114.zip".
Chris@4 579 If the zipfile cannot be opened (file doesn't exist or in not valid), the
Chris@4 580 return value is NULL.
Chris@4 581 Else, the return value is a unzFile Handle, usable with other function
Chris@4 582 of this unzip package.
Chris@4 583 */
Chris@4 584 local unzFile unzOpenInternal (const void *path,
Chris@4 585 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
Chris@4 586 int is64bitOpenFunction)
Chris@4 587 {
Chris@4 588 unz64_s us;
Chris@4 589 unz64_s *s;
Chris@4 590 ZPOS64_T central_pos;
Chris@4 591 uLong uL;
Chris@4 592
Chris@4 593 uLong number_disk; /* number of the current dist, used for
Chris@4 594 spaning ZIP, unsupported, always 0*/
Chris@4 595 uLong number_disk_with_CD; /* number the the disk with central dir, used
Chris@4 596 for spaning ZIP, unsupported, always 0*/
Chris@4 597 ZPOS64_T number_entry_CD; /* total number of entries in
Chris@4 598 the central dir
Chris@4 599 (same than number_entry on nospan) */
Chris@4 600
Chris@4 601 int err=UNZ_OK;
Chris@4 602
Chris@4 603 if (unz_copyright[0]!=' ')
Chris@4 604 return NULL;
Chris@4 605
Chris@4 606 us.z_filefunc.zseek32_file = NULL;
Chris@4 607 us.z_filefunc.ztell32_file = NULL;
Chris@4 608 if (pzlib_filefunc64_32_def==NULL)
Chris@4 609 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
Chris@4 610 else
Chris@4 611 us.z_filefunc = *pzlib_filefunc64_32_def;
Chris@4 612 us.is64bitOpenFunction = is64bitOpenFunction;
Chris@4 613
Chris@4 614
Chris@4 615
Chris@4 616 us.filestream = ZOPEN64(us.z_filefunc,
Chris@4 617 path,
Chris@4 618 ZLIB_FILEFUNC_MODE_READ |
Chris@4 619 ZLIB_FILEFUNC_MODE_EXISTING);
Chris@4 620 if (us.filestream==NULL)
Chris@4 621 return NULL;
Chris@4 622
Chris@4 623 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
Chris@4 624 if (central_pos)
Chris@4 625 {
Chris@4 626 uLong uS;
Chris@4 627 ZPOS64_T uL64;
Chris@4 628
Chris@4 629 us.isZip64 = 1;
Chris@4 630
Chris@4 631 if (ZSEEK64(us.z_filefunc, us.filestream,
Chris@4 632 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 633 err=UNZ_ERRNO;
Chris@4 634
Chris@4 635 /* the signature, already checked */
Chris@4 636 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 637 err=UNZ_ERRNO;
Chris@4 638
Chris@4 639 /* size of zip64 end of central directory record */
Chris@4 640 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
Chris@4 641 err=UNZ_ERRNO;
Chris@4 642
Chris@4 643 /* version made by */
Chris@4 644 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
Chris@4 645 err=UNZ_ERRNO;
Chris@4 646
Chris@4 647 /* version needed to extract */
Chris@4 648 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
Chris@4 649 err=UNZ_ERRNO;
Chris@4 650
Chris@4 651 /* number of this disk */
Chris@4 652 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
Chris@4 653 err=UNZ_ERRNO;
Chris@4 654
Chris@4 655 /* number of the disk with the start of the central directory */
Chris@4 656 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
Chris@4 657 err=UNZ_ERRNO;
Chris@4 658
Chris@4 659 /* total number of entries in the central directory on this disk */
Chris@4 660 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
Chris@4 661 err=UNZ_ERRNO;
Chris@4 662
Chris@4 663 /* total number of entries in the central directory */
Chris@4 664 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
Chris@4 665 err=UNZ_ERRNO;
Chris@4 666
Chris@4 667 if ((number_entry_CD!=us.gi.number_entry) ||
Chris@4 668 (number_disk_with_CD!=0) ||
Chris@4 669 (number_disk!=0))
Chris@4 670 err=UNZ_BADZIPFILE;
Chris@4 671
Chris@4 672 /* size of the central directory */
Chris@4 673 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
Chris@4 674 err=UNZ_ERRNO;
Chris@4 675
Chris@4 676 /* offset of start of central directory with respect to the
Chris@4 677 starting disk number */
Chris@4 678 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
Chris@4 679 err=UNZ_ERRNO;
Chris@4 680
Chris@4 681 us.gi.size_comment = 0;
Chris@4 682 }
Chris@4 683 else
Chris@4 684 {
Chris@4 685 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
Chris@4 686 if (central_pos==0)
Chris@4 687 err=UNZ_ERRNO;
Chris@4 688
Chris@4 689 us.isZip64 = 0;
Chris@4 690
Chris@4 691 if (ZSEEK64(us.z_filefunc, us.filestream,
Chris@4 692 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 693 err=UNZ_ERRNO;
Chris@4 694
Chris@4 695 /* the signature, already checked */
Chris@4 696 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 697 err=UNZ_ERRNO;
Chris@4 698
Chris@4 699 /* number of this disk */
Chris@4 700 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
Chris@4 701 err=UNZ_ERRNO;
Chris@4 702
Chris@4 703 /* number of the disk with the start of the central directory */
Chris@4 704 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
Chris@4 705 err=UNZ_ERRNO;
Chris@4 706
Chris@4 707 /* total number of entries in the central dir on this disk */
Chris@4 708 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 709 err=UNZ_ERRNO;
Chris@4 710 us.gi.number_entry = uL;
Chris@4 711
Chris@4 712 /* total number of entries in the central dir */
Chris@4 713 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 714 err=UNZ_ERRNO;
Chris@4 715 number_entry_CD = uL;
Chris@4 716
Chris@4 717 if ((number_entry_CD!=us.gi.number_entry) ||
Chris@4 718 (number_disk_with_CD!=0) ||
Chris@4 719 (number_disk!=0))
Chris@4 720 err=UNZ_BADZIPFILE;
Chris@4 721
Chris@4 722 /* size of the central directory */
Chris@4 723 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 724 err=UNZ_ERRNO;
Chris@4 725 us.size_central_dir = uL;
Chris@4 726
Chris@4 727 /* offset of start of central directory with respect to the
Chris@4 728 starting disk number */
Chris@4 729 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
Chris@4 730 err=UNZ_ERRNO;
Chris@4 731 us.offset_central_dir = uL;
Chris@4 732
Chris@4 733 /* zipfile comment length */
Chris@4 734 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
Chris@4 735 err=UNZ_ERRNO;
Chris@4 736 }
Chris@4 737
Chris@4 738 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
Chris@4 739 (err==UNZ_OK))
Chris@4 740 err=UNZ_BADZIPFILE;
Chris@4 741
Chris@4 742 if (err!=UNZ_OK)
Chris@4 743 {
Chris@4 744 ZCLOSE64(us.z_filefunc, us.filestream);
Chris@4 745 return NULL;
Chris@4 746 }
Chris@4 747
Chris@4 748 us.byte_before_the_zipfile = central_pos -
Chris@4 749 (us.offset_central_dir+us.size_central_dir);
Chris@4 750 us.central_pos = central_pos;
Chris@4 751 us.pfile_in_zip_read = NULL;
Chris@4 752 us.encrypted = 0;
Chris@4 753
Chris@4 754
Chris@4 755 s=(unz64_s*)ALLOC(sizeof(unz64_s));
Chris@4 756 if( s != NULL)
Chris@4 757 {
Chris@4 758 *s=us;
Chris@4 759 unzGoToFirstFile((unzFile)s);
Chris@4 760 }
Chris@4 761 return (unzFile)s;
Chris@4 762 }
Chris@4 763
Chris@4 764
Chris@4 765 extern unzFile ZEXPORT unzOpen2 (const char *path,
Chris@4 766 zlib_filefunc_def* pzlib_filefunc32_def)
Chris@4 767 {
Chris@4 768 if (pzlib_filefunc32_def != NULL)
Chris@4 769 {
Chris@4 770 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
Chris@4 771 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
Chris@4 772 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
Chris@4 773 }
Chris@4 774 else
Chris@4 775 return unzOpenInternal(path, NULL, 0);
Chris@4 776 }
Chris@4 777
Chris@4 778 extern unzFile ZEXPORT unzOpen2_64 (const void *path,
Chris@4 779 zlib_filefunc64_def* pzlib_filefunc_def)
Chris@4 780 {
Chris@4 781 if (pzlib_filefunc_def != NULL)
Chris@4 782 {
Chris@4 783 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
Chris@4 784 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
Chris@4 785 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
Chris@4 786 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
Chris@4 787 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
Chris@4 788 }
Chris@4 789 else
Chris@4 790 return unzOpenInternal(path, NULL, 1);
Chris@4 791 }
Chris@4 792
Chris@4 793 extern unzFile ZEXPORT unzOpen (const char *path)
Chris@4 794 {
Chris@4 795 return unzOpenInternal(path, NULL, 0);
Chris@4 796 }
Chris@4 797
Chris@4 798 extern unzFile ZEXPORT unzOpen64 (const void *path)
Chris@4 799 {
Chris@4 800 return unzOpenInternal(path, NULL, 1);
Chris@4 801 }
Chris@4 802
Chris@4 803 /*
Chris@4 804 Close a ZipFile opened with unzipOpen.
Chris@4 805 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
Chris@4 806 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
Chris@4 807 return UNZ_OK if there is no problem. */
Chris@4 808 extern int ZEXPORT unzClose (unzFile file)
Chris@4 809 {
Chris@4 810 unz64_s* s;
Chris@4 811 if (file==NULL)
Chris@4 812 return UNZ_PARAMERROR;
Chris@4 813 s=(unz64_s*)file;
Chris@4 814
Chris@4 815 if (s->pfile_in_zip_read!=NULL)
Chris@4 816 unzCloseCurrentFile(file);
Chris@4 817
Chris@4 818 ZCLOSE64(s->z_filefunc, s->filestream);
Chris@4 819 TRYFREE(s);
Chris@4 820 return UNZ_OK;
Chris@4 821 }
Chris@4 822
Chris@4 823
Chris@4 824 /*
Chris@4 825 Write info about the ZipFile in the *pglobal_info structure.
Chris@4 826 No preparation of the structure is needed
Chris@4 827 return UNZ_OK if there is no problem. */
Chris@4 828 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
Chris@4 829 {
Chris@4 830 unz64_s* s;
Chris@4 831 if (file==NULL)
Chris@4 832 return UNZ_PARAMERROR;
Chris@4 833 s=(unz64_s*)file;
Chris@4 834 *pglobal_info=s->gi;
Chris@4 835 return UNZ_OK;
Chris@4 836 }
Chris@4 837
Chris@4 838 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
Chris@4 839 {
Chris@4 840 unz64_s* s;
Chris@4 841 if (file==NULL)
Chris@4 842 return UNZ_PARAMERROR;
Chris@4 843 s=(unz64_s*)file;
Chris@4 844 /* to do : check if number_entry is not truncated */
Chris@4 845 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
Chris@4 846 pglobal_info32->size_comment = s->gi.size_comment;
Chris@4 847 return UNZ_OK;
Chris@4 848 }
Chris@4 849 /*
Chris@4 850 Translate date/time from Dos format to tm_unz (readable more easilty)
Chris@4 851 */
Chris@4 852 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
Chris@4 853 {
Chris@4 854 ZPOS64_T uDate;
Chris@4 855 uDate = (ZPOS64_T)(ulDosDate>>16);
Chris@4 856 ptm->tm_mday = (uInt)(uDate&0x1f) ;
Chris@4 857 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
Chris@4 858 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
Chris@4 859
Chris@4 860 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
Chris@4 861 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
Chris@4 862 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
Chris@4 863 }
Chris@4 864
Chris@4 865 /*
Chris@4 866 Get Info about the current file in the zipfile, with internal only info
Chris@4 867 */
Chris@4 868 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
Chris@4 869 unz_file_info64 *pfile_info,
Chris@4 870 unz_file_info64_internal
Chris@4 871 *pfile_info_internal,
Chris@4 872 char *szFileName,
Chris@4 873 uLong fileNameBufferSize,
Chris@4 874 void *extraField,
Chris@4 875 uLong extraFieldBufferSize,
Chris@4 876 char *szComment,
Chris@4 877 uLong commentBufferSize));
Chris@4 878
Chris@4 879 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
Chris@4 880 unz_file_info64 *pfile_info,
Chris@4 881 unz_file_info64_internal
Chris@4 882 *pfile_info_internal,
Chris@4 883 char *szFileName,
Chris@4 884 uLong fileNameBufferSize,
Chris@4 885 void *extraField,
Chris@4 886 uLong extraFieldBufferSize,
Chris@4 887 char *szComment,
Chris@4 888 uLong commentBufferSize)
Chris@4 889 {
Chris@4 890 unz64_s* s;
Chris@4 891 unz_file_info64 file_info;
Chris@4 892 unz_file_info64_internal file_info_internal;
Chris@4 893 int err=UNZ_OK;
Chris@4 894 uLong uMagic;
Chris@4 895 long lSeek=0;
Chris@4 896 uLong uL;
Chris@4 897
Chris@4 898 if (file==NULL)
Chris@4 899 return UNZ_PARAMERROR;
Chris@4 900 s=(unz64_s*)file;
Chris@4 901 if (ZSEEK64(s->z_filefunc, s->filestream,
Chris@4 902 s->pos_in_central_dir+s->byte_before_the_zipfile,
Chris@4 903 ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 904 err=UNZ_ERRNO;
Chris@4 905
Chris@4 906
Chris@4 907 /* we check the magic */
Chris@4 908 if (err==UNZ_OK)
Chris@4 909 {
Chris@4 910 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
Chris@4 911 err=UNZ_ERRNO;
Chris@4 912 else if (uMagic!=0x02014b50)
Chris@4 913 err=UNZ_BADZIPFILE;
Chris@4 914 }
Chris@4 915
Chris@4 916 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
Chris@4 917 err=UNZ_ERRNO;
Chris@4 918
Chris@4 919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
Chris@4 920 err=UNZ_ERRNO;
Chris@4 921
Chris@4 922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
Chris@4 923 err=UNZ_ERRNO;
Chris@4 924
Chris@4 925 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
Chris@4 926 err=UNZ_ERRNO;
Chris@4 927
Chris@4 928 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
Chris@4 929 err=UNZ_ERRNO;
Chris@4 930
Chris@4 931 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
Chris@4 932
Chris@4 933 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
Chris@4 934 err=UNZ_ERRNO;
Chris@4 935
Chris@4 936 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
Chris@4 937 err=UNZ_ERRNO;
Chris@4 938 file_info.compressed_size = uL;
Chris@4 939
Chris@4 940 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
Chris@4 941 err=UNZ_ERRNO;
Chris@4 942 file_info.uncompressed_size = uL;
Chris@4 943
Chris@4 944 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
Chris@4 945 err=UNZ_ERRNO;
Chris@4 946
Chris@4 947 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
Chris@4 948 err=UNZ_ERRNO;
Chris@4 949
Chris@4 950 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
Chris@4 951 err=UNZ_ERRNO;
Chris@4 952
Chris@4 953 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
Chris@4 954 err=UNZ_ERRNO;
Chris@4 955
Chris@4 956 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
Chris@4 957 err=UNZ_ERRNO;
Chris@4 958
Chris@4 959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
Chris@4 960 err=UNZ_ERRNO;
Chris@4 961
Chris@4 962 // relative offset of local header
Chris@4 963 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
Chris@4 964 err=UNZ_ERRNO;
Chris@4 965 file_info_internal.offset_curfile = uL;
Chris@4 966
Chris@4 967 lSeek+=file_info.size_filename;
Chris@4 968 if ((err==UNZ_OK) && (szFileName!=NULL))
Chris@4 969 {
Chris@4 970 uLong uSizeRead ;
Chris@4 971 if (file_info.size_filename<fileNameBufferSize)
Chris@4 972 {
Chris@4 973 *(szFileName+file_info.size_filename)='\0';
Chris@4 974 uSizeRead = file_info.size_filename;
Chris@4 975 }
Chris@4 976 else
Chris@4 977 uSizeRead = fileNameBufferSize;
Chris@4 978
Chris@4 979 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
Chris@4 980 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
Chris@4 981 err=UNZ_ERRNO;
Chris@4 982 lSeek -= uSizeRead;
Chris@4 983 }
Chris@4 984
Chris@4 985 // Read extrafield
Chris@4 986 if ((err==UNZ_OK) && (extraField!=NULL))
Chris@4 987 {
Chris@4 988 ZPOS64_T uSizeRead ;
Chris@4 989 if (file_info.size_file_extra<extraFieldBufferSize)
Chris@4 990 uSizeRead = file_info.size_file_extra;
Chris@4 991 else
Chris@4 992 uSizeRead = extraFieldBufferSize;
Chris@4 993
Chris@4 994 if (lSeek!=0)
Chris@4 995 {
Chris@4 996 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
Chris@4 997 lSeek=0;
Chris@4 998 else
Chris@4 999 err=UNZ_ERRNO;
Chris@4 1000 }
Chris@4 1001
Chris@4 1002 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
Chris@4 1003 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
Chris@4 1004 err=UNZ_ERRNO;
Chris@4 1005
Chris@4 1006 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
Chris@4 1007 }
Chris@4 1008 else
Chris@4 1009 lSeek += file_info.size_file_extra;
Chris@4 1010
Chris@4 1011
Chris@4 1012 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
Chris@4 1013 {
Chris@4 1014 uLong acc = 0;
Chris@4 1015
Chris@4 1016 // since lSeek now points to after the extra field we need to move back
Chris@4 1017 lSeek -= file_info.size_file_extra;
Chris@4 1018
Chris@4 1019 if (lSeek!=0)
Chris@4 1020 {
Chris@4 1021 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
Chris@4 1022 lSeek=0;
Chris@4 1023 else
Chris@4 1024 err=UNZ_ERRNO;
Chris@4 1025 }
Chris@4 1026
Chris@4 1027 while(acc < file_info.size_file_extra)
Chris@4 1028 {
Chris@4 1029 uLong headerId;
Chris@4 1030 uLong dataSize;
Chris@4 1031
Chris@4 1032 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
Chris@4 1033 err=UNZ_ERRNO;
Chris@4 1034
Chris@4 1035 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
Chris@4 1036 err=UNZ_ERRNO;
Chris@4 1037
Chris@4 1038 /* ZIP64 extra fields */
Chris@4 1039 if (headerId == 0x0001)
Chris@4 1040 {
Chris@4 1041 uLong uL;
Chris@4 1042
Chris@4 1043 if(file_info.uncompressed_size == MAXU32)
Chris@4 1044 {
Chris@4 1045 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
Chris@4 1046 err=UNZ_ERRNO;
Chris@4 1047 }
Chris@4 1048
Chris@4 1049 if(file_info.compressed_size == MAXU32)
Chris@4 1050 {
Chris@4 1051 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
Chris@4 1052 err=UNZ_ERRNO;
Chris@4 1053 }
Chris@4 1054
Chris@4 1055 if(file_info_internal.offset_curfile == MAXU32)
Chris@4 1056 {
Chris@4 1057 /* Relative Header offset */
Chris@4 1058 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
Chris@4 1059 err=UNZ_ERRNO;
Chris@4 1060 }
Chris@4 1061
Chris@4 1062 if(file_info.disk_num_start == MAXU32)
Chris@4 1063 {
Chris@4 1064 /* Disk Start Number */
Chris@4 1065 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
Chris@4 1066 err=UNZ_ERRNO;
Chris@4 1067 }
Chris@4 1068
Chris@4 1069 }
Chris@4 1070 else
Chris@4 1071 {
Chris@4 1072 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
Chris@4 1073 err=UNZ_ERRNO;
Chris@4 1074 }
Chris@4 1075
Chris@4 1076 acc += 2 + 2 + dataSize;
Chris@4 1077 }
Chris@4 1078 }
Chris@4 1079
Chris@4 1080 if ((err==UNZ_OK) && (szComment!=NULL))
Chris@4 1081 {
Chris@4 1082 uLong uSizeRead ;
Chris@4 1083 if (file_info.size_file_comment<commentBufferSize)
Chris@4 1084 {
Chris@4 1085 *(szComment+file_info.size_file_comment)='\0';
Chris@4 1086 uSizeRead = file_info.size_file_comment;
Chris@4 1087 }
Chris@4 1088 else
Chris@4 1089 uSizeRead = commentBufferSize;
Chris@4 1090
Chris@4 1091 if (lSeek!=0)
Chris@4 1092 {
Chris@4 1093 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
Chris@4 1094 lSeek=0;
Chris@4 1095 else
Chris@4 1096 err=UNZ_ERRNO;
Chris@4 1097 }
Chris@4 1098
Chris@4 1099 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
Chris@4 1100 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
Chris@4 1101 err=UNZ_ERRNO;
Chris@4 1102 lSeek+=file_info.size_file_comment - uSizeRead;
Chris@4 1103 }
Chris@4 1104 else
Chris@4 1105 lSeek+=file_info.size_file_comment;
Chris@4 1106
Chris@4 1107
Chris@4 1108 if ((err==UNZ_OK) && (pfile_info!=NULL))
Chris@4 1109 *pfile_info=file_info;
Chris@4 1110
Chris@4 1111 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
Chris@4 1112 *pfile_info_internal=file_info_internal;
Chris@4 1113
Chris@4 1114 return err;
Chris@4 1115 }
Chris@4 1116
Chris@4 1117
Chris@4 1118
Chris@4 1119 /*
Chris@4 1120 Write info about the ZipFile in the *pglobal_info structure.
Chris@4 1121 No preparation of the structure is needed
Chris@4 1122 return UNZ_OK if there is no problem.
Chris@4 1123 */
Chris@4 1124 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
Chris@4 1125 unz_file_info64 * pfile_info,
Chris@4 1126 char * szFileName, uLong fileNameBufferSize,
Chris@4 1127 void *extraField, uLong extraFieldBufferSize,
Chris@4 1128 char* szComment, uLong commentBufferSize)
Chris@4 1129 {
Chris@4 1130 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
Chris@4 1131 szFileName,fileNameBufferSize,
Chris@4 1132 extraField,extraFieldBufferSize,
Chris@4 1133 szComment,commentBufferSize);
Chris@4 1134 }
Chris@4 1135
Chris@4 1136 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
Chris@4 1137 unz_file_info * pfile_info,
Chris@4 1138 char * szFileName, uLong fileNameBufferSize,
Chris@4 1139 void *extraField, uLong extraFieldBufferSize,
Chris@4 1140 char* szComment, uLong commentBufferSize)
Chris@4 1141 {
Chris@4 1142 int err;
Chris@4 1143 unz_file_info64 file_info64;
Chris@4 1144 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
Chris@4 1145 szFileName,fileNameBufferSize,
Chris@4 1146 extraField,extraFieldBufferSize,
Chris@4 1147 szComment,commentBufferSize);
Chris@4 1148 if ((err==UNZ_OK) && (pfile_info != NULL))
Chris@4 1149 {
Chris@4 1150 pfile_info->version = file_info64.version;
Chris@4 1151 pfile_info->version_needed = file_info64.version_needed;
Chris@4 1152 pfile_info->flag = file_info64.flag;
Chris@4 1153 pfile_info->compression_method = file_info64.compression_method;
Chris@4 1154 pfile_info->dosDate = file_info64.dosDate;
Chris@4 1155 pfile_info->crc = file_info64.crc;
Chris@4 1156
Chris@4 1157 pfile_info->size_filename = file_info64.size_filename;
Chris@4 1158 pfile_info->size_file_extra = file_info64.size_file_extra;
Chris@4 1159 pfile_info->size_file_comment = file_info64.size_file_comment;
Chris@4 1160
Chris@4 1161 pfile_info->disk_num_start = file_info64.disk_num_start;
Chris@4 1162 pfile_info->internal_fa = file_info64.internal_fa;
Chris@4 1163 pfile_info->external_fa = file_info64.external_fa;
Chris@4 1164
Chris@4 1165 pfile_info->tmu_date = file_info64.tmu_date,
Chris@4 1166
Chris@4 1167
Chris@4 1168 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
Chris@4 1169 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
Chris@4 1170
Chris@4 1171 }
Chris@4 1172 return err;
Chris@4 1173 }
Chris@4 1174 /*
Chris@4 1175 Set the current file of the zipfile to the first file.
Chris@4 1176 return UNZ_OK if there is no problem
Chris@4 1177 */
Chris@4 1178 extern int ZEXPORT unzGoToFirstFile (unzFile file)
Chris@4 1179 {
Chris@4 1180 int err=UNZ_OK;
Chris@4 1181 unz64_s* s;
Chris@4 1182 if (file==NULL)
Chris@4 1183 return UNZ_PARAMERROR;
Chris@4 1184 s=(unz64_s*)file;
Chris@4 1185 s->pos_in_central_dir=s->offset_central_dir;
Chris@4 1186 s->num_file=0;
Chris@4 1187 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
Chris@4 1188 &s->cur_file_info_internal,
Chris@4 1189 NULL,0,NULL,0,NULL,0);
Chris@4 1190 s->current_file_ok = (err == UNZ_OK);
Chris@4 1191 return err;
Chris@4 1192 }
Chris@4 1193
Chris@4 1194 /*
Chris@4 1195 Set the current file of the zipfile to the next file.
Chris@4 1196 return UNZ_OK if there is no problem
Chris@4 1197 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
Chris@4 1198 */
Chris@4 1199 extern int ZEXPORT unzGoToNextFile (unzFile file)
Chris@4 1200 {
Chris@4 1201 unz64_s* s;
Chris@4 1202 int err;
Chris@4 1203
Chris@4 1204 if (file==NULL)
Chris@4 1205 return UNZ_PARAMERROR;
Chris@4 1206 s=(unz64_s*)file;
Chris@4 1207 if (!s->current_file_ok)
Chris@4 1208 return UNZ_END_OF_LIST_OF_FILE;
Chris@4 1209 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
Chris@4 1210 if (s->num_file+1==s->gi.number_entry)
Chris@4 1211 return UNZ_END_OF_LIST_OF_FILE;
Chris@4 1212
Chris@4 1213 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
Chris@4 1214 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
Chris@4 1215 s->num_file++;
Chris@4 1216 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
Chris@4 1217 &s->cur_file_info_internal,
Chris@4 1218 NULL,0,NULL,0,NULL,0);
Chris@4 1219 s->current_file_ok = (err == UNZ_OK);
Chris@4 1220 return err;
Chris@4 1221 }
Chris@4 1222
Chris@4 1223
Chris@4 1224 /*
Chris@4 1225 Try locate the file szFileName in the zipfile.
Chris@4 1226 For the iCaseSensitivity signification, see unzipStringFileNameCompare
Chris@4 1227
Chris@4 1228 return value :
Chris@4 1229 UNZ_OK if the file is found. It becomes the current file.
Chris@4 1230 UNZ_END_OF_LIST_OF_FILE if the file is not found
Chris@4 1231 */
Chris@4 1232 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
Chris@4 1233 {
Chris@4 1234 unz64_s* s;
Chris@4 1235 int err;
Chris@4 1236
Chris@4 1237 /* We remember the 'current' position in the file so that we can jump
Chris@4 1238 * back there if we fail.
Chris@4 1239 */
Chris@4 1240 unz_file_info64 cur_file_infoSaved;
Chris@4 1241 unz_file_info64_internal cur_file_info_internalSaved;
Chris@4 1242 ZPOS64_T num_fileSaved;
Chris@4 1243 ZPOS64_T pos_in_central_dirSaved;
Chris@4 1244
Chris@4 1245
Chris@4 1246 if (file==NULL)
Chris@4 1247 return UNZ_PARAMERROR;
Chris@4 1248
Chris@4 1249 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
Chris@4 1250 return UNZ_PARAMERROR;
Chris@4 1251
Chris@4 1252 s=(unz64_s*)file;
Chris@4 1253 if (!s->current_file_ok)
Chris@4 1254 return UNZ_END_OF_LIST_OF_FILE;
Chris@4 1255
Chris@4 1256 /* Save the current state */
Chris@4 1257 num_fileSaved = s->num_file;
Chris@4 1258 pos_in_central_dirSaved = s->pos_in_central_dir;
Chris@4 1259 cur_file_infoSaved = s->cur_file_info;
Chris@4 1260 cur_file_info_internalSaved = s->cur_file_info_internal;
Chris@4 1261
Chris@4 1262 err = unzGoToFirstFile(file);
Chris@4 1263
Chris@4 1264 while (err == UNZ_OK)
Chris@4 1265 {
Chris@4 1266 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
Chris@4 1267 err = unzGetCurrentFileInfo64(file,NULL,
Chris@4 1268 szCurrentFileName,sizeof(szCurrentFileName)-1,
Chris@4 1269 NULL,0,NULL,0);
Chris@4 1270 if (err == UNZ_OK)
Chris@4 1271 {
Chris@4 1272 if (unzStringFileNameCompare(szCurrentFileName,
Chris@4 1273 szFileName,iCaseSensitivity)==0)
Chris@4 1274 return UNZ_OK;
Chris@4 1275 err = unzGoToNextFile(file);
Chris@4 1276 }
Chris@4 1277 }
Chris@4 1278
Chris@4 1279 /* We failed, so restore the state of the 'current file' to where we
Chris@4 1280 * were.
Chris@4 1281 */
Chris@4 1282 s->num_file = num_fileSaved ;
Chris@4 1283 s->pos_in_central_dir = pos_in_central_dirSaved ;
Chris@4 1284 s->cur_file_info = cur_file_infoSaved;
Chris@4 1285 s->cur_file_info_internal = cur_file_info_internalSaved;
Chris@4 1286 return err;
Chris@4 1287 }
Chris@4 1288
Chris@4 1289
Chris@4 1290 /*
Chris@4 1291 ///////////////////////////////////////////
Chris@4 1292 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
Chris@4 1293 // I need random access
Chris@4 1294 //
Chris@4 1295 // Further optimization could be realized by adding an ability
Chris@4 1296 // to cache the directory in memory. The goal being a single
Chris@4 1297 // comprehensive file read to put the file I need in a memory.
Chris@4 1298 */
Chris@4 1299
Chris@4 1300 /*
Chris@4 1301 typedef struct unz_file_pos_s
Chris@4 1302 {
Chris@4 1303 ZPOS64_T pos_in_zip_directory; // offset in file
Chris@4 1304 ZPOS64_T num_of_file; // # of file
Chris@4 1305 } unz_file_pos;
Chris@4 1306 */
Chris@4 1307
Chris@4 1308 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
Chris@4 1309 {
Chris@4 1310 unz64_s* s;
Chris@4 1311
Chris@4 1312 if (file==NULL || file_pos==NULL)
Chris@4 1313 return UNZ_PARAMERROR;
Chris@4 1314 s=(unz64_s*)file;
Chris@4 1315 if (!s->current_file_ok)
Chris@4 1316 return UNZ_END_OF_LIST_OF_FILE;
Chris@4 1317
Chris@4 1318 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
Chris@4 1319 file_pos->num_of_file = s->num_file;
Chris@4 1320
Chris@4 1321 return UNZ_OK;
Chris@4 1322 }
Chris@4 1323
Chris@4 1324 extern int ZEXPORT unzGetFilePos(
Chris@4 1325 unzFile file,
Chris@4 1326 unz_file_pos* file_pos)
Chris@4 1327 {
Chris@4 1328 unz64_file_pos file_pos64;
Chris@4 1329 int err = unzGetFilePos64(file,&file_pos64);
Chris@4 1330 if (err==UNZ_OK)
Chris@4 1331 {
Chris@4 1332 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
Chris@4 1333 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
Chris@4 1334 }
Chris@4 1335 return err;
Chris@4 1336 }
Chris@4 1337
Chris@4 1338 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
Chris@4 1339 {
Chris@4 1340 unz64_s* s;
Chris@4 1341 int err;
Chris@4 1342
Chris@4 1343 if (file==NULL || file_pos==NULL)
Chris@4 1344 return UNZ_PARAMERROR;
Chris@4 1345 s=(unz64_s*)file;
Chris@4 1346
Chris@4 1347 /* jump to the right spot */
Chris@4 1348 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
Chris@4 1349 s->num_file = file_pos->num_of_file;
Chris@4 1350
Chris@4 1351 /* set the current file */
Chris@4 1352 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
Chris@4 1353 &s->cur_file_info_internal,
Chris@4 1354 NULL,0,NULL,0,NULL,0);
Chris@4 1355 /* return results */
Chris@4 1356 s->current_file_ok = (err == UNZ_OK);
Chris@4 1357 return err;
Chris@4 1358 }
Chris@4 1359
Chris@4 1360 extern int ZEXPORT unzGoToFilePos(
Chris@4 1361 unzFile file,
Chris@4 1362 unz_file_pos* file_pos)
Chris@4 1363 {
Chris@4 1364 unz64_file_pos file_pos64;
Chris@4 1365 if (file_pos == NULL)
Chris@4 1366 return UNZ_PARAMERROR;
Chris@4 1367
Chris@4 1368 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
Chris@4 1369 file_pos64.num_of_file = file_pos->num_of_file;
Chris@4 1370 return unzGoToFilePos64(file,&file_pos64);
Chris@4 1371 }
Chris@4 1372
Chris@4 1373 /*
Chris@4 1374 // Unzip Helper Functions - should be here?
Chris@4 1375 ///////////////////////////////////////////
Chris@4 1376 */
Chris@4 1377
Chris@4 1378 /*
Chris@4 1379 Read the local header of the current zipfile
Chris@4 1380 Check the coherency of the local header and info in the end of central
Chris@4 1381 directory about this file
Chris@4 1382 store in *piSizeVar the size of extra info in local header
Chris@4 1383 (filename and size of extra field data)
Chris@4 1384 */
Chris@4 1385 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
Chris@4 1386 ZPOS64_T * poffset_local_extrafield,
Chris@4 1387 uInt * psize_local_extrafield)
Chris@4 1388 {
Chris@4 1389 uLong uMagic,uData,uFlags;
Chris@4 1390 uLong size_filename;
Chris@4 1391 uLong size_extra_field;
Chris@4 1392 int err=UNZ_OK;
Chris@4 1393
Chris@4 1394 *piSizeVar = 0;
Chris@4 1395 *poffset_local_extrafield = 0;
Chris@4 1396 *psize_local_extrafield = 0;
Chris@4 1397
Chris@4 1398 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
Chris@4 1399 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 1400 return UNZ_ERRNO;
Chris@4 1401
Chris@4 1402
Chris@4 1403 if (err==UNZ_OK)
Chris@4 1404 {
Chris@4 1405 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
Chris@4 1406 err=UNZ_ERRNO;
Chris@4 1407 else if (uMagic!=0x04034b50)
Chris@4 1408 err=UNZ_BADZIPFILE;
Chris@4 1409 }
Chris@4 1410
Chris@4 1411 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
Chris@4 1412 err=UNZ_ERRNO;
Chris@4 1413 /*
Chris@4 1414 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
Chris@4 1415 err=UNZ_BADZIPFILE;
Chris@4 1416 */
Chris@4 1417 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
Chris@4 1418 err=UNZ_ERRNO;
Chris@4 1419
Chris@4 1420 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
Chris@4 1421 err=UNZ_ERRNO;
Chris@4 1422 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
Chris@4 1423 err=UNZ_BADZIPFILE;
Chris@4 1424
Chris@4 1425 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
Chris@4 1426 /* #ifdef HAVE_BZIP2 */
Chris@4 1427 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
Chris@4 1428 /* #endif */
Chris@4 1429 (s->cur_file_info.compression_method!=Z_DEFLATED))
Chris@4 1430 err=UNZ_BADZIPFILE;
Chris@4 1431
Chris@4 1432 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
Chris@4 1433 err=UNZ_ERRNO;
Chris@4 1434
Chris@4 1435 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
Chris@4 1436 err=UNZ_ERRNO;
Chris@4 1437 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
Chris@4 1438 err=UNZ_BADZIPFILE;
Chris@4 1439
Chris@4 1440 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
Chris@4 1441 err=UNZ_ERRNO;
Chris@4 1442 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
Chris@4 1443 err=UNZ_BADZIPFILE;
Chris@4 1444
Chris@4 1445 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
Chris@4 1446 err=UNZ_ERRNO;
Chris@4 1447 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
Chris@4 1448 err=UNZ_BADZIPFILE;
Chris@4 1449
Chris@4 1450 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
Chris@4 1451 err=UNZ_ERRNO;
Chris@4 1452 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
Chris@4 1453 err=UNZ_BADZIPFILE;
Chris@4 1454
Chris@4 1455 *piSizeVar += (uInt)size_filename;
Chris@4 1456
Chris@4 1457 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
Chris@4 1458 err=UNZ_ERRNO;
Chris@4 1459 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
Chris@4 1460 SIZEZIPLOCALHEADER + size_filename;
Chris@4 1461 *psize_local_extrafield = (uInt)size_extra_field;
Chris@4 1462
Chris@4 1463 *piSizeVar += (uInt)size_extra_field;
Chris@4 1464
Chris@4 1465 return err;
Chris@4 1466 }
Chris@4 1467
Chris@4 1468 /*
Chris@4 1469 Open for reading data the current file in the zipfile.
Chris@4 1470 If there is no error and the file is opened, the return value is UNZ_OK.
Chris@4 1471 */
Chris@4 1472 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
Chris@4 1473 int* level, int raw, const char* password)
Chris@4 1474 {
Chris@4 1475 int err=UNZ_OK;
Chris@4 1476 uInt iSizeVar;
Chris@4 1477 unz64_s* s;
Chris@4 1478 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1479 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
Chris@4 1480 uInt size_local_extrafield; /* size of the local extra field */
Chris@4 1481 # ifndef NOUNCRYPT
Chris@4 1482 char source[12];
Chris@4 1483 # else
Chris@4 1484 if (password != NULL)
Chris@4 1485 return UNZ_PARAMERROR;
Chris@4 1486 # endif
Chris@4 1487
Chris@4 1488 if (file==NULL)
Chris@4 1489 return UNZ_PARAMERROR;
Chris@4 1490 s=(unz64_s*)file;
Chris@4 1491 if (!s->current_file_ok)
Chris@4 1492 return UNZ_PARAMERROR;
Chris@4 1493
Chris@4 1494 if (s->pfile_in_zip_read != NULL)
Chris@4 1495 unzCloseCurrentFile(file);
Chris@4 1496
Chris@4 1497 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
Chris@4 1498 return UNZ_BADZIPFILE;
Chris@4 1499
Chris@4 1500 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
Chris@4 1501 if (pfile_in_zip_read_info==NULL)
Chris@4 1502 return UNZ_INTERNALERROR;
Chris@4 1503
Chris@4 1504 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
Chris@4 1505 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
Chris@4 1506 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
Chris@4 1507 pfile_in_zip_read_info->pos_local_extrafield=0;
Chris@4 1508 pfile_in_zip_read_info->raw=raw;
Chris@4 1509
Chris@4 1510 if (pfile_in_zip_read_info->read_buffer==NULL)
Chris@4 1511 {
Chris@4 1512 TRYFREE(pfile_in_zip_read_info);
Chris@4 1513 return UNZ_INTERNALERROR;
Chris@4 1514 }
Chris@4 1515
Chris@4 1516 pfile_in_zip_read_info->stream_initialised=0;
Chris@4 1517
Chris@4 1518 if (method!=NULL)
Chris@4 1519 *method = (int)s->cur_file_info.compression_method;
Chris@4 1520
Chris@4 1521 if (level!=NULL)
Chris@4 1522 {
Chris@4 1523 *level = 6;
Chris@4 1524 switch (s->cur_file_info.flag & 0x06)
Chris@4 1525 {
Chris@4 1526 case 6 : *level = 1; break;
Chris@4 1527 case 4 : *level = 2; break;
Chris@4 1528 case 2 : *level = 9; break;
Chris@4 1529 }
Chris@4 1530 }
Chris@4 1531
Chris@4 1532 if ((s->cur_file_info.compression_method!=0) &&
Chris@4 1533 /* #ifdef HAVE_BZIP2 */
Chris@4 1534 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
Chris@4 1535 /* #endif */
Chris@4 1536 (s->cur_file_info.compression_method!=Z_DEFLATED))
Chris@4 1537
Chris@4 1538 err=UNZ_BADZIPFILE;
Chris@4 1539
Chris@4 1540 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
Chris@4 1541 pfile_in_zip_read_info->crc32=0;
Chris@4 1542 pfile_in_zip_read_info->total_out_64=0;
Chris@4 1543 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
Chris@4 1544 pfile_in_zip_read_info->filestream=s->filestream;
Chris@4 1545 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
Chris@4 1546 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
Chris@4 1547
Chris@4 1548 pfile_in_zip_read_info->stream.total_out = 0;
Chris@4 1549
Chris@4 1550 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
Chris@4 1551 {
Chris@4 1552 #ifdef HAVE_BZIP2
Chris@4 1553 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
Chris@4 1554 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
Chris@4 1555 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
Chris@4 1556 pfile_in_zip_read_info->bstream.state = (voidpf)0;
Chris@4 1557
Chris@4 1558 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
Chris@4 1559 pfile_in_zip_read_info->stream.zfree = (free_func)0;
Chris@4 1560 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
Chris@4 1561 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
Chris@4 1562 pfile_in_zip_read_info->stream.avail_in = 0;
Chris@4 1563
Chris@4 1564 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
Chris@4 1565 if (err == Z_OK)
Chris@4 1566 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
Chris@4 1567 else
Chris@4 1568 {
Chris@4 1569 TRYFREE(pfile_in_zip_read_info);
Chris@4 1570 return err;
Chris@4 1571 }
Chris@4 1572 #else
Chris@4 1573 pfile_in_zip_read_info->raw=1;
Chris@4 1574 #endif
Chris@4 1575 }
Chris@4 1576 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
Chris@4 1577 {
Chris@4 1578 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
Chris@4 1579 pfile_in_zip_read_info->stream.zfree = (free_func)0;
Chris@4 1580 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
Chris@4 1581 pfile_in_zip_read_info->stream.next_in = 0;
Chris@4 1582 pfile_in_zip_read_info->stream.avail_in = 0;
Chris@4 1583
Chris@4 1584 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
Chris@4 1585 if (err == Z_OK)
Chris@4 1586 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
Chris@4 1587 else
Chris@4 1588 {
Chris@4 1589 TRYFREE(pfile_in_zip_read_info);
Chris@4 1590 return err;
Chris@4 1591 }
Chris@4 1592 /* windowBits is passed < 0 to tell that there is no zlib header.
Chris@4 1593 * Note that in this case inflate *requires* an extra "dummy" byte
Chris@4 1594 * after the compressed stream in order to complete decompression and
Chris@4 1595 * return Z_STREAM_END.
Chris@4 1596 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
Chris@4 1597 * size of both compressed and uncompressed data
Chris@4 1598 */
Chris@4 1599 }
Chris@4 1600 pfile_in_zip_read_info->rest_read_compressed =
Chris@4 1601 s->cur_file_info.compressed_size ;
Chris@4 1602 pfile_in_zip_read_info->rest_read_uncompressed =
Chris@4 1603 s->cur_file_info.uncompressed_size ;
Chris@4 1604
Chris@4 1605
Chris@4 1606 pfile_in_zip_read_info->pos_in_zipfile =
Chris@4 1607 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
Chris@4 1608 iSizeVar;
Chris@4 1609
Chris@4 1610 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
Chris@4 1611
Chris@4 1612 s->pfile_in_zip_read = pfile_in_zip_read_info;
Chris@4 1613 s->encrypted = 0;
Chris@4 1614
Chris@4 1615 # ifndef NOUNCRYPT
Chris@4 1616 if (password != NULL)
Chris@4 1617 {
Chris@4 1618 int i;
Chris@4 1619 s->pcrc_32_tab = get_crc_table();
Chris@4 1620 init_keys(password,s->keys,s->pcrc_32_tab);
Chris@4 1621 if (ZSEEK64(s->z_filefunc, s->filestream,
Chris@4 1622 s->pfile_in_zip_read->pos_in_zipfile +
Chris@4 1623 s->pfile_in_zip_read->byte_before_the_zipfile,
Chris@4 1624 SEEK_SET)!=0)
Chris@4 1625 return UNZ_INTERNALERROR;
Chris@4 1626 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
Chris@4 1627 return UNZ_INTERNALERROR;
Chris@4 1628
Chris@4 1629 for (i = 0; i<12; i++)
Chris@4 1630 zdecode(s->keys,s->pcrc_32_tab,source[i]);
Chris@4 1631
Chris@4 1632 s->pfile_in_zip_read->pos_in_zipfile+=12;
Chris@4 1633 s->encrypted=1;
Chris@4 1634 }
Chris@4 1635 # endif
Chris@4 1636
Chris@4 1637
Chris@4 1638 return UNZ_OK;
Chris@4 1639 }
Chris@4 1640
Chris@4 1641 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
Chris@4 1642 {
Chris@4 1643 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
Chris@4 1644 }
Chris@4 1645
Chris@4 1646 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
Chris@4 1647 {
Chris@4 1648 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
Chris@4 1649 }
Chris@4 1650
Chris@4 1651 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
Chris@4 1652 {
Chris@4 1653 return unzOpenCurrentFile3(file, method, level, raw, NULL);
Chris@4 1654 }
Chris@4 1655
Chris@4 1656 /** Addition for GDAL : START */
Chris@4 1657
Chris@4 1658 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
Chris@4 1659 {
Chris@4 1660 unz64_s* s;
Chris@4 1661 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1662 s=(unz64_s*)file;
Chris@4 1663 if (file==NULL)
Chris@4 1664 return 0; //UNZ_PARAMERROR;
Chris@4 1665 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1666 if (pfile_in_zip_read_info==NULL)
Chris@4 1667 return 0; //UNZ_PARAMERROR;
Chris@4 1668 return pfile_in_zip_read_info->pos_in_zipfile +
Chris@4 1669 pfile_in_zip_read_info->byte_before_the_zipfile;
Chris@4 1670 }
Chris@4 1671
Chris@4 1672 /** Addition for GDAL : END */
Chris@4 1673
Chris@4 1674 /*
Chris@4 1675 Read bytes from the current file.
Chris@4 1676 buf contain buffer where data must be copied
Chris@4 1677 len the size of buf.
Chris@4 1678
Chris@4 1679 return the number of byte copied if somes bytes are copied
Chris@4 1680 return 0 if the end of file was reached
Chris@4 1681 return <0 with error code if there is an error
Chris@4 1682 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
Chris@4 1683 */
Chris@4 1684 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
Chris@4 1685 {
Chris@4 1686 int err=UNZ_OK;
Chris@4 1687 uInt iRead = 0;
Chris@4 1688 unz64_s* s;
Chris@4 1689 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1690 if (file==NULL)
Chris@4 1691 return UNZ_PARAMERROR;
Chris@4 1692 s=(unz64_s*)file;
Chris@4 1693 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1694
Chris@4 1695 if (pfile_in_zip_read_info==NULL)
Chris@4 1696 return UNZ_PARAMERROR;
Chris@4 1697
Chris@4 1698
Chris@4 1699 if (pfile_in_zip_read_info->read_buffer == NULL)
Chris@4 1700 return UNZ_END_OF_LIST_OF_FILE;
Chris@4 1701 if (len==0)
Chris@4 1702 return 0;
Chris@4 1703
Chris@4 1704 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
Chris@4 1705
Chris@4 1706 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
Chris@4 1707
Chris@4 1708 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
Chris@4 1709 (!(pfile_in_zip_read_info->raw)))
Chris@4 1710 pfile_in_zip_read_info->stream.avail_out =
Chris@4 1711 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
Chris@4 1712
Chris@4 1713 if ((len>pfile_in_zip_read_info->rest_read_compressed+
Chris@4 1714 pfile_in_zip_read_info->stream.avail_in) &&
Chris@4 1715 (pfile_in_zip_read_info->raw))
Chris@4 1716 pfile_in_zip_read_info->stream.avail_out =
Chris@4 1717 (uInt)pfile_in_zip_read_info->rest_read_compressed+
Chris@4 1718 pfile_in_zip_read_info->stream.avail_in;
Chris@4 1719
Chris@4 1720 while (pfile_in_zip_read_info->stream.avail_out>0)
Chris@4 1721 {
Chris@4 1722 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
Chris@4 1723 (pfile_in_zip_read_info->rest_read_compressed>0))
Chris@4 1724 {
Chris@4 1725 uInt uReadThis = UNZ_BUFSIZE;
Chris@4 1726 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
Chris@4 1727 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
Chris@4 1728 if (uReadThis == 0)
Chris@4 1729 return UNZ_EOF;
Chris@4 1730 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
Chris@4 1731 pfile_in_zip_read_info->filestream,
Chris@4 1732 pfile_in_zip_read_info->pos_in_zipfile +
Chris@4 1733 pfile_in_zip_read_info->byte_before_the_zipfile,
Chris@4 1734 ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 1735 return UNZ_ERRNO;
Chris@4 1736 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
Chris@4 1737 pfile_in_zip_read_info->filestream,
Chris@4 1738 pfile_in_zip_read_info->read_buffer,
Chris@4 1739 uReadThis)!=uReadThis)
Chris@4 1740 return UNZ_ERRNO;
Chris@4 1741
Chris@4 1742
Chris@4 1743 # ifndef NOUNCRYPT
Chris@4 1744 if(s->encrypted)
Chris@4 1745 {
Chris@4 1746 uInt i;
Chris@4 1747 for(i=0;i<uReadThis;i++)
Chris@4 1748 pfile_in_zip_read_info->read_buffer[i] =
Chris@4 1749 zdecode(s->keys,s->pcrc_32_tab,
Chris@4 1750 pfile_in_zip_read_info->read_buffer[i]);
Chris@4 1751 }
Chris@4 1752 # endif
Chris@4 1753
Chris@4 1754
Chris@4 1755 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
Chris@4 1756
Chris@4 1757 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
Chris@4 1758
Chris@4 1759 pfile_in_zip_read_info->stream.next_in =
Chris@4 1760 (Bytef*)pfile_in_zip_read_info->read_buffer;
Chris@4 1761 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
Chris@4 1762 }
Chris@4 1763
Chris@4 1764 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
Chris@4 1765 {
Chris@4 1766 uInt uDoCopy,i ;
Chris@4 1767
Chris@4 1768 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
Chris@4 1769 (pfile_in_zip_read_info->rest_read_compressed == 0))
Chris@4 1770 return (iRead==0) ? UNZ_EOF : iRead;
Chris@4 1771
Chris@4 1772 if (pfile_in_zip_read_info->stream.avail_out <
Chris@4 1773 pfile_in_zip_read_info->stream.avail_in)
Chris@4 1774 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
Chris@4 1775 else
Chris@4 1776 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
Chris@4 1777
Chris@4 1778 for (i=0;i<uDoCopy;i++)
Chris@4 1779 *(pfile_in_zip_read_info->stream.next_out+i) =
Chris@4 1780 *(pfile_in_zip_read_info->stream.next_in+i);
Chris@4 1781
Chris@4 1782 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
Chris@4 1783
Chris@4 1784 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
Chris@4 1785 pfile_in_zip_read_info->stream.next_out,
Chris@4 1786 uDoCopy);
Chris@4 1787 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
Chris@4 1788 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
Chris@4 1789 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
Chris@4 1790 pfile_in_zip_read_info->stream.next_out += uDoCopy;
Chris@4 1791 pfile_in_zip_read_info->stream.next_in += uDoCopy;
Chris@4 1792 pfile_in_zip_read_info->stream.total_out += uDoCopy;
Chris@4 1793 iRead += uDoCopy;
Chris@4 1794 }
Chris@4 1795 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
Chris@4 1796 {
Chris@4 1797 #ifdef HAVE_BZIP2
Chris@4 1798 uLong uTotalOutBefore,uTotalOutAfter;
Chris@4 1799 const Bytef *bufBefore;
Chris@4 1800 uLong uOutThis;
Chris@4 1801
Chris@4 1802 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
Chris@4 1803 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
Chris@4 1804 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
Chris@4 1805 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
Chris@4 1806 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
Chris@4 1807 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
Chris@4 1808 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
Chris@4 1809 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
Chris@4 1810
Chris@4 1811 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
Chris@4 1812 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
Chris@4 1813
Chris@4 1814 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
Chris@4 1815
Chris@4 1816 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
Chris@4 1817 uOutThis = uTotalOutAfter-uTotalOutBefore;
Chris@4 1818
Chris@4 1819 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
Chris@4 1820
Chris@4 1821 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
Chris@4 1822 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
Chris@4 1823 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
Chris@4 1824
Chris@4 1825 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
Chris@4 1826 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
Chris@4 1827 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
Chris@4 1828 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
Chris@4 1829 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
Chris@4 1830 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
Chris@4 1831
Chris@4 1832 if (err==BZ_STREAM_END)
Chris@4 1833 return (iRead==0) ? UNZ_EOF : iRead;
Chris@4 1834 if (err!=BZ_OK)
Chris@4 1835 break;
Chris@4 1836 #endif
Chris@4 1837 } // end Z_BZIP2ED
Chris@4 1838 else
Chris@4 1839 {
Chris@4 1840 ZPOS64_T uTotalOutBefore,uTotalOutAfter;
Chris@4 1841 const Bytef *bufBefore;
Chris@4 1842 ZPOS64_T uOutThis;
Chris@4 1843 int flush=Z_SYNC_FLUSH;
Chris@4 1844
Chris@4 1845 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
Chris@4 1846 bufBefore = pfile_in_zip_read_info->stream.next_out;
Chris@4 1847
Chris@4 1848 /*
Chris@4 1849 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
Chris@4 1850 pfile_in_zip_read_info->stream.avail_out) &&
Chris@4 1851 (pfile_in_zip_read_info->rest_read_compressed == 0))
Chris@4 1852 flush = Z_FINISH;
Chris@4 1853 */
Chris@4 1854 err=inflate(&pfile_in_zip_read_info->stream,flush);
Chris@4 1855
Chris@4 1856 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
Chris@4 1857 err = Z_DATA_ERROR;
Chris@4 1858
Chris@4 1859 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
Chris@4 1860 uOutThis = uTotalOutAfter-uTotalOutBefore;
Chris@4 1861
Chris@4 1862 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
Chris@4 1863
Chris@4 1864 pfile_in_zip_read_info->crc32 =
Chris@4 1865 crc32(pfile_in_zip_read_info->crc32,bufBefore,
Chris@4 1866 (uInt)(uOutThis));
Chris@4 1867
Chris@4 1868 pfile_in_zip_read_info->rest_read_uncompressed -=
Chris@4 1869 uOutThis;
Chris@4 1870
Chris@4 1871 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
Chris@4 1872
Chris@4 1873 if (err==Z_STREAM_END)
Chris@4 1874 return (iRead==0) ? UNZ_EOF : iRead;
Chris@4 1875 if (err!=Z_OK)
Chris@4 1876 break;
Chris@4 1877 }
Chris@4 1878 }
Chris@4 1879
Chris@4 1880 if (err==Z_OK)
Chris@4 1881 return iRead;
Chris@4 1882 return err;
Chris@4 1883 }
Chris@4 1884
Chris@4 1885
Chris@4 1886 /*
Chris@4 1887 Give the current position in uncompressed data
Chris@4 1888 */
Chris@4 1889 extern z_off_t ZEXPORT unztell (unzFile file)
Chris@4 1890 {
Chris@4 1891 unz64_s* s;
Chris@4 1892 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1893 if (file==NULL)
Chris@4 1894 return UNZ_PARAMERROR;
Chris@4 1895 s=(unz64_s*)file;
Chris@4 1896 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1897
Chris@4 1898 if (pfile_in_zip_read_info==NULL)
Chris@4 1899 return UNZ_PARAMERROR;
Chris@4 1900
Chris@4 1901 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
Chris@4 1902 }
Chris@4 1903
Chris@4 1904 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
Chris@4 1905 {
Chris@4 1906
Chris@4 1907 unz64_s* s;
Chris@4 1908 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1909 if (file==NULL)
Chris@4 1910 return (ZPOS64_T)-1;
Chris@4 1911 s=(unz64_s*)file;
Chris@4 1912 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1913
Chris@4 1914 if (pfile_in_zip_read_info==NULL)
Chris@4 1915 return (ZPOS64_T)-1;
Chris@4 1916
Chris@4 1917 return pfile_in_zip_read_info->total_out_64;
Chris@4 1918 }
Chris@4 1919
Chris@4 1920
Chris@4 1921 /*
Chris@4 1922 return 1 if the end of file was reached, 0 elsewhere
Chris@4 1923 */
Chris@4 1924 extern int ZEXPORT unzeof (unzFile file)
Chris@4 1925 {
Chris@4 1926 unz64_s* s;
Chris@4 1927 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1928 if (file==NULL)
Chris@4 1929 return UNZ_PARAMERROR;
Chris@4 1930 s=(unz64_s*)file;
Chris@4 1931 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1932
Chris@4 1933 if (pfile_in_zip_read_info==NULL)
Chris@4 1934 return UNZ_PARAMERROR;
Chris@4 1935
Chris@4 1936 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
Chris@4 1937 return 1;
Chris@4 1938 else
Chris@4 1939 return 0;
Chris@4 1940 }
Chris@4 1941
Chris@4 1942
Chris@4 1943
Chris@4 1944 /*
Chris@4 1945 Read extra field from the current file (opened by unzOpenCurrentFile)
Chris@4 1946 This is the local-header version of the extra field (sometimes, there is
Chris@4 1947 more info in the local-header version than in the central-header)
Chris@4 1948
Chris@4 1949 if buf==NULL, it return the size of the local extra field that can be read
Chris@4 1950
Chris@4 1951 if buf!=NULL, len is the size of the buffer, the extra header is copied in
Chris@4 1952 buf.
Chris@4 1953 the return value is the number of bytes copied in buf, or (if <0)
Chris@4 1954 the error code
Chris@4 1955 */
Chris@4 1956 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
Chris@4 1957 {
Chris@4 1958 unz64_s* s;
Chris@4 1959 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 1960 uInt read_now;
Chris@4 1961 ZPOS64_T size_to_read;
Chris@4 1962
Chris@4 1963 if (file==NULL)
Chris@4 1964 return UNZ_PARAMERROR;
Chris@4 1965 s=(unz64_s*)file;
Chris@4 1966 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 1967
Chris@4 1968 if (pfile_in_zip_read_info==NULL)
Chris@4 1969 return UNZ_PARAMERROR;
Chris@4 1970
Chris@4 1971 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
Chris@4 1972 pfile_in_zip_read_info->pos_local_extrafield);
Chris@4 1973
Chris@4 1974 if (buf==NULL)
Chris@4 1975 return (int)size_to_read;
Chris@4 1976
Chris@4 1977 if (len>size_to_read)
Chris@4 1978 read_now = (uInt)size_to_read;
Chris@4 1979 else
Chris@4 1980 read_now = (uInt)len ;
Chris@4 1981
Chris@4 1982 if (read_now==0)
Chris@4 1983 return 0;
Chris@4 1984
Chris@4 1985 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
Chris@4 1986 pfile_in_zip_read_info->filestream,
Chris@4 1987 pfile_in_zip_read_info->offset_local_extrafield +
Chris@4 1988 pfile_in_zip_read_info->pos_local_extrafield,
Chris@4 1989 ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 1990 return UNZ_ERRNO;
Chris@4 1991
Chris@4 1992 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
Chris@4 1993 pfile_in_zip_read_info->filestream,
Chris@4 1994 buf,read_now)!=read_now)
Chris@4 1995 return UNZ_ERRNO;
Chris@4 1996
Chris@4 1997 return (int)read_now;
Chris@4 1998 }
Chris@4 1999
Chris@4 2000 /*
Chris@4 2001 Close the file in zip opened with unzipOpenCurrentFile
Chris@4 2002 Return UNZ_CRCERROR if all the file was read but the CRC is not good
Chris@4 2003 */
Chris@4 2004 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
Chris@4 2005 {
Chris@4 2006 int err=UNZ_OK;
Chris@4 2007
Chris@4 2008 unz64_s* s;
Chris@4 2009 file_in_zip64_read_info_s* pfile_in_zip_read_info;
Chris@4 2010 if (file==NULL)
Chris@4 2011 return UNZ_PARAMERROR;
Chris@4 2012 s=(unz64_s*)file;
Chris@4 2013 pfile_in_zip_read_info=s->pfile_in_zip_read;
Chris@4 2014
Chris@4 2015 if (pfile_in_zip_read_info==NULL)
Chris@4 2016 return UNZ_PARAMERROR;
Chris@4 2017
Chris@4 2018
Chris@4 2019 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
Chris@4 2020 (!pfile_in_zip_read_info->raw))
Chris@4 2021 {
Chris@4 2022 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
Chris@4 2023 err=UNZ_CRCERROR;
Chris@4 2024 }
Chris@4 2025
Chris@4 2026
Chris@4 2027 TRYFREE(pfile_in_zip_read_info->read_buffer);
Chris@4 2028 pfile_in_zip_read_info->read_buffer = NULL;
Chris@4 2029 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
Chris@4 2030 inflateEnd(&pfile_in_zip_read_info->stream);
Chris@4 2031 #ifdef HAVE_BZIP2
Chris@4 2032 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
Chris@4 2033 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
Chris@4 2034 #endif
Chris@4 2035
Chris@4 2036
Chris@4 2037 pfile_in_zip_read_info->stream_initialised = 0;
Chris@4 2038 TRYFREE(pfile_in_zip_read_info);
Chris@4 2039
Chris@4 2040 s->pfile_in_zip_read=NULL;
Chris@4 2041
Chris@4 2042 return err;
Chris@4 2043 }
Chris@4 2044
Chris@4 2045
Chris@4 2046 /*
Chris@4 2047 Get the global comment string of the ZipFile, in the szComment buffer.
Chris@4 2048 uSizeBuf is the size of the szComment buffer.
Chris@4 2049 return the number of byte copied or an error code <0
Chris@4 2050 */
Chris@4 2051 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
Chris@4 2052 {
Chris@4 2053 unz64_s* s;
Chris@4 2054 uLong uReadThis ;
Chris@4 2055 if (file==NULL)
Chris@4 2056 return (int)UNZ_PARAMERROR;
Chris@4 2057 s=(unz64_s*)file;
Chris@4 2058
Chris@4 2059 uReadThis = uSizeBuf;
Chris@4 2060 if (uReadThis>s->gi.size_comment)
Chris@4 2061 uReadThis = s->gi.size_comment;
Chris@4 2062
Chris@4 2063 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
Chris@4 2064 return UNZ_ERRNO;
Chris@4 2065
Chris@4 2066 if (uReadThis>0)
Chris@4 2067 {
Chris@4 2068 *szComment='\0';
Chris@4 2069 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
Chris@4 2070 return UNZ_ERRNO;
Chris@4 2071 }
Chris@4 2072
Chris@4 2073 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
Chris@4 2074 *(szComment+s->gi.size_comment)='\0';
Chris@4 2075 return (int)uReadThis;
Chris@4 2076 }
Chris@4 2077
Chris@4 2078 /* Additions by RX '2004 */
Chris@4 2079 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
Chris@4 2080 {
Chris@4 2081 unz64_s* s;
Chris@4 2082
Chris@4 2083 if (file==NULL)
Chris@4 2084 return 0; //UNZ_PARAMERROR;
Chris@4 2085 s=(unz64_s*)file;
Chris@4 2086 if (!s->current_file_ok)
Chris@4 2087 return 0;
Chris@4 2088 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
Chris@4 2089 if (s->num_file==s->gi.number_entry)
Chris@4 2090 return 0;
Chris@4 2091 return s->pos_in_central_dir;
Chris@4 2092 }
Chris@4 2093
Chris@4 2094 extern uLong ZEXPORT unzGetOffset (unzFile file)
Chris@4 2095 {
Chris@4 2096 ZPOS64_T offset64;
Chris@4 2097
Chris@4 2098 if (file==NULL)
Chris@4 2099 return 0; //UNZ_PARAMERROR;
Chris@4 2100 offset64 = unzGetOffset64(file);
Chris@4 2101 return (uLong)offset64;
Chris@4 2102 }
Chris@4 2103
Chris@4 2104 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
Chris@4 2105 {
Chris@4 2106 unz64_s* s;
Chris@4 2107 int err;
Chris@4 2108
Chris@4 2109 if (file==NULL)
Chris@4 2110 return UNZ_PARAMERROR;
Chris@4 2111 s=(unz64_s*)file;
Chris@4 2112
Chris@4 2113 s->pos_in_central_dir = pos;
Chris@4 2114 s->num_file = s->gi.number_entry; /* hack */
Chris@4 2115 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
Chris@4 2116 &s->cur_file_info_internal,
Chris@4 2117 NULL,0,NULL,0,NULL,0);
Chris@4 2118 s->current_file_ok = (err == UNZ_OK);
Chris@4 2119 return err;
Chris@4 2120 }
Chris@4 2121
Chris@4 2122 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
Chris@4 2123 {
Chris@4 2124 return unzSetOffset64(file,pos);
Chris@4 2125 }