|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: Zipped disc support, uses zlib ! 5: ! 6: This file is originally from the minizip code by Gilles Vollant ! 7: ! 8: */ ! 9: /* unzip.c -- IO on .zip files using zlib ! 10: Version 0.15 beta, Mar 19th, 1998, ! 11: ! 12: Read unzip.h for more info ! 13: */ ! 14: ! 15: ! 16: #include <stdio.h> ! 17: #include <stdlib.h> ! 18: #include <string.h> ! 19: #include "zlib.h" ! 20: #include "unzip.h" ! 21: ! 22: #ifdef STDC ! 23: # include <stddef.h> ! 24: # include <string.h> ! 25: # include <stdlib.h> ! 26: #endif ! 27: #ifdef NO_ERRNO_H ! 28: extern int errno; ! 29: #else ! 30: # include <errno.h> ! 31: #endif ! 32: ! 33: ! 34: #ifndef local ! 35: # define local static ! 36: #endif ! 37: /* compile with -Dlocal if your debugger can't find static symbols */ ! 38: ! 39: ! 40: ! 41: #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ ! 42: !defined(CASESENSITIVITYDEFAULT_NO) ! 43: #define CASESENSITIVITYDEFAULT_NO ! 44: #endif ! 45: ! 46: ! 47: #ifndef UNZ_BUFSIZE ! 48: #define UNZ_BUFSIZE (16384) ! 49: #endif ! 50: ! 51: #ifndef UNZ_MAXFILENAMEINZIP ! 52: #define UNZ_MAXFILENAMEINZIP (256) ! 53: #endif ! 54: ! 55: #ifndef ALLOC ! 56: # define ALLOC(size) (malloc(size)) ! 57: #endif ! 58: #ifndef TRYFREE ! 59: # define TRYFREE(p) {if (p) free(p);} ! 60: #endif ! 61: ! 62: #define SIZECENTRALDIRITEM (0x2e) ! 63: #define SIZEZIPLOCALHEADER (0x1e) ! 64: ! 65: ! 66: /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ ! 67: ! 68: #ifndef SEEK_CUR ! 69: #define SEEK_CUR 1 ! 70: #endif ! 71: ! 72: #ifndef SEEK_END ! 73: #define SEEK_END 2 ! 74: #endif ! 75: ! 76: #ifndef SEEK_SET ! 77: #define SEEK_SET 0 ! 78: #endif ! 79: ! 80: const char unz_copyright[] = ! 81: " unzip 0.15 Copyright 1998 Gilles Vollant "; ! 82: ! 83: /* unz_file_info_interntal contain internal info about a file in zipfile*/ ! 84: typedef struct unz_file_info_internal_s ! 85: { ! 86: uLong offset_curfile;/* relative offset of local header 4 bytes */ ! 87: } unz_file_info_internal; ! 88: ! 89: ! 90: /* file_in_zip_read_info_s contain internal information about a file in zipfile, ! 91: when reading and decompress it */ ! 92: typedef struct ! 93: { ! 94: char *read_buffer; /* internal buffer for compressed data */ ! 95: z_stream stream; /* zLib stream structure for inflate */ ! 96: ! 97: uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ ! 98: uLong stream_initialised; /* flag set if stream structure is initialised*/ ! 99: ! 100: uLong offset_local_extrafield;/* offset of the local extra field */ ! 101: uInt size_local_extrafield;/* size of the local extra field */ ! 102: uLong pos_local_extrafield; /* position in the local extra field in read*/ ! 103: ! 104: uLong crc32; /* crc32 of all data uncompressed */ ! 105: uLong crc32_wait; /* crc32 we must obtain after decompress all */ ! 106: uLong rest_read_compressed; /* number of byte to be decompressed */ ! 107: uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ ! 108: FILE* file; /* io structore of the zipfile */ ! 109: uLong compression_method; /* compression method (0==store) */ ! 110: uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ! 111: } file_in_zip_read_info_s; ! 112: ! 113: ! 114: /* unz_s contain internal information about the zipfile ! 115: */ ! 116: typedef struct ! 117: { ! 118: FILE* file; /* io structore of the zipfile */ ! 119: unz_global_info gi; /* public global information */ ! 120: uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ! 121: uLong num_file; /* number of the current file in the zipfile*/ ! 122: uLong pos_in_central_dir; /* pos of the current file in the central dir*/ ! 123: uLong current_file_ok; /* flag about the usability of the current file*/ ! 124: uLong central_pos; /* position of the beginning of the central dir*/ ! 125: ! 126: uLong size_central_dir; /* size of the central directory */ ! 127: uLong offset_central_dir; /* offset of start of central directory with ! 128: respect to the starting disk number */ ! 129: ! 130: unz_file_info cur_file_info; /* public info about the current file in zip*/ ! 131: unz_file_info_internal cur_file_info_internal; /* private info about it*/ ! 132: file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current ! 133: file if we are decompressing it */ ! 134: } unz_s; ! 135: ! 136: ! 137: /* =========================================================================== ! 138: Read a byte from a gz_stream; update next_in and avail_in. Return EOF ! 139: for end of file. ! 140: IN assertion: the stream s has been sucessfully opened for reading. ! 141: */ ! 142: ! 143: ! 144: local int unzlocal_getByte(fin,pi) ! 145: FILE *fin; ! 146: int *pi; ! 147: { ! 148: unsigned char c; ! 149: int err = fread(&c, 1, 1, fin); ! 150: if (err==1) ! 151: { ! 152: *pi = (int)c; ! 153: return UNZ_OK; ! 154: } ! 155: else ! 156: { ! 157: if (ferror(fin)) ! 158: return UNZ_ERRNO; ! 159: else ! 160: return UNZ_EOF; ! 161: } ! 162: } ! 163: ! 164: ! 165: /* =========================================================================== ! 166: Reads a long in LSB order from the given gz_stream. Sets ! 167: */ ! 168: local int unzlocal_getShort (fin,pX) ! 169: FILE* fin; ! 170: uLong *pX; ! 171: { ! 172: uLong x ; ! 173: int i; ! 174: int err; ! 175: ! 176: err = unzlocal_getByte(fin,&i); ! 177: x = (uLong)i; ! 178: ! 179: if (err==UNZ_OK) ! 180: err = unzlocal_getByte(fin,&i); ! 181: x += ((uLong)i)<<8; ! 182: ! 183: if (err==UNZ_OK) ! 184: *pX = x; ! 185: else ! 186: *pX = 0; ! 187: return err; ! 188: } ! 189: ! 190: local int unzlocal_getLong (fin,pX) ! 191: FILE* fin; ! 192: uLong *pX; ! 193: { ! 194: uLong x ; ! 195: int i; ! 196: int err; ! 197: ! 198: err = unzlocal_getByte(fin,&i); ! 199: x = (uLong)i; ! 200: ! 201: if (err==UNZ_OK) ! 202: err = unzlocal_getByte(fin,&i); ! 203: x += ((uLong)i)<<8; ! 204: ! 205: if (err==UNZ_OK) ! 206: err = unzlocal_getByte(fin,&i); ! 207: x += ((uLong)i)<<16; ! 208: ! 209: if (err==UNZ_OK) ! 210: err = unzlocal_getByte(fin,&i); ! 211: x += ((uLong)i)<<24; ! 212: ! 213: if (err==UNZ_OK) ! 214: *pX = x; ! 215: else ! 216: *pX = 0; ! 217: return err; ! 218: } ! 219: ! 220: ! 221: /* My own strcmpi / strcasecmp */ ! 222: local int strcmpcasenosensitive_internal (fileName1,fileName2) ! 223: const char* fileName1; ! 224: const char* fileName2; ! 225: { ! 226: for (;;) ! 227: { ! 228: char c1=*(fileName1++); ! 229: char c2=*(fileName2++); ! 230: if ((c1>='a') && (c1<='z')) ! 231: c1 -= 0x20; ! 232: if ((c2>='a') && (c2<='z')) ! 233: c2 -= 0x20; ! 234: if (c1=='\0') ! 235: return ((c2=='\0') ? 0 : -1); ! 236: if (c2=='\0') ! 237: return 1; ! 238: if (c1<c2) ! 239: return -1; ! 240: if (c1>c2) ! 241: return 1; ! 242: } ! 243: } ! 244: ! 245: ! 246: #ifdef CASESENSITIVITYDEFAULT_NO ! 247: #define CASESENSITIVITYDEFAULTVALUE 2 ! 248: #else ! 249: #define CASESENSITIVITYDEFAULTVALUE 1 ! 250: #endif ! 251: ! 252: #ifndef STRCMPCASENOSENTIVEFUNCTION ! 253: #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal ! 254: #endif ! 255: ! 256: /* ! 257: Compare two filename (fileName1,fileName2). ! 258: If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) ! 259: If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi ! 260: or strcasecmp) ! 261: If iCaseSenisivity = 0, case sensitivity is defaut of your operating system ! 262: (like 1 on Unix, 2 on Windows) ! 263: ! 264: */ ! 265: extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) ! 266: const char* fileName1; ! 267: const char* fileName2; ! 268: int iCaseSensitivity; ! 269: { ! 270: if (iCaseSensitivity==0) ! 271: iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; ! 272: ! 273: if (iCaseSensitivity==1) ! 274: return strcmp(fileName1,fileName2); ! 275: ! 276: return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); ! 277: } ! 278: ! 279: #define BUFREADCOMMENT (0x400) ! 280: ! 281: /* ! 282: Locate the Central directory of a zipfile (at the end, just before ! 283: the global comment) ! 284: */ ! 285: local uLong unzlocal_SearchCentralDir(fin) ! 286: FILE *fin; ! 287: { ! 288: unsigned char* buf; ! 289: uLong uSizeFile; ! 290: uLong uBackRead; ! 291: uLong uMaxBack=0xffff; /* maximum size of global comment */ ! 292: uLong uPosFound=0; ! 293: ! 294: if (fseek(fin,0,SEEK_END) != 0) ! 295: return 0; ! 296: ! 297: ! 298: uSizeFile = ftell( fin ); ! 299: ! 300: if (uMaxBack>uSizeFile) ! 301: uMaxBack = uSizeFile; ! 302: ! 303: buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); ! 304: if (buf==NULL) ! 305: return 0; ! 306: ! 307: uBackRead = 4; ! 308: while (uBackRead<uMaxBack) ! 309: { ! 310: uLong uReadSize,uReadPos ; ! 311: int i; ! 312: if (uBackRead+BUFREADCOMMENT>uMaxBack) ! 313: uBackRead = uMaxBack; ! 314: else ! 315: uBackRead+=BUFREADCOMMENT; ! 316: uReadPos = uSizeFile-uBackRead ; ! 317: ! 318: uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? ! 319: (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); ! 320: if (fseek(fin,uReadPos,SEEK_SET)!=0) ! 321: break; ! 322: ! 323: if (fread(buf,(uInt)uReadSize,1,fin)!=1) ! 324: break; ! 325: ! 326: for (i=(int)uReadSize-3; (i--)>0;) ! 327: if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ! 328: ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) ! 329: { ! 330: uPosFound = uReadPos+i; ! 331: break; ! 332: } ! 333: ! 334: if (uPosFound!=0) ! 335: break; ! 336: } ! 337: TRYFREE(buf); ! 338: return uPosFound; ! 339: } ! 340: ! 341: /* ! 342: Open a Zip file. path contain the full pathname (by example, ! 343: on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer ! 344: "zlib/zlib109.zip". ! 345: If the zipfile cannot be opened (file don't exist or in not valid), the ! 346: return value is NULL. ! 347: Else, the return value is a unzFile Handle, usable with other function ! 348: of this unzip package. ! 349: */ ! 350: extern unzFile ZEXPORT unzOpen (path) ! 351: const char *path; ! 352: { ! 353: unz_s us; ! 354: unz_s *s; ! 355: uLong central_pos,uL; ! 356: FILE * fin ; ! 357: ! 358: uLong number_disk; /* number of the current dist, used for ! 359: spaning ZIP, unsupported, always 0*/ ! 360: uLong number_disk_with_CD; /* number the the disk with central dir, used ! 361: for spaning ZIP, unsupported, always 0*/ ! 362: uLong number_entry_CD; /* total number of entries in ! 363: the central dir ! 364: (same than number_entry on nospan) */ ! 365: ! 366: int err=UNZ_OK; ! 367: ! 368: if (unz_copyright[0]!=' ') ! 369: return NULL; ! 370: ! 371: fin=fopen(path,"rb"); ! 372: if (fin==NULL) ! 373: return NULL; ! 374: ! 375: central_pos = unzlocal_SearchCentralDir(fin); ! 376: if (central_pos==0) ! 377: err=UNZ_ERRNO; ! 378: ! 379: if (fseek(fin,central_pos,SEEK_SET)!=0) ! 380: err=UNZ_ERRNO; ! 381: ! 382: /* the signature, already checked */ ! 383: if (unzlocal_getLong(fin,&uL)!=UNZ_OK) ! 384: err=UNZ_ERRNO; ! 385: ! 386: /* number of this disk */ ! 387: if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) ! 388: err=UNZ_ERRNO; ! 389: ! 390: /* number of the disk with the start of the central directory */ ! 391: if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) ! 392: err=UNZ_ERRNO; ! 393: ! 394: /* total number of entries in the central dir on this disk */ ! 395: if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) ! 396: err=UNZ_ERRNO; ! 397: ! 398: /* total number of entries in the central dir */ ! 399: if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) ! 400: err=UNZ_ERRNO; ! 401: ! 402: if ((number_entry_CD!=us.gi.number_entry) || ! 403: (number_disk_with_CD!=0) || ! 404: (number_disk!=0)) ! 405: err=UNZ_BADZIPFILE; ! 406: ! 407: /* size of the central directory */ ! 408: if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) ! 409: err=UNZ_ERRNO; ! 410: ! 411: /* offset of start of central directory with respect to the ! 412: starting disk number */ ! 413: if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) ! 414: err=UNZ_ERRNO; ! 415: ! 416: /* zipfile comment length */ ! 417: if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) ! 418: err=UNZ_ERRNO; ! 419: ! 420: if ((central_pos<us.offset_central_dir+us.size_central_dir) && ! 421: (err==UNZ_OK)) ! 422: err=UNZ_BADZIPFILE; ! 423: ! 424: if (err!=UNZ_OK) ! 425: { ! 426: fclose(fin); ! 427: return NULL; ! 428: } ! 429: ! 430: us.file=fin; ! 431: us.byte_before_the_zipfile = central_pos - ! 432: (us.offset_central_dir+us.size_central_dir); ! 433: us.central_pos = central_pos; ! 434: us.pfile_in_zip_read = NULL; ! 435: ! 436: ! 437: s=(unz_s*)ALLOC(sizeof(unz_s)); ! 438: *s=us; ! 439: unzGoToFirstFile((unzFile)s); ! 440: return (unzFile)s; ! 441: } ! 442: ! 443: ! 444: /* ! 445: Close a ZipFile opened with unzipOpen. ! 446: If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), ! 447: these files MUST be closed with unzipCloseCurrentFile before call unzipClose. ! 448: return UNZ_OK if there is no problem. */ ! 449: extern int ZEXPORT unzClose (file) ! 450: unzFile file; ! 451: { ! 452: unz_s* s; ! 453: if (file==NULL) ! 454: return UNZ_PARAMERROR; ! 455: s=(unz_s*)file; ! 456: ! 457: if (s->pfile_in_zip_read!=NULL) ! 458: unzCloseCurrentFile(file); ! 459: ! 460: fclose(s->file); ! 461: TRYFREE(s); ! 462: return UNZ_OK; ! 463: } ! 464: ! 465: ! 466: /* ! 467: Write info about the ZipFile in the *pglobal_info structure. ! 468: No preparation of the structure is needed ! 469: return UNZ_OK if there is no problem. */ ! 470: extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) ! 471: unzFile file; ! 472: unz_global_info *pglobal_info; ! 473: { ! 474: unz_s* s; ! 475: if (file==NULL) ! 476: return UNZ_PARAMERROR; ! 477: s=(unz_s*)file; ! 478: *pglobal_info=s->gi; ! 479: return UNZ_OK; ! 480: } ! 481: ! 482: ! 483: /* ! 484: Translate date/time from Dos format to tm_unz (readable more easilty) ! 485: */ ! 486: local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) ! 487: uLong ulDosDate; ! 488: tm_unz* ptm; ! 489: { ! 490: uLong uDate; ! 491: uDate = (uLong)(ulDosDate>>16); ! 492: ptm->tm_mday = (uInt)(uDate&0x1f) ; ! 493: ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ! 494: ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ! 495: ! 496: ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ! 497: ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ! 498: ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; ! 499: } ! 500: ! 501: /* ! 502: Get Info about the current file in the zipfile, with internal only info ! 503: */ ! 504: local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, ! 505: unz_file_info *pfile_info, ! 506: unz_file_info_internal ! 507: *pfile_info_internal, ! 508: char *szFileName, ! 509: uLong fileNameBufferSize, ! 510: void *extraField, ! 511: uLong extraFieldBufferSize, ! 512: char *szComment, ! 513: uLong commentBufferSize)); ! 514: ! 515: local int unzlocal_GetCurrentFileInfoInternal (file, ! 516: pfile_info, ! 517: pfile_info_internal, ! 518: szFileName, fileNameBufferSize, ! 519: extraField, extraFieldBufferSize, ! 520: szComment, commentBufferSize) ! 521: unzFile file; ! 522: unz_file_info *pfile_info; ! 523: unz_file_info_internal *pfile_info_internal; ! 524: char *szFileName; ! 525: uLong fileNameBufferSize; ! 526: void *extraField; ! 527: uLong extraFieldBufferSize; ! 528: char *szComment; ! 529: uLong commentBufferSize; ! 530: { ! 531: unz_s* s; ! 532: unz_file_info file_info; ! 533: unz_file_info_internal file_info_internal; ! 534: int err=UNZ_OK; ! 535: uLong uMagic; ! 536: long lSeek=0; ! 537: ! 538: if (file==NULL) ! 539: return UNZ_PARAMERROR; ! 540: s=(unz_s*)file; ! 541: if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) ! 542: err=UNZ_ERRNO; ! 543: ! 544: ! 545: /* we check the magic */ ! 546: if (err==UNZ_OK) ! 547: { ! 548: if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) ! 549: err=UNZ_ERRNO; ! 550: else if (uMagic!=0x02014b50) ! 551: err=UNZ_BADZIPFILE; ! 552: } ! 553: ! 554: if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) ! 555: err=UNZ_ERRNO; ! 556: ! 557: if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) ! 558: err=UNZ_ERRNO; ! 559: ! 560: if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) ! 561: err=UNZ_ERRNO; ! 562: ! 563: if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) ! 564: err=UNZ_ERRNO; ! 565: ! 566: if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) ! 567: err=UNZ_ERRNO; ! 568: ! 569: unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); ! 570: ! 571: if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) ! 572: err=UNZ_ERRNO; ! 573: ! 574: if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) ! 575: err=UNZ_ERRNO; ! 576: ! 577: if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) ! 578: err=UNZ_ERRNO; ! 579: ! 580: if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) ! 581: err=UNZ_ERRNO; ! 582: ! 583: if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) ! 584: err=UNZ_ERRNO; ! 585: ! 586: if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) ! 587: err=UNZ_ERRNO; ! 588: ! 589: if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) ! 590: err=UNZ_ERRNO; ! 591: ! 592: if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) ! 593: err=UNZ_ERRNO; ! 594: ! 595: if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) ! 596: err=UNZ_ERRNO; ! 597: ! 598: if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) ! 599: err=UNZ_ERRNO; ! 600: ! 601: lSeek+=file_info.size_filename; ! 602: if ((err==UNZ_OK) && (szFileName!=NULL)) ! 603: { ! 604: uLong uSizeRead ; ! 605: if (file_info.size_filename<fileNameBufferSize) ! 606: { ! 607: *(szFileName+file_info.size_filename)='\0'; ! 608: uSizeRead = file_info.size_filename; ! 609: } ! 610: else ! 611: uSizeRead = fileNameBufferSize; ! 612: ! 613: if ((file_info.size_filename>0) && (fileNameBufferSize>0)) ! 614: if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) ! 615: err=UNZ_ERRNO; ! 616: lSeek -= uSizeRead; ! 617: } ! 618: ! 619: ! 620: if ((err==UNZ_OK) && (extraField!=NULL)) ! 621: { ! 622: uLong uSizeRead ; ! 623: if (file_info.size_file_extra<extraFieldBufferSize) ! 624: { ! 625: uSizeRead = file_info.size_file_extra; ! 626: } else { ! 627: uSizeRead = extraFieldBufferSize; ! 628: } ! 629: ! 630: if (lSeek!=0) ! 631: { ! 632: if (fseek(s->file,lSeek,SEEK_CUR)==0) ! 633: { ! 634: lSeek=0; ! 635: } else { ! 636: err=UNZ_ERRNO; ! 637: } ! 638: } ! 639: if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) ! 640: if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) ! 641: err=UNZ_ERRNO; ! 642: lSeek += file_info.size_file_extra - uSizeRead; ! 643: } ! 644: else ! 645: lSeek+=file_info.size_file_extra; ! 646: ! 647: ! 648: if ((err==UNZ_OK) && (szComment!=NULL)) ! 649: { ! 650: uLong uSizeRead ; ! 651: if (file_info.size_file_comment<commentBufferSize) ! 652: { ! 653: *(szComment+file_info.size_file_comment)='\0'; ! 654: uSizeRead = file_info.size_file_comment; ! 655: } else { ! 656: uSizeRead = commentBufferSize; ! 657: } ! 658: ! 659: if (lSeek!=0) ! 660: { ! 661: if (fseek(s->file,lSeek,SEEK_CUR)==0) ! 662: { ! 663: lSeek=0; ! 664: } else { ! 665: err=UNZ_ERRNO; ! 666: } ! 667: } ! 668: if ((file_info.size_file_comment>0) && (commentBufferSize>0)) ! 669: if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) ! 670: err=UNZ_ERRNO; ! 671: lSeek+=file_info.size_file_comment - uSizeRead; ! 672: } ! 673: else ! 674: lSeek+=file_info.size_file_comment; ! 675: ! 676: if ((err==UNZ_OK) && (pfile_info!=NULL)) ! 677: *pfile_info=file_info; ! 678: ! 679: if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) ! 680: *pfile_info_internal=file_info_internal; ! 681: ! 682: return err; ! 683: } ! 684: ! 685: ! 686: ! 687: /* ! 688: Write info about the ZipFile in the *pglobal_info structure. ! 689: No preparation of the structure is needed ! 690: return UNZ_OK if there is no problem. ! 691: */ ! 692: extern int ZEXPORT unzGetCurrentFileInfo (file, ! 693: pfile_info, ! 694: szFileName, fileNameBufferSize, ! 695: extraField, extraFieldBufferSize, ! 696: szComment, commentBufferSize) ! 697: unzFile file; ! 698: unz_file_info *pfile_info; ! 699: char *szFileName; ! 700: uLong fileNameBufferSize; ! 701: void *extraField; ! 702: uLong extraFieldBufferSize; ! 703: char *szComment; ! 704: uLong commentBufferSize; ! 705: { ! 706: return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, ! 707: szFileName,fileNameBufferSize, ! 708: extraField,extraFieldBufferSize, ! 709: szComment,commentBufferSize); ! 710: } ! 711: ! 712: /* ! 713: Set the current file of the zipfile to the first file. ! 714: return UNZ_OK if there is no problem ! 715: */ ! 716: extern int ZEXPORT unzGoToFirstFile (file) ! 717: unzFile file; ! 718: { ! 719: int err=UNZ_OK; ! 720: unz_s* s; ! 721: if (file==NULL) ! 722: return UNZ_PARAMERROR; ! 723: s=(unz_s*)file; ! 724: s->pos_in_central_dir=s->offset_central_dir; ! 725: s->num_file=0; ! 726: err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ! 727: &s->cur_file_info_internal, ! 728: NULL,0,NULL,0,NULL,0); ! 729: s->current_file_ok = (err == UNZ_OK); ! 730: return err; ! 731: } ! 732: ! 733: ! 734: /* ! 735: Set the current file of the zipfile to the next file. ! 736: return UNZ_OK if there is no problem ! 737: return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. ! 738: */ ! 739: extern int ZEXPORT unzGoToNextFile (file) ! 740: unzFile file; ! 741: { ! 742: unz_s* s; ! 743: int err; ! 744: ! 745: if (file==NULL) ! 746: return UNZ_PARAMERROR; ! 747: s=(unz_s*)file; ! 748: if (!s->current_file_ok) ! 749: return UNZ_END_OF_LIST_OF_FILE; ! 750: if (s->num_file+1==s->gi.number_entry) ! 751: return UNZ_END_OF_LIST_OF_FILE; ! 752: ! 753: s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + ! 754: s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; ! 755: s->num_file++; ! 756: err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ! 757: &s->cur_file_info_internal, ! 758: NULL,0,NULL,0,NULL,0); ! 759: s->current_file_ok = (err == UNZ_OK); ! 760: return err; ! 761: } ! 762: ! 763: ! 764: /* ! 765: Try locate the file szFileName in the zipfile. ! 766: For the iCaseSensitivity signification, see unzipStringFileNameCompare ! 767: ! 768: return value : ! 769: UNZ_OK if the file is found. It becomes the current file. ! 770: UNZ_END_OF_LIST_OF_FILE if the file is not found ! 771: */ ! 772: extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) ! 773: unzFile file; ! 774: const char *szFileName; ! 775: int iCaseSensitivity; ! 776: { ! 777: unz_s* s; ! 778: int err; ! 779: ! 780: ! 781: uLong num_fileSaved; ! 782: uLong pos_in_central_dirSaved; ! 783: ! 784: ! 785: if (file==NULL) ! 786: return UNZ_PARAMERROR; ! 787: ! 788: if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) ! 789: return UNZ_PARAMERROR; ! 790: ! 791: s=(unz_s*)file; ! 792: if (!s->current_file_ok) ! 793: return UNZ_END_OF_LIST_OF_FILE; ! 794: ! 795: num_fileSaved = s->num_file; ! 796: pos_in_central_dirSaved = s->pos_in_central_dir; ! 797: ! 798: err = unzGoToFirstFile(file); ! 799: ! 800: while (err == UNZ_OK) ! 801: { ! 802: char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; ! 803: unzGetCurrentFileInfo(file,NULL, ! 804: szCurrentFileName,sizeof(szCurrentFileName)-1, ! 805: NULL,0,NULL,0); ! 806: if (unzStringFileNameCompare(szCurrentFileName, ! 807: szFileName,iCaseSensitivity)==0) ! 808: return UNZ_OK; ! 809: err = unzGoToNextFile(file); ! 810: } ! 811: ! 812: s->num_file = num_fileSaved ; ! 813: s->pos_in_central_dir = pos_in_central_dirSaved ; ! 814: return err; ! 815: } ! 816: ! 817: ! 818: /* ! 819: Read the local header of the current zipfile ! 820: Check the coherency of the local header and info in the end of central ! 821: directory about this file ! 822: store in *piSizeVar the size of extra info in local header ! 823: (filename and size of extra field data) ! 824: */ ! 825: local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, ! 826: poffset_local_extrafield, ! 827: psize_local_extrafield) ! 828: unz_s* s; ! 829: uInt* piSizeVar; ! 830: uLong *poffset_local_extrafield; ! 831: uInt *psize_local_extrafield; ! 832: { ! 833: uLong uMagic,uData,uFlags; ! 834: uLong size_filename; ! 835: uLong size_extra_field; ! 836: int err=UNZ_OK; ! 837: ! 838: *piSizeVar = 0; ! 839: *poffset_local_extrafield = 0; ! 840: *psize_local_extrafield = 0; ! 841: ! 842: if (fseek(s->file,s->cur_file_info_internal.offset_curfile + ! 843: s->byte_before_the_zipfile,SEEK_SET)!=0) ! 844: return UNZ_ERRNO; ! 845: ! 846: if (err==UNZ_OK) ! 847: { ! 848: if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) ! 849: err=UNZ_ERRNO; ! 850: else if (uMagic!=0x04034b50) ! 851: err=UNZ_BADZIPFILE; ! 852: } ! 853: ! 854: if (unzlocal_getShort(s->file,&uData) != UNZ_OK) ! 855: err=UNZ_ERRNO; ! 856: /* ! 857: else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) ! 858: err=UNZ_BADZIPFILE; ! 859: */ ! 860: if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) ! 861: err=UNZ_ERRNO; ! 862: ! 863: if (unzlocal_getShort(s->file,&uData) != UNZ_OK) ! 864: err=UNZ_ERRNO; ! 865: else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) ! 866: err=UNZ_BADZIPFILE; ! 867: ! 868: if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && ! 869: (s->cur_file_info.compression_method!=Z_DEFLATED)) ! 870: err=UNZ_BADZIPFILE; ! 871: ! 872: if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ ! 873: err=UNZ_ERRNO; ! 874: ! 875: if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ ! 876: err=UNZ_ERRNO; ! 877: else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ! 878: ((uFlags & 8)==0)) ! 879: err=UNZ_BADZIPFILE; ! 880: ! 881: if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ ! 882: err=UNZ_ERRNO; ! 883: else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ! 884: ((uFlags & 8)==0)) ! 885: err=UNZ_BADZIPFILE; ! 886: ! 887: if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ ! 888: err=UNZ_ERRNO; ! 889: else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ! 890: ((uFlags & 8)==0)) ! 891: err=UNZ_BADZIPFILE; ! 892: ! 893: ! 894: if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) ! 895: err=UNZ_ERRNO; ! 896: else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) ! 897: err=UNZ_BADZIPFILE; ! 898: ! 899: *piSizeVar += (uInt)size_filename; ! 900: ! 901: if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) ! 902: err=UNZ_ERRNO; ! 903: *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + ! 904: SIZEZIPLOCALHEADER + size_filename; ! 905: *psize_local_extrafield = (uInt)size_extra_field; ! 906: ! 907: *piSizeVar += (uInt)size_extra_field; ! 908: ! 909: return err; ! 910: } ! 911: ! 912: /* ! 913: Open for reading data the current file in the zipfile. ! 914: If there is no error and the file is opened, the return value is UNZ_OK. ! 915: */ ! 916: extern int ZEXPORT unzOpenCurrentFile (file) ! 917: unzFile file; ! 918: { ! 919: int err=UNZ_OK; ! 920: int Store; ! 921: uInt iSizeVar; ! 922: unz_s* s; ! 923: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 924: uLong offset_local_extrafield; /* offset of the local extra field */ ! 925: uInt size_local_extrafield; /* size of the local extra field */ ! 926: ! 927: if (file==NULL) ! 928: return UNZ_PARAMERROR; ! 929: s=(unz_s*)file; ! 930: if (!s->current_file_ok) ! 931: return UNZ_PARAMERROR; ! 932: ! 933: if (s->pfile_in_zip_read != NULL) ! 934: unzCloseCurrentFile(file); ! 935: ! 936: if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, ! 937: &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) ! 938: return UNZ_BADZIPFILE; ! 939: ! 940: pfile_in_zip_read_info = (file_in_zip_read_info_s*) ! 941: ALLOC(sizeof(file_in_zip_read_info_s)); ! 942: if (pfile_in_zip_read_info==NULL) ! 943: return UNZ_INTERNALERROR; ! 944: ! 945: pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); ! 946: pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; ! 947: pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; ! 948: pfile_in_zip_read_info->pos_local_extrafield=0; ! 949: ! 950: if (pfile_in_zip_read_info->read_buffer==NULL) ! 951: { ! 952: TRYFREE(pfile_in_zip_read_info); ! 953: return UNZ_INTERNALERROR; ! 954: } ! 955: ! 956: pfile_in_zip_read_info->stream_initialised=0; ! 957: ! 958: if ((s->cur_file_info.compression_method!=0) && ! 959: (s->cur_file_info.compression_method!=Z_DEFLATED)) ! 960: err=UNZ_BADZIPFILE; ! 961: Store = s->cur_file_info.compression_method==0; ! 962: ! 963: pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; ! 964: pfile_in_zip_read_info->crc32=0; ! 965: pfile_in_zip_read_info->compression_method = ! 966: s->cur_file_info.compression_method; ! 967: pfile_in_zip_read_info->file=s->file; ! 968: pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; ! 969: ! 970: pfile_in_zip_read_info->stream.total_out = 0; ! 971: ! 972: if (!Store) ! 973: { ! 974: pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; ! 975: pfile_in_zip_read_info->stream.zfree = (free_func)0; ! 976: pfile_in_zip_read_info->stream.opaque = (voidpf)0; ! 977: ! 978: err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); ! 979: if (err == Z_OK) ! 980: pfile_in_zip_read_info->stream_initialised=1; ! 981: /* windowBits is passed < 0 to tell that there is no zlib header. ! 982: * Note that in this case inflate *requires* an extra "dummy" byte ! 983: * after the compressed stream in order to complete decompression and ! 984: * return Z_STREAM_END. ! 985: * In unzip, i don't wait absolutely Z_STREAM_END because I known the ! 986: * size of both compressed and uncompressed data ! 987: */ ! 988: } ! 989: pfile_in_zip_read_info->rest_read_compressed = ! 990: s->cur_file_info.compressed_size ; ! 991: pfile_in_zip_read_info->rest_read_uncompressed = ! 992: s->cur_file_info.uncompressed_size ; ! 993: ! 994: ! 995: pfile_in_zip_read_info->pos_in_zipfile = ! 996: s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + ! 997: iSizeVar; ! 998: ! 999: pfile_in_zip_read_info->stream.avail_in = (uInt)0; ! 1000: ! 1001: ! 1002: s->pfile_in_zip_read = pfile_in_zip_read_info; ! 1003: return UNZ_OK; ! 1004: } ! 1005: ! 1006: ! 1007: /* ! 1008: Read bytes from the current file. ! 1009: buf contain buffer where data must be copied ! 1010: len the size of buf. ! 1011: ! 1012: return the number of byte copied if somes bytes are copied ! 1013: return 0 if the end of file was reached ! 1014: return <0 with error code if there is an error ! 1015: (UNZ_ERRNO for IO error, or zLib error for uncompress error) ! 1016: */ ! 1017: extern int ZEXPORT unzReadCurrentFile (file, buf, len) ! 1018: unzFile file; ! 1019: voidp buf; ! 1020: unsigned len; ! 1021: { ! 1022: int err=UNZ_OK; ! 1023: uInt iRead = 0; ! 1024: unz_s* s; ! 1025: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 1026: if (file==NULL) ! 1027: return UNZ_PARAMERROR; ! 1028: s=(unz_s*)file; ! 1029: pfile_in_zip_read_info=s->pfile_in_zip_read; ! 1030: ! 1031: if (pfile_in_zip_read_info==NULL) ! 1032: return UNZ_PARAMERROR; ! 1033: ! 1034: ! 1035: if ((pfile_in_zip_read_info->read_buffer == NULL)) ! 1036: return UNZ_END_OF_LIST_OF_FILE; ! 1037: if (len==0) ! 1038: return 0; ! 1039: ! 1040: pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; ! 1041: ! 1042: pfile_in_zip_read_info->stream.avail_out = (uInt)len; ! 1043: ! 1044: if (len>pfile_in_zip_read_info->rest_read_uncompressed) ! 1045: pfile_in_zip_read_info->stream.avail_out = ! 1046: (uInt)pfile_in_zip_read_info->rest_read_uncompressed; ! 1047: ! 1048: while (pfile_in_zip_read_info->stream.avail_out>0) ! 1049: { ! 1050: if ((pfile_in_zip_read_info->stream.avail_in==0) && ! 1051: (pfile_in_zip_read_info->rest_read_compressed>0)) ! 1052: { ! 1053: uInt uReadThis = UNZ_BUFSIZE; ! 1054: if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) ! 1055: uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; ! 1056: if (uReadThis == 0) ! 1057: return UNZ_EOF; ! 1058: if (fseek(pfile_in_zip_read_info->file, ! 1059: pfile_in_zip_read_info->pos_in_zipfile + ! 1060: pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) ! 1061: return UNZ_ERRNO; ! 1062: if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, ! 1063: pfile_in_zip_read_info->file)!=1) ! 1064: return UNZ_ERRNO; ! 1065: pfile_in_zip_read_info->pos_in_zipfile += uReadThis; ! 1066: ! 1067: pfile_in_zip_read_info->rest_read_compressed-=uReadThis; ! 1068: ! 1069: pfile_in_zip_read_info->stream.next_in = ! 1070: (Bytef*)pfile_in_zip_read_info->read_buffer; ! 1071: pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; ! 1072: } ! 1073: ! 1074: if (pfile_in_zip_read_info->compression_method==0) ! 1075: { ! 1076: uInt uDoCopy,i ; ! 1077: if (pfile_in_zip_read_info->stream.avail_out < ! 1078: pfile_in_zip_read_info->stream.avail_in) ! 1079: uDoCopy = pfile_in_zip_read_info->stream.avail_out ; ! 1080: else ! 1081: uDoCopy = pfile_in_zip_read_info->stream.avail_in ; ! 1082: ! 1083: for (i=0;i<uDoCopy;i++) ! 1084: *(pfile_in_zip_read_info->stream.next_out+i) = ! 1085: *(pfile_in_zip_read_info->stream.next_in+i); ! 1086: ! 1087: pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, ! 1088: pfile_in_zip_read_info->stream.next_out, ! 1089: uDoCopy); ! 1090: pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; ! 1091: pfile_in_zip_read_info->stream.avail_in -= uDoCopy; ! 1092: pfile_in_zip_read_info->stream.avail_out -= uDoCopy; ! 1093: pfile_in_zip_read_info->stream.next_out += uDoCopy; ! 1094: pfile_in_zip_read_info->stream.next_in += uDoCopy; ! 1095: pfile_in_zip_read_info->stream.total_out += uDoCopy; ! 1096: iRead += uDoCopy; ! 1097: } ! 1098: else ! 1099: { ! 1100: uLong uTotalOutBefore,uTotalOutAfter; ! 1101: const Bytef *bufBefore; ! 1102: uLong uOutThis; ! 1103: int flush=Z_SYNC_FLUSH; ! 1104: ! 1105: uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; ! 1106: bufBefore = pfile_in_zip_read_info->stream.next_out; ! 1107: ! 1108: /* ! 1109: if ((pfile_in_zip_read_info->rest_read_uncompressed == ! 1110: pfile_in_zip_read_info->stream.avail_out) && ! 1111: (pfile_in_zip_read_info->rest_read_compressed == 0)) ! 1112: flush = Z_FINISH; ! 1113: */ ! 1114: err=inflate(&pfile_in_zip_read_info->stream,flush); ! 1115: ! 1116: uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; ! 1117: uOutThis = uTotalOutAfter-uTotalOutBefore; ! 1118: ! 1119: pfile_in_zip_read_info->crc32 = ! 1120: crc32(pfile_in_zip_read_info->crc32,bufBefore, ! 1121: (uInt)(uOutThis)); ! 1122: ! 1123: pfile_in_zip_read_info->rest_read_uncompressed -= ! 1124: uOutThis; ! 1125: ! 1126: iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); ! 1127: ! 1128: if (err==Z_STREAM_END) ! 1129: return (iRead==0) ? UNZ_EOF : iRead; ! 1130: if (err!=Z_OK) ! 1131: break; ! 1132: } ! 1133: } ! 1134: ! 1135: if (err==Z_OK) ! 1136: return iRead; ! 1137: return err; ! 1138: } ! 1139: ! 1140: ! 1141: /* ! 1142: Give the current position in uncompressed data ! 1143: */ ! 1144: extern z_off_t ZEXPORT unztell (file) ! 1145: unzFile file; ! 1146: { ! 1147: unz_s* s; ! 1148: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 1149: if (file==NULL) ! 1150: return UNZ_PARAMERROR; ! 1151: s=(unz_s*)file; ! 1152: pfile_in_zip_read_info=s->pfile_in_zip_read; ! 1153: ! 1154: if (pfile_in_zip_read_info==NULL) ! 1155: return UNZ_PARAMERROR; ! 1156: ! 1157: return (z_off_t)pfile_in_zip_read_info->stream.total_out; ! 1158: } ! 1159: ! 1160: ! 1161: /* ! 1162: return 1 if the end of file was reached, 0 elsewhere ! 1163: */ ! 1164: extern int ZEXPORT unzeof (file) ! 1165: unzFile file; ! 1166: { ! 1167: unz_s* s; ! 1168: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 1169: if (file==NULL) ! 1170: return UNZ_PARAMERROR; ! 1171: s=(unz_s*)file; ! 1172: pfile_in_zip_read_info=s->pfile_in_zip_read; ! 1173: ! 1174: if (pfile_in_zip_read_info==NULL) ! 1175: return UNZ_PARAMERROR; ! 1176: ! 1177: if (pfile_in_zip_read_info->rest_read_uncompressed == 0) ! 1178: return 1; ! 1179: else ! 1180: return 0; ! 1181: } ! 1182: ! 1183: ! 1184: ! 1185: /* ! 1186: Read extra field from the current file (opened by unzOpenCurrentFile) ! 1187: This is the local-header version of the extra field (sometimes, there is ! 1188: more info in the local-header version than in the central-header) ! 1189: ! 1190: if buf==NULL, it return the size of the local extra field that can be read ! 1191: ! 1192: if buf!=NULL, len is the size of the buffer, the extra header is copied in ! 1193: buf. ! 1194: the return value is the number of bytes copied in buf, or (if <0) ! 1195: the error code ! 1196: */ ! 1197: extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) ! 1198: unzFile file; ! 1199: voidp buf; ! 1200: unsigned len; ! 1201: { ! 1202: unz_s* s; ! 1203: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 1204: uInt read_now; ! 1205: uLong size_to_read; ! 1206: ! 1207: if (file==NULL) ! 1208: return UNZ_PARAMERROR; ! 1209: s=(unz_s*)file; ! 1210: pfile_in_zip_read_info=s->pfile_in_zip_read; ! 1211: ! 1212: if (pfile_in_zip_read_info==NULL) ! 1213: return UNZ_PARAMERROR; ! 1214: ! 1215: size_to_read = (pfile_in_zip_read_info->size_local_extrafield - ! 1216: pfile_in_zip_read_info->pos_local_extrafield); ! 1217: ! 1218: if (buf==NULL) ! 1219: return (int)size_to_read; ! 1220: ! 1221: if (len>size_to_read) ! 1222: read_now = (uInt)size_to_read; ! 1223: else ! 1224: read_now = (uInt)len ; ! 1225: ! 1226: if (read_now==0) ! 1227: return 0; ! 1228: ! 1229: if (fseek(pfile_in_zip_read_info->file, ! 1230: pfile_in_zip_read_info->offset_local_extrafield + ! 1231: pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) ! 1232: return UNZ_ERRNO; ! 1233: ! 1234: if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) ! 1235: return UNZ_ERRNO; ! 1236: ! 1237: return (int)read_now; ! 1238: } ! 1239: ! 1240: /* ! 1241: Close the file in zip opened with unzipOpenCurrentFile ! 1242: Return UNZ_CRCERROR if all the file was read but the CRC is not good ! 1243: */ ! 1244: extern int ZEXPORT unzCloseCurrentFile (file) ! 1245: unzFile file; ! 1246: { ! 1247: int err=UNZ_OK; ! 1248: ! 1249: unz_s* s; ! 1250: file_in_zip_read_info_s* pfile_in_zip_read_info; ! 1251: if (file==NULL) ! 1252: return UNZ_PARAMERROR; ! 1253: s=(unz_s*)file; ! 1254: pfile_in_zip_read_info=s->pfile_in_zip_read; ! 1255: ! 1256: if (pfile_in_zip_read_info==NULL) ! 1257: return UNZ_PARAMERROR; ! 1258: ! 1259: ! 1260: if (pfile_in_zip_read_info->rest_read_uncompressed == 0) ! 1261: { ! 1262: if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) ! 1263: err=UNZ_CRCERROR; ! 1264: } ! 1265: ! 1266: ! 1267: TRYFREE(pfile_in_zip_read_info->read_buffer); ! 1268: pfile_in_zip_read_info->read_buffer = NULL; ! 1269: if (pfile_in_zip_read_info->stream_initialised) ! 1270: inflateEnd(&pfile_in_zip_read_info->stream); ! 1271: ! 1272: pfile_in_zip_read_info->stream_initialised = 0; ! 1273: TRYFREE(pfile_in_zip_read_info); ! 1274: ! 1275: s->pfile_in_zip_read=NULL; ! 1276: ! 1277: return err; ! 1278: } ! 1279: ! 1280: ! 1281: /* ! 1282: Get the global comment string of the ZipFile, in the szComment buffer. ! 1283: uSizeBuf is the size of the szComment buffer. ! 1284: return the number of byte copied or an error code <0 ! 1285: */ ! 1286: extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) ! 1287: unzFile file; ! 1288: char *szComment; ! 1289: uLong uSizeBuf; ! 1290: { ! 1291: int err=UNZ_OK; ! 1292: unz_s* s; ! 1293: uLong uReadThis ; ! 1294: if (file==NULL) ! 1295: return UNZ_PARAMERROR; ! 1296: s=(unz_s*)file; ! 1297: ! 1298: uReadThis = uSizeBuf; ! 1299: if (uReadThis>s->gi.size_comment) ! 1300: uReadThis = s->gi.size_comment; ! 1301: ! 1302: if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) ! 1303: return UNZ_ERRNO; ! 1304: ! 1305: if (uReadThis>0) ! 1306: { ! 1307: *szComment='\0'; ! 1308: if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) ! 1309: return UNZ_ERRNO; ! 1310: } ! 1311: ! 1312: if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) ! 1313: *(szComment+s->gi.size_comment)='\0'; ! 1314: return (int)uReadThis; ! 1315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.