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