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