unzip: Drop unneeded files and Jam rules.
We only use this for the host tools now, so a lot of the files can just be deleted altogether.
This commit is contained in:
+2
-48
@@ -1,48 +1,2 @@
|
||||
SubDir HAIKU_TOP src bin unzip ;
|
||||
|
||||
StaticLibrary libunzip.a :
|
||||
crc32.c
|
||||
ttyio.c
|
||||
crctab.c
|
||||
crypt.c
|
||||
envargs.c
|
||||
explode.c
|
||||
extract.c
|
||||
fileio.c
|
||||
globals.c
|
||||
inflate.c
|
||||
list.c
|
||||
match.c
|
||||
process.c
|
||||
zipinfo.c
|
||||
beos.c
|
||||
beosmain.cpp
|
||||
;
|
||||
|
||||
BinCommand unzip :
|
||||
unzip.c
|
||||
unreduce.c
|
||||
unshrink.c
|
||||
: libunzip.a be : unzip.rdef
|
||||
;
|
||||
|
||||
BinCommand funzip :
|
||||
funzip.c
|
||||
cryptf.c
|
||||
globalsf.c
|
||||
inflatef.c
|
||||
crc32.c
|
||||
ttyio.c
|
||||
: be : unzip.rdef
|
||||
;
|
||||
|
||||
BinCommand unzipsfx :
|
||||
unzip.c
|
||||
sfxdefs.c
|
||||
: libunzip.a be : unzip.rdef
|
||||
;
|
||||
|
||||
{
|
||||
MakeLocatePlatform <bin>zipgrep ;
|
||||
Shell <bin>zipgrep : zipgrep ;
|
||||
}
|
||||
# Nothing here.
|
||||
# (The rules for <build>unzip are in src/tools/unzip/.)
|
||||
|
||||
@@ -1,610 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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:
|
||||
|
||||
UzpVer *UzpVersion(void);
|
||||
void 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
|
||||
#include <setjmp.h>
|
||||
|
||||
#define UNZIP_INTERNAL
|
||||
#include "unzip.h"
|
||||
#ifdef WINDLL
|
||||
# include "windll/windll.h"
|
||||
#endif
|
||||
#include "unzvers.h"
|
||||
|
||||
#ifdef DLL /* This source file supplies DLL-only interface code. */
|
||||
|
||||
jmp_buf dll_error_return;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Documented API entry points
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
UzpVer * UZ_EXP UzpVersion() /* should be pointer to const struct */
|
||||
{
|
||||
static UzpVer version; /* doesn't change between calls */
|
||||
|
||||
|
||||
version.structlen = UZPVER_LEN;
|
||||
|
||||
#ifdef BETA
|
||||
version.flag = 1;
|
||||
#else
|
||||
version.flag = 0;
|
||||
#endif
|
||||
version.betalevel = UZ_BETALEVEL;
|
||||
version.date = UZ_VERSION_DATE;
|
||||
|
||||
#ifdef ZLIB_VERSION
|
||||
version.zlib_version = ZLIB_VERSION;
|
||||
version.flag |= 2;
|
||||
#else
|
||||
version.zlib_version = NULL;
|
||||
#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;
|
||||
|
||||
return &version;
|
||||
}
|
||||
|
||||
void UZ_EXP UzpVersion2(UzpVer2 *version)
|
||||
{
|
||||
|
||||
version->structlen = UZPVER_LEN;
|
||||
|
||||
#ifdef BETA
|
||||
version->flag = 1;
|
||||
#else
|
||||
version->flag = 0;
|
||||
#endif
|
||||
strcpy(version->betalevel, UZ_BETALEVEL);
|
||||
strcpy(version->date, UZ_VERSION_DATE);
|
||||
|
||||
#ifdef ZLIB_VERSION
|
||||
strcpy(version->zlib_version, ZLIB_VERSION);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#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->strptr != NULL) {
|
||||
free(retstr->strptr);
|
||||
retstr->strptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Helper functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void setFileNotFound(__G)
|
||||
__GDEF
|
||||
{
|
||||
G.filenotfound++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int unzipToMemory(__GPRO__ char *zip, char *file, UzpBuffer *retstr)
|
||||
{
|
||||
int r;
|
||||
char *incname[2];
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int redirect_outfile(__G)
|
||||
__GDEF
|
||||
{
|
||||
if (G.redirect_size != 0 || G.redirect_buffer != NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifndef NO_SLIDE_REDIR
|
||||
G.redirect_slide = !G.pInfo->textmode;
|
||||
#endif
|
||||
G.redirect_size = (G.pInfo->textmode ?
|
||||
G.lrec.ucsize * lenEOL : G.lrec.ucsize);
|
||||
#ifdef OS2
|
||||
DosAllocMem((void **)&G.redirect_buffer, G.redirect_size+1,
|
||||
PAG_READ|PAG_WRITE|PAG_COMMIT);
|
||||
G.redirect_pointer = G.redirect_buffer;
|
||||
#else
|
||||
#ifdef __16BIT__
|
||||
if ((ulg)((extent)G.redirect_size) != G.redirect_size)
|
||||
return FALSE;
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
if ((uch *)rawbuf != G.redirect_pointer)
|
||||
memcpy(G.redirect_pointer, rawbuf, size);
|
||||
G.redirect_pointer += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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 __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 wild card 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 */
|
||||
#ifdef WINDLL
|
||||
Wiz_NoPrinting(TRUE);
|
||||
#endif
|
||||
|
||||
if (archive == NULL) { /* something is screwed up: no filename */
|
||||
DESTROYGLOBALS();
|
||||
return PK_NOZIP;
|
||||
}
|
||||
|
||||
G.wildzipfn = (char *)malloc(FILNAMSIZ + 1);
|
||||
strcpy(G.wildzipfn, archive);
|
||||
#if (defined(WINDLL) && !defined(CRTL_CP_IS_ISO))
|
||||
_ISO_INTERN(G.wildzipfn);
|
||||
#endif
|
||||
|
||||
G.process_all_files = TRUE; /* for speed */
|
||||
|
||||
retcode = setjmp(dll_error_return);
|
||||
|
||||
if (retcode) {
|
||||
#ifdef WINDLL
|
||||
Wiz_NoPrinting(FALSE);
|
||||
#endif
|
||||
free(G.wildzipfn);
|
||||
DESTROYGLOBALS();
|
||||
return PK_BADERR;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
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 /* DLL */
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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
|
||||
*/
|
||||
/* apihelp.c */
|
||||
|
||||
#ifdef API_DOC
|
||||
|
||||
#define UNZIP_INTERNAL
|
||||
#include "unzip.h"
|
||||
#include "unzvers.h"
|
||||
|
||||
|
||||
APIDocStruct APIDoc[] = {
|
||||
{
|
||||
"UZPVERSION" , "UzpVersion" ,
|
||||
"UzpVer *UzpVersion(void);",
|
||||
"Get version numbers of the API and the underlying UnZip code.\n\n"
|
||||
"\t\tThis is used for comparing the version numbers of the run-time\n"
|
||||
"\t\tDLL code with those expected from the unzip.h at compile time.\n"
|
||||
"\t\tIf the version numbers do not match, there may be compatibility\n"
|
||||
"\t\tproblems with further use of the DLL.\n\n"
|
||||
" Example:\t/* Check the major version number of the DLL code. */\n"
|
||||
"\t\tUzpVer *pVersion;\n"
|
||||
"\t\tpVersion = UzpVersion();\n"
|
||||
"\t\tif (pVersion->unzip.major != UZ_MAJORVER)\n"
|
||||
"\t\t fprintf(stderr, \"error: using wrong version of DLL\\n\");\n\n"
|
||||
"\t\tSee unzip.h for details and unzipstb.c for an example.\n"
|
||||
},
|
||||
|
||||
{
|
||||
"UZPMAIN" , "UzpMain" ,
|
||||
"int UzpMain(int argc, char *argv[]);",
|
||||
"Provide a direct entry point to the command line interface.\n\n"
|
||||
"\t\tThis is used by the UnZip stub but you can use it in your\n"
|
||||
"\t\town program as well. Output is sent to stdout.\n"
|
||||
"\t\t0 on return indicates success.\n\n"
|
||||
" Example:\t/* Extract 'test.zip' silently, junking paths. */\n"
|
||||
"\t\tchar *argv[] = { \"-q\", \"-j\", \"test.zip\" };\n"
|
||||
"\t\tint argc = 3;\n"
|
||||
"\t\tif (UzpMain(argc,argv))\n"
|
||||
"\t\t printf(\"error: unzip failed\\n\");\n\n"
|
||||
"\t\tSee unzip.h for details.\n"
|
||||
},
|
||||
|
||||
{
|
||||
"UZPALTMAIN" , "UzpAltMain" ,
|
||||
"int UzpAltMain(int argc, char *argv[], UzpInit *init);",
|
||||
"Provide a direct entry point to the command line interface,\n"
|
||||
"optionally installing replacement I/O handler functions.\n\n"
|
||||
"\t\tAs with UzpMain(), output is sent to stdout by default.\n"
|
||||
"\t\t`InputFn *inputfn' is not yet implemented. 0 on return\n"
|
||||
"\t\tindicates success.\n\n"
|
||||
" Example:\t/* Replace normal output and `more' functions. */\n"
|
||||
"\t\tchar *argv[] = { \"-q\", \"-j\", \"test.zip\" };\n"
|
||||
"\t\tint argc = 3;\n"
|
||||
"\t\tUzpInit init = { 16, MyMessageFn, NULL, MyPauseFn };\n"
|
||||
"\t\tif (UzpAltMain(argc,argv,&init))\n"
|
||||
"\t\t printf(\"error: unzip failed\\n\");\n\n"
|
||||
"\t\tSee unzip.h for details.\n"
|
||||
},
|
||||
|
||||
{
|
||||
"UZPUNZIPTOMEMORY", "UzpUnzipToMemory",
|
||||
"int UzpUnzipToMemory(char *zip, char *file, UzpBuffer *retstr);",
|
||||
"Pass the name of the zip file and the name of the file\n"
|
||||
"\t\tyou wish to extract. UzpUnzipToMemory will create a\n"
|
||||
"\t\tbuffer and return it in *retstr; 0 on return indicates\n"
|
||||
"\t\tfailure.\n\n"
|
||||
"\t\tSee unzip.h for details.\n"
|
||||
},
|
||||
|
||||
{
|
||||
"UZPFILETREE", "UzpFileTree",
|
||||
"int UzpFileTree(char *name, cbList(callBack),\n"
|
||||
"\t\t\tchar *cpInclude[], char *cpExclude[]);",
|
||||
"Pass the name of the zip file, a callback function, an\n"
|
||||
"\t\tinclude and exclude file list. UzpFileTree calls the\n"
|
||||
"\t\tcallback for each valid file found in the zip file.\n"
|
||||
"\t\t0 on return indicates failure.\n\n"
|
||||
"\t\tSee unzip.h for details.\n"
|
||||
},
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
static int function_help OF((__GPRO__ APIDocStruct *doc, char *fname));
|
||||
|
||||
|
||||
|
||||
static int function_help(__G__ doc, fname)
|
||||
__GDEF
|
||||
APIDocStruct *doc;
|
||||
char *fname;
|
||||
{
|
||||
strcpy(slide, fname);
|
||||
/* strupr(slide); non-standard */
|
||||
while (doc->compare && STRNICMP(doc->compare,slide,strlen(fname)))
|
||||
doc++;
|
||||
if (!doc->compare)
|
||||
return 0;
|
||||
else
|
||||
Info(slide, 0, ((char *)slide,
|
||||
" Function:\t%s\n\n Syntax:\t%s\n\n Purpose:\t%s",
|
||||
doc->function, doc->syntax, doc->purpose));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void APIhelp(__G__ argc, argv)
|
||||
__GDEF
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
if (argc > 1) {
|
||||
struct APIDocStruct *doc;
|
||||
|
||||
if (function_help(__G__ APIDoc, argv[1]))
|
||||
return;
|
||||
#ifdef SYSTEM_API_DETAILS
|
||||
if (function_help(__G__ SYSTEM_API_DETAILS, argv[1]))
|
||||
return;
|
||||
#endif
|
||||
Info(slide, 0, ((char *)slide,
|
||||
"%s is not a documented command.\n\n", argv[1]));
|
||||
}
|
||||
|
||||
Info(slide, 0, ((char *)slide, "\
|
||||
This API provides a number of external C and REXX functions for handling\n\
|
||||
zipfiles in OS/2. Programmers are encouraged to expand this API.\n\
|
||||
\n\
|
||||
C functions: -- See unzip.h for details\n\
|
||||
UzpVer *UzpVersion(void);\n\
|
||||
int UzpMain(int argc, char *argv[]);\n\
|
||||
int UzpAltMain(int argc, char *argv[], UzpInit *init);\n\
|
||||
int UzpUnzipToMemory(char *zip, char *file, UzpBuffer *retstr);\n\
|
||||
int UzpFileTree(char *name, cbList(callBack),\n\
|
||||
char *cpInclude[], char *cpExclude[]);\n\n"));
|
||||
|
||||
#ifdef SYSTEM_API_BRIEF
|
||||
Info(slide, 0, ((char *)slide, SYSTEM_API_BRIEF));
|
||||
#endif
|
||||
|
||||
Info(slide, 0, ((char *)slide,
|
||||
"\nFor more information, type 'unzip -A <function-name>'\n"));
|
||||
}
|
||||
|
||||
#endif /* API_DOC */
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
/*
|
||||
* crc_i386.S, optimized CRC calculation function for Zip and UnZip,
|
||||
* created by Paul Kienitz and Christian Spieler. Last revised 24 Dec 98.
|
||||
*
|
||||
* GRR 961110: incorporated Scott Field optimizations from win32/crc_i386.asm
|
||||
* => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
|
||||
*
|
||||
* SPC 970402: revised for Rodney Brown's optimizations (32-bit-wide
|
||||
* aligned reads for most of the data from buffer), can be
|
||||
* disabled by defining the macro NO_32_BIT_LOADS
|
||||
*
|
||||
* SPC 971012: added Rodney Brown's additional tweaks for 32-bit-optimized
|
||||
* CPUs (like the Pentium Pro, Pentium II, and probably some
|
||||
* Pentium clones). This optimization is controlled by the
|
||||
* preprocessor switch "__686" and is disabled by default.
|
||||
* (This default is based on the assumption that most users
|
||||
* do not yet work on a Pentium Pro or Pentium II machine ...)
|
||||
*
|
||||
* FLAT memory model assumed. Calling interface:
|
||||
* - args are pushed onto the stack from right to left,
|
||||
* - return value is given in the EAX register,
|
||||
* - all other registers (with exception of EFLAGS) are preserved. (With
|
||||
* GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
|
||||
* them nevertheless adds only 4 single byte instructions.)
|
||||
*
|
||||
* This source generates the function
|
||||
* ulg crc32(ulg crc, ZCONST uch *buf, extent len).
|
||||
*
|
||||
* The loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
|
||||
* This results in shorter code at the expense of reduced performance.
|
||||
*/
|
||||
|
||||
/* This file is NOT used in conjunction with zlib. */
|
||||
#ifndef USE_ZLIB
|
||||
|
||||
/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
|
||||
* external symbols with an underline character '_'.
|
||||
*/
|
||||
#if defined(NO_UNDERLINE) || defined(__ELF__)
|
||||
# define _crc32 crc32
|
||||
# define _get_crc_table get_crc_table
|
||||
#endif
|
||||
/* Use 16-byte alignment if your assembler supports it. Warning: gas
|
||||
* uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
|
||||
* the parameter is a number of bytes.
|
||||
*/
|
||||
#ifndef ALIGNMENT
|
||||
# define ALIGNMENT .align 4,0x90
|
||||
#endif
|
||||
|
||||
#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
|
||||
|
||||
/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
|
||||
* Warning: it uses the AT&T syntax: mov source,dest
|
||||
* This file is only optional. If you want to use the C version,
|
||||
* remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
|
||||
*/
|
||||
|
||||
.file "crc_i386.S"
|
||||
|
||||
#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
|
||||
# undef USE_STACKFRAME
|
||||
#else
|
||||
/* The default is to use standard stack frame entry, because it
|
||||
* results in smaller code!
|
||||
*/
|
||||
# ifndef USE_STD_STACKFRAME
|
||||
# define USE_STD_STACKFRAME
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_STD_STACKFRAME
|
||||
# define _STD_ENTRY pushl %ebp ; movl %esp,%ebp
|
||||
# define arg1 8(%ebp)
|
||||
# define arg2 12(%ebp)
|
||||
# define arg3 16(%ebp)
|
||||
# define _STD_LEAVE popl %ebp
|
||||
#else /* !USE_STD_STACKFRAME */
|
||||
# define _STD_ENTRY
|
||||
# define arg1 24(%esp)
|
||||
# define arg2 28(%esp)
|
||||
# define arg3 32(%esp)
|
||||
# define _STD_LEAVE
|
||||
#endif /* ?USE_STD_STACKFRAME */
|
||||
|
||||
/*
|
||||
* These two (three) macros make up the loop body of the CRC32 cruncher.
|
||||
* registers modified:
|
||||
* eax : crc value "c"
|
||||
* esi : pointer to next data byte (or lword) "buf++"
|
||||
* registers read:
|
||||
* edi : pointer to base of crc_table array
|
||||
* scratch registers:
|
||||
* ebx : index into crc_table array
|
||||
* (requires upper three bytes = 0 when __686 is undefined)
|
||||
*/
|
||||
#ifndef __686 /* optimize for 386, 486, Pentium */
|
||||
#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
|
||||
movb %al, %bl ;/* tmp = c & 0xFF */\
|
||||
shrl $8, %eax ;/* c = (c >> 8) */\
|
||||
xorl (%edi, %ebx, 4), %eax ;/* c ^= table[tmp] */
|
||||
#else /* __686 : optimize for Pentium Pro and compatible CPUs */
|
||||
#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\
|
||||
movzbl %al, %ebx ;/* tmp = c & 0xFF */\
|
||||
shrl $8, %eax ;/* c = (c >> 8) */\
|
||||
xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */
|
||||
#endif /* ?__686 */
|
||||
|
||||
#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
|
||||
xorb (%esi), %al ;/* c ^= *buf */\
|
||||
incl %esi ;/* buf++ */\
|
||||
Do_CRC
|
||||
|
||||
#ifndef NO_32_BIT_LOADS
|
||||
#define Do_CRC_lword \
|
||||
xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
|
||||
addl $4, %esi ;/* ((ulg *)buf)++ */\
|
||||
Do_CRC \
|
||||
Do_CRC \
|
||||
Do_CRC \
|
||||
Do_CRC
|
||||
#endif /* !NO_32_BIT_LOADS */
|
||||
|
||||
|
||||
.text
|
||||
|
||||
.globl _crc32
|
||||
|
||||
_crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */
|
||||
_STD_ENTRY
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
|
||||
movl arg2, %esi /* 2nd arg: uch *buf */
|
||||
subl %eax, %eax /* > if (!buf) */
|
||||
testl %esi, %esi /* > return 0; */
|
||||
jz .L_fine /* > else { */
|
||||
call _get_crc_table
|
||||
movl %eax, %edi
|
||||
movl arg1, %eax /* 1st arg: ulg crc */
|
||||
#ifndef __686
|
||||
subl %ebx, %ebx /* ebx=0; bl usable as dword */
|
||||
#endif
|
||||
movl arg3, %ecx /* 3rd arg: extent len */
|
||||
notl %eax /* > c = ~crc; */
|
||||
|
||||
testl %ecx, %ecx
|
||||
#ifndef NO_UNROLLED_LOOPS
|
||||
jz .L_bail
|
||||
# ifndef NO_32_BIT_LOADS
|
||||
/* Assert now have positive length */
|
||||
.L_align_loop:
|
||||
testl $3, %esi /* Align buf on lword boundary */
|
||||
jz .L_aligned_now
|
||||
Do_CRC_byte
|
||||
decl %ecx
|
||||
jnz .L_align_loop
|
||||
.L_aligned_now:
|
||||
# endif /* !NO_32_BIT_LOADS */
|
||||
movl %ecx, %edx /* save len in edx */
|
||||
shrl $3, %ecx /* ecx = len / 8 */
|
||||
jz .L_No_Eights
|
||||
/* align loop head at start of 486 internal cache line !! */
|
||||
ALIGNMENT
|
||||
.L_Next_Eight:
|
||||
# ifndef NO_32_BIT_LOADS
|
||||
/* Do_CRC_lword */
|
||||
xorl (%esi), %eax ;/* c ^= *(ulg *)buf */
|
||||
addl $4, %esi ;/* ((ulg *)buf)++ */
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
/* Do_CRC_lword */
|
||||
xorl (%esi), %eax ;/* c ^= *(ulg *)buf */
|
||||
addl $4, %esi ;/* ((ulg *)buf)++ */
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
Do_CRC
|
||||
# else /* NO_32_BIT_LOADS */
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
Do_CRC_byte
|
||||
# endif /* ?NO_32_BIT_LOADS */
|
||||
decl %ecx
|
||||
jnz .L_Next_Eight
|
||||
|
||||
.L_No_Eights:
|
||||
movl %edx, %ecx
|
||||
andl $7, %ecx /* ecx = len % 8 */
|
||||
#endif /* !NO_UNROLLED_LOOPS */
|
||||
jz .L_bail /* > if (len) */
|
||||
/* align loop head at start of 486 internal cache line !! */
|
||||
ALIGNMENT
|
||||
.L_loupe: /* > do { */
|
||||
Do_CRC_byte /* c = CRC32(c, *buf++); */
|
||||
decl %ecx /* > } while (--len); */
|
||||
jnz .L_loupe
|
||||
|
||||
.L_bail: /* > } */
|
||||
notl %eax /* > return ~c; */
|
||||
.L_fine:
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
_STD_LEAVE
|
||||
ret
|
||||
|
||||
#else
|
||||
error: this asm version is for 386 only
|
||||
#endif /* i386 || _i386 || _I386 || __i386 */
|
||||
|
||||
#endif /* !USE_ZLIB */
|
||||
@@ -1,583 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
/*
|
||||
crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
|
||||
|
||||
This encryption/decryption source code for Info-Zip software was
|
||||
originally written in Europe. The whole source package can be
|
||||
freely distributed, including from the USA. (Prior to January 2000,
|
||||
re-export from the US was a violation of US law.)
|
||||
|
||||
NOTE on copyright history:
|
||||
Previous versions of this source package (up to version 2.8) were
|
||||
not copyrighted and put in the public domain. If you cannot comply
|
||||
with the Info-Zip LICENSE, you may want to look for one of those
|
||||
public domain versions.
|
||||
*/
|
||||
|
||||
/*
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
*/
|
||||
|
||||
#define ZCRYPT_INTERNAL
|
||||
#include "zip.h"
|
||||
#include "crypt.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
#if CRYPT
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifdef ZIP
|
||||
/* For the encoding task used in Zip (and ZipCloak), we want to initialize
|
||||
the crypt algorithm with some reasonably unpredictable bytes, see
|
||||
the crypthead() function. The standard rand() library function is
|
||||
used to supply these `random' bytes, which in turn is initialized by
|
||||
a srand() call. The srand() function takes an "unsigned" (at least 16bit)
|
||||
seed value as argument to determine the starting point of the rand()
|
||||
pseudo-random number generator.
|
||||
This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
|
||||
Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
|
||||
as some (hopefully) nondeterministic bitmask. On many (most) systems,
|
||||
we use some "process specific" number, as the PID or something similar,
|
||||
but when nothing unpredictable is available, a fixed number may be
|
||||
sufficient.
|
||||
NOTE:
|
||||
1.) This implementation requires the availability of the following
|
||||
standard UNIX C runtime library functions: time(), rand(), srand().
|
||||
On systems where some of them are missing, the environment that
|
||||
incorporates the crypt routines must supply suitable replacement
|
||||
functions.
|
||||
2.) It is a very bad idea to use a second call to time() to set the
|
||||
"Seed2" number! In this case, both "Seed1" and "Seed2" would be
|
||||
(almost) identical, resulting in a (mostly) "zero" constant seed
|
||||
number passed to srand().
|
||||
|
||||
The implementation environment defined in the "zip.h" header should
|
||||
supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
|
||||
most implementations of rand() and srand(), only the lower 16 bits are
|
||||
significant!). An example that works on many systems would be
|
||||
"#define ZCR_SEED2 (unsigned)getpid()".
|
||||
The default definition for ZCR_SEED2 supplied below should be regarded
|
||||
as a fallback to allow successful compilation in "beta state"
|
||||
environments.
|
||||
*/
|
||||
# include <time.h> /* time() function supplies first part of crypt seed */
|
||||
/* "last resort" source for second part of crypt seed pattern */
|
||||
# ifndef ZCR_SEED2
|
||||
# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
|
||||
# endif
|
||||
# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
|
||||
# undef GLOBAL
|
||||
# endif
|
||||
# define GLOBAL(g) g
|
||||
#else /* !ZIP */
|
||||
# define GLOBAL(g) G.g
|
||||
#endif /* ?ZIP */
|
||||
|
||||
|
||||
#ifdef UNZIP
|
||||
/* char *key = (char *)NULL; moved to globals.h */
|
||||
# ifndef FUNZIP
|
||||
local int testp OF((__GPRO__ ZCONST uch *h));
|
||||
local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
|
||||
# endif
|
||||
#endif /* UNZIP */
|
||||
|
||||
#ifndef UNZIP /* moved to globals.h for UnZip */
|
||||
local ulg keys[3]; /* keys defining the pseudo-random sequence */
|
||||
#endif /* !UNZIP */
|
||||
|
||||
#ifndef Trace
|
||||
# ifdef CRYPT_DEBUG
|
||||
# define Trace(x) fprintf x
|
||||
# else
|
||||
# define Trace(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CRC_32_TAB
|
||||
# define CRC_32_TAB crc_32_tab
|
||||
#endif
|
||||
|
||||
#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
int decrypt_byte(__G)
|
||||
__GDEF
|
||||
{
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
|
||||
temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
|
||||
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Update the encryption keys with the next byte of plain text
|
||||
*/
|
||||
int update_keys(__G__ c)
|
||||
__GDEF
|
||||
int c; /* byte of plain text */
|
||||
{
|
||||
GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
|
||||
GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
|
||||
GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
|
||||
{
|
||||
register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
|
||||
GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialize the encryption keys and the random header according to
|
||||
* the given password.
|
||||
*/
|
||||
void init_keys(__G__ passwd)
|
||||
__GDEF
|
||||
ZCONST char *passwd; /* password string with which to modify keys */
|
||||
{
|
||||
GLOBAL(keys[0]) = 305419896L;
|
||||
GLOBAL(keys[1]) = 591751049L;
|
||||
GLOBAL(keys[2]) = 878082192L;
|
||||
while (*passwd != '\0') {
|
||||
update_keys(__G__ (int)*passwd);
|
||||
passwd++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZIP
|
||||
|
||||
/***********************************************************************
|
||||
* Write encryption header to file zfile using the password passwd
|
||||
* and the cyclic redundancy check crc.
|
||||
*/
|
||||
void crypthead(passwd, crc, zfile)
|
||||
ZCONST char *passwd; /* password string */
|
||||
ulg crc; /* crc of file being encrypted */
|
||||
FILE *zfile; /* where to write header */
|
||||
{
|
||||
int n; /* index in random header */
|
||||
int t; /* temporary */
|
||||
int c; /* random byte */
|
||||
int ztemp; /* temporary for zencoded value */
|
||||
uch header[RAND_HEAD_LEN-2]; /* random header */
|
||||
static unsigned calls = 0; /* ensure different random header each time */
|
||||
|
||||
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
|
||||
* output of rand() to get less predictability, since rand() is
|
||||
* often poorly implemented.
|
||||
*/
|
||||
if (++calls == 1) {
|
||||
srand((unsigned)time(NULL) ^ ZCR_SEED2);
|
||||
}
|
||||
init_keys(passwd);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
||||
c = (rand() >> 7) & 0xff;
|
||||
header[n] = (uch)zencode(c, t);
|
||||
}
|
||||
/* Encrypt random header (last two bytes is high word of crc) */
|
||||
init_keys(passwd);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
||||
ztemp = zencode(header[n], t);
|
||||
putc(ztemp, zfile);
|
||||
}
|
||||
ztemp = zencode((int)(crc >> 16) & 0xff, t);
|
||||
putc(ztemp, zfile);
|
||||
ztemp = zencode((int)(crc >> 24) & 0xff, t);
|
||||
putc(ztemp, zfile);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UTIL
|
||||
|
||||
/***********************************************************************
|
||||
* Encrypt the zip entry described by z from file source to file dest
|
||||
* using the password passwd. Return an error code in the ZE_ class.
|
||||
*/
|
||||
int zipcloak(z, source, dest, passwd)
|
||||
struct zlist far *z; /* zip entry to encrypt */
|
||||
FILE *source, *dest; /* source and destination files */
|
||||
ZCONST char *passwd; /* password string */
|
||||
{
|
||||
int c; /* input byte */
|
||||
int res; /* result code */
|
||||
ulg n; /* holds offset and counts size */
|
||||
ush flag; /* previous flags */
|
||||
int t; /* temporary */
|
||||
int ztemp; /* temporary storage for zencode value */
|
||||
|
||||
/* Set encrypted bit, clear extended local header bit and write local
|
||||
header to output file */
|
||||
if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
||||
z->off = n;
|
||||
flag = z->flg;
|
||||
z->flg |= 1, z->flg &= ~8;
|
||||
z->lflg |= 1, z->lflg &= ~8;
|
||||
z->siz += RAND_HEAD_LEN;
|
||||
if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
||||
|
||||
/* Initialize keys with password and write random header */
|
||||
crypthead(passwd, z->crc, dest);
|
||||
|
||||
/* Skip local header in input file */
|
||||
if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
||||
SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
|
||||
/* Encrypt data */
|
||||
for (n = z->siz - RAND_HEAD_LEN; n; n--) {
|
||||
if ((c = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
ztemp = zencode(c, t);
|
||||
putc(ztemp, dest);
|
||||
}
|
||||
/* Skip extended local header in input file if there is one */
|
||||
if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if (fflush(dest) == EOF) return ZE_TEMP;
|
||||
return ZE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Decrypt the zip entry described by z from file source to file dest
|
||||
* using the password passwd. Return an error code in the ZE_ class.
|
||||
*/
|
||||
int zipbare(z, source, dest, passwd)
|
||||
struct zlist far *z; /* zip entry to encrypt */
|
||||
FILE *source, *dest; /* source and destination files */
|
||||
ZCONST char *passwd; /* password string */
|
||||
{
|
||||
int c0, c1; /* last two input bytes */
|
||||
ulg offset; /* used for file offsets */
|
||||
ulg size; /* size of input data */
|
||||
int r; /* size of encryption header */
|
||||
int res; /* return code */
|
||||
ush flag; /* previous flags */
|
||||
|
||||
/* Save position and skip local header in input file */
|
||||
if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
|
||||
fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
||||
SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
/* Initialize keys with password */
|
||||
init_keys(passwd);
|
||||
|
||||
/* Decrypt encryption header, save last two bytes */
|
||||
c1 = 0;
|
||||
for (r = RAND_HEAD_LEN; r; r--) {
|
||||
c0 = c1;
|
||||
if ((c1 = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
Trace((stdout, " (%02x)", c1));
|
||||
zdecode(c1);
|
||||
Trace((stdout, " %02x", c1));
|
||||
}
|
||||
Trace((stdout, "\n"));
|
||||
|
||||
/* If last two bytes of header don't match crc (or file time in the
|
||||
* case of an extended local header), back up and just copy. For
|
||||
* pkzip 2.0, the check has been reduced to one byte only.
|
||||
*/
|
||||
#ifdef ZIP10
|
||||
if ((ush)(c0 | (c1<<8)) !=
|
||||
(z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
|
||||
#else
|
||||
c0++; /* avoid warning on unused variable */
|
||||
if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
|
||||
#endif
|
||||
if (fseek(source, offset, SEEK_SET)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
|
||||
return ZE_MISS;
|
||||
}
|
||||
|
||||
/* Clear encrypted bit and local header bit, and write local header to
|
||||
output file */
|
||||
if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
||||
z->off = offset;
|
||||
flag = z->flg;
|
||||
z->flg &= ~9;
|
||||
z->lflg &= ~9;
|
||||
z->siz -= RAND_HEAD_LEN;
|
||||
if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
||||
|
||||
/* Decrypt data */
|
||||
for (size = z->siz; size; size--) {
|
||||
if ((c1 = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
zdecode(c1);
|
||||
putc(c1, dest);
|
||||
}
|
||||
/* Skip extended local header in input file if there is one */
|
||||
if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if (fflush(dest) == EOF) return ZE_TEMP;
|
||||
|
||||
return ZE_OK;
|
||||
}
|
||||
|
||||
|
||||
#else /* !UTIL */
|
||||
|
||||
/***********************************************************************
|
||||
* If requested, encrypt the data in buf, and in any case call fwrite()
|
||||
* with the arguments to zfwrite(). Return what fwrite() returns.
|
||||
*/
|
||||
unsigned zfwrite(buf, item_size, nb, f)
|
||||
zvoid *buf; /* data buffer */
|
||||
extent item_size; /* size of each item in bytes */
|
||||
extent nb; /* number of items */
|
||||
FILE *f; /* file to write to */
|
||||
{
|
||||
int t; /* temporary */
|
||||
|
||||
if (key != (char *)NULL) { /* key is the global password pointer */
|
||||
ulg size; /* buffer size */
|
||||
char *p = (char*)buf; /* steps through buffer */
|
||||
|
||||
/* Encrypt data in buffer */
|
||||
for (size = item_size*(ulg)nb; size != 0; p++, size--) {
|
||||
*p = (char)zencode(*p, t);
|
||||
}
|
||||
}
|
||||
/* Write the buffer out */
|
||||
return fwrite(buf, item_size, nb, f);
|
||||
}
|
||||
|
||||
#endif /* ?UTIL */
|
||||
#endif /* ZIP */
|
||||
|
||||
|
||||
#if (defined(UNZIP) && !defined(FUNZIP))
|
||||
|
||||
/***********************************************************************
|
||||
* Get the password and set up keys for current zipfile member.
|
||||
* Return PK_ class error.
|
||||
*/
|
||||
int decrypt(__G__ passwrd)
|
||||
__GDEF
|
||||
ZCONST char *passwrd;
|
||||
{
|
||||
ush b;
|
||||
int n, r;
|
||||
uch h[RAND_HEAD_LEN];
|
||||
|
||||
Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
|
||||
|
||||
/* get header once (turn off "encrypted" flag temporarily so we don't
|
||||
* try to decrypt the same data twice) */
|
||||
GLOBAL(pInfo->encrypted) = FALSE;
|
||||
defer_leftover_input(__G);
|
||||
for (n = 0; n < RAND_HEAD_LEN; n++) {
|
||||
b = NEXTBYTE;
|
||||
h[n] = (uch)b;
|
||||
Trace((stdout, " (%02x)", h[n]));
|
||||
}
|
||||
undefer_input(__G);
|
||||
GLOBAL(pInfo->encrypted) = TRUE;
|
||||
|
||||
if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
|
||||
GLOBAL(newzip) = FALSE;
|
||||
if (passwrd != (char *)NULL) { /* user gave password on command line */
|
||||
if (!GLOBAL(key)) {
|
||||
if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
|
||||
(char *)NULL)
|
||||
return PK_MEM2;
|
||||
strcpy(GLOBAL(key), passwrd);
|
||||
GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
|
||||
}
|
||||
} else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
|
||||
free(GLOBAL(key));
|
||||
GLOBAL(key) = (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* if have key already, test it; else allocate memory for it */
|
||||
if (GLOBAL(key)) {
|
||||
if (!testp(__G__ h))
|
||||
return PK_COOL; /* existing password OK (else prompt for new) */
|
||||
else if (GLOBAL(nopwd))
|
||||
return PK_WARN; /* user indicated no more prompting */
|
||||
} else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
|
||||
return PK_MEM2;
|
||||
|
||||
/* try a few keys */
|
||||
n = 0;
|
||||
do {
|
||||
r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
|
||||
GLOBAL(zipfn), GLOBAL(filename));
|
||||
if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
|
||||
free (GLOBAL(key));
|
||||
GLOBAL(key) = NULL;
|
||||
return PK_MEM2;
|
||||
}
|
||||
if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
|
||||
*GLOBAL(key) = '\0'; /* We try the NIL password, ... */
|
||||
n = 0; /* and cancel fetch for this item. */
|
||||
}
|
||||
if (!testp(__G__ h))
|
||||
return PK_COOL;
|
||||
if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
|
||||
GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
|
||||
} while (n > 0);
|
||||
|
||||
return PK_WARN;
|
||||
|
||||
} /* end function decrypt() */
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Test the password. Return -1 if bad, 0 if OK.
|
||||
*/
|
||||
local int testp(__G__ h)
|
||||
__GDEF
|
||||
ZCONST uch *h;
|
||||
{
|
||||
int r;
|
||||
char *key_translated;
|
||||
|
||||
/* On systems with "obscure" native character coding (e.g., EBCDIC),
|
||||
* the first test translates the password to the "main standard"
|
||||
* character coding. */
|
||||
|
||||
#ifdef STR_TO_CP1
|
||||
/* allocate buffer for translated password */
|
||||
if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
||||
return -1;
|
||||
/* first try, test password translated "standard" charset */
|
||||
r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
|
||||
#else /* !STR_TO_CP1 */
|
||||
/* first try, test password as supplied on the extractor's host */
|
||||
r = testkey(__G__ h, GLOBAL(key));
|
||||
#endif /* ?STR_TO_CP1 */
|
||||
|
||||
#ifdef STR_TO_CP2
|
||||
if (r != 0) {
|
||||
#ifndef STR_TO_CP1
|
||||
/* now prepare for second (and maybe third) test with translated pwd */
|
||||
if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
||||
return -1;
|
||||
#endif
|
||||
/* second try, password translated to alternate ("standard") charset */
|
||||
r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
|
||||
#ifdef STR_TO_CP3
|
||||
if (r != 0)
|
||||
/* third try, password translated to another "standard" charset */
|
||||
r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
|
||||
#endif
|
||||
#ifndef STR_TO_CP1
|
||||
free(key_translated);
|
||||
#endif
|
||||
}
|
||||
#endif /* STR_TO_CP2 */
|
||||
|
||||
#ifdef STR_TO_CP1
|
||||
free(key_translated);
|
||||
if (r != 0) {
|
||||
/* last resort, test password as supplied on the extractor's host */
|
||||
r = testkey(__G__ h, GLOBAL(key));
|
||||
}
|
||||
#endif /* STR_TO_CP1 */
|
||||
|
||||
return r;
|
||||
|
||||
} /* end function testp() */
|
||||
|
||||
|
||||
local int testkey(__G__ h, key)
|
||||
__GDEF
|
||||
ZCONST uch *h; /* decrypted header */
|
||||
ZCONST char *key; /* decryption password to test */
|
||||
{
|
||||
ush b;
|
||||
#ifdef ZIP10
|
||||
ush c;
|
||||
#endif
|
||||
int n;
|
||||
uch *p;
|
||||
uch hh[RAND_HEAD_LEN]; /* decrypted header */
|
||||
|
||||
/* set keys and save the encrypted header */
|
||||
init_keys(__G__ key);
|
||||
memcpy(hh, h, RAND_HEAD_LEN);
|
||||
|
||||
/* check password */
|
||||
for (n = 0; n < RAND_HEAD_LEN; n++) {
|
||||
zdecode(hh[n]);
|
||||
Trace((stdout, " %02x", hh[n]));
|
||||
}
|
||||
|
||||
Trace((stdout,
|
||||
"\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
|
||||
GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
|
||||
GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
|
||||
Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
|
||||
GLOBAL(incnt),
|
||||
GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
|
||||
|
||||
/* same test as in zipbare(): */
|
||||
|
||||
#ifdef ZIP10 /* check two bytes */
|
||||
c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
|
||||
Trace((stdout,
|
||||
" (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
|
||||
(ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
|
||||
if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
|
||||
(ush)(GLOBAL(lrec.crc32) >> 16)))
|
||||
return -1; /* bad */
|
||||
#else
|
||||
b = hh[RAND_HEAD_LEN-1];
|
||||
Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
|
||||
b, (ush)(GLOBAL(lrec.crc32) >> 24),
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
|
||||
if (b != (GLOBAL(pInfo->ExtLocHdr) ?
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
|
||||
(ush)(GLOBAL(lrec.crc32) >> 24)))
|
||||
return -1; /* bad */
|
||||
#endif
|
||||
/* password OK: decrypt current buffer contents before leaving */
|
||||
for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
|
||||
(int)GLOBAL(csize) : GLOBAL(incnt),
|
||||
p = GLOBAL(inptr); n--; p++)
|
||||
zdecode(*p);
|
||||
return 0; /* OK */
|
||||
|
||||
} /* end function testkey() */
|
||||
|
||||
#endif /* UNZIP && !FUNZIP */
|
||||
|
||||
#else /* !CRYPT */
|
||||
|
||||
/* something "externally visible" to shut up compiler/linker warnings */
|
||||
int zcr_dummy;
|
||||
|
||||
#endif /* ?CRYPT */
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
/*
|
||||
crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE]
|
||||
|
||||
This encryption/decryption source code for Info-Zip software was
|
||||
originally written in Europe. The whole source package can be
|
||||
freely distributed, including from the USA. (Prior to January 2000,
|
||||
re-export from the US was a violation of US law.)
|
||||
|
||||
NOTE on copyright history:
|
||||
Previous versions of this source package (up to version 2.8) were
|
||||
not copyrighted and put in the public domain. If you cannot comply
|
||||
with the Info-Zip LICENSE, you may want to look for one of those
|
||||
public domain versions.
|
||||
*/
|
||||
|
||||
#ifndef __crypt_h /* don't include more than once */
|
||||
#define __crypt_h
|
||||
|
||||
#ifdef CRYPT
|
||||
# undef CRYPT
|
||||
#endif
|
||||
/*
|
||||
Logic of selecting "full crypt" code:
|
||||
a) default behaviour:
|
||||
- dummy crypt code when used to compile Zip
|
||||
(because we do not distribute encrypting versions of Zip from US
|
||||
servers)
|
||||
- dummy crypt code when compiling UnZipSFX stub, to minimize size
|
||||
- full crypt code when used to compile UnZip and fUnZip
|
||||
b) USE_CRYPT defined:
|
||||
- always full crypt code
|
||||
c) NO_CRYPT defined:
|
||||
- never full crypt code
|
||||
NO_CRYPT takes precedence over USE_CRYPT
|
||||
*/
|
||||
#if defined(NO_CRYPT)
|
||||
# define CRYPT 0 /* dummy version */
|
||||
#else
|
||||
#if defined(USE_CRYPT)
|
||||
# define CRYPT 1 /* full version */
|
||||
#else
|
||||
#if (!defined(ZIP) && !defined(SFX))
|
||||
# define CRYPT 1 /* full version */
|
||||
#else
|
||||
# define CRYPT 0 /* dummy version */
|
||||
#endif
|
||||
#endif /* ?USE_CRYPT */
|
||||
#endif /* ?NO_CRYPT */
|
||||
|
||||
#if CRYPT
|
||||
/* full version */
|
||||
|
||||
#ifdef CR_BETA
|
||||
# undef CR_BETA /* this is not a beta release */
|
||||
#endif
|
||||
|
||||
#define CR_MAJORVER 2
|
||||
#define CR_MINORVER 9
|
||||
#ifdef CR_BETA
|
||||
# define CR_BETA_VER "a BETA"
|
||||
# define CR_VERSION_DATE "05 May 2000" /* last real code change */
|
||||
#else
|
||||
# define CR_BETA_VER ""
|
||||
# define CR_VERSION_DATE "05 May 2000" /* last public release date */
|
||||
# define CR_RELEASE
|
||||
#endif
|
||||
|
||||
#ifndef __G /* UnZip only, for now (DLL stuff) */
|
||||
# define __G
|
||||
# define __G__
|
||||
# define __GDEF
|
||||
# define __GPRO void
|
||||
# define __GPRO__
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32)
|
||||
# ifndef DOS_OS2_W32
|
||||
# define DOS_OS2_W32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(DOS_OS2_W32) || defined(__human68k__)
|
||||
# ifndef DOS_H68_OS2_W32
|
||||
# define DOS_H68_OS2_W32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(VM_CMS) || defined(MVS)
|
||||
# ifndef CMS_MVS
|
||||
# define CMS_MVS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* To allow combining of Zip and UnZip static libraries in a single binary,
|
||||
* the Zip and UnZip versions of the crypt core functions have to be named
|
||||
* differently.
|
||||
*/
|
||||
#ifdef ZIP
|
||||
# ifdef REALLY_SHORT_SYMS
|
||||
# define decrypt_byte zdcrby
|
||||
# else
|
||||
# define decrypt_byte zp_decrypt_byte
|
||||
# endif
|
||||
# define update_keys zp_update_keys
|
||||
# define init_keys zp_init_keys
|
||||
#else /* !ZIP */
|
||||
# ifdef REALLY_SHORT_SYMS
|
||||
# define decrypt_byte dcrbyt
|
||||
# endif
|
||||
#endif /* ?ZIP */
|
||||
|
||||
#define IZ_PWLEN 80 /* input buffer size for reading encryption key */
|
||||
#ifndef PWLEN /* for compatibility with previous zcrypt release... */
|
||||
# define PWLEN IZ_PWLEN
|
||||
#endif
|
||||
#define RAND_HEAD_LEN 12 /* length of encryption random header */
|
||||
|
||||
/* the crc_32_tab array has to be provided externally for the crypt calculus */
|
||||
#ifndef CRC_32_TAB /* UnZip provides this in globals.h */
|
||||
# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
|
||||
extern ZCONST ulg near *crc_32_tab;
|
||||
# else
|
||||
extern ZCONST ulg Far *crc_32_tab;
|
||||
# endif
|
||||
#endif /* !CRC_32_TAB */
|
||||
|
||||
/* encode byte c, using temp t. Warning: c must not have side effects. */
|
||||
#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c))
|
||||
|
||||
/* decode byte c in place */
|
||||
#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G))
|
||||
|
||||
int decrypt_byte OF((__GPRO));
|
||||
int update_keys OF((__GPRO__ int c));
|
||||
void init_keys OF((__GPRO__ ZCONST char *passwd));
|
||||
|
||||
#ifdef ZIP
|
||||
void crypthead OF((ZCONST char *, ulg, FILE *));
|
||||
# ifdef UTIL
|
||||
int zipcloak OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
|
||||
int zipbare OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
|
||||
# else
|
||||
unsigned zfwrite OF((zvoid *, extent, extent, FILE *));
|
||||
extern char *key;
|
||||
# endif
|
||||
#endif /* ZIP */
|
||||
|
||||
#if (defined(UNZIP) && !defined(FUNZIP))
|
||||
int decrypt OF((__GPRO__ ZCONST char *passwrd));
|
||||
#endif
|
||||
|
||||
#ifdef FUNZIP
|
||||
extern int encrypted;
|
||||
# ifdef NEXTBYTE
|
||||
# undef NEXTBYTE
|
||||
# endif
|
||||
# define NEXTBYTE \
|
||||
(encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in))
|
||||
#endif /* FUNZIP */
|
||||
|
||||
#else /* !CRYPT */
|
||||
/* dummy version */
|
||||
|
||||
#define zencode
|
||||
#define zdecode
|
||||
|
||||
#define zfwrite fwrite
|
||||
|
||||
#endif /* ?CRYPT */
|
||||
#endif /* !__crypt_h */
|
||||
@@ -1,586 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
/*
|
||||
cryptf.c (full version) by Info-ZIP. Last revised: [see crypt.h]
|
||||
*** This is only needed to build funzip correctly and is a direct copy
|
||||
of crypt.c. Don't forget to update here if you update crypt.c!! ***
|
||||
|
||||
This encryption/decryption source code for Info-Zip software was
|
||||
originally written in Europe. The whole source package can be
|
||||
freely distributed, including from the USA. (Prior to January 2000,
|
||||
re-export from the US was a violation of US law.)
|
||||
|
||||
NOTE on copyright history:
|
||||
Previous versions of this source package (up to version 2.8) were
|
||||
not copyrighted and put in the public domain. If you cannot comply
|
||||
with the Info-Zip LICENSE, you may want to look for one of those
|
||||
public domain versions.
|
||||
*/
|
||||
|
||||
/*
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
*/
|
||||
|
||||
#define FUNZIP
|
||||
#define ZCRYPT_INTERNAL
|
||||
#include "zip.h"
|
||||
#include "crypt.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
#if CRYPT
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifdef ZIP
|
||||
/* For the encoding task used in Zip (and ZipCloak), we want to initialize
|
||||
the crypt algorithm with some reasonably unpredictable bytes, see
|
||||
the crypthead() function. The standard rand() library function is
|
||||
used to supply these `random' bytes, which in turn is initialized by
|
||||
a srand() call. The srand() function takes an "unsigned" (at least 16bit)
|
||||
seed value as argument to determine the starting point of the rand()
|
||||
pseudo-random number generator.
|
||||
This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
|
||||
Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
|
||||
as some (hopefully) nondeterministic bitmask. On many (most) systems,
|
||||
we use some "process specific" number, as the PID or something similar,
|
||||
but when nothing unpredictable is available, a fixed number may be
|
||||
sufficient.
|
||||
NOTE:
|
||||
1.) This implementation requires the availability of the following
|
||||
standard UNIX C runtime library functions: time(), rand(), srand().
|
||||
On systems where some of them are missing, the environment that
|
||||
incorporates the crypt routines must supply suitable replacement
|
||||
functions.
|
||||
2.) It is a very bad idea to use a second call to time() to set the
|
||||
"Seed2" number! In this case, both "Seed1" and "Seed2" would be
|
||||
(almost) identical, resulting in a (mostly) "zero" constant seed
|
||||
number passed to srand().
|
||||
|
||||
The implementation environment defined in the "zip.h" header should
|
||||
supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
|
||||
most implementations of rand() and srand(), only the lower 16 bits are
|
||||
significant!). An example that works on many systems would be
|
||||
"#define ZCR_SEED2 (unsigned)getpid()".
|
||||
The default definition for ZCR_SEED2 supplied below should be regarded
|
||||
as a fallback to allow successful compilation in "beta state"
|
||||
environments.
|
||||
*/
|
||||
# include <time.h> /* time() function supplies first part of crypt seed */
|
||||
/* "last resort" source for second part of crypt seed pattern */
|
||||
# ifndef ZCR_SEED2
|
||||
# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
|
||||
# endif
|
||||
# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
|
||||
# undef GLOBAL
|
||||
# endif
|
||||
# define GLOBAL(g) g
|
||||
#else /* !ZIP */
|
||||
# define GLOBAL(g) G.g
|
||||
#endif /* ?ZIP */
|
||||
|
||||
|
||||
#ifdef UNZIP
|
||||
/* char *key = (char *)NULL; moved to globals.h */
|
||||
# ifndef FUNZIP
|
||||
local int testp OF((__GPRO__ ZCONST uch *h));
|
||||
local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
|
||||
# endif
|
||||
#endif /* UNZIP */
|
||||
|
||||
#ifndef UNZIP /* moved to globals.h for UnZip */
|
||||
local ulg keys[3]; /* keys defining the pseudo-random sequence */
|
||||
#endif /* !UNZIP */
|
||||
|
||||
#ifndef Trace
|
||||
# ifdef CRYPT_DEBUG
|
||||
# define Trace(x) fprintf x
|
||||
# else
|
||||
# define Trace(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CRC_32_TAB
|
||||
# define CRC_32_TAB crc_32_tab
|
||||
#endif
|
||||
|
||||
#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
int decrypt_byte(__G)
|
||||
__GDEF
|
||||
{
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
|
||||
temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
|
||||
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Update the encryption keys with the next byte of plain text
|
||||
*/
|
||||
int update_keys(__G__ c)
|
||||
__GDEF
|
||||
int c; /* byte of plain text */
|
||||
{
|
||||
GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
|
||||
GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
|
||||
GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
|
||||
{
|
||||
register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
|
||||
GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialize the encryption keys and the random header according to
|
||||
* the given password.
|
||||
*/
|
||||
void init_keys(__G__ passwd)
|
||||
__GDEF
|
||||
ZCONST char *passwd; /* password string with which to modify keys */
|
||||
{
|
||||
GLOBAL(keys[0]) = 305419896L;
|
||||
GLOBAL(keys[1]) = 591751049L;
|
||||
GLOBAL(keys[2]) = 878082192L;
|
||||
while (*passwd != '\0') {
|
||||
update_keys(__G__ (int)*passwd);
|
||||
passwd++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZIP
|
||||
|
||||
/***********************************************************************
|
||||
* Write encryption header to file zfile using the password passwd
|
||||
* and the cyclic redundancy check crc.
|
||||
*/
|
||||
void crypthead(passwd, crc, zfile)
|
||||
ZCONST char *passwd; /* password string */
|
||||
ulg crc; /* crc of file being encrypted */
|
||||
FILE *zfile; /* where to write header */
|
||||
{
|
||||
int n; /* index in random header */
|
||||
int t; /* temporary */
|
||||
int c; /* random byte */
|
||||
int ztemp; /* temporary for zencoded value */
|
||||
uch header[RAND_HEAD_LEN-2]; /* random header */
|
||||
static unsigned calls = 0; /* ensure different random header each time */
|
||||
|
||||
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
|
||||
* output of rand() to get less predictability, since rand() is
|
||||
* often poorly implemented.
|
||||
*/
|
||||
if (++calls == 1) {
|
||||
srand((unsigned)time(NULL) ^ ZCR_SEED2);
|
||||
}
|
||||
init_keys(passwd);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
||||
c = (rand() >> 7) & 0xff;
|
||||
header[n] = (uch)zencode(c, t);
|
||||
}
|
||||
/* Encrypt random header (last two bytes is high word of crc) */
|
||||
init_keys(passwd);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
||||
ztemp = zencode(header[n], t);
|
||||
putc(ztemp, zfile);
|
||||
}
|
||||
ztemp = zencode((int)(crc >> 16) & 0xff, t);
|
||||
putc(ztemp, zfile);
|
||||
ztemp = zencode((int)(crc >> 24) & 0xff, t);
|
||||
putc(ztemp, zfile);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UTIL
|
||||
|
||||
/***********************************************************************
|
||||
* Encrypt the zip entry described by z from file source to file dest
|
||||
* using the password passwd. Return an error code in the ZE_ class.
|
||||
*/
|
||||
int zipcloak(z, source, dest, passwd)
|
||||
struct zlist far *z; /* zip entry to encrypt */
|
||||
FILE *source, *dest; /* source and destination files */
|
||||
ZCONST char *passwd; /* password string */
|
||||
{
|
||||
int c; /* input byte */
|
||||
int res; /* result code */
|
||||
ulg n; /* holds offset and counts size */
|
||||
ush flag; /* previous flags */
|
||||
int t; /* temporary */
|
||||
int ztemp; /* temporary storage for zencode value */
|
||||
|
||||
/* Set encrypted bit, clear extended local header bit and write local
|
||||
header to output file */
|
||||
if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
||||
z->off = n;
|
||||
flag = z->flg;
|
||||
z->flg |= 1, z->flg &= ~8;
|
||||
z->lflg |= 1, z->lflg &= ~8;
|
||||
z->siz += RAND_HEAD_LEN;
|
||||
if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
||||
|
||||
/* Initialize keys with password and write random header */
|
||||
crypthead(passwd, z->crc, dest);
|
||||
|
||||
/* Skip local header in input file */
|
||||
if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
||||
SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
|
||||
/* Encrypt data */
|
||||
for (n = z->siz - RAND_HEAD_LEN; n; n--) {
|
||||
if ((c = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
ztemp = zencode(c, t);
|
||||
putc(ztemp, dest);
|
||||
}
|
||||
/* Skip extended local header in input file if there is one */
|
||||
if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if (fflush(dest) == EOF) return ZE_TEMP;
|
||||
return ZE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Decrypt the zip entry described by z from file source to file dest
|
||||
* using the password passwd. Return an error code in the ZE_ class.
|
||||
*/
|
||||
int zipbare(z, source, dest, passwd)
|
||||
struct zlist far *z; /* zip entry to encrypt */
|
||||
FILE *source, *dest; /* source and destination files */
|
||||
ZCONST char *passwd; /* password string */
|
||||
{
|
||||
int c0, c1; /* last two input bytes */
|
||||
ulg offset; /* used for file offsets */
|
||||
ulg size; /* size of input data */
|
||||
int r; /* size of encryption header */
|
||||
int res; /* return code */
|
||||
ush flag; /* previous flags */
|
||||
|
||||
/* Save position and skip local header in input file */
|
||||
if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
|
||||
fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
||||
SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
/* Initialize keys with password */
|
||||
init_keys(passwd);
|
||||
|
||||
/* Decrypt encryption header, save last two bytes */
|
||||
c1 = 0;
|
||||
for (r = RAND_HEAD_LEN; r; r--) {
|
||||
c0 = c1;
|
||||
if ((c1 = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
Trace((stdout, " (%02x)", c1));
|
||||
zdecode(c1);
|
||||
Trace((stdout, " %02x", c1));
|
||||
}
|
||||
Trace((stdout, "\n"));
|
||||
|
||||
/* If last two bytes of header don't match crc (or file time in the
|
||||
* case of an extended local header), back up and just copy. For
|
||||
* pkzip 2.0, the check has been reduced to one byte only.
|
||||
*/
|
||||
#ifdef ZIP10
|
||||
if ((ush)(c0 | (c1<<8)) !=
|
||||
(z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
|
||||
#else
|
||||
c0++; /* avoid warning on unused variable */
|
||||
if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
|
||||
#endif
|
||||
if (fseek(source, offset, SEEK_SET)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
|
||||
return ZE_MISS;
|
||||
}
|
||||
|
||||
/* Clear encrypted bit and local header bit, and write local header to
|
||||
output file */
|
||||
if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
||||
z->off = offset;
|
||||
flag = z->flg;
|
||||
z->flg &= ~9;
|
||||
z->lflg &= ~9;
|
||||
z->siz -= RAND_HEAD_LEN;
|
||||
if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
||||
|
||||
/* Decrypt data */
|
||||
for (size = z->siz; size; size--) {
|
||||
if ((c1 = getc(source)) == EOF) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
zdecode(c1);
|
||||
putc(c1, dest);
|
||||
}
|
||||
/* Skip extended local header in input file if there is one */
|
||||
if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
||||
return ferror(source) ? ZE_READ : ZE_EOF;
|
||||
}
|
||||
if (fflush(dest) == EOF) return ZE_TEMP;
|
||||
|
||||
return ZE_OK;
|
||||
}
|
||||
|
||||
|
||||
#else /* !UTIL */
|
||||
|
||||
/***********************************************************************
|
||||
* If requested, encrypt the data in buf, and in any case call fwrite()
|
||||
* with the arguments to zfwrite(). Return what fwrite() returns.
|
||||
*/
|
||||
unsigned zfwrite(buf, item_size, nb, f)
|
||||
zvoid *buf; /* data buffer */
|
||||
extent item_size; /* size of each item in bytes */
|
||||
extent nb; /* number of items */
|
||||
FILE *f; /* file to write to */
|
||||
{
|
||||
int t; /* temporary */
|
||||
|
||||
if (key != (char *)NULL) { /* key is the global password pointer */
|
||||
ulg size; /* buffer size */
|
||||
char *p = (char*)buf; /* steps through buffer */
|
||||
|
||||
/* Encrypt data in buffer */
|
||||
for (size = item_size*(ulg)nb; size != 0; p++, size--) {
|
||||
*p = (char)zencode(*p, t);
|
||||
}
|
||||
}
|
||||
/* Write the buffer out */
|
||||
return fwrite(buf, item_size, nb, f);
|
||||
}
|
||||
|
||||
#endif /* ?UTIL */
|
||||
#endif /* ZIP */
|
||||
|
||||
|
||||
#if (defined(UNZIP) && !defined(FUNZIP))
|
||||
|
||||
/***********************************************************************
|
||||
* Get the password and set up keys for current zipfile member.
|
||||
* Return PK_ class error.
|
||||
*/
|
||||
int decrypt(__G__ passwrd)
|
||||
__GDEF
|
||||
ZCONST char *passwrd;
|
||||
{
|
||||
ush b;
|
||||
int n, r;
|
||||
uch h[RAND_HEAD_LEN];
|
||||
|
||||
Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
|
||||
|
||||
/* get header once (turn off "encrypted" flag temporarily so we don't
|
||||
* try to decrypt the same data twice) */
|
||||
GLOBAL(pInfo->encrypted) = FALSE;
|
||||
defer_leftover_input(__G);
|
||||
for (n = 0; n < RAND_HEAD_LEN; n++) {
|
||||
b = NEXTBYTE;
|
||||
h[n] = (uch)b;
|
||||
Trace((stdout, " (%02x)", h[n]));
|
||||
}
|
||||
undefer_input(__G);
|
||||
GLOBAL(pInfo->encrypted) = TRUE;
|
||||
|
||||
if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
|
||||
GLOBAL(newzip) = FALSE;
|
||||
if (passwrd != (char *)NULL) { /* user gave password on command line */
|
||||
if (!GLOBAL(key)) {
|
||||
if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
|
||||
(char *)NULL)
|
||||
return PK_MEM2;
|
||||
strcpy(GLOBAL(key), passwrd);
|
||||
GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
|
||||
}
|
||||
} else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
|
||||
free(GLOBAL(key));
|
||||
GLOBAL(key) = (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* if have key already, test it; else allocate memory for it */
|
||||
if (GLOBAL(key)) {
|
||||
if (!testp(__G__ h))
|
||||
return PK_COOL; /* existing password OK (else prompt for new) */
|
||||
else if (GLOBAL(nopwd))
|
||||
return PK_WARN; /* user indicated no more prompting */
|
||||
} else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
|
||||
return PK_MEM2;
|
||||
|
||||
/* try a few keys */
|
||||
n = 0;
|
||||
do {
|
||||
r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
|
||||
GLOBAL(zipfn), GLOBAL(filename));
|
||||
if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
|
||||
free (GLOBAL(key));
|
||||
GLOBAL(key) = NULL;
|
||||
return PK_MEM2;
|
||||
}
|
||||
if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
|
||||
*GLOBAL(key) = '\0'; /* We try the NIL password, ... */
|
||||
n = 0; /* and cancel fetch for this item. */
|
||||
}
|
||||
if (!testp(__G__ h))
|
||||
return PK_COOL;
|
||||
if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
|
||||
GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
|
||||
} while (n > 0);
|
||||
|
||||
return PK_WARN;
|
||||
|
||||
} /* end function decrypt() */
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Test the password. Return -1 if bad, 0 if OK.
|
||||
*/
|
||||
local int testp(__G__ h)
|
||||
__GDEF
|
||||
ZCONST uch *h;
|
||||
{
|
||||
int r;
|
||||
char *key_translated;
|
||||
|
||||
/* On systems with "obscure" native character coding (e.g., EBCDIC),
|
||||
* the first test translates the password to the "main standard"
|
||||
* character coding. */
|
||||
|
||||
#ifdef STR_TO_CP1
|
||||
/* allocate buffer for translated password */
|
||||
if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
||||
return -1;
|
||||
/* first try, test password translated "standard" charset */
|
||||
r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
|
||||
#else /* !STR_TO_CP1 */
|
||||
/* first try, test password as supplied on the extractor's host */
|
||||
r = testkey(__G__ h, GLOBAL(key));
|
||||
#endif /* ?STR_TO_CP1 */
|
||||
|
||||
#ifdef STR_TO_CP2
|
||||
if (r != 0) {
|
||||
#ifndef STR_TO_CP1
|
||||
/* now prepare for second (and maybe third) test with translated pwd */
|
||||
if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
||||
return -1;
|
||||
#endif
|
||||
/* second try, password translated to alternate ("standard") charset */
|
||||
r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
|
||||
#ifdef STR_TO_CP3
|
||||
if (r != 0)
|
||||
/* third try, password translated to another "standard" charset */
|
||||
r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
|
||||
#endif
|
||||
#ifndef STR_TO_CP1
|
||||
free(key_translated);
|
||||
#endif
|
||||
}
|
||||
#endif /* STR_TO_CP2 */
|
||||
|
||||
#ifdef STR_TO_CP1
|
||||
free(key_translated);
|
||||
if (r != 0) {
|
||||
/* last resort, test password as supplied on the extractor's host */
|
||||
r = testkey(__G__ h, GLOBAL(key));
|
||||
}
|
||||
#endif /* STR_TO_CP1 */
|
||||
|
||||
return r;
|
||||
|
||||
} /* end function testp() */
|
||||
|
||||
|
||||
local int testkey(__G__ h, key)
|
||||
__GDEF
|
||||
ZCONST uch *h; /* decrypted header */
|
||||
ZCONST char *key; /* decryption password to test */
|
||||
{
|
||||
ush b;
|
||||
#ifdef ZIP10
|
||||
ush c;
|
||||
#endif
|
||||
int n;
|
||||
uch *p;
|
||||
uch hh[RAND_HEAD_LEN]; /* decrypted header */
|
||||
|
||||
/* set keys and save the encrypted header */
|
||||
init_keys(__G__ key);
|
||||
memcpy(hh, h, RAND_HEAD_LEN);
|
||||
|
||||
/* check password */
|
||||
for (n = 0; n < RAND_HEAD_LEN; n++) {
|
||||
zdecode(hh[n]);
|
||||
Trace((stdout, " %02x", hh[n]));
|
||||
}
|
||||
|
||||
Trace((stdout,
|
||||
"\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
|
||||
GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
|
||||
GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
|
||||
Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
|
||||
GLOBAL(incnt),
|
||||
GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
|
||||
|
||||
/* same test as in zipbare(): */
|
||||
|
||||
#ifdef ZIP10 /* check two bytes */
|
||||
c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
|
||||
Trace((stdout,
|
||||
" (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
|
||||
(ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
|
||||
if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
|
||||
(ush)(GLOBAL(lrec.crc32) >> 16)))
|
||||
return -1; /* bad */
|
||||
#else
|
||||
b = hh[RAND_HEAD_LEN-1];
|
||||
Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
|
||||
b, (ush)(GLOBAL(lrec.crc32) >> 24),
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
|
||||
if (b != (GLOBAL(pInfo->ExtLocHdr) ?
|
||||
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
|
||||
(ush)(GLOBAL(lrec.crc32) >> 24)))
|
||||
return -1; /* bad */
|
||||
#endif
|
||||
/* password OK: decrypt current buffer contents before leaving */
|
||||
for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
|
||||
(int)GLOBAL(csize) : GLOBAL(incnt),
|
||||
p = GLOBAL(inptr); n--; p++)
|
||||
zdecode(*p);
|
||||
return 0; /* OK */
|
||||
|
||||
} /* end function testkey() */
|
||||
|
||||
#endif /* UNZIP && !FUNZIP */
|
||||
|
||||
#else /* !CRYPT */
|
||||
|
||||
/* something "externally visible" to shut up compiler/linker warnings */
|
||||
int zcr_dummy;
|
||||
|
||||
#endif /* ?CRYPT */
|
||||
@@ -1,562 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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
|
||||
*/
|
||||
/* funzip.c -- by Mark Adler */
|
||||
|
||||
#define VERSION "3.94 of 20 January 2002"
|
||||
|
||||
|
||||
/* Copyright history:
|
||||
- Starting with UnZip 5.41 of 16-April-2000, this source file
|
||||
is covered by the Info-Zip LICENSE cited above.
|
||||
- Prior versions of this source file, found in UnZip source packages
|
||||
up to UnZip 5.40, were put in the public domain.
|
||||
The original copyright note by Mark Adler was:
|
||||
"You can do whatever you like with this source file,
|
||||
though I would prefer that if you modify it and
|
||||
redistribute it that you include comments to that effect
|
||||
with your name and the date. Thank you."
|
||||
|
||||
History:
|
||||
vers date who what
|
||||
---- --------- -------------- ------------------------------------
|
||||
1.0 13 Aug 92 M. Adler really simple unzip filter.
|
||||
1.1 13 Aug 92 M. Adler cleaned up somewhat, give help if
|
||||
stdin not redirected, warn if more
|
||||
zip file entries after the first.
|
||||
1.2 15 Aug 92 M. Adler added check of lengths for stored
|
||||
entries, added more help.
|
||||
1.3 16 Aug 92 M. Adler removed redundant #define's, added
|
||||
decryption.
|
||||
1.4 27 Aug 92 G. Roelofs added exit(0).
|
||||
1.5 1 Sep 92 K. U. Rommel changed read/write modes for OS/2.
|
||||
1.6 6 Sep 92 G. Roelofs modified to use dummy crypt.c and
|
||||
crypt.h instead of -DCRYPT.
|
||||
1.7 23 Sep 92 G. Roelofs changed to use DOS_OS2; included
|
||||
crypt.c under MS-DOS.
|
||||
1.8 9 Oct 92 M. Adler improved inflation error msgs.
|
||||
1.9 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch;
|
||||
renamed inflate_entry() to inflate();
|
||||
adapted to use new, in-place zdecode.
|
||||
2.0 22 Oct 92 M. Adler allow filename argument, prompt for
|
||||
passwords and don't echo, still allow
|
||||
command-line password entry, but as an
|
||||
option.
|
||||
2.1 23 Oct 92 J-l. Gailly fixed crypt/store bug,
|
||||
G. Roelofs removed crypt.c under MS-DOS, fixed
|
||||
decryption check to compare single byte.
|
||||
2.2 28 Oct 92 G. Roelofs removed declaration of key.
|
||||
2.3 14 Dec 92 M. Adler replaced fseek (fails on stdin for SCO
|
||||
Unix V.3.2.4). added quietflg for
|
||||
inflate.c.
|
||||
3.0 11 May 93 M. Adler added gzip support
|
||||
3.1 9 Jul 93 K. U. Rommel fixed OS/2 pipe bug (PIPE_ERROR)
|
||||
3.2 4 Sep 93 G. Roelofs moved crc_32_tab[] to tables.h; used FOPx
|
||||
from unzip.h; nuked OUTB macro and outbuf;
|
||||
replaced flush(); inlined FlushOutput();
|
||||
renamed decrypt to encrypted
|
||||
3.3 29 Sep 93 G. Roelofs replaced ReadByte() with NEXTBYTE macro;
|
||||
revised (restored?) flush(); added FUNZIP
|
||||
3.4 21 Oct 93 G. Roelofs renamed quietflg to qflag; changed outcnt,
|
||||
H. Gessau second updcrc() arg and flush() arg to ulg;
|
||||
added inflate_free(); added "g =" to null
|
||||
getc(in) to avoid compiler warnings
|
||||
3.5 31 Oct 93 H. Gessau changed DOS_OS2 to DOS_NT_OS2
|
||||
3.6 6 Dec 93 H. Gessau added "near" to mask_bits[]
|
||||
3.7 9 Dec 93 G. Roelofs added extent typecasts to fwrite() checks
|
||||
3.8 28 Jan 94 GRR/JlG initialized g variable in main() for gcc
|
||||
3.81 22 Feb 94 M. Hanning-Lee corrected usage message
|
||||
3.82 27 Feb 94 G. Roelofs added some typecasts to avoid warnings
|
||||
3.83 22 Jul 94 G. Roelofs changed fprintf to macro for DLLs
|
||||
- 2 Aug 94 - public release with UnZip 5.11
|
||||
- 28 Aug 94 - public release with UnZip 5.12
|
||||
3.84 1 Oct 94 K. U. Rommel changes for Metaware High C
|
||||
3.85 29 Oct 94 G. Roelofs changed fprintf macro to Info
|
||||
3.86 7 May 95 K. Davis RISCOS patches;
|
||||
P. Kienitz Amiga patches
|
||||
3.87 12 Aug 95 G. Roelofs inflate_free(), DESTROYGLOBALS fixes
|
||||
3.88 4 Sep 95 C. Spieler reordered macro to work around MSC 5.1 bug
|
||||
3.89 22 Nov 95 PK/CS ifdef'd out updcrc() for ASM_CRC
|
||||
3.9 17 Dec 95 G. Roelofs modified for USE_ZLIB (new fillinbuf())
|
||||
- 30 Apr 96 - public release with UnZip 5.2
|
||||
3.91 17 Aug 96 G. Roelofs main() -> return int (Peter Seebach)
|
||||
3.92 13 Apr 97 G. Roelofs minor cosmetic fixes to messages
|
||||
- 22 Apr 97 - public release with UnZip 5.3
|
||||
- 31 May 97 - public release with UnZip 5.31
|
||||
3.93 20 Sep 97 G. Roelofs minor cosmetic fixes to messages
|
||||
- 3 Nov 97 - public release with UnZip 5.32
|
||||
- 28 Nov 98 - public release with UnZip 5.4
|
||||
- 16 Apr 00 - public release with UnZip 5.41
|
||||
- 14 Jan 01 - public release with UnZip 5.42
|
||||
3.94 20 Feb 01 C. Spieler added support for Deflate64(tm)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
All funzip does is take a zipfile from stdin and decompress the
|
||||
first entry to stdout. The entry has to be either deflated or
|
||||
stored. If the entry is encrypted, then the decryption password
|
||||
must be supplied on the command line as the first argument.
|
||||
|
||||
funzip needs to be linked with inflate.o and crypt.o compiled from
|
||||
the unzip source. If decryption is desired, the full version of
|
||||
crypt.c (and crypt.h) from zcrypt28.zip or later must be used.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FUNZIP
|
||||
# define FUNZIP
|
||||
#endif
|
||||
#define UNZIP_INTERNAL
|
||||
#include "unzip.h"
|
||||
#include "crypt.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
#ifdef EBCDIC
|
||||
# undef EBCDIC /* don't need ebcdic[] */
|
||||
#endif
|
||||
#include "tables.h" /* crc_32_tab[] */
|
||||
|
||||
#ifndef USE_ZLIB /* zlib's function is called inflate(), too */
|
||||
# define UZinflate inflate
|
||||
#endif
|
||||
|
||||
/* PKZIP header definitions */
|
||||
#define ZIPMAG 0x4b50 /* two-byte zip lead-in */
|
||||
#define LOCREM 0x0403 /* remaining two bytes in zip signature */
|
||||
#define LOCSIG 0x04034b50L /* full signature */
|
||||
#define LOCFLG 4 /* offset of bit flag */
|
||||
#define CRPFLG 1 /* bit for encrypted entry */
|
||||
#define EXTFLG 8 /* bit for extended local header */
|
||||
#define LOCHOW 6 /* offset of compression method */
|
||||
#define LOCTIM 8 /* file mod time (for decryption) */
|
||||
#define LOCCRC 12 /* offset of crc */
|
||||
#define LOCSIZ 16 /* offset of compressed size */
|
||||
#define LOCLEN 20 /* offset of uncompressed length */
|
||||
#define LOCFIL 24 /* offset of file name field length */
|
||||
#define LOCEXT 26 /* offset of extra field length */
|
||||
#define LOCHDR 28 /* size of local header, including LOCREM */
|
||||
#define EXTHDR 16 /* size of extended local header, inc sig */
|
||||
|
||||
/* GZIP header definitions */
|
||||
#define GZPMAG 0x8b1f /* two-byte gzip lead-in */
|
||||
#define GZPHOW 0 /* offset of method number */
|
||||
#define GZPFLG 1 /* offset of gzip flags */
|
||||
#define GZPMUL 2 /* bit for multiple-part gzip file */
|
||||
#define GZPISX 4 /* bit for extra field present */
|
||||
#define GZPISF 8 /* bit for filename present */
|
||||
#define GZPISC 16 /* bit for comment present */
|
||||
#define GZPISE 32 /* bit for encryption */
|
||||
#define GZPTIM 2 /* offset of Unix file modification time */
|
||||
#define GZPEXF 6 /* offset of extra flags */
|
||||
#define GZPCOS 7 /* offset of operating system compressed on */
|
||||
#define GZPHDR 8 /* length of minimal gzip header */
|
||||
|
||||
#ifdef THEOS
|
||||
/* Macros cause stack overflow in compiler */
|
||||
ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); }
|
||||
ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
|
||||
#else /* !THEOS */
|
||||
/* Macros for getting two-byte and four-byte header values */
|
||||
#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
|
||||
#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
|
||||
#endif /* ?THEOS */
|
||||
|
||||
/* Function prototypes */
|
||||
static void err OF((int, char *));
|
||||
#if (defined(USE_DEFLATE64) && defined(__16BIT__))
|
||||
static int partflush OF((uch *rawbuf, unsigned w));
|
||||
#endif
|
||||
int main OF((int, char **));
|
||||
|
||||
/* Globals */
|
||||
FILE *out; /* output file (*in moved to G struct) */
|
||||
ulg outsiz; /* total bytes written to out */
|
||||
int encrypted; /* flag to turn on decryption */
|
||||
|
||||
/* Masks for inflate.c */
|
||||
ZCONST ush near mask_bits[] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
|
||||
int fillinbuf(__G)
|
||||
__GDEF
|
||||
/* Fill input buffer for pull-model inflate() in zlib. Return the number of
|
||||
* bytes in inbuf. */
|
||||
{
|
||||
/* GRR: check return value from fread(): same as read()? check errno? */
|
||||
if ((G.incnt = fread((char *)G.inbuf, 1, INBUFSIZ, G.in)) <= 0)
|
||||
return 0;
|
||||
G.inptr = G.inbuf;
|
||||
|
||||
#if CRYPT
|
||||
if (encrypted) {
|
||||
uch *p;
|
||||
int n;
|
||||
|
||||
for (n = G.incnt, p = G.inptr; n--; p++)
|
||||
zdecode(*p);
|
||||
}
|
||||
#endif /* CRYPT */
|
||||
|
||||
return G.incnt;
|
||||
|
||||
}
|
||||
|
||||
#endif /* USE_ZLIB */
|
||||
|
||||
|
||||
#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
|
||||
#ifdef USE_ZLIB
|
||||
ZCONST uLongf *get_crc_table()
|
||||
{
|
||||
return (ZCONST uLongf *)crc_32_tab;
|
||||
}
|
||||
#else /* !USE_ZLIB */
|
||||
ZCONST ulg near *get_crc_table()
|
||||
{
|
||||
return crc_32_tab;
|
||||
}
|
||||
#endif /* ?USE_ZLIB */
|
||||
#endif /* !USE_ZLIB || USE_OWN_CRCTAB */
|
||||
|
||||
|
||||
static void err(n, m)
|
||||
int n;
|
||||
char *m;
|
||||
/* Exit on error with a message and a code */
|
||||
{
|
||||
Info(slide, 1, ((char *)slide, "funzip error: %s\n", m));
|
||||
DESTROYGLOBALS();
|
||||
EXIT(n);
|
||||
}
|
||||
|
||||
|
||||
#if (defined(USE_DEFLATE64) && defined(__16BIT__))
|
||||
|
||||
static int partflush(rawbuf, w)
|
||||
uch *rawbuf; /* start of buffer area to flush */
|
||||
extent w; /* number of bytes to flush */
|
||||
{
|
||||
G.crc32val = crc32(G.crc32val, rawbuf, (extent)w);
|
||||
if (fwrite((char *)rawbuf,1,(extent)w,out) != (extent)w && !PIPE_ERROR)
|
||||
err(9, "out of space on stdout");
|
||||
outsiz += w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int flush(w) /* used by inflate.c (FLUSH macro) */
|
||||
ulg w; /* number of bytes to flush */
|
||||
{
|
||||
uch *rawbuf;
|
||||
int ret;
|
||||
|
||||
/* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions
|
||||
* cannot handle writes of 64k blocks at once. For these systems, the
|
||||
* blocks to flush are split into pieces of 32k or less.
|
||||
*/
|
||||
rawbuf = slide;
|
||||
while (w > 0x8000L) {
|
||||
ret = partflush(rawbuf, 0x8000);
|
||||
if (ret != PK_OK)
|
||||
return ret;
|
||||
w -= 0x8000L;
|
||||
rawbuf += (unsigned)0x8000;
|
||||
}
|
||||
return partflush(rawbuf, (extent)w);
|
||||
} /* end function flush() */
|
||||
|
||||
#else /* !(USE_DEFLATE64 && __16BIT__) */
|
||||
|
||||
int flush(w) /* used by inflate.c (FLUSH macro) */
|
||||
ulg w; /* number of bytes to flush */
|
||||
{
|
||||
G.crc32val = crc32(G.crc32val, slide, (extent)w);
|
||||
if (fwrite((char *)slide,1,(extent)w,out) != (extent)w && !PIPE_ERROR)
|
||||
err(9, "out of space on stdout");
|
||||
outsiz += w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ?(USE_DEFLATE64 && __16BIT__) */
|
||||
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
/* Given a zipfile on stdin, decompress the first entry to stdout. */
|
||||
{
|
||||
ush n;
|
||||
uch h[LOCHDR]; /* first local header (GZPHDR < LOCHDR) */
|
||||
int g = 0; /* true if gzip format */
|
||||
unsigned method = 0; /* initialized here to shut up gcc warning */
|
||||
#if CRYPT
|
||||
char *s = " [-password]";
|
||||
char *p; /* password */
|
||||
#else /* !CRYPT */
|
||||
char *s = "";
|
||||
#endif /* ?CRYPT */
|
||||
CONSTRUCTGLOBALS();
|
||||
|
||||
/* skip executable name */
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
#if CRYPT
|
||||
/* get the command line password, if any */
|
||||
p = (char *)NULL;
|
||||
if (argc && **argv == '-')
|
||||
{
|
||||
argc--;
|
||||
p = 1 + *argv++;
|
||||
}
|
||||
#endif /* CRYPT */
|
||||
|
||||
#ifdef MALLOC_WORK
|
||||
/* The following expression is a cooked-down simplyfication of the
|
||||
calculation for the work area size of UnZip (see unzip.c). For
|
||||
fUnZip, the work area does not need to match the granularity
|
||||
of the complex unshrink structures, because it only supports
|
||||
inflation. But, like in UnZip, the zcalloc() wrapper function
|
||||
is needed for the allocation, to support the 64kByte buffer on
|
||||
16-bit systems.
|
||||
*/
|
||||
# define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
|
||||
# define UZ_NUMOF_CHUNKS (unsigned)( (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK )
|
||||
G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
|
||||
# undef UZ_SLIDE_CHUNK
|
||||
# undef UZ_NUMOF_CHUNKS
|
||||
#endif
|
||||
|
||||
/* if no file argument and stdin not redirected, give the user help */
|
||||
if (argc == 0 && isatty(0))
|
||||
{
|
||||
Info(slide, 1, ((char *)slide, "fUnZip (filter UnZip), version %s\n",
|
||||
VERSION));
|
||||
Info(slide, 1, ((char *)slide, "usage: ... | funzip%s | ...\n", s));
|
||||
Info(slide, 1, ((char *)slide, " ... | funzip%s > outfile\n", s));
|
||||
Info(slide, 1, ((char *)slide, " funzip%s infile.zip > outfile\n",s));
|
||||
Info(slide, 1, ((char *)slide, " funzip%s infile.gz > outfile\n", s));
|
||||
Info(slide, 1, ((char *)slide, "Extracts to stdout the gzip file or first\
|
||||
zip entry of stdin or the given file.\n"));
|
||||
DESTROYGLOBALS();
|
||||
EXIT(3);
|
||||
}
|
||||
|
||||
/* prepare to be a binary filter */
|
||||
if (argc)
|
||||
{
|
||||
if ((G.in = fopen(*argv, FOPR)) == (FILE *)NULL)
|
||||
err(2, "cannot find input file");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DOS_FLX_NLM_OS2_W32
|
||||
#if (defined(__HIGHC__) && !defined(FLEXOS))
|
||||
setmode(stdin, _BINARY);
|
||||
#else
|
||||
setmode(0, O_BINARY); /* some buggy C libraries require BOTH setmode() */
|
||||
#endif /* call AND the fdopen() in binary mode :-( */
|
||||
#endif /* DOS_FLX_NLM_OS2_W32 */
|
||||
|
||||
#ifdef RISCOS
|
||||
G.in = stdin;
|
||||
#else
|
||||
if ((G.in = fdopen(0, FOPR)) == (FILE *)NULL)
|
||||
err(2, "cannot find stdin");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DOS_FLX_H68_NLM_OS2_W32
|
||||
#if (defined(__HIGHC__) && !defined(FLEXOS))
|
||||
setmode(stdout, _BINARY);
|
||||
#else
|
||||
setmode(1, O_BINARY);
|
||||
#endif
|
||||
#endif /* DOS_FLX_H68_NLM_OS2_W32 */
|
||||
|
||||
#ifdef RISCOS
|
||||
out = stdout;
|
||||
#else
|
||||
if ((out = fdopen(1, FOPW)) == (FILE *)NULL)
|
||||
err(2, "cannot write to stdout");
|
||||
#endif
|
||||
|
||||
/* read local header, check validity, and skip name and extra fields */
|
||||
n = getc(G.in); n |= getc(G.in) << 8;
|
||||
if (n == ZIPMAG)
|
||||
{
|
||||
if (fread((char *)h, 1, LOCHDR, G.in) != LOCHDR || SH(h) != LOCREM)
|
||||
err(3, "invalid zipfile");
|
||||
switch (method = SH(h + LOCHOW)) {
|
||||
case STORED:
|
||||
case DEFLATED:
|
||||
#ifdef USE_DEFLATE64
|
||||
case ENHDEFLATED:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
err(3, "first entry not deflated or stored--cannot unpack");
|
||||
break;
|
||||
}
|
||||
for (n = SH(h + LOCFIL); n--; ) g = getc(G.in);
|
||||
for (n = SH(h + LOCEXT); n--; ) g = getc(G.in);
|
||||
g = 0;
|
||||
encrypted = h[LOCFLG] & CRPFLG;
|
||||
}
|
||||
else if (n == GZPMAG)
|
||||
{
|
||||
if (fread((char *)h, 1, GZPHDR, G.in) != GZPHDR)
|
||||
err(3, "invalid gzip file");
|
||||
if ((method = h[GZPHOW]) != DEFLATED && method != ENHDEFLATED)
|
||||
err(3, "gzip file not deflated");
|
||||
if (h[GZPFLG] & GZPMUL)
|
||||
err(3, "cannot handle multi-part gzip files");
|
||||
if (h[GZPFLG] & GZPISX)
|
||||
{
|
||||
n = getc(G.in); n |= getc(G.in) << 8;
|
||||
while (n--) g = getc(G.in);
|
||||
}
|
||||
if (h[GZPFLG] & GZPISF)
|
||||
while ((g = getc(G.in)) != 0 && g != EOF) ;
|
||||
if (h[GZPFLG] & GZPISC)
|
||||
while ((g = getc(G.in)) != 0 && g != EOF) ;
|
||||
g = 1;
|
||||
encrypted = h[GZPFLG] & GZPISE;
|
||||
}
|
||||
else
|
||||
err(3, "input not a zip or gzip file");
|
||||
|
||||
/* if entry encrypted, decrypt and validate encryption header */
|
||||
if (encrypted)
|
||||
#if CRYPT
|
||||
{
|
||||
ush i, e;
|
||||
|
||||
if (p == (char *)NULL) {
|
||||
if ((p = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
|
||||
err(1, "out of memory");
|
||||
else if ((p = getp("Enter password: ", p, IZ_PWLEN+1)) == (char *)NULL)
|
||||
err(1, "no tty to prompt for password");
|
||||
}
|
||||
#if (defined(USE_ZLIB) && !defined(USE_OWN_CRCTAB))
|
||||
/* initialize crc_32_tab pointer for decryption */
|
||||
CRC_32_TAB = (ZCONST ulg Far *)get_crc_table();
|
||||
#endif
|
||||
init_keys(p);
|
||||
for (i = 0; i < RAND_HEAD_LEN; i++)
|
||||
e = NEXTBYTE;
|
||||
if (e != (ush)(h[LOCFLG] & EXTFLG ? h[LOCTIM + 1] : h[LOCCRC + 3]))
|
||||
err(3, "incorrect password for first entry");
|
||||
}
|
||||
#else /* !CRYPT */
|
||||
err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
|
||||
#endif /* ?CRYPT */
|
||||
|
||||
/* prepare output buffer and crc */
|
||||
G.outptr = slide;
|
||||
G.outcnt = 0L;
|
||||
outsiz = 0L;
|
||||
G.crc32val = CRCVAL_INITIAL;
|
||||
|
||||
/* decompress */
|
||||
if (g || h[LOCHOW])
|
||||
{ /* deflated entry */
|
||||
int r;
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
/* need to allocate and prepare input buffer */
|
||||
if ((G.inbuf = (uch *)malloc(INBUFSIZ)) == (uch *)NULL)
|
||||
err(1, "out of memory");
|
||||
#endif /* USE_ZLIB */
|
||||
if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
|
||||
if (r == 3)
|
||||
err(1, "out of memory");
|
||||
else
|
||||
err(4, "invalid compressed data--format violated");
|
||||
}
|
||||
inflate_free(__G);
|
||||
}
|
||||
else
|
||||
{ /* stored entry */
|
||||
register ulg n;
|
||||
|
||||
n = LG(h + LOCLEN);
|
||||
#if CRYPT
|
||||
if (n != LG(h + LOCSIZ) - (encrypted ? RAND_HEAD_LEN : 0)) {
|
||||
#else
|
||||
if (n != LG(h + LOCSIZ)) {
|
||||
#endif
|
||||
Info(slide, 1, ((char *)slide, "len %ld, siz %ld\n", n, LG(h + LOCSIZ)));
|
||||
err(4, "invalid compressed data--length mismatch");
|
||||
}
|
||||
while (n--) {
|
||||
ush c = getc(G.in);
|
||||
#if CRYPT
|
||||
if (encrypted)
|
||||
zdecode(c);
|
||||
#endif
|
||||
*G.outptr++ = (uch)c;
|
||||
#if (defined(USE_DEFLATE64) && defined(__16BIT__))
|
||||
if (++G.outcnt == (WSIZE>>1)) /* do FlushOutput() */
|
||||
#else
|
||||
if (++G.outcnt == WSIZE) /* do FlushOutput() */
|
||||
#endif
|
||||
{
|
||||
G.crc32val = crc32(G.crc32val, slide, (extent)G.outcnt);
|
||||
if (fwrite((char *)slide, 1,(extent)G.outcnt,out) != (extent)G.outcnt
|
||||
&& !PIPE_ERROR)
|
||||
err(9, "out of space on stdout");
|
||||
outsiz += G.outcnt;
|
||||
G.outptr = slide;
|
||||
G.outcnt = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (G.outcnt) /* flush one last time; no need to reset G.outptr/outcnt */
|
||||
{
|
||||
G.crc32val = crc32(G.crc32val, slide, (extent)G.outcnt);
|
||||
if (fwrite((char *)slide, 1,(extent)G.outcnt,out) != (extent)G.outcnt
|
||||
&& !PIPE_ERROR)
|
||||
err(9, "out of space on stdout");
|
||||
outsiz += G.outcnt;
|
||||
}
|
||||
fflush(out);
|
||||
|
||||
/* if extended header, get it */
|
||||
if (g)
|
||||
{
|
||||
if (fread((char *)h + LOCCRC, 1, 8, G.in) != 8)
|
||||
err(3, "gzip file ended prematurely");
|
||||
}
|
||||
else
|
||||
if ((h[LOCFLG] & EXTFLG) &&
|
||||
fread((char *)h + LOCCRC - 4, 1, EXTHDR, G.in) != EXTHDR)
|
||||
err(3, "zipfile ended prematurely");
|
||||
|
||||
/* validate decompression */
|
||||
if (LG(h + LOCCRC) != G.crc32val)
|
||||
err(4, "invalid compressed data--crc error");
|
||||
if (LG((g ? (h + LOCSIZ) : (h + LOCLEN))) != outsiz)
|
||||
err(4, "invalid compressed data--length error");
|
||||
|
||||
/* check if there are more entries */
|
||||
if (!g && fread((char *)h, 1, 4, G.in) == 4 && LG(h) == LOCSIG)
|
||||
Info(slide, 1, ((char *)slide,
|
||||
"funzip warning: zipfile has more than one entry--rest ignored\n"));
|
||||
|
||||
DESTROYGLOBALS();
|
||||
RETURN (0);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
|
||||
FUNZIP(1L) FUNZIP(1L)
|
||||
|
||||
NAME
|
||||
funzip - filter for extracting from a ZIP archive in a
|
||||
pipe
|
||||
|
||||
SYNOPSIS
|
||||
funzip [-password] [input[.zip|.gz]]
|
||||
|
||||
ARGUMENTS
|
||||
[-password]
|
||||
Optional password to be used if ZIP archive is
|
||||
encrypted. Decryption may not be supported at some
|
||||
sites. See DESCRIPTION for more details.
|
||||
|
||||
[input[.zip|.gz]]
|
||||
Optional input archive file specification. See
|
||||
DESCRIPTION for details.
|
||||
|
||||
DESCRIPTION
|
||||
funzip without a file argument acts as a filter; that is,
|
||||
it assumes that a ZIP archive (or a gzip'd(1) file) is
|
||||
being piped into standard input, and it extracts the first
|
||||
member from the archive to stdout. When stdin comes from
|
||||
a tty device, funzip assumes that this cannot be a stream
|
||||
of (binary) compressed data and shows a short help text,
|
||||
instead. If there is a file argument, then input is read
|
||||
from the specified file instead of from stdin.
|
||||
|
||||
A password for encrypted zip files can be specified on the
|
||||
command line (preceding the file name, if any) by prefix-
|
||||
ing the password with a dash. Note that this constitutes
|
||||
a security risk on many systems; currently running pro-
|
||||
cesses are often visible via simple commands (e.g., ps(1)
|
||||
under Unix), and command-line histories can be read. If
|
||||
the first entry of the zip file is encrypted and no pass-
|
||||
word is specified on the command line, then the user is
|
||||
prompted for a password and the password is not echoed on
|
||||
the console.
|
||||
|
||||
Given the limitation on single-member extraction, funzip
|
||||
is most useful in conjunction with a secondary archiver
|
||||
program such as tar(1). The following section includes an
|
||||
example illustrating this usage in the case of disk back-
|
||||
ups to tape.
|
||||
|
||||
EXAMPLES
|
||||
To use funzip to extract the first member file of the
|
||||
archive test.zip and to pipe it into more(1):
|
||||
|
||||
funzip test.zip | more
|
||||
|
||||
To use funzip to test the first member file of test.zip
|
||||
(any errors will be reported on standard error):
|
||||
|
||||
funzip test.zip > /dev/null
|
||||
|
||||
Info-ZIP 17 February 2002 (v3.94) 1
|
||||
|
||||
FUNZIP(1L) FUNZIP(1L)
|
||||
|
||||
To use zip and funzip in place of compress(1) and zcat(1)
|
||||
(or gzip(1L) and gzcat(1L)) for tape backups:
|
||||
|
||||
tar cf - . | zip -7 | dd of=/dev/nrst0 obs=8k
|
||||
dd if=/dev/nrst0 ibs=8k | funzip | tar xf -
|
||||
|
||||
(where, for example, nrst0 is a SCSI tape drive).
|
||||
|
||||
BUGS
|
||||
When piping an encrypted file into more and allowing fun-
|
||||
zip to prompt for password, the terminal may sometimes be
|
||||
reset to a non-echo mode. This is apparently due to a
|
||||
race condition between the two programs; funzip changes
|
||||
the terminal mode to non-echo before more reads its state,
|
||||
and more then ``restores'' the terminal to this mode
|
||||
before exiting. To recover, run funzip on the same file
|
||||
but redirect to /dev/null rather than piping into more;
|
||||
after prompting again for the password, funzip will reset
|
||||
the terminal properly.
|
||||
|
||||
There is presently no way to extract any member but the
|
||||
first from a ZIP archive. This would be useful in the
|
||||
case where a ZIP archive is included within another
|
||||
archive. In the case where the first member is a direc-
|
||||
tory, funzip simply creates the directory and exits.
|
||||
|
||||
The functionality of funzip should be incorporated into
|
||||
unzip itself (future release).
|
||||
|
||||
SEE ALSO
|
||||
gzip(1L), unzip(1L), unzipsfx(1L), zip(1L), zipcloak(1L),
|
||||
zipinfo(1L), zipnote(1L), zipsplit(1L)
|
||||
|
||||
URL
|
||||
The Info-ZIP home page is currently at
|
||||
http://www.info-zip.org/pub/infozip/
|
||||
or
|
||||
ftp://ftp.info-zip.org/pub/infozip/ .
|
||||
|
||||
AUTHOR
|
||||
Mark Adler (Info-ZIP)
|
||||
|
||||
Info-ZIP 17 February 2002 (v3.94) 2
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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
|
||||
*/
|
||||
/* Write out a fragment of assembly source giving offsets in "Uz_Globs"
|
||||
* and "struct huft":
|
||||
*/
|
||||
|
||||
#define UNZIP_INTERNAL
|
||||
#include "unzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#ifndef REENTRANT
|
||||
Uz_Globs G;
|
||||
#endif
|
||||
|
||||
static int asm_setflag(const char *flagname);
|
||||
static int ccp_setflag(const char *flagname);
|
||||
|
||||
static int asm_setflag(const char *flagname)
|
||||
{
|
||||
static const char asm_flagdef[] = "%-15s EQU 1\n";
|
||||
return printf(asm_flagdef, flagname);
|
||||
}
|
||||
static int ccp_setflag(const char *flagname)
|
||||
{
|
||||
static const char ccp_flagdef[] = "#ifndef %s\n# define %s\n#endif\n";
|
||||
return printf(ccp_flagdef, flagname, flagname);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
#ifdef REENTRANT
|
||||
Uz_Globs *pG = NULL;
|
||||
#endif
|
||||
struct huft *t = NULL;
|
||||
static const char asm_offsdef[] = "%-15s EQU %lu\n";
|
||||
static const char ccp_offsdef[] = "#define %-15s %lu\n";
|
||||
|
||||
const char *out_format;
|
||||
int (*set_flag)(const char *flagname);
|
||||
int ccp_select = 0;
|
||||
|
||||
if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-ccp"))
|
||||
ccp_select = 1;
|
||||
|
||||
if (ccp_select) {
|
||||
out_format = ccp_offsdef;
|
||||
set_flag = ccp_setflag;
|
||||
} else {
|
||||
out_format = asm_offsdef;
|
||||
set_flag = asm_setflag;
|
||||
}
|
||||
|
||||
printf(out_format, "h_e", (ulg)&t->e - (ulg)t);
|
||||
printf(out_format, "h_b", (ulg)&t->b - (ulg)t);
|
||||
printf(out_format, "h_v_n", (ulg)&t->v.n - (ulg)t);
|
||||
printf(out_format, "h_v_t", (ulg)&t->v.t - (ulg)t);
|
||||
printf(out_format, "SIZEOF_huft", (ulg)sizeof(struct huft));
|
||||
|
||||
printf(out_format, "bb", (ulg)&G.bb - (ulg)&G);
|
||||
printf(out_format, "bk", (ulg)&G.bk - (ulg)&G);
|
||||
printf(out_format, "wp", (ulg)&G.wp - (ulg)&G);
|
||||
#ifdef FUNZIP
|
||||
printf(out_format, "in", (ulg)&G.in - (ulg)&G);
|
||||
#else
|
||||
printf(out_format, "incnt", (ulg)&G.incnt - (ulg)&G);
|
||||
printf(out_format, "inptr", (ulg)&G.inptr - (ulg)&G);
|
||||
printf(out_format, "csize", (ulg)&G.csize - (ulg)&G);
|
||||
printf(out_format, "mem_mode", (ulg)&G.mem_mode - (ulg)&G);
|
||||
#endif
|
||||
printf(out_format, "redirslide", (ulg)&redirSlide - (ulg)&G);
|
||||
printf(out_format, "SIZEOF_slide", (ulg)sizeof(redirSlide));
|
||||
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
|
||||
printf(out_format, "_wsize", (ulg)&G._wsize - (ulg)&G);
|
||||
#endif /* DLL && !NO_SLIDE_REDIR */
|
||||
printf(out_format, "CRYPT", (ulg)CRYPT);
|
||||
#ifdef FUNZIP
|
||||
(*set_flag)("FUNZIP");
|
||||
#endif
|
||||
#ifdef SFX
|
||||
(*set_flag)("SFX");
|
||||
#endif
|
||||
#ifdef REENTRANT
|
||||
(*set_flag)("REENTRANT");
|
||||
#endif
|
||||
#ifdef DLL
|
||||
(*set_flag)("DLL");
|
||||
# ifdef NO_SLIDE_REDIR
|
||||
(*set_flag)("NO_SLIDE_REDIR");
|
||||
# endif
|
||||
#endif
|
||||
#ifdef USE_DEFLATE64
|
||||
(*set_flag)("USE_DEFLATE64");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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
|
||||
*/
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
globalsf.c
|
||||
*** This is only needed to build funzip correctly and is a direct copy
|
||||
of globals.c. Don't forget to update here if you update globals.c!! ***
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define FUNZIP
|
||||
#define UNZIP_INTERNAL
|
||||
#include "unzip.h"
|
||||
|
||||
#ifndef FUNZIP
|
||||
/* initialization of sigs is completed at runtime so unzip(sfx) executable
|
||||
* won't look like a zipfile
|
||||
*/
|
||||
char central_hdr_sig[4] = {0, 0, 0x01, 0x02};
|
||||
char local_hdr_sig[4] = {0, 0, 0x03, 0x04};
|
||||
char end_central_sig[4] = {0, 0, 0x05, 0x06};
|
||||
/* extern char extd_local_sig[4] = {0, 0, 0x07, 0x08}; NOT USED YET */
|
||||
|
||||
ZCONST char *fnames[2] = {"*", NULL}; /* default filenames vector */
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef REENTRANT
|
||||
Uz_Globs G;
|
||||
#else /* REENTRANT */
|
||||
|
||||
# ifndef USETHREADID
|
||||
Uz_Globs *GG;
|
||||
# else /* USETHREADID */
|
||||
# define THREADID_ENTRIES 0x40
|
||||
|
||||
int lastScan;
|
||||
Uz_Globs *threadPtrTable[THREADID_ENTRIES];
|
||||
ulg threadIdTable [THREADID_ENTRIES] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* Make sure there are */
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* THREADID_ENTRIES 0s */
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
|
||||
static ZCONST char Far TooManyThreads[] =
|
||||
"error: more than %d simultaneous threads.\n\
|
||||
Some threads are probably not calling DESTROYTHREAD()\n";
|
||||
static ZCONST char Far EntryNotFound[] =
|
||||
"error: couldn't find global pointer in table.\n\
|
||||
Maybe somebody accidentally called DESTROYTHREAD() twice.\n";
|
||||
static ZCONST char Far GlobalPointerMismatch[] =
|
||||
"error: global pointer in table does not match pointer passed as\
|
||||
parameter\n";
|
||||
|
||||
static void registerGlobalPointer OF((__GPRO));
|
||||
|
||||
|
||||
|
||||
static void registerGlobalPointer(__G)
|
||||
__GDEF
|
||||
{
|
||||
int scan=0;
|
||||
ulg tid = GetThreadId();
|
||||
|
||||
while (threadIdTable[scan] && scan < THREADID_ENTRIES)
|
||||
scan++;
|
||||
|
||||
if (scan == THREADID_ENTRIES) {
|
||||
ZCONST char *tooMany = LoadFarString(TooManyThreads);
|
||||
Info(slide, 0x421, ((char *)slide, tooMany, THREADID_ENTRIES));
|
||||
free(pG);
|
||||
EXIT(PK_MEM); /* essentially memory error before we've started */
|
||||
}
|
||||
|
||||
threadIdTable [scan] = tid;
|
||||
threadPtrTable[scan] = pG;
|
||||
lastScan = scan;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void deregisterGlobalPointer(__G)
|
||||
__GDEF
|
||||
{
|
||||
int scan=0;
|
||||
ulg tid = GetThreadId();
|
||||
|
||||
|
||||
while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES)
|
||||
scan++;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
There are two things we can do if we can't find the entry: ignore it or
|
||||
scream. The most likely reason for it not to be here is the user calling
|
||||
this routine twice. Since this could cause BIG problems if any globals
|
||||
are accessed after the first call, we'd better scream.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
if (scan == THREADID_ENTRIES || threadPtrTable[scan] != pG) {
|
||||
ZCONST char *noEntry;
|
||||
if (scan == THREADID_ENTRIES)
|
||||
noEntry = LoadFarString(EntryNotFound);
|
||||
else
|
||||
noEntry = LoadFarString(GlobalPointerMismatch);
|
||||
Info(slide, 0x421, ((char *)slide, noEntry));
|
||||
EXIT(PK_WARN); /* programming error, but after we're all done */
|
||||
}
|
||||
|
||||
threadIdTable [scan] = 0;
|
||||
lastScan = scan;
|
||||
free(threadPtrTable[scan]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uz_Globs *getGlobalPointer()
|
||||
{
|
||||
int scan=0;
|
||||
ulg tid = GetThreadId();
|
||||
|
||||
while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES)
|
||||
scan++;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
There are two things we can do if we can't find the entry: ignore it or
|
||||
scream. The most likely reason for it not to be here is the user calling
|
||||
this routine twice. Since this could cause BIG problems if any globals
|
||||
are accessed after the first call, we'd better scream.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
if (scan == THREADID_ENTRIES) {
|
||||
ZCONST char *noEntry = LoadFarString(EntryNotFound);
|
||||
fprintf(stderr, noEntry); /* can't use Info w/o a global pointer */
|
||||
EXIT(PK_ERR); /* programming error while still working */
|
||||
}
|
||||
|
||||
return threadPtrTable[scan];
|
||||
}
|
||||
|
||||
# endif /* ?USETHREADID */
|
||||
#endif /* ?REENTRANT */
|
||||
|
||||
|
||||
|
||||
Uz_Globs *globalsCtor()
|
||||
{
|
||||
#ifdef REENTRANT
|
||||
Uz_Globs *pG = (Uz_Globs *)malloc(sizeof(Uz_Globs));
|
||||
|
||||
if (!pG)
|
||||
return (Uz_Globs *)NULL;
|
||||
#endif /* REENTRANT */
|
||||
|
||||
/* for REENTRANT version, G is defined as (*pG) */
|
||||
|
||||
memzero(&G, sizeof(Uz_Globs));
|
||||
|
||||
#ifndef FUNZIP
|
||||
#ifdef CMS_MVS
|
||||
uO.aflag=1;
|
||||
uO.C_flag=1;
|
||||
#endif
|
||||
#ifdef TANDEM
|
||||
uO.aflag=1; /* default to '-a' auto create Text Files as type 101 */
|
||||
#endif
|
||||
|
||||
uO.lflag=(-1);
|
||||
G.wildzipfn = "";
|
||||
G.pfnames = (char **)fnames;
|
||||
G.pxnames = (char **)&fnames[1];
|
||||
G.pInfo = G.info;
|
||||
G.sol = TRUE; /* at start of line */
|
||||
|
||||
G.message = UzpMessagePrnt;
|
||||
G.input = UzpInput; /* not used by anyone at the moment... */
|
||||
#if defined(WINDLL) || defined(MACOS)
|
||||
G.mpause = NULL; /* has scrollbars: no need for pausing */
|
||||
#else
|
||||
G.mpause = UzpMorePause;
|
||||
#endif
|
||||
G.decr_passwd = UzpPassword;
|
||||
#endif /* !FUNZIP */
|
||||
|
||||
#if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
|
||||
#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
|
||||
G.echofd = -1;
|
||||
#endif /* !(MACOS || ATARI || VMS) */
|
||||
#endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
|
||||
|
||||
#ifdef SYSTEM_SPECIFIC_CTOR
|
||||
SYSTEM_SPECIFIC_CTOR(__G);
|
||||
#endif
|
||||
|
||||
#ifdef REENTRANT
|
||||
#ifdef USETHREADID
|
||||
registerGlobalPointer(__G);
|
||||
#else
|
||||
GG = &G;
|
||||
#endif /* ?USETHREADID */
|
||||
#endif /* REENTRANT */
|
||||
|
||||
return &G;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
/*
|
||||
Quick hack so that I can compile unzipsfx without playing with Jam rules
|
||||
*/
|
||||
#define SFX
|
||||
@@ -1,813 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
/* Replacement time library functions, based on platform independent public
|
||||
* domain timezone code from ftp://elsie.nci.nih.gov/pub, with mktime and
|
||||
* mkgmtime from our own mktime.c in Zip.
|
||||
*
|
||||
* Contains: tzset()
|
||||
* __tzset()
|
||||
* gmtime()
|
||||
* localtime()
|
||||
* mktime()
|
||||
* mkgmtime()
|
||||
* GetPlatformLocalTimezone() [different versions]
|
||||
*/
|
||||
|
||||
/* HISTORY/CHANGES
|
||||
* 17 Jun 00, Paul Kienitz, added the PD-based tzset(), localtime(), and so on
|
||||
* to amiga/filedate.c, replacing GNU-based functions which had
|
||||
* replaced time_lib.c, both having been rejected for licensing
|
||||
* reasons. Support for timezone files and leap seconds was removed.
|
||||
*
|
||||
* 23 Aug 00, Paul Kienitz, split into separate timezone.c file, made platform
|
||||
* independent, copied in mktime() and mkgmtime() from Zip, renamed
|
||||
* locale_TZ as GetPlatformLocalTimezone(), for use as a generic
|
||||
* hook by other platforms.
|
||||
*/
|
||||
|
||||
#ifndef __timezone_c
|
||||
#define __timezone_c
|
||||
|
||||
|
||||
#include "zip.h"
|
||||
#include "timezone.h"
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef IZTZ_DEFINESTDGLOBALS
|
||||
long timezone = 0;
|
||||
int daylight = 0;
|
||||
char *tzname[2];
|
||||
#endif
|
||||
|
||||
#ifndef IZTZ_GETLOCALETZINFO
|
||||
# define IZTZ_GETLOCALETZINFO(ptzstruct, pgenrulefunct) (FALSE)
|
||||
#endif
|
||||
|
||||
int real_timezone_is_set = FALSE; /* set by tzset() */
|
||||
|
||||
|
||||
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
|
||||
#define TZDEFAULT "EST5EDT"
|
||||
|
||||
#define SECSPERMIN 60
|
||||
#define MINSPERHOUR 60
|
||||
#define HOURSPERDAY 24
|
||||
#define DAYSPERWEEK 7
|
||||
#define DAYSPERNYEAR 365
|
||||
#define DAYSPERLYEAR 366
|
||||
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
|
||||
#define MONSPERYEAR 12
|
||||
|
||||
#define EPOCH_WDAY 4 /* Jan 1, 1970 was thursday */
|
||||
#define EPOCH_YEAR 1970
|
||||
#define TM_YEAR_BASE 1900
|
||||
#define FIRST_GOOD_YEAR ((time_t) -1 < (time_t) 1 ? EPOCH_YEAR-68 : EPOCH_YEAR)
|
||||
#define LAST_GOOD_YEAR (EPOCH_YEAR + ((time_t) -1 < (time_t) 1 ? 67 : 135))
|
||||
|
||||
#define YDAYS(month, year) yr_days[leap(year)][month]
|
||||
|
||||
/* Nonzero if `y' is a leap year, else zero. */
|
||||
#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
|
||||
|
||||
/* Number of leap years from EPOCH_YEAR to `y' (not including `y' itself). */
|
||||
#define _P4 ((EPOCH_YEAR / 4) * 4 + 1)
|
||||
#define _P100 ((EPOCH_YEAR / 100) * 100 + 1)
|
||||
#define _P400 ((EPOCH_YEAR / 400) * 400 + 1)
|
||||
#define nleap(y) (((y) - _P4) / 4 - ((y) - _P100) / 100 + ((y) - _P400) / 400)
|
||||
|
||||
/* Length of month `m' (0 .. 11) */
|
||||
#define monthlen(m, y) (yr_days[0][(m)+1] - yr_days[0][m] + \
|
||||
((m) == 1 && leap(y)))
|
||||
|
||||
/* internal module-level constants */
|
||||
#ifndef IZ_MKTIME_ONLY
|
||||
static ZCONST char gmt[] = "GMT";
|
||||
static ZCONST int mon_lengths[2][MONSPERYEAR] = {
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
};
|
||||
#endif /* !IZ_MKTIME_ONLY */
|
||||
static ZCONST int yr_days[2][MONSPERYEAR+1] = {
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
#ifndef IZ_MKTIME_ONLY
|
||||
static ZCONST int year_lengths[2] = {
|
||||
DAYSPERNYEAR, DAYSPERLYEAR
|
||||
};
|
||||
|
||||
/* internal variables */
|
||||
static struct state statism;
|
||||
|
||||
|
||||
/* prototypes of static functions */
|
||||
static time_t transtime OF((ZCONST time_t janfirst, ZCONST int year,
|
||||
ZCONST struct rule * ZCONST rulep,
|
||||
ZCONST long offset));
|
||||
static void generate_transitions OF((register struct state * ZCONST sp,
|
||||
ZCONST struct rule * ZCONST start,
|
||||
ZCONST struct rule * ZCONST end));
|
||||
static ZCONST char *getzname OF((ZCONST char *strp));
|
||||
static ZCONST char *getnum OF((ZCONST char *strp, int * ZCONST nump,
|
||||
ZCONST int min, ZCONST int max));
|
||||
static ZCONST char *getsecs OF((ZCONST char *strp, long * ZCONST secsp));
|
||||
static ZCONST char *getoffset OF((ZCONST char *strp, long * ZCONST offsetp));
|
||||
static ZCONST char *getrule OF((ZCONST char *strp, struct rule * ZCONST rulep));
|
||||
static int Parse_TZ OF((ZCONST char *name, register struct state * ZCONST sp));
|
||||
|
||||
|
||||
static time_t transtime(janfirst, year, rulep, offset)
|
||||
ZCONST time_t janfirst;
|
||||
ZCONST int year;
|
||||
ZCONST struct rule * ZCONST rulep;
|
||||
ZCONST long offset;
|
||||
{
|
||||
register int leapyear;
|
||||
register time_t value;
|
||||
register int i;
|
||||
int d, m1, yy0, yy1, yy2, dow;
|
||||
|
||||
value = 0;
|
||||
leapyear = leap(year);
|
||||
switch (rulep->r_type) {
|
||||
|
||||
case JULIAN_DAY:
|
||||
/*
|
||||
** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
|
||||
** years.
|
||||
** In non-leap years, or if the day number is 59 or less, just
|
||||
** add SECSPERDAY times the day number-1 to the time of
|
||||
** January 1, midnight, to get the day.
|
||||
*/
|
||||
value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
|
||||
if (leapyear && rulep->r_day >= 60)
|
||||
value += SECSPERDAY;
|
||||
break;
|
||||
|
||||
case DAY_OF_YEAR:
|
||||
/*
|
||||
** n - day of year.
|
||||
** Just add SECSPERDAY times the day number to the time of
|
||||
** January 1, midnight, to get the day.
|
||||
*/
|
||||
value = janfirst + rulep->r_day * SECSPERDAY;
|
||||
break;
|
||||
|
||||
case MONTH_NTH_DAY_OF_WEEK:
|
||||
/*
|
||||
** Mm.n.d - nth "dth day" of month m.
|
||||
*/
|
||||
value = janfirst;
|
||||
/*
|
||||
for (i = 0; i < rulep->r_mon - 1; ++i)
|
||||
value += mon_lengths[leapyear][i] * SECSPERDAY;
|
||||
*/
|
||||
value += yr_days[leapyear][rulep->r_mon - 1] * SECSPERDAY;
|
||||
|
||||
/*
|
||||
** Use Zeller's Congruence to get day-of-week of first day of
|
||||
** month.
|
||||
*/
|
||||
m1 = (rulep->r_mon + 9) % 12 + 1;
|
||||
yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
|
||||
yy1 = yy0 / 100;
|
||||
yy2 = yy0 % 100;
|
||||
dow = ((26 * m1 - 2) / 10 +
|
||||
1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
|
||||
if (dow < 0)
|
||||
dow += DAYSPERWEEK;
|
||||
|
||||
/*
|
||||
** "dow" is the day-of-week of the first day of the month. Get
|
||||
** the day-of-month (zero-origin) of the first "dow" day of the
|
||||
** month.
|
||||
*/
|
||||
d = rulep->r_day - dow;
|
||||
if (d < 0)
|
||||
d += DAYSPERWEEK;
|
||||
for (i = 1; i < rulep->r_week; ++i) {
|
||||
if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
|
||||
break;
|
||||
d += DAYSPERWEEK;
|
||||
}
|
||||
|
||||
/*
|
||||
** "d" is the day-of-month (zero-origin) of the day we want.
|
||||
*/
|
||||
value += d * SECSPERDAY;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
|
||||
** question. To get the Epoch-relative time of the specified local
|
||||
** time on that day, add the transition time and the current offset
|
||||
** from UTC.
|
||||
*/
|
||||
return value + rulep->r_time + offset;
|
||||
}
|
||||
|
||||
static void generate_transitions(sp, start, end)
|
||||
register struct state * ZCONST sp;
|
||||
ZCONST struct rule * ZCONST start;
|
||||
ZCONST struct rule * ZCONST end;
|
||||
{
|
||||
register int year;
|
||||
register time_t janfirst;
|
||||
time_t starttime;
|
||||
time_t endtime;
|
||||
long stdoffset = -sp->ttis[0].tt_gmtoff;
|
||||
long dstoffset = -sp->ttis[1].tt_gmtoff;
|
||||
register time_t * atp;
|
||||
register unsigned char * typep;
|
||||
|
||||
/*
|
||||
** Two transitions per year, from EPOCH_YEAR to LAST_GOOD_YEAR.
|
||||
*/
|
||||
sp->timecnt = 2 * (LAST_GOOD_YEAR - EPOCH_YEAR + 1);
|
||||
atp = sp->ats;
|
||||
typep = sp->types;
|
||||
janfirst = 0;
|
||||
for (year = EPOCH_YEAR; year <= LAST_GOOD_YEAR; ++year) {
|
||||
starttime = transtime(janfirst, year, start, stdoffset);
|
||||
endtime = transtime(janfirst, year, end, dstoffset);
|
||||
if (starttime > endtime) {
|
||||
*atp++ = endtime;
|
||||
*typep++ = 0; /* DST ends */
|
||||
*atp++ = starttime;
|
||||
*typep++ = 1; /* DST begins */
|
||||
} else {
|
||||
*atp++ = starttime;
|
||||
*typep++ = 1; /* DST begins */
|
||||
*atp++ = endtime;
|
||||
*typep++ = 0; /* DST ends */
|
||||
}
|
||||
janfirst += year_lengths[leap(year)] * SECSPERDAY;
|
||||
}
|
||||
}
|
||||
|
||||
static ZCONST char *getzname(strp)
|
||||
ZCONST char *strp;
|
||||
{
|
||||
register char c;
|
||||
|
||||
while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
|
||||
c != '+')
|
||||
++strp;
|
||||
return strp;
|
||||
}
|
||||
|
||||
static ZCONST char *getnum(strp, nump, min, max)
|
||||
ZCONST char *strp;
|
||||
int * ZCONST nump;
|
||||
ZCONST int min;
|
||||
ZCONST int max;
|
||||
{
|
||||
register char c;
|
||||
register int num;
|
||||
|
||||
if (strp == NULL || !isdigit(c = *strp))
|
||||
return NULL;
|
||||
num = 0;
|
||||
do {
|
||||
num = num * 10 + (c - '0');
|
||||
if (num > max)
|
||||
return NULL; /* illegal value */
|
||||
c = *++strp;
|
||||
} while (isdigit(c));
|
||||
if (num < min)
|
||||
return NULL; /* illegal value */
|
||||
*nump = num;
|
||||
return strp;
|
||||
}
|
||||
|
||||
static ZCONST char *getsecs(strp, secsp)
|
||||
ZCONST char *strp;
|
||||
long * ZCONST secsp;
|
||||
{
|
||||
int num;
|
||||
|
||||
/*
|
||||
** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
|
||||
** "M10.4.6/26", which does not conform to Posix,
|
||||
** but which specifies the equivalent of
|
||||
** ``02:00 on the first Sunday on or after 23 Oct''.
|
||||
*/
|
||||
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp = num * (long) SECSPERHOUR;
|
||||
if (*strp == ':') {
|
||||
++strp;
|
||||
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp += num * SECSPERMIN;
|
||||
if (*strp == ':') {
|
||||
++strp;
|
||||
/* `SECSPERMIN' allows for leap seconds. */
|
||||
strp = getnum(strp, &num, 0, SECSPERMIN);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp += num;
|
||||
}
|
||||
}
|
||||
return strp;
|
||||
}
|
||||
|
||||
static ZCONST char *getoffset(strp, offsetp)
|
||||
ZCONST char *strp;
|
||||
long * ZCONST offsetp;
|
||||
{
|
||||
register int neg = 0;
|
||||
|
||||
if (*strp == '-') {
|
||||
neg = 1;
|
||||
++strp;
|
||||
} else if (*strp == '+')
|
||||
++strp;
|
||||
strp = getsecs(strp, offsetp);
|
||||
if (strp == NULL)
|
||||
return NULL; /* illegal time */
|
||||
if (neg)
|
||||
*offsetp = -*offsetp;
|
||||
return strp;
|
||||
}
|
||||
|
||||
static ZCONST char *getrule(strp, rulep)
|
||||
ZCONST char *strp;
|
||||
struct rule * ZCONST rulep;
|
||||
{
|
||||
if (*strp == 'J') {
|
||||
/*
|
||||
** Julian day.
|
||||
*/
|
||||
rulep->r_type = JULIAN_DAY;
|
||||
++strp;
|
||||
strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
|
||||
} else if (*strp == 'M') {
|
||||
/*
|
||||
** Month, week, day.
|
||||
*/
|
||||
rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
|
||||
++strp;
|
||||
strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp++ != '.')
|
||||
return NULL;
|
||||
strp = getnum(strp, &rulep->r_week, 1, 5);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp++ != '.')
|
||||
return NULL;
|
||||
strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
|
||||
} else if (isdigit(*strp)) {
|
||||
/*
|
||||
** Day of year.
|
||||
*/
|
||||
rulep->r_type = DAY_OF_YEAR;
|
||||
strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
|
||||
} else return NULL; /* invalid format */
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp == '/') {
|
||||
/*
|
||||
** Time specified.
|
||||
*/
|
||||
++strp;
|
||||
strp = getsecs(strp, &rulep->r_time);
|
||||
} else
|
||||
rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
|
||||
return strp;
|
||||
}
|
||||
|
||||
static int Parse_TZ(name, sp)
|
||||
ZCONST char *name;
|
||||
register struct state * ZCONST sp;
|
||||
{
|
||||
ZCONST char * stdname;
|
||||
ZCONST char * dstname;
|
||||
size_t stdlen;
|
||||
size_t dstlen;
|
||||
long stdoffset;
|
||||
long dstoffset;
|
||||
register char * cp;
|
||||
|
||||
dstname = NULL;
|
||||
stdname = name;
|
||||
name = getzname(name);
|
||||
stdlen = name - stdname;
|
||||
if (stdlen < 3)
|
||||
return -1;
|
||||
if (*name == '\0')
|
||||
return -1;
|
||||
name = getoffset(name, &stdoffset);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
if (*name != '\0') {
|
||||
dstname = name;
|
||||
name = getzname(name);
|
||||
dstlen = name - dstname; /* length of DST zone name */
|
||||
if (dstlen < 3)
|
||||
return -1;
|
||||
if (*name != '\0' && *name != ',' && *name != ';') {
|
||||
name = getoffset(name, &dstoffset);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
} else
|
||||
dstoffset = stdoffset - SECSPERHOUR;
|
||||
if (*name == '\0')
|
||||
name = TZDEFRULESTRING;
|
||||
if (*name == ',' || *name == ';') {
|
||||
struct rule start;
|
||||
struct rule end;
|
||||
|
||||
++name;
|
||||
if ((name = getrule(name, &start)) == NULL)
|
||||
return -1;
|
||||
if (*name++ != ',')
|
||||
return -1;
|
||||
if ((name = getrule(name, &end)) == NULL)
|
||||
return -1;
|
||||
if (*name != '\0')
|
||||
return -1;
|
||||
sp->typecnt = 2; /* standard time and DST */
|
||||
sp->ttis[0].tt_gmtoff = -stdoffset;
|
||||
sp->ttis[0].tt_isdst = 0;
|
||||
sp->ttis[0].tt_abbrind = 0;
|
||||
sp->ttis[1].tt_gmtoff = -dstoffset;
|
||||
sp->ttis[1].tt_isdst = 1;
|
||||
sp->ttis[1].tt_abbrind = stdlen + 1;
|
||||
generate_transitions(sp, &start, &end);
|
||||
}
|
||||
} else {
|
||||
dstlen = 0;
|
||||
sp->typecnt = 1; /* only standard time */
|
||||
sp->timecnt = 0;
|
||||
sp->ttis[0].tt_gmtoff = -stdoffset;
|
||||
sp->ttis[0].tt_isdst = 0;
|
||||
sp->ttis[0].tt_abbrind = 0;
|
||||
}
|
||||
sp->charcnt = stdlen + 1;
|
||||
if (dstlen != 0)
|
||||
sp->charcnt += dstlen + 1;
|
||||
if ((size_t) sp->charcnt > sizeof(sp->chars))
|
||||
return -1;
|
||||
cp = sp->chars;
|
||||
(void) strncpy(cp, stdname, stdlen);
|
||||
cp += stdlen;
|
||||
*cp++ = '\0';
|
||||
if (dstlen != 0) {
|
||||
(void) strncpy(cp, dstname, dstlen);
|
||||
*(cp + dstlen) = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tzset()
|
||||
{
|
||||
char *TZstring;
|
||||
int dstfirst;
|
||||
static char *old_TZstring = NULL;
|
||||
|
||||
TZstring = getenv("TZ"); /* read TZ envvar */
|
||||
if (old_TZstring && TZstring && !strcmp(old_TZstring, TZstring))
|
||||
/* do not repeatedly parse an unchanged TZ specification */
|
||||
return;
|
||||
if ((TZstring && TZstring[0] && Parse_TZ(TZstring, &statism) == 0)
|
||||
|| IZTZ_GETLOCALETZINFO(&statism, generate_transitions)
|
||||
|| Parse_TZ(gmt, &statism) == 0) {
|
||||
daylight = statism.typecnt > 1;
|
||||
dstfirst = daylight && statism.ttis[0].tt_isdst && !statism.ttis[1].tt_isdst;
|
||||
timezone = -statism.ttis[dstfirst].tt_gmtoff;
|
||||
tzname[0] = statism.chars + statism.ttis[dstfirst].tt_abbrind;
|
||||
tzname[1] = statism.chars + statism.ttis[!dstfirst].tt_abbrind;
|
||||
real_timezone_is_set = TRUE;
|
||||
if (TZstring) {
|
||||
if (old_TZstring)
|
||||
old_TZstring = realloc(old_TZstring, strlen(TZstring) + 1);
|
||||
else
|
||||
old_TZstring = malloc(strlen(TZstring) + 1);
|
||||
if (old_TZstring)
|
||||
strcpy(old_TZstring, TZstring);
|
||||
}
|
||||
} else {
|
||||
timezone = 0; /* default is GMT0 which means no offsets */
|
||||
daylight = 0; /* from local system time */
|
||||
real_timezone_is_set = FALSE;
|
||||
if (old_TZstring) {
|
||||
free(old_TZstring);
|
||||
old_TZstring = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef IZTZ_SETLOCALTZINFO
|
||||
/* Some SAS/C library functions, e.g. stat(), call library */
|
||||
/* __tzset() themselves. So envvar TZ *must* exist in order to */
|
||||
/* to get the right offset from GMT. XXX TRY HARD to fix this! */
|
||||
set_TZ(timezone, daylight);
|
||||
#endif /* IZTZ_SETLOCALTZINFO */
|
||||
}
|
||||
|
||||
/* XXX Does this also help SAS/C library work? */
|
||||
void __tzset()
|
||||
{
|
||||
if (!real_timezone_is_set) tzset();
|
||||
}
|
||||
|
||||
static struct tm _tmbuf;
|
||||
|
||||
struct tm *gmtime(when)
|
||||
ZCONST time_t *when;
|
||||
{
|
||||
long days = *when / SECSPERDAY;
|
||||
long secs = *when % SECSPERDAY;
|
||||
int isleap;
|
||||
|
||||
memset(&_tmbuf, 0, sizeof(_tmbuf)); /* get any nonstandard fields */
|
||||
_tmbuf.tm_wday = (days + EPOCH_WDAY) % 7;
|
||||
_tmbuf.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
|
||||
isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
|
||||
while (days >= year_lengths[isleap]) {
|
||||
days -= year_lengths[isleap];
|
||||
_tmbuf.tm_year++;
|
||||
isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
|
||||
}
|
||||
_tmbuf.tm_mon = 0;
|
||||
_tmbuf.tm_yday = days;
|
||||
while (days >= mon_lengths[isleap][_tmbuf.tm_mon])
|
||||
days -= mon_lengths[isleap][_tmbuf.tm_mon++];
|
||||
_tmbuf.tm_mday = days + 1;
|
||||
_tmbuf.tm_isdst = 0;
|
||||
_tmbuf.tm_sec = secs % SECSPERMIN;
|
||||
_tmbuf.tm_min = (secs / SECSPERMIN) % SECSPERMIN;
|
||||
_tmbuf.tm_hour = secs / SECSPERHOUR;
|
||||
return &_tmbuf;
|
||||
}
|
||||
|
||||
struct tm *localtime(when)
|
||||
ZCONST time_t *when;
|
||||
{
|
||||
time_t localwhen = *when;
|
||||
int timetype;
|
||||
struct tm *ret;
|
||||
|
||||
__tzset();
|
||||
if (statism.timecnt == 0 || localwhen < statism.ats[0])
|
||||
timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
|
||||
!statism.ttis[1].tt_isdst;
|
||||
else {
|
||||
for (timetype = 1; timetype < statism.timecnt; ++timetype)
|
||||
if (localwhen < statism.ats[timetype])
|
||||
break;
|
||||
timetype = statism.types[timetype - 1];
|
||||
}
|
||||
localwhen += statism.ttis[timetype].tt_gmtoff;
|
||||
ret = gmtime(&localwhen);
|
||||
ret->tm_isdst = statism.ttis[timetype].tt_isdst;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef NEED__ISINDST
|
||||
int _isindst(tb)
|
||||
struct tm *tb;
|
||||
{
|
||||
time_t localt; /* time_t equivalent of given tm struct */
|
||||
time_t univt; /* assumed UTC value of given time */
|
||||
long tzoffset_adj; /* timezone-adjustment `remainder' */
|
||||
int bailout_cnt; /* counter of tries for tz correction */
|
||||
int timetype;
|
||||
|
||||
__tzset();
|
||||
|
||||
/* when DST is unsupported in current timezone, DST is always off */
|
||||
if (statism.typecnt <= 1) return FALSE;
|
||||
|
||||
localt = mkgmtime(tb);
|
||||
if (localt == (time_t)-1)
|
||||
/* specified time is out-of-range, default to FALSE */
|
||||
return FALSE;
|
||||
|
||||
univt = localt - statism.ttis[0].tt_gmtoff;
|
||||
bailout_cnt = 3;
|
||||
do {
|
||||
if (statism.timecnt == 0 || univt < statism.ats[0])
|
||||
timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
|
||||
!statism.ttis[1].tt_isdst;
|
||||
else {
|
||||
for (timetype = 1; timetype < statism.timecnt; ++timetype)
|
||||
if (univt < statism.ats[timetype])
|
||||
break;
|
||||
timetype = statism.types[timetype - 1];
|
||||
}
|
||||
if ((tzoffset_adj = localt - univt - statism.ttis[timetype].tt_gmtoff)
|
||||
== 0L)
|
||||
break;
|
||||
univt += tzoffset_adj;
|
||||
} while (--bailout_cnt > 0);
|
||||
|
||||
/* return TRUE when DST is active at given time */
|
||||
return (statism.ttis[timetype].tt_isdst);
|
||||
}
|
||||
#endif /* NEED__ISINDST */
|
||||
#endif /* !IZ_MKTIME_ONLY */
|
||||
|
||||
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
|
||||
of the local time and date in the exploded time structure `tm',
|
||||
adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'.
|
||||
If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of
|
||||
tm_isdst is determined and returned. Otherwise, mktime() assumes this
|
||||
field as valid; its information is used when converting local time
|
||||
to UTC.
|
||||
Return -1 if time in `tm' cannot be represented as time_t value. */
|
||||
|
||||
time_t mktime(tm)
|
||||
struct tm *tm;
|
||||
{
|
||||
struct tm *ltm; /* Local time. */
|
||||
time_t loctime; /* The time_t value of local time. */
|
||||
time_t then; /* The time to return. */
|
||||
long tzoffset_adj; /* timezone-adjustment `remainder' */
|
||||
int bailout_cnt; /* counter of tries for tz correction */
|
||||
int save_isdst; /* Copy of the tm->isdst input value */
|
||||
|
||||
save_isdst = tm->tm_isdst;
|
||||
loctime = mkgmtime(tm);
|
||||
if (loctime == -1) {
|
||||
tm->tm_isdst = save_isdst;
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
/* Correct for the timezone and any daylight savings time.
|
||||
The correction is verified and repeated when not correct, to
|
||||
take into account the rare case that a change to or from daylight
|
||||
savings time occurs between when it is the time in `tm' locally
|
||||
and when it is that time in Greenwich. After the second correction,
|
||||
the "timezone & daylight" offset should be correct in all cases. To
|
||||
be sure, we allow a third try, but then the loop is stopped. */
|
||||
bailout_cnt = 3;
|
||||
then = loctime;
|
||||
do {
|
||||
ltm = localtime(&then);
|
||||
if (ltm == (struct tm *)NULL ||
|
||||
(tzoffset_adj = loctime - mkgmtime(ltm)) == 0L)
|
||||
break;
|
||||
then += tzoffset_adj;
|
||||
} while (--bailout_cnt > 0);
|
||||
|
||||
if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) {
|
||||
/* Signal failure if timezone adjustment did not converge. */
|
||||
tm->tm_isdst = save_isdst;
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
if (save_isdst >= 0) {
|
||||
if (ltm->tm_isdst && !save_isdst)
|
||||
{
|
||||
if (then + 3600 < then)
|
||||
then = (time_t)-1;
|
||||
else
|
||||
then += 3600;
|
||||
}
|
||||
else if (!ltm->tm_isdst && save_isdst)
|
||||
{
|
||||
if (then - 3600 > then)
|
||||
then = (time_t)-1;
|
||||
else
|
||||
then -= 3600;
|
||||
}
|
||||
ltm->tm_isdst = save_isdst;
|
||||
}
|
||||
|
||||
if (tm != ltm) /* `tm' may already point to localtime's internal storage */
|
||||
*tm = *ltm;
|
||||
|
||||
return then;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_TIME_T_MAX
|
||||
/* Provide default values for the upper limit of the time_t range.
|
||||
These are the result of the decomposition into a `struct tm' for
|
||||
the time value 0xFFFFFFFEL ( = (time_t)-2 ).
|
||||
Note: `(time_t)-1' is reserved for "invalid time"! */
|
||||
# ifndef TM_YEAR_MAX
|
||||
# define TM_YEAR_MAX 2106
|
||||
# endif
|
||||
# ifndef TM_MON_MAX
|
||||
# define TM_MON_MAX 1 /* February */
|
||||
# endif
|
||||
# ifndef TM_MDAY_MAX
|
||||
# define TM_MDAY_MAX 7
|
||||
# endif
|
||||
# ifndef TM_HOUR_MAX
|
||||
# define TM_HOUR_MAX 6
|
||||
# endif
|
||||
# ifndef TM_MIN_MAX
|
||||
# define TM_MIN_MAX 28
|
||||
# endif
|
||||
# ifndef TM_SEC_MAX
|
||||
# define TM_SEC_MAX 14
|
||||
# endif
|
||||
#endif /* NO_TIME_T_MAX */
|
||||
|
||||
/* Adjusts out-of-range values for `tm' field `tm_member'. */
|
||||
#define ADJUST_TM(tm_member, tm_carry, modulus) \
|
||||
if ((tm_member) < 0) { \
|
||||
tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
|
||||
tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
|
||||
} else if ((tm_member) >= (modulus)) { \
|
||||
tm_carry += (tm_member) / (modulus); \
|
||||
tm_member = (tm_member) % (modulus); \
|
||||
}
|
||||
|
||||
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
|
||||
of the Greenwich Mean time and date in the exploded time structure `tm'.
|
||||
This function does always put back normalized values into the `tm' struct,
|
||||
parameter, including the calculated numbers for `tm->tm_yday',
|
||||
`tm->tm_wday', and `tm->tm_isdst'.
|
||||
Returns -1 if the time in the `tm' parameter cannot be represented
|
||||
as valid `time_t' number. */
|
||||
|
||||
time_t mkgmtime(tm)
|
||||
struct tm *tm;
|
||||
{
|
||||
int years, months, days, hours, minutes, seconds;
|
||||
|
||||
years = tm->tm_year + TM_YEAR_BASE; /* year - 1900 -> year */
|
||||
months = tm->tm_mon; /* 0..11 */
|
||||
days = tm->tm_mday - 1; /* 1..31 -> 0..30 */
|
||||
hours = tm->tm_hour; /* 0..23 */
|
||||
minutes = tm->tm_min; /* 0..59 */
|
||||
seconds = tm->tm_sec; /* 0..61 in ANSI C. */
|
||||
|
||||
ADJUST_TM(seconds, minutes, 60)
|
||||
ADJUST_TM(minutes, hours, 60)
|
||||
ADJUST_TM(hours, days, 24)
|
||||
ADJUST_TM(months, years, 12)
|
||||
if (days < 0)
|
||||
do {
|
||||
if (--months < 0) {
|
||||
--years;
|
||||
months = 11;
|
||||
}
|
||||
days += monthlen(months, years);
|
||||
} while (days < 0);
|
||||
else
|
||||
while (days >= monthlen(months, years)) {
|
||||
days -= monthlen(months, years);
|
||||
if (++months >= 12) {
|
||||
++years;
|
||||
months = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore adjusted values in tm structure */
|
||||
tm->tm_year = years - TM_YEAR_BASE;
|
||||
tm->tm_mon = months;
|
||||
tm->tm_mday = days + 1;
|
||||
tm->tm_hour = hours;
|
||||
tm->tm_min = minutes;
|
||||
tm->tm_sec = seconds;
|
||||
|
||||
/* Set `days' to the number of days into the year. */
|
||||
days += YDAYS(months, years);
|
||||
tm->tm_yday = days;
|
||||
|
||||
/* Now calculate `days' to the number of days since Jan 1, 1970. */
|
||||
days = (unsigned)days + 365 * (unsigned)(years - EPOCH_YEAR) +
|
||||
(unsigned)(nleap (years));
|
||||
tm->tm_wday = ((unsigned)days + EPOCH_WDAY) % 7;
|
||||
tm->tm_isdst = 0;
|
||||
|
||||
if (years < EPOCH_YEAR)
|
||||
return (time_t)-1;
|
||||
|
||||
#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
|
||||
#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
|
||||
if (years > TM_YEAR_MAX ||
|
||||
(years == TM_YEAR_MAX &&
|
||||
(tm->tm_yday > (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) ||
|
||||
(tm->tm_yday == (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) &&
|
||||
(hours > TM_HOUR_MAX ||
|
||||
(hours == TM_HOUR_MAX &&
|
||||
(minutes > TM_MIN_MAX ||
|
||||
(minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
|
||||
return (time_t)-1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return (time_t)(SECSPERDAY * (unsigned long)(unsigned)days +
|
||||
SECSPERHOUR * (unsigned long)hours +
|
||||
(unsigned long)(SECSPERMIN * minutes + seconds));
|
||||
}
|
||||
|
||||
#endif /* __timezone_c */
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||||
(the contents of which are also included in zip.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
|
||||
*/
|
||||
#ifndef __timezone_h
|
||||
#define __timezone_h
|
||||
|
||||
#ifndef IZ_MKTIME_ONLY
|
||||
|
||||
/* limits for our timezone info data:
|
||||
* we support only basic standard and daylight time, with max 2 transitions
|
||||
* per year, but for the maximum range of years a 32-bit second counter
|
||||
* can cover (these are 136 years plus a bit more than one month)
|
||||
*/
|
||||
#define TZ_MAX_TIMES 272 /* (=2*(LastGoodYr + 1 - FirstGoodYr) */
|
||||
#define TZ_MAX_TYPES 2 /* We only support basic standard and daylight */
|
||||
#ifdef WIN32 /* Win32 tzinfo supplies at max (2 * 32) chars of tz names */
|
||||
#define TZ_MAX_CHARS 64 /* Maximum number of abbreviation characters */
|
||||
#else
|
||||
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
#endif
|
||||
|
||||
/* supported types of transition rules */
|
||||
#define JULIAN_DAY 0 /* Jn - Julian day */
|
||||
#define DAY_OF_YEAR 1 /* n - day of year */
|
||||
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
|
||||
|
||||
|
||||
struct ttinfo {
|
||||
long tt_gmtoff; /* UTC offset in seconds */
|
||||
int tt_isdst; /* used to set tm_isdst */
|
||||
int tt_abbrind; /* abbreviation list index */
|
||||
};
|
||||
|
||||
struct state {
|
||||
int timecnt;
|
||||
int typecnt;
|
||||
int charcnt;
|
||||
time_t ats[TZ_MAX_TIMES];
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
char chars[TZ_MAX_CHARS];
|
||||
};
|
||||
|
||||
struct rule {
|
||||
int r_type; /* type of rule--JULIAN_DAY etc */
|
||||
int r_day; /* day number of rule */
|
||||
int r_week; /* week number of rule */
|
||||
int r_mon; /* month number of rule */
|
||||
long r_time; /* transition time of rule */
|
||||
};
|
||||
|
||||
extern int real_timezone_is_set; /* set by tzset() */
|
||||
|
||||
|
||||
/* prototypes of functions not in time.h */
|
||||
|
||||
void __tzset OF((void));
|
||||
|
||||
#ifdef NEED__ISINDST
|
||||
int _isindst OF((struct tm *tb));
|
||||
#endif
|
||||
|
||||
/* callback function to be supplied by the program that uses this library */
|
||||
int GetPlatformLocalTimezone OF((register struct state * ZCONST sp,
|
||||
void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res,
|
||||
ZCONST struct rule * ZCONST start,
|
||||
ZCONST struct rule * ZCONST end)));
|
||||
#ifdef IZTZ_SETLOCALTZINFO
|
||||
void set_TZ OF((long time_zone, int day_light));
|
||||
#endif
|
||||
|
||||
#endif /* !IZ_MKTIME_ONLY */
|
||||
|
||||
time_t mkgmtime OF((struct tm *tm));
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,342 +0,0 @@
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
NAME
|
||||
unzipsfx - self-extracting stub for prepending to ZIP
|
||||
archives
|
||||
|
||||
SYNOPSIS
|
||||
<name of unzipsfx+archive combo> [-cfptuz[ajnoqsCLV$]]
|
||||
[file(s) ... [-x xfile(s) ...]]
|
||||
|
||||
DESCRIPTION
|
||||
unzipsfx is a modified version of unzip(1L) designed to be
|
||||
prepended to existing ZIP archives in order to form self-
|
||||
extracting archives. Instead of taking its first non-flag
|
||||
argument to be the zipfile(s) to be extracted, unzipsfx
|
||||
seeks itself under the name by which it was invoked and
|
||||
tests or extracts the contents of the appended archive.
|
||||
Because the executable stub adds bulk to the archive (the
|
||||
whole purpose of which is to be as small as possible), a
|
||||
number of the less-vital capabilities in regular unzip
|
||||
have been removed. Among these are the usage (or help)
|
||||
screen, the listing and diagnostic functions (-l and -v),
|
||||
the ability to decompress older compression formats (the
|
||||
``reduce,'' ``shrink'' and ``implode'' methods). The
|
||||
ability to extract to a directory other than the current
|
||||
one can be selected as a compile-time option, which is now
|
||||
enabled by default since UnZipSFX version 5.5. Similary,
|
||||
decryption is supported as a compile-time option but
|
||||
should be avoided unless the attached archive contains
|
||||
encrypted files. Starting with release 5.5, another com-
|
||||
pile-time option adds a simple ``run command after extrac-
|
||||
tion'' feature. This feature is currently incompatible
|
||||
with the ``extract to different directory'' feature and
|
||||
remains disabled by default.
|
||||
|
||||
Note that self-extracting archives made with unzipsfx are
|
||||
no more (or less) portable across different operating sys-
|
||||
tems than is the unzip executable itself. In general a
|
||||
self-extracting archive made on a particular Unix system,
|
||||
for example, will only self-extract under the same flavor
|
||||
of Unix. Regular unzip may still be used to extract the
|
||||
embedded archive as with any normal zipfile, although it
|
||||
will generate a harmless warning about extra bytes at the
|
||||
beginning of the zipfile. Despite this, however, the
|
||||
self-extracting archive is technically not a valid ZIP
|
||||
archive, and PKUNZIP may be unable to test or extract it.
|
||||
This limitation is due to the simplistic manner in which
|
||||
the archive is created; the internal directory structure
|
||||
is not updated to reflect the extra bytes prepended to the
|
||||
original zipfile.
|
||||
|
||||
ARGUMENTS
|
||||
[file(s)]
|
||||
An optional list of archive members to be pro-
|
||||
cessed. Regular expressions (wildcards) similar to
|
||||
those in Unix egrep(1) may be used to match
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 1
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
multiple members. These wildcards may contain:
|
||||
|
||||
* matches a sequence of 0 or more characters
|
||||
|
||||
? matches exactly 1 character
|
||||
|
||||
[...] matches any single character found inside
|
||||
the brackets; ranges are specified by a
|
||||
beginning character, a hyphen, and an ending
|
||||
character. If an exclamation point or a
|
||||
caret (`!' or `^') follows the left bracket,
|
||||
then the range of characters within the
|
||||
brackets is complemented (that is, anything
|
||||
except the characters inside the brackets is
|
||||
considered a match).
|
||||
|
||||
(Be sure to quote any character that might other-
|
||||
wise be interpreted or modified by the operating
|
||||
system, particularly under Unix and VMS.)
|
||||
|
||||
[-x xfile(s)]
|
||||
An optional list of archive members to be excluded
|
||||
from processing. Since wildcard characters match
|
||||
directory separators (`/'), this option may be used
|
||||
to exclude any files that are in subdirectories.
|
||||
For example, ``foosfx *.[ch] -x */*'' would extract
|
||||
all C source files in the main directory, but none
|
||||
in any subdirectories. Without the -x option, all
|
||||
C source files in all directories within the zip-
|
||||
file would be extracted.
|
||||
|
||||
If unzipsfx is compiled with SFX_EXDIR defined, the fol-
|
||||
lowing option is also enabled:
|
||||
|
||||
[-d exdir]
|
||||
An optional directory to which to extract files.
|
||||
By default, all files and subdirectories are recre-
|
||||
ated in the current directory; the -d option allows
|
||||
extraction in an arbitrary directory (always assum-
|
||||
ing one has permission to write to the directory).
|
||||
The option and directory may be concatenated with-
|
||||
out any white space between them, but note that
|
||||
this may cause normal shell behavior to be sup-
|
||||
pressed. In particular, ``-d ~'' (tilde) is
|
||||
expanded by Unix C shells into the name of the
|
||||
user's home directory, but ``-d~'' is treated as a
|
||||
literal subdirectory ``~'' of the current direc-
|
||||
tory.
|
||||
|
||||
OPTIONS
|
||||
unzipsfx supports the following unzip(1L) options: -c and
|
||||
-p (extract to standard output/screen), -f and -u (freshen
|
||||
and update existing files upon extraction), -t (test
|
||||
archive) and -z (print archive comment). All normal
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 2
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
listing options (-l, -v and -Z) have been removed, but the
|
||||
testing option (-t) may be used as a ``poor man's'' list-
|
||||
ing. Alternatively, those creating self-extracting
|
||||
archives may wish to include a short listing in the zip-
|
||||
file comment.
|
||||
|
||||
See unzip(1L) for a more complete description of these
|
||||
options.
|
||||
|
||||
MODIFIERS
|
||||
unzipsfx currently supports all unzip(1L) modifiers: -a
|
||||
(convert text files), -n (never overwrite), -o (overwrite
|
||||
without prompting), -q (operate quietly), -C (match names
|
||||
case-insensitively), -L (convert uppercase-OS names to
|
||||
lowercase), -j (junk paths) and -V (retain version num-
|
||||
bers); plus the following operating-system specific
|
||||
options: -X (restore VMS owner/protection info), -s (con-
|
||||
vert spaces in filenames to underscores [DOS, OS/2, NT])
|
||||
and -$ (restore volume label [DOS, OS/2, NT, Amiga]).
|
||||
|
||||
(Support for regular ASCII text-conversion may be removed
|
||||
in future versions, since it is simple enough for the
|
||||
archive's creator to ensure that text files have the
|
||||
appropriate format for the local OS. EBCDIC conversion
|
||||
will of course continue to be supported since the zipfile
|
||||
format implies ASCII storage of text files.)
|
||||
|
||||
See unzip(1L) for a more complete description of these
|
||||
modifiers.
|
||||
|
||||
ENVIRONMENT OPTIONS
|
||||
unzipsfx uses the same environment variables as unzip(1L)
|
||||
does, although this is likely to be an issue only for the
|
||||
person creating and testing the self-extracting archive.
|
||||
See unzip(1L) for details.
|
||||
|
||||
DECRYPTION
|
||||
Decryption is supported exactly as in unzip(1L); that is,
|
||||
interactively with a non-echoing prompt for the pass-
|
||||
word(s). See unzip(1L) for details. Once again, note
|
||||
that if the archive has no encrypted files there is no
|
||||
reason to use a version of unzipsfx with decryption sup-
|
||||
port; that only adds to the size of the archive.
|
||||
|
||||
AUTORUN COMMAND
|
||||
When unzipsfx was compiled with CHEAP_SFX_AUTORUN defined,
|
||||
a simple ``command autorun'' feature is supported. You may
|
||||
enter a command into the Zip archive comment, using the
|
||||
following format:
|
||||
|
||||
$AUTORUN$>[command line string]
|
||||
|
||||
When unzipsfxP recognizes the ``$AUTORUN$>'' token at the
|
||||
beginning of the Zip archive comment, the remainder of the
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 3
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
first line of the comment (until the first newline charac-
|
||||
ter) is passed as a shell command to the operating system
|
||||
using the C rtl ``system'' function. Before executing the
|
||||
command, unzipsfxP displays the command on the console and
|
||||
prompts the user for confirmation. When the user has
|
||||
switched off prompting by specifying the -q option,
|
||||
autorun commands are never executed.
|
||||
|
||||
In case the archive comment contains additonal lines of
|
||||
text, the remainder of the archive comment following the
|
||||
first line is displayed normally, unless quiet operation
|
||||
was requested by supplying a -q option.
|
||||
|
||||
EXAMPLES
|
||||
To create a self-extracting archive letters from a regular
|
||||
zipfile letters.zip and change the new archive's permis-
|
||||
sions to be world-executable under Unix:
|
||||
|
||||
cat unzipsfx letters.zip > letters
|
||||
chmod 755 letters
|
||||
zip -A letters
|
||||
|
||||
To create the same archive under MS-DOS, OS/2 or NT (note
|
||||
the use of the /b [binary] option to the copy command):
|
||||
|
||||
copy /b unzipsfx.exe+letters.zip letters.exe
|
||||
zip -A letters.exe
|
||||
|
||||
Under VMS:
|
||||
|
||||
copy unzipsfx.exe,letters.zip letters.exe
|
||||
letters == "$currentdisk:[currentdir]letters.exe"
|
||||
zip -A letters.exe
|
||||
|
||||
(The VMS append command may also be used. The second com-
|
||||
mand installs the new program as a ``foreign command''
|
||||
capable of taking arguments. The third line assumes that
|
||||
Zip is already installed as a foreign command.) Under
|
||||
AmigaDOS:
|
||||
|
||||
MakeSFX letters letters.zip UnZipSFX
|
||||
|
||||
(MakeSFX is included with the UnZip source distribution
|
||||
and with Amiga binary distributions. ``zip -A'' doesn't
|
||||
work on Amiga self-extracting archives.) To test (or
|
||||
list) the newly created self-extracting archive:
|
||||
|
||||
letters -t
|
||||
|
||||
To test letters quietly, printing only a summary message
|
||||
indicating whether the archive is OK or not:
|
||||
|
||||
letters -tqq
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 4
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
To extract the complete contents into the current direc-
|
||||
tory, recreating all files and subdirectories as neces-
|
||||
sary:
|
||||
|
||||
letters
|
||||
|
||||
To extract all *.txt files (in Unix quote the `*'):
|
||||
|
||||
letters *.txt
|
||||
|
||||
To extract everything except the *.txt files:
|
||||
|
||||
letters -x *.txt
|
||||
|
||||
To extract only the README file to standard output (the
|
||||
screen):
|
||||
|
||||
letters -c README
|
||||
|
||||
To print only the zipfile comment:
|
||||
|
||||
letters -z
|
||||
|
||||
LIMITATIONS
|
||||
The principle and fundamental limitation of unzipsfx is
|
||||
that it is not portable across architectures or operating
|
||||
systems, and therefore neither are the resulting archives.
|
||||
For some architectures there is limited portability, how-
|
||||
ever (e.g., between some flavors of Intel-based Unix).
|
||||
|
||||
Another problem with the current implementation is that
|
||||
any archive with ``junk'' prepended to the beginning tech-
|
||||
nically is no longer a zipfile (unless zip(1) is used to
|
||||
adjust the zipfile offsets appropriately, as noted above).
|
||||
unzip(1) takes note of the prepended bytes and ignores
|
||||
them since some file-transfer protocols, notably MacBi-
|
||||
nary, are also known to prepend junk. But PKWARE's
|
||||
archiver suite may not be able to deal with the modified
|
||||
archive unless its offsets have been adjusted.
|
||||
|
||||
unzipsfx has no knowledge of the user's PATH, so in gen-
|
||||
eral an archive must either be in the current directory
|
||||
when it is invoked, or else a full or relative path must
|
||||
be given. If a user attempts to extract the archive from
|
||||
a directory in the PATH other than the current one,
|
||||
unzipsfx will print a warning to the effect, ``can't find
|
||||
myself.'' This is always true under Unix and may be true
|
||||
in some cases under MS-DOS, depending on the compiler used
|
||||
(Microsoft C fully qualifies the program name, but other
|
||||
compilers may not). Under OS/2 and NT there are operat-
|
||||
ing-system calls available that provide the full path
|
||||
name, so the archive may be invoked from anywhere in the
|
||||
user's path. The situation is not known for AmigaDOS,
|
||||
Atari TOS, MacOS, etc.
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 5
|
||||
|
||||
UNZIPSFX(1L) UNZIPSFX(1L)
|
||||
|
||||
As noted above, a number of the normal unzip(1L) functions
|
||||
have been removed in order to make unzipsfx smaller:
|
||||
usage and diagnostic info, listing functions and extrac-
|
||||
tion to other directories. Also, only stored and deflated
|
||||
files are supported. The latter limitation is mainly rel-
|
||||
evant to those who create SFX archives, however.
|
||||
|
||||
VMS users must know how to set up self-extracting archives
|
||||
as foreign commands in order to use any of unzipsfx's
|
||||
options. This is not necessary for simple extraction, but
|
||||
the command to do so then becomes, e.g., ``run letters''
|
||||
(to continue the examples given above).
|
||||
|
||||
unzipsfx on the Amiga requires the use of a special pro-
|
||||
gram, MakeSFX, in order to create working self-extracting
|
||||
archives; simple concatenation does not work. (For tech-
|
||||
nically oriented users, the attached archive is defined as
|
||||
a ``debug hunk.'') There may be compatibility problems
|
||||
between the ROM levels of older Amigas and newer ones.
|
||||
|
||||
All current bugs in unzip(1L) exist in unzipsfx as well.
|
||||
|
||||
DIAGNOSTICS
|
||||
unzipsfx's exit status (error level) is identical to that
|
||||
of unzip(1L); see the corresponding man page.
|
||||
|
||||
SEE ALSO
|
||||
funzip(1L), unzip(1L), zip(1L), zipcloak(1L), zipgrep(1L),
|
||||
zipinfo(1L), zipnote(1L), zipsplit(1L)
|
||||
|
||||
URL
|
||||
The Info-ZIP home page is currently at
|
||||
http://www.info-zip.org/pub/infozip/
|
||||
or
|
||||
ftp://ftp.info-zip.org/pub/infozip/ .
|
||||
|
||||
AUTHORS
|
||||
Greg Roelofs was responsible for the basic modifications
|
||||
to UnZip necessary to create UnZipSFX. See unzip(1L) for
|
||||
the current list of Zip-Bugs authors, or the file CONTRIBS
|
||||
in the UnZip source distribution for the full list of
|
||||
Info-ZIP contributors.
|
||||
|
||||
Info-ZIP 17 February 2002 (v5.5) 6
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
|
||||
|
||||
See the accompanying file LICENSE, version 2000-Apr-09 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
|
||||
*/
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
unzipstb.c
|
||||
|
||||
Simple stub function for UnZip DLL (or shared library, whatever); does
|
||||
exactly the same thing as normal UnZip, except for additional printf()s
|
||||
of various version numbers, solely as a demonstration of what can/should
|
||||
be checked when using the DLL. (If major version numbers ever differ,
|
||||
assume program is incompatible with DLL--especially if DLL version is
|
||||
older. This is not likely to be a problem with *this* simple program,
|
||||
but most user programs will be much more complex.)
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "unzip.h"
|
||||
#include "unzvers.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
static UzpVer *pVersion; /* no pervert jokes, please... */
|
||||
|
||||
pVersion = UzpVersion();
|
||||
|
||||
printf("UnZip stub: checking version numbers (DLL is dated %s)\n",
|
||||
pVersion->date);
|
||||
printf(" UnZip versions: expecting %d.%d%d, using %d.%d%d%s\n",
|
||||
UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, pVersion->unzip.major,
|
||||
pVersion->unzip.minor, pVersion->unzip.patchlevel, pVersion->betalevel);
|
||||
printf(" ZipInfo versions: expecting %d.%d%d, using %d.%d%d\n",
|
||||
ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, pVersion->zipinfo.major,
|
||||
pVersion->zipinfo.minor, pVersion->zipinfo.patchlevel);
|
||||
|
||||
/*
|
||||
D2_M*VER and os2dll.* are obsolete, though retained for compatibility:
|
||||
|
||||
printf(" OS2 DLL versions: expecting %d.%d%d, using %d.%d%d\n",
|
||||
D2_MAJORVER, D2_MINORVER, D2_PATCHLEVEL, pVersion->os2dll.major,
|
||||
pVersion->os2dll.minor, pVersion->os2dll.patchlevel);
|
||||
*/
|
||||
|
||||
if (pVersion->flag & 2)
|
||||
printf(" using zlib version %s\n", pVersion->zlib_version);
|
||||
printf("\n");
|
||||
|
||||
/* call the actual UnZip routine (string-arguments version) */
|
||||
return UzpMain(argc, argv);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#! /bin/sh
|
||||
# zipgrep: searches the given zip members for a string or pattern
|
||||
# This shell script assumes that you have installed UnZip.
|
||||
|
||||
pat=""
|
||||
opt=""
|
||||
while test $# -ne 0; do
|
||||
case "$1" in
|
||||
-e | -f) opt="$opt $1"; shift; pat="$1";;
|
||||
-*) opt="$opt $1";;
|
||||
*) if test -z "$pat"; then
|
||||
pat="$1"
|
||||
else
|
||||
break;
|
||||
fi;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# = 0; then
|
||||
echo "usage: `basename $0` [egrep_options] pattern zipfile [members...]"
|
||||
echo searches the given zip members for a string or pattern
|
||||
exit 1
|
||||
fi
|
||||
zipfile="$1"; shift
|
||||
|
||||
list=0
|
||||
silent=0
|
||||
opt=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
|
||||
case "$opt" in
|
||||
*l*) list=1; opt=`echo $opt | sed s/l//`
|
||||
esac
|
||||
case "$opt" in
|
||||
*h*) silent=1
|
||||
esac
|
||||
if test -n "$opt"; then
|
||||
opt="-$opt"
|
||||
fi
|
||||
|
||||
res=0
|
||||
for i in `unzip -Z1 "$zipfile" ${1+"$@"}`; do
|
||||
if test $list -eq 1; then
|
||||
|
||||
unzip -p-L "$zipfile" "$i" | grep -E $opt "$pat" > /dev/null && echo $i
|
||||
r=$?
|
||||
elif test $silent -eq 1; then
|
||||
|
||||
unzip -p-L "$zipfile" "$i" | grep -E $opt "$pat"
|
||||
r=$?
|
||||
else
|
||||
unzip -p-L "$zipfile" "$i" | grep -E $opt "$pat" | sed "s|^|${i}:|"
|
||||
r=$?
|
||||
fi
|
||||
test "$r" -ne 0 && res="$r"
|
||||
done
|
||||
exit $res
|
||||
@@ -1,89 +0,0 @@
|
||||
|
||||
ZIPGREP(1L) ZIPGREP(1L)
|
||||
|
||||
NAME
|
||||
zipgrep - search files in a ZIP archive for lines matching
|
||||
a pattern
|
||||
|
||||
SYNOPSIS
|
||||
zipgrep [egrep_options] pattern file[.zip] [file(s) ...]
|
||||
[-x xfile(s) ...]
|
||||
|
||||
DESCRIPTION
|
||||
zipgrep will search files within a ZIP archive for lines
|
||||
matching the given string or pattern. zipgrep is a shell
|
||||
script and requires egrep(1) and unzip(1L) to function.
|
||||
Its output is identical to that of egrep(1).
|
||||
|
||||
ARGUMENTS
|
||||
pattern
|
||||
The pattern to be located within a ZIP archive.
|
||||
Any string or regular expression accepted by
|
||||
egrep(1) may be used. file[.zip] Path of the ZIP
|
||||
archive. (Wildcard expressions for the ZIP archive
|
||||
name are not supported.) If the literal filename
|
||||
is not found, the suffix .zip is appended. Note
|
||||
that self-extracting ZIP files are supported, as
|
||||
with any other ZIP archive; just specify the .exe
|
||||
suffix (if any) explicitly.
|
||||
|
||||
[file(s)]
|
||||
An optional list of archive members to be pro-
|
||||
cessed, separated by spaces. If no member files
|
||||
are specified, all members of the ZIP archive are
|
||||
searched. Regular expressions (wildcards) may be
|
||||
used to match multiple members:
|
||||
|
||||
* matches a sequence of 0 or more characters
|
||||
|
||||
? matches exactly 1 character
|
||||
|
||||
[...] matches any single character found inside
|
||||
the brackets; ranges are specified by a
|
||||
beginning character, a hyphen, and an ending
|
||||
character. If an exclamation point or a
|
||||
caret (`!' or `^') follows the left bracket,
|
||||
then the range of characters within the
|
||||
brackets is complemented (that is, anything
|
||||
except the characters inside the brackets is
|
||||
considered a match).
|
||||
|
||||
(Be sure to quote any character that might other-
|
||||
wise be interpreted or modified by the operating
|
||||
system.)
|
||||
|
||||
[-x xfile(s)]
|
||||
An optional list of archive members to be excluded
|
||||
from processing. Since wildcard characters match
|
||||
|
||||
Info-ZIP 17 February 2002 1
|
||||
|
||||
ZIPGREP(1L) ZIPGREP(1L)
|
||||
|
||||
directory separators (`/'), this option may be used
|
||||
to exclude any files that are in subdirectories.
|
||||
For example, ``zipgrep grumpy foo *.[ch] -x */*''
|
||||
would search for the string ``grumpy'' in all C
|
||||
source files in the main directory of the ``foo''
|
||||
archive, but none in any subdirectories. Without
|
||||
the -x option, all C source files in all directo-
|
||||
ries within the zipfile would be searched.
|
||||
|
||||
OPTIONS
|
||||
All options prior to the ZIP archive filename are passed
|
||||
to egrep(1).
|
||||
|
||||
SEE ALSO
|
||||
egrep(1), unzip(1L), zip(1L), funzip(1L), zipcloak(1L),
|
||||
zipinfo(1L), zipnote(1L), zipsplit(1L)
|
||||
|
||||
URL
|
||||
The Info-ZIP home page is currently at http://www.info-
|
||||
zip.org/pub/infozip/ or ftp://ftp.info-
|
||||
zip.org/pub/infozip/ .
|
||||
|
||||
AUTHORS
|
||||
zipgrep was written by Jean-loup Gailly.
|
||||
|
||||
Info-ZIP 17 February 2002 2
|
||||
|
||||
@@ -2,8 +2,9 @@ SubDir HAIKU_TOP src tools unzip ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin unzip ] ;
|
||||
|
||||
DEFINES += NO_CRYPT HAS_JUNK_EXTRA_FIELD_OPTION=1 ;
|
||||
if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
DEFINES += HAVE_TERMIOS_H=1 HAS_JUNK_EXTRA_FIELD_OPTION=1 ;
|
||||
DEFINES += HAVE_TERMIOS_H=1 ;
|
||||
}
|
||||
|
||||
# avoid building host unzip with DEBUG, as that would pollute the build
|
||||
@@ -16,7 +17,6 @@ BuildPlatformStaticLibrary <build>libunzip.a :
|
||||
crc32.c
|
||||
ttyio.c
|
||||
crctab.c
|
||||
crypt.c
|
||||
envargs.c
|
||||
explode.c
|
||||
extract.c
|
||||
@@ -37,4 +37,3 @@ BuildPlatformMain <build>unzip :
|
||||
unshrink.c
|
||||
: <build>libunzip.a $(HOST_LIBBE) $(HOST_LIBSUPC++)
|
||||
;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user