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