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