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