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