?? unzip.c
字號:
/* unzip.c -- IO on .zip files using zlib Version 0.15 beta, Mar 19th, 1998, Read unzip.h for more info*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "zlib.h"#include "unzip.h"#ifdef STDC# include <stddef.h># include <string.h># include <stdlib.h>#endif#ifdef NO_ERRNO_H extern int errno;#else# include <errno.h>#endif#ifndef local# define local static#endif/* compile with -Dlocal if your debugger can't find static symbols */#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ !defined(CASESENSITIVITYDEFAULT_NO)#define CASESENSITIVITYDEFAULT_NO#endif#ifndef UNZ_BUFSIZE#define UNZ_BUFSIZE (16384)#endif#ifndef UNZ_MAXFILENAMEINZIP#define UNZ_MAXFILENAMEINZIP (256)#endif#ifndef ALLOC# define ALLOC(size) (malloc(size))#endif#ifndef TRYFREE# define TRYFREE(p) {if (p) free(p);}#endif#define SIZECENTRALDIRITEM (0x2e)#define SIZEZIPLOCALHEADER (0x1e)/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */#ifndef SEEK_CUR#define SEEK_CUR 1#endif#ifndef SEEK_END#define SEEK_END 2#endif#ifndef SEEK_SET#define SEEK_SET 0#endifconst char unz_copyright[] = " unzip 0.15 Copyright 1998 Gilles Vollant ";/* unz_file_info_interntal contain internal info about a file in zipfile*/typedef struct unz_file_info_internal_s{ uLong offset_curfile;/* relative offset of local header 4 bytes */} unz_file_info_internal;/* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */typedef struct{ char *read_buffer; /* internal buffer for compressed data */ z_stream stream; /* zLib stream structure for inflate */ uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ uLong stream_initialised; /* flag set if stream structure is initialised*/ uLong offset_local_extrafield;/* offset of the local extra field */ uInt size_local_extrafield;/* size of the local extra field */ uLong pos_local_extrafield; /* position in the local extra field in read*/ uLong crc32; /* crc32 of all data uncompressed */ uLong crc32_wait; /* crc32 we must obtain after decompress all */ uLong rest_read_compressed; /* number of byte to be decompressed */ uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ FILE* file; /* io structore of the zipfile */ uLong compression_method; /* compression method (0==store) */ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/} file_in_zip_read_info_s;/* unz_s contain internal information about the zipfile*/typedef struct{ FILE* file; /* io structore of the zipfile */ unz_global_info gi; /* public global information */ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ uLong num_file; /* number of the current file in the zipfile*/ uLong pos_in_central_dir; /* pos of the current file in the central dir*/ uLong current_file_ok; /* flag about the usability of the current file*/ uLong central_pos; /* position of the beginning of the central dir*/ uLong size_central_dir; /* size of the central directory */ uLong offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ unz_file_info cur_file_info; /* public info about the current file in zip*/ unz_file_info_internal cur_file_info_internal; /* private info about it*/ file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current file if we are decompressing it */} unz_s;/* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading.*/local int unzlocal_getByte(fin,pi) FILE *fin; int *pi;{ unsigned char c; int err = fread(&c, 1, 1, fin); if (err==1) { *pi = (int)c; return UNZ_OK; } else { if (ferror(fin)) return UNZ_ERRNO; else return UNZ_EOF; }}/* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */local int unzlocal_getShort (fin,pX) FILE* fin; uLong *pX;{ uLong x ; int i; int err; err = unzlocal_getByte(fin,&i); x = (uLong)i; if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; if (err==UNZ_OK) *pX = x; else *pX = 0; return err;}local int unzlocal_getLong (fin,pX) FILE* fin; uLong *pX;{ uLong x ; int i; int err; err = unzlocal_getByte(fin,&i); x = (uLong)i; if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<16; if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<24; if (err==UNZ_OK) *pX = x; else *pX = 0; return err;}/* My own strcmpi / strcasecmp */local int strcmpcasenosensitive_internal (fileName1,fileName2) const char* fileName1; const char* fileName2;{ for (;;) { char c1=*(fileName1++); char c2=*(fileName2++); if ((c1>='a') && (c1<='z')) c1 -= 0x20; if ((c2>='a') && (c2<='z')) c2 -= 0x20; if (c1=='\0') return ((c2=='\0') ? 0 : -1); if (c2=='\0') return 1; if (c1<c2) return -1; if (c1>c2) return 1; }}#ifdef CASESENSITIVITYDEFAULT_NO#define CASESENSITIVITYDEFAULTVALUE 2#else#define CASESENSITIVITYDEFAULTVALUE 1#endif#ifndef STRCMPCASENOSENTIVEFUNCTION#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal#endif/* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows)*/extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) const char* fileName1; const char* fileName2; int iCaseSensitivity;{ if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);} #define BUFREADCOMMENT (0x400)/* Locate the Central directory of a zipfile (at the end, just before the global comment)*/local uLong unzlocal_SearchCentralDir(fin) FILE *fin;{ unsigned char* buf; uLong uSizeFile; uLong uBackRead; uLong uMaxBack=0xffff; /* maximum size of global comment */ uLong uPosFound=0; if (fseek(fin,0,SEEK_END) != 0) return 0; uSizeFile = ftell( fin ); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackRead<uMaxBack) { uLong uReadSize,uReadPos ; int i; if (uBackRead+BUFREADCOMMENT>uMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); if (fseek(fin,uReadPos,SEEK_SET)!=0) break; if (fread(buf,(uInt)uReadSize,1,fin)!=1) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound;}/* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer "zlib/zlib109.zip". If the zipfile cannot be opened (file don't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package.*/extern unzFile ZEXPORT unzOpen (path) const char *path;{ unz_s us; unz_s *s; uLong central_pos,uL; FILE * fin ; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int err=UNZ_OK; if (unz_copyright[0]!=' ') return NULL; fin=fopen(path,"rb"); if (fin==NULL) return NULL; central_pos = unzlocal_SearchCentralDir(fin); if (central_pos==0) err=UNZ_ERRNO; if (fseek(fin,central_pos,SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unzlocal_getLong(fin,&uL)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir */ if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) err=UNZ_ERRNO; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* zipfile comment length */ if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) err=UNZ_ERRNO; if ((central_pos<us.offset_central_dir+us.size_central_dir) && (err==UNZ_OK)) err=UNZ_BADZIPFILE; if (err!=UNZ_OK) { fclose(fin); return NULL; } us.file=fin; us.byte_before_the_zipfile = central_pos - (us.offset_central_dir+us.size_central_dir); us.central_pos = central_pos; us.pfile_in_zip_read = NULL; s=(unz_s*)ALLOC(sizeof(unz_s)); *s=us; unzGoToFirstFile((unzFile)s); return (unzFile)s;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -