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:
Augustin Cavalier
2025-02-04 01:13:06 -05:00
parent 97d45387df
commit a1448cbdcd
21 changed files with 4 additions and 6076 deletions
+2 -48
View File
@@ -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/.)
-610
View File
@@ -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 */
-155
View File
@@ -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 */
-232
View File
@@ -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 */
-583
View File
@@ -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 */
-178
View File
@@ -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 */
-586
View File
@@ -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 */
-562
View File
@@ -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);
}
-106
View File
@@ -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
-104
View File
@@ -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;
}
-211
View File
@@ -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
-4
View File
@@ -1,4 +0,0 @@
/*
Quick hack so that I can compile unzipsfx without playing with Jam rules
*/
#define SFX
-813
View File
@@ -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 */
-81
View File
@@ -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.
-342
View File
@@ -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
-56
View File
@@ -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);
}
-56
View File
@@ -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
-89
View File
@@ -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 -3
View File
@@ -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++)
;