123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- /*
- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2009-Jan-02 or later
- (the contents of which are also included in unzip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
- */
- /*---------------------------------------------------------------------------
- api.c
- This module supplies an UnZip engine for use directly from C/C++
- programs. The functions are:
- ZCONST UzpVer *UzpVersion(void);
- unsigned UzpVersion2(UzpVer2 *version)
- int UzpMain(int argc, char *argv[]);
- int UzpAltMain(int argc, char *argv[], UzpInit *init);
- int UzpValidate(char *archive, int AllCodes);
- void UzpFreeMemBuffer(UzpBuffer *retstr);
- int UzpUnzipToMemory(char *zip, char *file, UzpOpts *optflgs,
- UzpCB *UsrFuncts, UzpBuffer *retstr);
- non-WINDLL only (a special WINDLL variant is defined in windll/windll.c):
- int UzpGrep(char *archive, char *file, char *pattern, int cmd, int SkipBin,
- UzpCB *UsrFuncts);
- OS/2 only (for now):
- int UzpFileTree(char *name, cbList(callBack), char *cpInclude[],
- char *cpExclude[]);
- You must define `DLL' in order to include the API extensions.
- ---------------------------------------------------------------------------*/
- #ifdef OS2
- # define INCL_DOSMEMMGR
- # include <os2.h>
- #endif
- #define UNZIP_INTERNAL
- #include "unzip.h"
- #ifdef WINDLL
- # ifdef POCKET_UNZIP
- # include "wince/intrface.h"
- # else
- # include "windll/windll.h"
- # endif
- #endif
- #include "unzvers.h"
- #include <setjmp.h>
- #ifdef DLL /* This source file supplies DLL-only interface code. */
- #ifndef POCKET_UNZIP /* WinCE pUnZip defines this elsewhere. */
- jmp_buf dll_error_return;
- #endif
- /*---------------------------------------------------------------------------
- Documented API entry points
- ---------------------------------------------------------------------------*/
- ZCONST UzpVer * UZ_EXP UzpVersion() /* returns pointer to const struct */
- {
- static ZCONST UzpVer version = { /* doesn't change between calls */
- /* structure size */
- UZPVER_LEN,
- /* version flags */
- #ifdef BETA
- # ifdef ZLIB_VERSION
- 3,
- # else
- 1,
- # endif
- #else
- # ifdef ZLIB_VERSION
- 2,
- # else
- 0,
- # endif
- #endif
- /* betalevel and date strings */
- UZ_BETALEVEL, UZ_VERSION_DATE,
- /* zlib_version string */
- #ifdef ZLIB_VERSION
- ZLIB_VERSION,
- #else
- NULL,
- #endif
- /*== someday each of these may have a separate patchlevel: ==*/
- /* unzip version */
- {UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, 0},
- /* zipinfo version */
- {ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, 0},
- /* os2dll version (retained for backward compatibility) */
- {UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, 0},
- /* windll version (retained for backward compatibility)*/
- {UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, 0},
- #ifdef OS2DLL
- /* os2dll API minimum compatible version*/
- {UZ_OS2API_COMP_MAJOR, UZ_OS2API_COMP_MINOR, UZ_OS2API_COMP_REVIS, 0}
- #else /* !OS2DLL */
- #ifdef WINDLL
- /* windll API minimum compatible version*/
- {UZ_WINAPI_COMP_MAJOR, UZ_WINAPI_COMP_MINOR, UZ_WINAPI_COMP_REVIS, 0}
- #else /* !WINDLL */
- /* generic DLL API minimum compatible version*/
- {UZ_GENAPI_COMP_MAJOR, UZ_GENAPI_COMP_MINOR, UZ_GENAPI_COMP_REVIS, 0}
- #endif /* ?WINDLL */
- #endif /* ?OS2DLL */
- };
- return &version;
- }
- unsigned UZ_EXP UzpVersion2(UzpVer2 *version)
- {
- if (version->structlen != sizeof(UzpVer2))
- return sizeof(UzpVer2);
- #ifdef BETA
- version->flag = 1;
- #else
- version->flag = 0;
- #endif
- strcpy(version->betalevel, UZ_BETALEVEL);
- strcpy(version->date, UZ_VERSION_DATE);
- #ifdef ZLIB_VERSION
- /* Although ZLIB_VERSION is a compile-time constant, we implement an
- "overrun-safe" copy because its actual value is not under our control.
- */
- strncpy(version->zlib_version, ZLIB_VERSION,
- sizeof(version->zlib_version) - 1);
- version->zlib_version[sizeof(version->zlib_version) - 1] = '\0';
- version->flag |= 2;
- #else
- version->zlib_version[0] = '\0';
- #endif
- /* someday each of these may have a separate patchlevel: */
- version->unzip.major = UZ_MAJORVER;
- version->unzip.minor = UZ_MINORVER;
- version->unzip.patchlevel = UZ_PATCHLEVEL;
- version->zipinfo.major = ZI_MAJORVER;
- version->zipinfo.minor = ZI_MINORVER;
- version->zipinfo.patchlevel = UZ_PATCHLEVEL;
- /* these are retained for backward compatibility only: */
- version->os2dll.major = UZ_MAJORVER;
- version->os2dll.minor = UZ_MINORVER;
- version->os2dll.patchlevel = UZ_PATCHLEVEL;
- version->windll.major = UZ_MAJORVER;
- version->windll.minor = UZ_MINORVER;
- version->windll.patchlevel = UZ_PATCHLEVEL;
- #ifdef OS2DLL
- /* os2dll API minimum compatible version*/
- version->dllapimin.major = UZ_OS2API_COMP_MAJOR;
- version->dllapimin.minor = UZ_OS2API_COMP_MINOR;
- version->dllapimin.patchlevel = UZ_OS2API_COMP_REVIS;
- #else /* !OS2DLL */
- #ifdef WINDLL
- /* windll API minimum compatible version*/
- version->dllapimin.major = UZ_WINAPI_COMP_MAJOR;
- version->dllapimin.minor = UZ_WINAPI_COMP_MINOR;
- version->dllapimin.patchlevel = UZ_WINAPI_COMP_REVIS;
- #else /* !WINDLL */
- /* generic DLL API minimum compatible version*/
- version->dllapimin.major = UZ_GENAPI_COMP_MAJOR;
- version->dllapimin.minor = UZ_GENAPI_COMP_MINOR;
- version->dllapimin.patchlevel = UZ_GENAPI_COMP_REVIS;
- #endif /* ?WINDLL */
- #endif /* ?OS2DLL */
- return 0;
- }
- #ifndef SFX
- #ifndef WINDLL
- int UZ_EXP UzpAltMain(int argc, char *argv[], UzpInit *init)
- {
- int r, (*dummyfn)();
- CONSTRUCTGLOBALS();
- if (init->structlen >= (sizeof(ulg) + sizeof(dummyfn)) && init->msgfn)
- G.message = init->msgfn;
- if (init->structlen >= (sizeof(ulg) + 2*sizeof(dummyfn)) && init->inputfn)
- G.input = init->inputfn;
- if (init->structlen >= (sizeof(ulg) + 3*sizeof(dummyfn)) && init->pausefn)
- G.mpause = init->pausefn;
- if (init->structlen >= (sizeof(ulg) + 4*sizeof(dummyfn)) && init->userfn)
- (*init->userfn)(); /* allow void* arg? */
- r = unzip(__G__ argc, argv);
- DESTROYGLOBALS();
- RETURN(r);
- }
- #endif /* !WINDLL */
- #ifndef __16BIT__
- void UZ_EXP UzpFreeMemBuffer(UzpBuffer *retstr)
- {
- if (retstr != NULL && retstr->strptr != NULL) {
- free(retstr->strptr);
- retstr->strptr = NULL;
- retstr->strlength = 0;
- }
- }
- #ifndef WINDLL
- static int UzpDLL_Init OF((zvoid *pG, UzpCB *UsrFuncts));
- static int UzpDLL_Init(pG, UsrFuncts)
- zvoid *pG;
- UzpCB *UsrFuncts;
- {
- int (*dummyfn)();
- if (UsrFuncts->structlen >= (sizeof(ulg) + sizeof(dummyfn)) &&
- UsrFuncts->msgfn)
- ((Uz_Globs *)pG)->message = UsrFuncts->msgfn;
- else
- return FALSE;
- if (UsrFuncts->structlen >= (sizeof(ulg) + 2*sizeof(dummyfn)) &&
- UsrFuncts->inputfn)
- ((Uz_Globs *)pG)->input = UsrFuncts->inputfn;
- if (UsrFuncts->structlen >= (sizeof(ulg) + 3*sizeof(dummyfn)) &&
- UsrFuncts->pausefn)
- ((Uz_Globs *)pG)->mpause = UsrFuncts->pausefn;
- if (UsrFuncts->structlen >= (sizeof(ulg) + 4*sizeof(dummyfn)) &&
- UsrFuncts->passwdfn)
- ((Uz_Globs *)pG)->decr_passwd = UsrFuncts->passwdfn;
- if (UsrFuncts->structlen >= (sizeof(ulg) + 5*sizeof(dummyfn)) &&
- UsrFuncts->statrepfn)
- ((Uz_Globs *)pG)->statreportcb = UsrFuncts->statrepfn;
- return TRUE;
- }
- int UZ_EXP UzpUnzipToMemory(char *zip, char *file, UzpOpts *optflgs,
- UzpCB *UsrFuncts, UzpBuffer *retstr)
- {
- int r;
- #if (defined(WINDLL) && !defined(CRTL_CP_IS_ISO))
- char *intern_zip, *intern_file;
- #endif
- CONSTRUCTGLOBALS();
- #if (defined(WINDLL) && !defined(CRTL_CP_IS_ISO))
- intern_zip = (char *)malloc(strlen(zip)+1);
- if (intern_zip == NULL) {
- DESTROYGLOBALS();
- return PK_MEM;
- }
- intern_file = (char *)malloc(strlen(file)+1);
- if (intern_file == NULL) {
- DESTROYGLOBALS();
- free(intern_zip);
- return PK_MEM;
- }
- ISO_TO_INTERN(zip, intern_zip);
- ISO_TO_INTERN(file, intern_file);
- # define zip intern_zip
- # define file intern_file
- #endif
- /* Copy those options that are meaningful for UzpUnzipToMemory, instead of
- * a simple "memcpy(G.UzO, optflgs, sizeof(UzpOpts));"
- */
- uO.pwdarg = optflgs->pwdarg;
- uO.aflag = optflgs->aflag;
- uO.C_flag = optflgs->C_flag;
- uO.qflag = optflgs->qflag; /* currently, overridden in unzipToMemory */
- if (!UzpDLL_Init((zvoid *)&G, UsrFuncts)) {
- DESTROYGLOBALS();
- return PK_BADERR;
- }
- G.redirect_data = 1;
- r = (unzipToMemory(__G__ zip, file, retstr) <= PK_WARN);
- DESTROYGLOBALS();
- #if (defined(WINDLL) && !defined(CRTL_CP_IS_ISO))
- # undef file
- # undef zip
- free(intern_file);
- free(intern_zip);
- #endif
- if (!r && retstr->strlength) {
- free(retstr->strptr);
- retstr->strptr = NULL;
- }
- return r;
- }
- #endif /* !WINDLL */
- #endif /* !__16BIT__ */
- #ifdef OS2DLL
- int UZ_EXP UzpFileTree(char *name, cbList(callBack), char *cpInclude[],
- char *cpExclude[])
- {
- int r;
- CONSTRUCTGLOBALS();
- uO.qflag = 2;
- uO.vflag = 1;
- uO.C_flag = 1;
- G.wildzipfn = name;
- G.process_all_files = TRUE;
- if (cpInclude) {
- char **ptr = cpInclude;
- while (*ptr != NULL) ptr++;
- G.filespecs = ptr - cpInclude;
- G.pfnames = cpInclude, G.process_all_files = FALSE;
- }
- if (cpExclude) {
- char **ptr = cpExclude;
- while (*ptr != NULL) ptr++;
- G.xfilespecs = ptr - cpExclude;
- G.pxnames = cpExclude, G.process_all_files = FALSE;
- }
- G.processExternally = callBack;
- r = process_zipfiles(__G)==0;
- DESTROYGLOBALS();
- return r;
- }
- #endif /* OS2DLL */
- #endif /* !SFX */
- /*---------------------------------------------------------------------------
- Helper functions
- ---------------------------------------------------------------------------*/
- void setFileNotFound(__G)
- __GDEF
- {
- G.filenotfound++;
- }
- #ifndef SFX
- int unzipToMemory(__GPRO__ char *zip, char *file, UzpBuffer *retstr)
- {
- int r;
- char *incname[2];
- if ((zip == NULL) || (strlen(zip) > ((WSIZE>>2) - 160)))
- return PK_PARAM;
- if ((file == NULL) || (strlen(file) > ((WSIZE>>2) - 160)))
- return PK_PARAM;
- G.process_all_files = FALSE;
- G.extract_flag = TRUE;
- uO.qflag = 2;
- G.wildzipfn = zip;
- G.pfnames = incname;
- incname[0] = file;
- incname[1] = NULL;
- G.filespecs = 1;
- r = process_zipfiles(__G);
- if (retstr) {
- retstr->strptr = (char *)G.redirect_buffer;
- retstr->strlength = G.redirect_size;
- }
- return r; /* returns `PK_???' error values */
- }
- #endif /* !SFX */
- /*
- With the advent of 64 bit support, for now I am assuming that
- if the size of the file is greater than an unsigned long, there
- will simply not be enough memory to handle it, and am returning
- FALSE.
- */
- int redirect_outfile(__G)
- __GDEF
- {
- #ifdef ZIP64_SUPPORT
- __int64 check_conversion;
- #endif
- if (G.redirect_size != 0 || G.redirect_buffer != NULL)
- return FALSE;
- #ifndef NO_SLIDE_REDIR
- G.redirect_slide = !G.pInfo->textmode;
- #endif
- #if (lenEOL != 1)
- if (G.pInfo->textmode) {
- G.redirect_size = (ulg)(G.lrec.ucsize * lenEOL);
- if (G.redirect_size < G.lrec.ucsize)
- G.redirect_size = (ulg)((G.lrec.ucsize > (ulg)-2L) ?
- G.lrec.ucsize : -2L);
- #ifdef ZIP64_SUPPORT
- check_conversion = G.lrec.ucsize * lenEOL;
- #endif
- } else
- #endif
- {
- G.redirect_size = (ulg)G.lrec.ucsize;
- #ifdef ZIP64_SUPPORT
- check_conversion = (__int64)G.lrec.ucsize;
- #endif
- }
- #ifdef ZIP64_SUPPORT
- if ((__int64)G.redirect_size != check_conversion)
- return FALSE;
- #endif
- #ifdef __16BIT__
- if ((ulg)((extent)G.redirect_size) != G.redirect_size)
- return FALSE;
- #endif
- #ifdef OS2
- DosAllocMem((void **)&G.redirect_buffer, G.redirect_size+1,
- PAG_READ|PAG_WRITE|PAG_COMMIT);
- G.redirect_pointer = G.redirect_buffer;
- #else
- G.redirect_pointer =
- G.redirect_buffer = malloc((extent)(G.redirect_size+1));
- #endif
- if (!G.redirect_buffer)
- return FALSE;
- G.redirect_pointer[G.redirect_size] = '\0';
- return TRUE;
- }
- int writeToMemory(__GPRO__ ZCONST uch *rawbuf, extent size)
- {
- int errflg = FALSE;
- if ((uch *)rawbuf != G.redirect_pointer) {
- extent redir_avail = (G.redirect_buffer + G.redirect_size) -
- G.redirect_pointer;
- /* Check for output buffer overflow */
- if (size > redir_avail) {
- /* limit transfer data to available space, set error return flag */
- size = redir_avail;
- errflg = TRUE;
- }
- memcpy(G.redirect_pointer, rawbuf, size);
- }
- G.redirect_pointer += size;
- return errflg;
- }
- int close_redirect(__G)
- __GDEF
- {
- if (G.pInfo->textmode) {
- *G.redirect_pointer = '\0';
- G.redirect_size = (ulg)(G.redirect_pointer - G.redirect_buffer);
- if ((G.redirect_buffer =
- realloc(G.redirect_buffer, G.redirect_size + 1)) == NULL) {
- G.redirect_size = 0;
- return EOF;
- }
- }
- return 0;
- }
- #ifndef SFX
- #ifndef __16BIT__
- #ifndef WINDLL
- /* Purpose: Determine if file in archive contains the string szSearch
- Parameters: archive = archive name
- file = file contained in the archive. This cannot be
- a wildcard to be meaningful
- pattern = string to search for
- cmd = 0 - case-insensitive search
- 1 - case-sensitve search
- 2 - case-insensitive, whole words only
- 3 - case-sensitive, whole words only
- SkipBin = if true, skip any files that have control
- characters other than CR, LF, or tab in the first
- 100 characters.
- Returns: TRUE if a match is found
- FALSE if no match is found
- -1 on error
- Comments: This does not pretend to be as useful as the standard
- Unix grep, which returns the strings associated with a
- particular pattern, nor does it search past the first
- matching occurrence of the pattern.
- */
- int UZ_EXP UzpGrep(char *archive, char *file, char *pattern, int cmd,
- int SkipBin, UzpCB *UsrFuncts)
- {
- int retcode = FALSE, compare;
- ulg i, j, patternLen, buflen;
- char * sz, *p;
- UzpOpts flgopts;
- UzpBuffer retstr;
- memzero(&flgopts, sizeof(UzpOpts)); /* no special options */
- if (!UzpUnzipToMemory(archive, file, &flgopts, UsrFuncts, &retstr)) {
- return -1; /* not enough memory, file not found, or other error */
- }
- if (SkipBin) {
- if (retstr.strlength < 100)
- buflen = retstr.strlength;
- else
- buflen = 100;
- for (i = 0; i < buflen; i++) {
- if (iscntrl(retstr.strptr[i])) {
- if ((retstr.strptr[i] != 0x0A) &&
- (retstr.strptr[i] != 0x0D) &&
- (retstr.strptr[i] != 0x09))
- {
- /* OK, we now think we have a binary file of some sort */
- free(retstr.strptr);
- return FALSE;
- }
- }
- }
- }
- patternLen = strlen(pattern);
- if (retstr.strlength < patternLen) {
- free(retstr.strptr);
- return FALSE;
- }
- sz = malloc(patternLen + 3); /* add two in case doing whole words only */
- if (cmd > 1) {
- strcpy(sz, " ");
- strcat(sz, pattern);
- strcat(sz, " ");
- } else
- strcpy(sz, pattern);
- if ((cmd == 0) || (cmd == 2)) {
- for (i = 0; i < strlen(sz); i++)
- sz[i] = toupper(sz[i]);
- for (i = 0; i < retstr.strlength; i++)
- retstr.strptr[i] = toupper(retstr.strptr[i]);
- }
- for (i = 0; i < (retstr.strlength - patternLen); i++) {
- p = &retstr.strptr[i];
- compare = TRUE;
- for (j = 0; j < patternLen; j++) {
- /* We cannot do strncmp here, as we may be dealing with a
- * "binary" file, such as a word processing file, or perhaps
- * even a true executable of some sort. */
- if (p[j] != sz[j]) {
- compare = FALSE;
- break;
- }
- }
- if (compare == TRUE) {
- retcode = TRUE;
- break;
- }
- }
- free(sz);
- free(retstr.strptr);
- return retcode;
- }
- #endif /* !WINDLL */
- #endif /* !__16BIT__ */
- int UZ_EXP UzpValidate(char *archive, int AllCodes)
- {
- int retcode;
- CONSTRUCTGLOBALS();
- uO.jflag = 1;
- uO.tflag = 1;
- uO.overwrite_none = 0;
- G.extract_flag = (!uO.zipinfo_mode &&
- !uO.cflag && !uO.tflag && !uO.vflag && !uO.zflag
- #ifdef TIMESTAMP
- && !uO.T_flag
- #endif
- );
- uO.qflag = 2; /* turn off all messages */
- G.fValidate = TRUE;
- G.pfnames = (char **)&fnames[0]; /* assign default filename vector */
- if (archive == NULL) { /* something is screwed up: no filename */
- DESTROYGLOBALS();
- retcode = PK_NOZIP;
- goto exit_retcode;
- }
- if (strlen(archive) >= FILNAMSIZ) {
- /* length of supplied archive name exceed the system's filename limit */
- DESTROYGLOBALS();
- retcode = PK_PARAM;
- goto exit_retcode;
- }
- G.wildzipfn = (char *)malloc(FILNAMSIZ);
- strcpy(G.wildzipfn, archive);
- #if (defined(WINDLL) && !defined(CRTL_CP_IS_ISO))
- _ISO_INTERN(G.wildzipfn);
- #endif
- #ifdef WINDLL
- Wiz_NoPrinting(TRUE);
- #endif
- G.process_all_files = TRUE; /* for speed */
- if (setjmp(dll_error_return) != 0) {
- #ifdef WINDLL
- Wiz_NoPrinting(FALSE);
- #endif
- free(G.wildzipfn);
- DESTROYGLOBALS();
- retcode = PK_BADERR;
- goto exit_retcode;
- }
- retcode = process_zipfiles(__G);
- free(G.wildzipfn);
- #ifdef WINDLL
- Wiz_NoPrinting(FALSE);
- #endif
- DESTROYGLOBALS();
- /* PK_WARN == 1 and PK_FIND == 11. When we are just looking at an
- archive, we should still be able to see the files inside it,
- even if we can't decode them for some reason.
- We also still want to be able to get at files even if there is
- something odd about the zip archive, hence allow PK_WARN,
- PK_FIND, IZ_UNSUP as well as PK_ERR
- */
- exit_retcode:
- if (AllCodes)
- return retcode;
- if ((retcode == PK_OK) || (retcode == PK_WARN) || (retcode == PK_ERR) ||
- (retcode == IZ_UNSUP) || (retcode == PK_FIND))
- return TRUE;
- else
- return FALSE;
- }
- #endif /* !SFX */
- #endif /* DLL */
|