00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include "zlib.h"
00012 #include "unzip.h"
00013
00014 #ifdef STDC
00015 # include <stddef.h>
00016 # include <string.h>
00017 # include <stdlib.h>
00018 #endif
00019 #ifdef NO_ERRNO_H
00020 extern int errno;
00021 #else
00022 # include <errno.h>
00023 #endif
00024
00025
00026 #ifndef local
00027 # define local static
00028 #endif
00029
00030
00031
00032
00033 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
00034 !defined(CASESENSITIVITYDEFAULT_NO)
00035 #define CASESENSITIVITYDEFAULT_NO
00036 #endif
00037
00038
00039 #ifndef UNZ_BUFSIZE
00040 #define UNZ_BUFSIZE (16384)
00041 #endif
00042
00043 #ifndef UNZ_MAXFILENAMEINZIP
00044 #define UNZ_MAXFILENAMEINZIP (256)
00045 #endif
00046
00047 #ifndef ALLOC
00048 # define ALLOC(size) (malloc(size))
00049 #endif
00050 #ifndef TRYFREE
00051 # define TRYFREE(p) {if (p) free(p);}
00052 #endif
00053
00054 #define SIZECENTRALDIRITEM (0x2e)
00055 #define SIZEZIPLOCALHEADER (0x1e)
00056
00057
00058
00059
00060 #ifndef SEEK_CUR
00061 #define SEEK_CUR 1
00062 #endif
00063
00064 #ifndef SEEK_END
00065 #define SEEK_END 2
00066 #endif
00067
00068 #ifndef SEEK_SET
00069 #define SEEK_SET 0
00070 #endif
00071
00072 const char unz_copyright[] =
00073 " unzip 0.15 Copyright 1998 Gilles Vollant ";
00074
00075
00076 typedef struct unz_file_info_internal_s
00077 {
00078 uLong offset_curfile;
00079 } unz_file_info_internal;
00080
00081
00082
00083
00084 typedef struct
00085 {
00086 char *read_buffer;
00087 z_stream stream;
00088
00089 uLong pos_in_zipfile;
00090 uLong stream_initialised;
00091
00092 uLong offset_local_extrafield;
00093 uInt size_local_extrafield;
00094 uLong pos_local_extrafield;
00095
00096 uLong crc32;
00097 uLong crc32_wait;
00098 uLong rest_read_compressed;
00099 uLong rest_read_uncompressed;
00100 FILE* file;
00101 uLong compression_method;
00102 uLong byte_before_the_zipfile;
00103 } file_in_zip_read_info_s;
00104
00105
00106
00107
00108 typedef struct
00109 {
00110 FILE* file;
00111 unz_global_info gi;
00112 uLong byte_before_the_zipfile;
00113 uLong num_file;
00114 uLong pos_in_central_dir;
00115 uLong current_file_ok;
00116 uLong central_pos;
00117
00118 uLong size_central_dir;
00119 uLong offset_central_dir;
00120
00121
00122 unz_file_info cur_file_info;
00123 unz_file_info_internal cur_file_info_internal;
00124 file_in_zip_read_info_s* pfile_in_zip_read;
00125
00126 } unz_s;
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 local int unzlocal_getByte(fin,pi)
00137 FILE *fin;
00138 int *pi;
00139 {
00140 unsigned char c;
00141 int err = fread(&c, 1, 1, fin);
00142 if (err==1)
00143 {
00144 *pi = (int)c;
00145 return UNZ_OK;
00146 }
00147 else
00148 {
00149 if (ferror(fin))
00150 return UNZ_ERRNO;
00151 else
00152 return UNZ_EOF;
00153 }
00154 }
00155
00156
00157
00158
00159
00160 local int unzlocal_getShort (fin,pX)
00161 FILE* fin;
00162 uLong *pX;
00163 {
00164 uLong x ;
00165 int i = 0;
00166 int err;
00167
00168 err = unzlocal_getByte(fin,&i);
00169 x = (uLong)i;
00170
00171 if (err==UNZ_OK)
00172 err = unzlocal_getByte(fin,&i);
00173 x += ((uLong)i)<<8;
00174
00175 if (err==UNZ_OK)
00176 *pX = x;
00177 else
00178 *pX = 0;
00179 return err;
00180 }
00181
00182 local int unzlocal_getLong (fin,pX)
00183 FILE* fin;
00184 uLong *pX;
00185 {
00186 uLong x ;
00187 int i = 0;
00188 int err;
00189
00190 err = unzlocal_getByte(fin,&i);
00191 x = (uLong)i;
00192
00193 if (err==UNZ_OK)
00194 err = unzlocal_getByte(fin,&i);
00195 x += ((uLong)i)<<8;
00196
00197 if (err==UNZ_OK)
00198 err = unzlocal_getByte(fin,&i);
00199 x += ((uLong)i)<<16;
00200
00201 if (err==UNZ_OK)
00202 err = unzlocal_getByte(fin,&i);
00203 x += ((uLong)i)<<24;
00204
00205 if (err==UNZ_OK)
00206 *pX = x;
00207 else
00208 *pX = 0;
00209 return err;
00210 }
00211
00212
00213
00214 local int strcmpcasenosensitive_internal (fileName1,fileName2)
00215 const char* fileName1;
00216 const char* fileName2;
00217 {
00218 for (;;)
00219 {
00220 char c1=*(fileName1++);
00221 char c2=*(fileName2++);
00222 if ((c1>='a') && (c1<='z'))
00223 c1 -= 0x20;
00224 if ((c2>='a') && (c2<='z'))
00225 c2 -= 0x20;
00226 if (c1=='\0')
00227 return ((c2=='\0') ? 0 : -1);
00228 if (c2=='\0')
00229 return 1;
00230 if (c1<c2)
00231 return -1;
00232 if (c1>c2)
00233 return 1;
00234 }
00235 }
00236
00237
00238 #ifdef CASESENSITIVITYDEFAULT_NO
00239 #define CASESENSITIVITYDEFAULTVALUE 2
00240 #else
00241 #define CASESENSITIVITYDEFAULTVALUE 1
00242 #endif
00243
00244 #ifndef STRCMPCASENOSENTIVEFUNCTION
00245 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
00246 #endif
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
00258 const char* fileName1;
00259 const char* fileName2;
00260 int iCaseSensitivity;
00261 {
00262 if (iCaseSensitivity==0)
00263 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
00264
00265 if (iCaseSensitivity==1)
00266 return strcmp(fileName1,fileName2);
00267
00268 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
00269 }
00270
00271 #define BUFREADCOMMENT (0x400)
00272
00273
00274
00275
00276
00277 local uLong unzlocal_SearchCentralDir(fin)
00278 FILE *fin;
00279 {
00280 unsigned char* buf;
00281 uLong uSizeFile;
00282 uLong uBackRead;
00283 uLong uMaxBack=0xffff;
00284 uLong uPosFound=0;
00285
00286 if (fseek(fin,0,SEEK_END) != 0)
00287 return 0;
00288
00289
00290 uSizeFile = ftell( fin );
00291
00292 if (uMaxBack>uSizeFile)
00293 uMaxBack = uSizeFile;
00294
00295 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00296 if (buf==NULL)
00297 return 0;
00298
00299 uBackRead = 4;
00300 while (uBackRead<uMaxBack)
00301 {
00302 uLong uReadSize,uReadPos ;
00303 int i;
00304 if (uBackRead+BUFREADCOMMENT>uMaxBack)
00305 uBackRead = uMaxBack;
00306 else
00307 uBackRead+=BUFREADCOMMENT;
00308 uReadPos = uSizeFile-uBackRead ;
00309
00310 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00311 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
00312 if (fseek(fin,uReadPos,SEEK_SET)!=0)
00313 break;
00314
00315 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
00316 break;
00317
00318 for (i=(int)uReadSize-3; (i--)>0;)
00319 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
00320 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
00321 {
00322 uPosFound = uReadPos+i;
00323 break;
00324 }
00325
00326 if (uPosFound!=0)
00327 break;
00328 }
00329 TRYFREE(buf);
00330 return uPosFound;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 extern unzFile ZEXPORT unzOpen (path)
00343 const char *path;
00344 {
00345 unz_s us;
00346 unz_s *s;
00347 uLong central_pos,uL;
00348 FILE * fin ;
00349
00350 uLong number_disk;
00351
00352 uLong number_disk_with_CD;
00353
00354 uLong number_entry_CD;
00355
00356
00357
00358 int err=UNZ_OK;
00359
00360 if (unz_copyright[0]!=' ')
00361 return NULL;
00362
00363 fin=fopen(path,"rb");
00364 if (fin==NULL)
00365 return NULL;
00366
00367 central_pos = unzlocal_SearchCentralDir(fin);
00368 if (central_pos==0)
00369 err=UNZ_ERRNO;
00370
00371 if (fseek(fin,central_pos,SEEK_SET)!=0)
00372 err=UNZ_ERRNO;
00373
00374
00375 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
00376 err=UNZ_ERRNO;
00377
00378
00379 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
00380 err=UNZ_ERRNO;
00381
00382
00383 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
00384 err=UNZ_ERRNO;
00385
00386
00387 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
00388 err=UNZ_ERRNO;
00389
00390
00391 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
00392 err=UNZ_ERRNO;
00393
00394 if ((number_entry_CD!=us.gi.number_entry) ||
00395 (number_disk_with_CD!=0) ||
00396 (number_disk!=0))
00397 err=UNZ_BADZIPFILE;
00398
00399
00400 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
00401 err=UNZ_ERRNO;
00402
00403
00404
00405 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
00406 err=UNZ_ERRNO;
00407
00408
00409 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
00410 err=UNZ_ERRNO;
00411
00412 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
00413 (err==UNZ_OK))
00414 err=UNZ_BADZIPFILE;
00415
00416 if (err!=UNZ_OK)
00417 {
00418 fclose(fin);
00419 return NULL;
00420 }
00421
00422 us.file=fin;
00423 us.byte_before_the_zipfile = central_pos -
00424 (us.offset_central_dir+us.size_central_dir);
00425 us.central_pos = central_pos;
00426 us.pfile_in_zip_read = NULL;
00427
00428
00429 s=(unz_s*)ALLOC(sizeof(unz_s));
00430 *s=us;
00431 unzGoToFirstFile((unzFile)s);
00432 return (unzFile)s;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 extern int ZEXPORT unzClose (file)
00442 unzFile file;
00443 {
00444 unz_s* s;
00445 if (file==NULL)
00446 return UNZ_PARAMERROR;
00447 s=(unz_s*)file;
00448
00449 if (s->pfile_in_zip_read!=NULL)
00450 unzCloseCurrentFile(file);
00451
00452 fclose(s->file);
00453 TRYFREE(s);
00454 return UNZ_OK;
00455 }
00456
00457
00458
00459
00460
00461
00462 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
00463 unzFile file;
00464 unz_global_info *pglobal_info;
00465 {
00466 unz_s* s;
00467 if (file==NULL)
00468 return UNZ_PARAMERROR;
00469 s=(unz_s*)file;
00470 *pglobal_info=s->gi;
00471 return UNZ_OK;
00472 }
00473
00474
00475
00476
00477
00478 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
00479 uLong ulDosDate;
00480 tm_unz* ptm;
00481 {
00482 uLong uDate;
00483 uDate = (uLong)(ulDosDate>>16);
00484 ptm->tm_mday = (uInt)(uDate&0x1f) ;
00485 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
00486 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
00487
00488 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
00489 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
00490 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
00491 }
00492
00493
00494
00495
00496 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
00497 unz_file_info *pfile_info,
00498 unz_file_info_internal
00499 *pfile_info_internal,
00500 char *szFileName,
00501 uLong fileNameBufferSize,
00502 void *extraField,
00503 uLong extraFieldBufferSize,
00504 char *szComment,
00505 uLong commentBufferSize));
00506
00507 local int unzlocal_GetCurrentFileInfoInternal (file,
00508 pfile_info,
00509 pfile_info_internal,
00510 szFileName, fileNameBufferSize,
00511 extraField, extraFieldBufferSize,
00512 szComment, commentBufferSize)
00513 unzFile file;
00514 unz_file_info *pfile_info;
00515 unz_file_info_internal *pfile_info_internal;
00516 char *szFileName;
00517 uLong fileNameBufferSize;
00518 void *extraField;
00519 uLong extraFieldBufferSize;
00520 char *szComment;
00521 uLong commentBufferSize;
00522 {
00523 unz_s* s;
00524 unz_file_info file_info;
00525 unz_file_info_internal file_info_internal;
00526 int err=UNZ_OK;
00527 uLong uMagic;
00528 long lSeek=0;
00529
00530 if (file==NULL)
00531 return UNZ_PARAMERROR;
00532 s=(unz_s*)file;
00533 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
00534 err=UNZ_ERRNO;
00535
00536
00537
00538 if (err==UNZ_OK){
00539 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) {
00540 err=UNZ_ERRNO;
00541 } else if (uMagic!=0x02014b50) {
00542 err=UNZ_BADZIPFILE;
00543 }
00544 }
00545
00546 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
00547 err=UNZ_ERRNO;
00548
00549 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
00550 err=UNZ_ERRNO;
00551
00552 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
00553 err=UNZ_ERRNO;
00554
00555 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
00556 err=UNZ_ERRNO;
00557
00558 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
00559 err=UNZ_ERRNO;
00560
00561 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
00562
00563 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
00564 err=UNZ_ERRNO;
00565
00566 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
00567 err=UNZ_ERRNO;
00568
00569 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
00570 err=UNZ_ERRNO;
00571
00572 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
00573 err=UNZ_ERRNO;
00574
00575 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
00576 err=UNZ_ERRNO;
00577
00578 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
00579 err=UNZ_ERRNO;
00580
00581 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
00582 err=UNZ_ERRNO;
00583
00584 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
00585 err=UNZ_ERRNO;
00586
00587 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
00588 err=UNZ_ERRNO;
00589
00590 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
00591 err=UNZ_ERRNO;
00592
00593 lSeek+=file_info.size_filename;
00594 if ((err==UNZ_OK) && (szFileName!=NULL))
00595 {
00596 uLong uSizeRead ;
00597 if (file_info.size_filename<fileNameBufferSize)
00598 {
00599 *(szFileName+file_info.size_filename)='\0';
00600 uSizeRead = file_info.size_filename;
00601 } else {
00602 uSizeRead = fileNameBufferSize;
00603 }
00604
00605 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
00606 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
00607 err=UNZ_ERRNO;
00608 lSeek -= uSizeRead;
00609 }
00610
00611
00612 if ((err==UNZ_OK) && (extraField!=NULL))
00613 {
00614 uLong uSizeRead ;
00615 if (file_info.size_file_extra<extraFieldBufferSize)
00616 uSizeRead = file_info.size_file_extra;
00617 else
00618 uSizeRead = extraFieldBufferSize;
00619
00620 if (lSeek!=0) {
00621 if (fseek(s->file,lSeek,SEEK_CUR)==0) {
00622 lSeek=0;
00623 } else {
00624 err=UNZ_ERRNO;
00625 }
00626 }
00627 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
00628 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
00629 err=UNZ_ERRNO;
00630 lSeek += file_info.size_file_extra - uSizeRead;
00631 }
00632 else
00633 lSeek+=file_info.size_file_extra;
00634
00635
00636 if ((err==UNZ_OK) && (szComment!=NULL))
00637 {
00638 uLong uSizeRead ;
00639 if (file_info.size_file_comment<commentBufferSize)
00640 {
00641 *(szComment+file_info.size_file_comment)='\0';
00642 uSizeRead = file_info.size_file_comment;
00643 }
00644 else
00645 uSizeRead = commentBufferSize;
00646
00647 if (lSeek!=0) {
00648 if (fseek(s->file,lSeek,SEEK_CUR)==0)
00649 lSeek=0;
00650 else
00651 err=UNZ_ERRNO;
00652 }
00653 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
00654 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
00655 err=UNZ_ERRNO;
00656 lSeek+=file_info.size_file_comment - uSizeRead;
00657 }
00658 else
00659 lSeek+=file_info.size_file_comment;
00660
00661 if ((err==UNZ_OK) && (pfile_info!=NULL))
00662 *pfile_info=file_info;
00663
00664 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
00665 *pfile_info_internal=file_info_internal;
00666
00667 return err;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677 extern int ZEXPORT unzGetCurrentFileInfo (file,
00678 pfile_info,
00679 szFileName, fileNameBufferSize,
00680 extraField, extraFieldBufferSize,
00681 szComment, commentBufferSize)
00682 unzFile file;
00683 unz_file_info *pfile_info;
00684 char *szFileName;
00685 uLong fileNameBufferSize;
00686 void *extraField;
00687 uLong extraFieldBufferSize;
00688 char *szComment;
00689 uLong commentBufferSize;
00690 {
00691 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
00692 szFileName,fileNameBufferSize,
00693 extraField,extraFieldBufferSize,
00694 szComment,commentBufferSize);
00695 }
00696
00697
00698
00699
00700
00701 extern int ZEXPORT unzGoToFirstFile (file)
00702 unzFile file;
00703 {
00704 int err=UNZ_OK;
00705 unz_s* s;
00706 if (file==NULL)
00707 return UNZ_PARAMERROR;
00708 s=(unz_s*)file;
00709 s->pos_in_central_dir=s->offset_central_dir;
00710 s->num_file=0;
00711 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
00712 &s->cur_file_info_internal,
00713 NULL,0,NULL,0,NULL,0);
00714 s->current_file_ok = (err == UNZ_OK);
00715 return err;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724 extern int ZEXPORT unzGoToNextFile (file)
00725 unzFile file;
00726 {
00727 unz_s* s;
00728 int err;
00729
00730 if (file==NULL)
00731 return UNZ_PARAMERROR;
00732 s=(unz_s*)file;
00733 if (!s->current_file_ok)
00734 return UNZ_END_OF_LIST_OF_FILE;
00735 if (s->num_file+1==s->gi.number_entry)
00736 return UNZ_END_OF_LIST_OF_FILE;
00737
00738 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
00739 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
00740 s->num_file++;
00741 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
00742 &s->cur_file_info_internal,
00743 NULL,0,NULL,0,NULL,0);
00744 s->current_file_ok = (err == UNZ_OK);
00745 return err;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
00758 unzFile file;
00759 const char *szFileName;
00760 int iCaseSensitivity;
00761 {
00762 unz_s* s;
00763 int err;
00764
00765
00766 uLong num_fileSaved;
00767 uLong pos_in_central_dirSaved;
00768
00769
00770 if (file==NULL)
00771 return UNZ_PARAMERROR;
00772
00773 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
00774 return UNZ_PARAMERROR;
00775
00776 s=(unz_s*)file;
00777 if (!s->current_file_ok)
00778 return UNZ_END_OF_LIST_OF_FILE;
00779
00780 num_fileSaved = s->num_file;
00781 pos_in_central_dirSaved = s->pos_in_central_dir;
00782
00783 err = unzGoToFirstFile(file);
00784
00785 while (err == UNZ_OK)
00786 {
00787 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
00788 unzGetCurrentFileInfo(file,NULL,
00789 szCurrentFileName,sizeof(szCurrentFileName)-1,
00790 NULL,0,NULL,0);
00791 if (unzStringFileNameCompare(szCurrentFileName,
00792 szFileName,iCaseSensitivity)==0)
00793 return UNZ_OK;
00794 err = unzGoToNextFile(file);
00795 }
00796
00797 s->num_file = num_fileSaved ;
00798 s->pos_in_central_dir = pos_in_central_dirSaved ;
00799 return err;
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
00811 poffset_local_extrafield,
00812 psize_local_extrafield)
00813 unz_s* s;
00814 uInt* piSizeVar;
00815 uLong *poffset_local_extrafield;
00816 uInt *psize_local_extrafield;
00817 {
00818 uLong uMagic,uData,uFlags;
00819 uLong size_filename;
00820 uLong size_extra_field;
00821 int err=UNZ_OK;
00822
00823 *piSizeVar = 0;
00824 *poffset_local_extrafield = 0;
00825 *psize_local_extrafield = 0;
00826
00827 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
00828 s->byte_before_the_zipfile,SEEK_SET)!=0)
00829 return UNZ_ERRNO;
00830
00831
00832 if (err==UNZ_OK) {
00833 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
00834 err=UNZ_ERRNO;
00835 else if (uMagic!=0x04034b50)
00836 err=UNZ_BADZIPFILE;
00837 }
00838
00839 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
00840 err=UNZ_ERRNO;
00841
00842
00843
00844
00845 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
00846 err=UNZ_ERRNO;
00847
00848 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
00849 err=UNZ_ERRNO;
00850 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
00851 err=UNZ_BADZIPFILE;
00852
00853 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
00854 (s->cur_file_info.compression_method!=Z_DEFLATED))
00855 err=UNZ_BADZIPFILE;
00856
00857 if (unzlocal_getLong(s->file,&uData) != UNZ_OK)
00858 err=UNZ_ERRNO;
00859
00860 if (unzlocal_getLong(s->file,&uData) != UNZ_OK)
00861 err=UNZ_ERRNO;
00862 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
00863 ((uFlags & 8)==0))
00864 err=UNZ_BADZIPFILE;
00865
00866 if (unzlocal_getLong(s->file,&uData) != UNZ_OK)
00867 err=UNZ_ERRNO;
00868 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
00869 ((uFlags & 8)==0))
00870 err=UNZ_BADZIPFILE;
00871
00872 if (unzlocal_getLong(s->file,&uData) != UNZ_OK)
00873 err=UNZ_ERRNO;
00874 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
00875 ((uFlags & 8)==0))
00876 err=UNZ_BADZIPFILE;
00877
00878
00879 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
00880 err=UNZ_ERRNO;
00881 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
00882 err=UNZ_BADZIPFILE;
00883
00884 *piSizeVar += (uInt)size_filename;
00885
00886 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
00887 err=UNZ_ERRNO;
00888 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
00889 SIZEZIPLOCALHEADER + size_filename;
00890 *psize_local_extrafield = (uInt)size_extra_field;
00891
00892 *piSizeVar += (uInt)size_extra_field;
00893
00894 return err;
00895 }
00896
00897
00898
00899
00900
00901 extern int ZEXPORT unzOpenCurrentFile (file)
00902 unzFile file;
00903 {
00904 int err=UNZ_OK;
00905 int Store;
00906 uInt iSizeVar;
00907 unz_s* s;
00908 file_in_zip_read_info_s* pfile_in_zip_read_info;
00909 uLong offset_local_extrafield;
00910 uInt size_local_extrafield;
00911
00912 if (file==NULL)
00913 return UNZ_PARAMERROR;
00914 s=(unz_s*)file;
00915 if (!s->current_file_ok)
00916 return UNZ_PARAMERROR;
00917
00918 if (s->pfile_in_zip_read != NULL)
00919 unzCloseCurrentFile(file);
00920
00921 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
00922 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
00923 return UNZ_BADZIPFILE;
00924
00925 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
00926 ALLOC(sizeof(file_in_zip_read_info_s));
00927 if (pfile_in_zip_read_info==NULL)
00928 return UNZ_INTERNALERROR;
00929
00930 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
00931 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
00932 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
00933 pfile_in_zip_read_info->pos_local_extrafield=0;
00934
00935 if (pfile_in_zip_read_info->read_buffer==NULL)
00936 {
00937 TRYFREE(pfile_in_zip_read_info);
00938 return UNZ_INTERNALERROR;
00939 }
00940
00941 pfile_in_zip_read_info->stream_initialised=0;
00942
00943 if ((s->cur_file_info.compression_method!=0) &&
00944 (s->cur_file_info.compression_method!=Z_DEFLATED))
00945 err=UNZ_BADZIPFILE;
00946 Store = s->cur_file_info.compression_method==0;
00947
00948 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
00949 pfile_in_zip_read_info->crc32=0;
00950 pfile_in_zip_read_info->compression_method =
00951 s->cur_file_info.compression_method;
00952 pfile_in_zip_read_info->file=s->file;
00953 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
00954
00955 pfile_in_zip_read_info->stream.total_out = 0;
00956
00957 if (!Store)
00958 {
00959 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
00960 pfile_in_zip_read_info->stream.zfree = (free_func)0;
00961 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
00962
00963 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
00964 if (err == Z_OK)
00965 pfile_in_zip_read_info->stream_initialised=1;
00966
00967
00968
00969
00970
00971
00972
00973 }
00974 pfile_in_zip_read_info->rest_read_compressed =
00975 s->cur_file_info.compressed_size ;
00976 pfile_in_zip_read_info->rest_read_uncompressed =
00977 s->cur_file_info.uncompressed_size ;
00978
00979
00980 pfile_in_zip_read_info->pos_in_zipfile =
00981 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
00982 iSizeVar;
00983
00984 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
00985
00986
00987 s->pfile_in_zip_read = pfile_in_zip_read_info;
00988 return UNZ_OK;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
01003 unzFile file;
01004 voidp buf;
01005 unsigned len;
01006 {
01007 int err=UNZ_OK;
01008 uInt iRead = 0;
01009 unz_s* s;
01010 file_in_zip_read_info_s* pfile_in_zip_read_info;
01011 if (file==NULL)
01012 return UNZ_PARAMERROR;
01013 s=(unz_s*)file;
01014 pfile_in_zip_read_info=s->pfile_in_zip_read;
01015
01016 if (pfile_in_zip_read_info==NULL)
01017 return UNZ_PARAMERROR;
01018
01019
01020 if ((pfile_in_zip_read_info->read_buffer == NULL))
01021 return UNZ_END_OF_LIST_OF_FILE;
01022 if (len==0)
01023 return 0;
01024
01025 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
01026
01027 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
01028
01029 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
01030 pfile_in_zip_read_info->stream.avail_out =
01031 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
01032
01033 while (pfile_in_zip_read_info->stream.avail_out>0)
01034 {
01035 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
01036 (pfile_in_zip_read_info->rest_read_compressed>0))
01037 {
01038 uInt uReadThis = UNZ_BUFSIZE;
01039 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
01040 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
01041 if (uReadThis == 0)
01042 return UNZ_EOF;
01043 if (fseek(pfile_in_zip_read_info->file,
01044 pfile_in_zip_read_info->pos_in_zipfile +
01045 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
01046 return UNZ_ERRNO;
01047 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
01048 pfile_in_zip_read_info->file)!=1)
01049 return UNZ_ERRNO;
01050 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
01051
01052 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
01053
01054 pfile_in_zip_read_info->stream.next_in =
01055 (Bytef*)pfile_in_zip_read_info->read_buffer;
01056 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
01057 }
01058
01059 if (pfile_in_zip_read_info->compression_method==0)
01060 {
01061 uInt uDoCopy,i ;
01062 if (pfile_in_zip_read_info->stream.avail_out <
01063 pfile_in_zip_read_info->stream.avail_in)
01064 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
01065 else
01066 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
01067
01068 for (i=0;i<uDoCopy;i++)
01069 *(pfile_in_zip_read_info->stream.next_out+i) =
01070 *(pfile_in_zip_read_info->stream.next_in+i);
01071
01072 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
01073 pfile_in_zip_read_info->stream.next_out,
01074 uDoCopy);
01075 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
01076 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
01077 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
01078 pfile_in_zip_read_info->stream.next_out += uDoCopy;
01079 pfile_in_zip_read_info->stream.next_in += uDoCopy;
01080 pfile_in_zip_read_info->stream.total_out += uDoCopy;
01081 iRead += uDoCopy;
01082 }
01083 else
01084 {
01085 uLong uTotalOutBefore,uTotalOutAfter;
01086 const Bytef *bufBefore;
01087 uLong uOutThis;
01088 int flush=Z_SYNC_FLUSH;
01089
01090 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
01091 bufBefore = pfile_in_zip_read_info->stream.next_out;
01092
01093
01094
01095
01096
01097
01098
01099 err=inflate(&pfile_in_zip_read_info->stream,flush);
01100
01101 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
01102 uOutThis = uTotalOutAfter-uTotalOutBefore;
01103
01104 pfile_in_zip_read_info->crc32 =
01105 crc32(pfile_in_zip_read_info->crc32,bufBefore,
01106 (uInt)(uOutThis));
01107
01108 pfile_in_zip_read_info->rest_read_uncompressed -=
01109 uOutThis;
01110
01111 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
01112
01113 if (err==Z_STREAM_END)
01114 return (iRead==0) ? UNZ_EOF : iRead;
01115 if (err!=Z_OK)
01116 break;
01117 }
01118 }
01119
01120 if (err==Z_OK)
01121 return iRead;
01122 return err;
01123 }
01124
01125
01126
01127
01128
01129 extern z_off_t ZEXPORT unztell (file)
01130 unzFile file;
01131 {
01132 unz_s* s;
01133 file_in_zip_read_info_s* pfile_in_zip_read_info;
01134 if (file==NULL)
01135 return UNZ_PARAMERROR;
01136 s=(unz_s*)file;
01137 pfile_in_zip_read_info=s->pfile_in_zip_read;
01138
01139 if (pfile_in_zip_read_info==NULL)
01140 return UNZ_PARAMERROR;
01141
01142 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
01143 }
01144
01145
01146
01147
01148
01149 extern int ZEXPORT unzeof (file)
01150 unzFile file;
01151 {
01152 unz_s* s;
01153 file_in_zip_read_info_s* pfile_in_zip_read_info;
01154 if (file==NULL)
01155 return UNZ_PARAMERROR;
01156 s=(unz_s*)file;
01157 pfile_in_zip_read_info=s->pfile_in_zip_read;
01158
01159 if (pfile_in_zip_read_info==NULL)
01160 return UNZ_PARAMERROR;
01161
01162 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
01163 return 1;
01164 else
01165 return 0;
01166 }
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
01183 unzFile file;
01184 voidp buf;
01185 unsigned len;
01186 {
01187 unz_s* s;
01188 file_in_zip_read_info_s* pfile_in_zip_read_info;
01189 uInt read_now;
01190 uLong size_to_read;
01191
01192 if (file==NULL)
01193 return UNZ_PARAMERROR;
01194 s=(unz_s*)file;
01195 pfile_in_zip_read_info=s->pfile_in_zip_read;
01196
01197 if (pfile_in_zip_read_info==NULL)
01198 return UNZ_PARAMERROR;
01199
01200 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
01201 pfile_in_zip_read_info->pos_local_extrafield);
01202
01203 if (buf==NULL)
01204 return (int)size_to_read;
01205
01206 if (len>size_to_read)
01207 read_now = (uInt)size_to_read;
01208 else
01209 read_now = (uInt)len ;
01210
01211 if (read_now==0)
01212 return 0;
01213
01214 if (fseek(pfile_in_zip_read_info->file,
01215 pfile_in_zip_read_info->offset_local_extrafield +
01216 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
01217 return UNZ_ERRNO;
01218
01219 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
01220 return UNZ_ERRNO;
01221
01222 return (int)read_now;
01223 }
01224
01225
01226
01227
01228
01229 extern int ZEXPORT unzCloseCurrentFile (file)
01230 unzFile file;
01231 {
01232 int err=UNZ_OK;
01233
01234 unz_s* s;
01235 file_in_zip_read_info_s* pfile_in_zip_read_info;
01236 if (file==NULL)
01237 return UNZ_PARAMERROR;
01238 s=(unz_s*)file;
01239 pfile_in_zip_read_info=s->pfile_in_zip_read;
01240
01241 if (pfile_in_zip_read_info==NULL)
01242 return UNZ_PARAMERROR;
01243
01244
01245 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
01246 {
01247 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
01248 err=UNZ_CRCERROR;
01249 }
01250
01251
01252 TRYFREE(pfile_in_zip_read_info->read_buffer);
01253 pfile_in_zip_read_info->read_buffer = NULL;
01254 if (pfile_in_zip_read_info->stream_initialised)
01255 inflateEnd(&pfile_in_zip_read_info->stream);
01256
01257 pfile_in_zip_read_info->stream_initialised = 0;
01258 TRYFREE(pfile_in_zip_read_info);
01259
01260 s->pfile_in_zip_read=NULL;
01261
01262 return err;
01263 }
01264
01265
01266
01267
01268
01269
01270
01271 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
01272 unzFile file;
01273 char *szComment;
01274 uLong uSizeBuf;
01275 {
01276
01277 unz_s* s;
01278 uLong uReadThis ;
01279 if (file==NULL)
01280 return UNZ_PARAMERROR;
01281 s=(unz_s*)file;
01282
01283 uReadThis = uSizeBuf;
01284 if (uReadThis>s->gi.size_comment)
01285 uReadThis = s->gi.size_comment;
01286
01287 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
01288 return UNZ_ERRNO;
01289
01290 if (uReadThis>0)
01291 {
01292 *szComment='\0';
01293 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
01294 return UNZ_ERRNO;
01295 }
01296
01297 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
01298 *(szComment+s->gi.size_comment)='\0';
01299 return (int)uReadThis;
01300 }