?? unzip.c
字號(hào):
/* 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
#endif
const 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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -