📄 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"#include "unzipP.h"#ifdef STDC#include <stddef.h>#include <string.h>#include <stdlib.h>#endif#ifdef NO_ERRNO_Hextern int errno;#else#include <errno.h>#endifconst char unz_copyright[] =" unzip 0.15 Copyright 1998 Gilles Vollant ";void unShrink ();void unReduce ();int explode ();/* * =========================================================================== * 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 (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 (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 (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 (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 (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 (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 = 0; i < (int) uReadSize - 3; i++) 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 (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;}/* * Close a ZipFile opened with unzipOpen. If there is files inside the .Zip * opened with unzipOpenCurrentFile (see later), these files MUST be closed * with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there * is no problem. */extern int ZEXPORT unzClose (unzFile file){ unz_s *s; if (file == NULL) return UNZ_PARAMERROR; s = (unz_s *) file; if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile (file); fclose (s->file); TRYFREE (s); return UNZ_OK;}/* * Write info about the ZipFile in the *pglobal_info structure. No * preparation of the structure is needed return UNZ_OK if there is no * problem. */extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info * pglobal_info){ unz_s *s; if (file == NULL) return UNZ_PARAMERROR; s = (unz_s *) file; *pglobal_info = s->gi; return UNZ_OK;}/* * Translate date/time from Dos format to tm_unz (readable more easilty) */local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz * ptm){ uLong uDate; uDate = (uLong) (ulDosDate >> 16); ptm->tm_mday = (uInt) (uDate & 0x1f); ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1); ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980); ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800); ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20); ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f));}/* * Get Info about the current file in the zipfile, with internal only info */local int unzlocal_GetCurrentFileInfoInternal OF ((unzFile file, unz_file_info * pfile_info, unz_file_info_internal * pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); local int unzlocal_GetCurrentFileInfoInternal ( unzFile file, unz_file_info * pfile_info,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -