merged 2.2 branch

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Bryan Petty
2000-07-15 19:51:35 +00:00
parent 8a693e6e04
commit f6bcfd974e
1835 changed files with 237729 additions and 67990 deletions

601
utils/Install/sfxzip/api.c Normal file
View File

@@ -0,0 +1,601 @@
/*---------------------------------------------------------------------------
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"
#include "version.h"
#ifdef WINDLL
# include "windll/windll.h"
#endif
#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 = BETALEVEL;
version.date = 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 = PATCHLEVEL;
version.zipinfo.major = ZI_MAJORVER;
version.zipinfo.minor = ZI_MINORVER;
version.zipinfo.patchlevel = PATCHLEVEL;
/* these are retained for backward compatibility only: */
version.os2dll.major = UZ_MAJORVER;
version.os2dll.minor = UZ_MINORVER;
version.os2dll.patchlevel = PATCHLEVEL;
version.windll.major = UZ_MAJORVER;
version.windll.minor = UZ_MINORVER;
version.windll.patchlevel = 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, BETALEVEL);
strcpy(version->date, 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 = PATCHLEVEL;
version->zipinfo.major = ZI_MAJORVER;
version->zipinfo.minor = ZI_MINORVER;
version->zipinfo.patchlevel = PATCHLEVEL;
/* these are retained for backward compatibility only: */
version->os2dll.major = UZ_MAJORVER;
version->os2dll.minor = UZ_MINORVER;
version->os2dll.patchlevel = PATCHLEVEL;
version->windll.major = UZ_MAJORVER;
version->windll.minor = UZ_MINORVER;
version->windll.patchlevel = 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(G.redirect_size+1);
#endif
if (!G.redirect_buffer)
return FALSE;
G.redirect_pointer[G.redirect_size] = '\0';
return TRUE;
}
int writeToMemory(__GPRO__ uch *rawbuf, ulg size)
{
if (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 = 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 */

View File

@@ -0,0 +1,147 @@
/* apihelp.c */
#ifdef API_DOC
#define UNZIP_INTERNAL
#include "unzip.h"
#include "version.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 */

View File

@@ -0,0 +1,56 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* $Id$ */
#define __CRC32_C /* identifies this source module */
#include "zip.h"
#ifndef USE_ZLIB
#ifndef ASM_CRC
#ifndef ZCONST
# define ZCONST const
#endif
#ifdef CRC32
# undef CRC32
#endif
#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
#define DO1(buf) crc = CRC32(crc, *buf++)
#define DO2(buf) DO1(buf); DO1(buf)
#define DO4(buf) DO2(buf); DO2(buf)
#define DO8(buf) DO4(buf); DO4(buf)
/* ========================================================================= */
ulg crc32(crc, buf, len)
register ulg crc; /* crc shift register */
register ZCONST uch *buf; /* pointer to bytes to pump through */
extent len; /* number of bytes in buf[] */
/* Run a set of bytes through the crc shift register. If buf is a NULL
pointer, then initialize the crc shift register contents instead.
Return the current crc in either case. */
{
register ZCONST ulg near *crc_table;
if (buf == NULL) return 0L;
crc_table = get_crc_table();
crc = crc ^ 0xffffffffL;
#ifndef NO_UNROLLED_LOOPS
while (len >= 8) {
DO8(buf);
len -= 8;
}
#endif
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
}
#endif /* !ASM_CRC */
#endif /* !USE_ZLIB */

View File

@@ -0,0 +1,230 @@
/*
* crc_i386.S, optimized CRC calculation function for Zip and UnZip, not
* copyrighted by Paul Kienitz and Christian Spieler. Last revised 12 Oct 97.
*
* 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, ulg 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; */
#ifndef NO_UNROLLED_LOOPS
# ifndef NO_32_BIT_LOADS
testl %ecx, %ecx
jz .L_bail
/* 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 */
andl $7, %edx /* edx = len % 8 */
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
#endif /* NO_UNROLLED_LOOPS */
#ifndef NO_JECXZ_SUPPORT
jecxz .L_bail /* > if (len) */
#else
testl %ecx, %ecx /* > if (len) */
jz .L_bail
#endif
/* 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 */

View File

@@ -0,0 +1,229 @@
; crc_i386.asm, optimized CRC calculation function for Zip and UnZip, not
; copyrighted by Paul Kienitz and Christian Spieler. Last revised 25 Mar 98.
;
; Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
; fixed to assemble with masm by not using .model directive which makes
; assumptions about segment alignment. Also,
; avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
; than lodsb, and other misc. changes resulting in the following performance
; increases:
;
; unrolled loops NO_UNROLLED_LOOPS
; *8 >8 <8 *8 >8 <8
;
; +54% +42% +35% +82% +52% +25%
;
; first item in each table is input buffer length, even multiple of 8
; second item in each table is input buffer length, > 8
; third item in each table is input buffer length, < 8
;
; Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
; Incorporated Rodney Brown's 32-bit-reads optimization as found in the
; UNIX AS source crc_i386.S. This new code can be disabled by defining
; the macro symbol NO_32_BIT_LOADS.
;
; Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
; Incorporated 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 macro symbol __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.
;
; The loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
; This results in shorter code at the expense of reduced performance.
;
; Revised 25-Mar-98, Cosmin Truta (cosmint@cs.ubbcluj.ro)
; Working without .model directive caused tasm32 version 5.0 to produce
; bad object code. The optimized alignments can be optionally disabled
; by defining NO_ALIGN, thus allowing to use .model flat. There is no need
; to define this macro if using other version of tasm.
;
;==============================================================================
;
; Do NOT assemble this source if external crc32 routine from zlib gets used.
;
IFNDEF USE_ZLIB
;
.386p
name crc_i386
IFDEF NO_ALIGN
.model flat
ENDIF
extrn _get_crc_table:near ; ZCONST ulg near *get_crc_table(void);
;
IFNDEF NO_STD_STACKFRAME
; Use a `standard' stack frame setup on routine entry and exit.
; Actually, this option is set as default, because it results
; in smaller code !!
STD_ENTRY MACRO
push ebp
mov ebp,esp
ENDM
Arg1 EQU 08H[ebp]
Arg2 EQU 0CH[ebp]
Arg3 EQU 10H[ebp]
STD_LEAVE MACRO
pop ebp
ENDM
ELSE ; NO_STD_STACKFRAME
STD_ENTRY MACRO
ENDM
Arg1 EQU 18H[esp]
Arg2 EQU 1CH[esp]
Arg3 EQU 20H[esp]
STD_LEAVE MACRO
ENDM
ENDIF ; ?NO_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 dword) "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
Do_CRC MACRO
mov bl,al ; tmp = c & 0xFF
shr eax,8 ; c = (c >> 8)
xor eax,[edi+ebx*4] ; ^ table[tmp]
ENDM
ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUs
Do_CRC MACRO
movzx ebx,al ; tmp = c & 0xFF
shr eax,8 ; c = (c >> 8)
xor eax,[edi+ebx*4] ; ^ table[tmp]
ENDM
ENDIF ; ?__686
Do_CRC_byte MACRO
xor al, byte ptr [esi] ; c ^= *buf
inc esi ; buf++
Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
ENDM
IFNDEF NO_32_BIT_LOADS
Do_CRC_dword MACRO
xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
add esi, 4 ; ((ulg *)buf)++
Do_CRC
Do_CRC
Do_CRC
Do_CRC
ENDM
ENDIF ; !NO_32_BIT_LOADS
IFNDEF NO_ALIGN
_TEXT segment use32 para public 'CODE'
ELSE
_TEXT segment use32
ENDIF
assume CS: _TEXT
public _crc32
_crc32 proc near ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)
STD_ENTRY
push edi
push esi
push ebx
push edx
push ecx
mov esi,Arg2 ; 2nd arg: uch *buf
sub eax,eax ;> if (!buf)
test esi,esi ;> return 0;
jz fine ;> else {
call _get_crc_table
mov edi,eax
mov eax,Arg1 ; 1st arg: ulg crc
IFNDEF __686
sub ebx,ebx ; ebx=0; make bl usable as a dword
ENDIF
mov ecx,Arg3 ; 3rd arg: extent len
not eax ;> c = ~crc;
IFNDEF NO_UNROLLED_LOOPS
IFNDEF NO_32_BIT_LOADS
test ecx,ecx
je bail
align_loop:
test esi,3 ; align buf pointer on next
jz SHORT aligned_now ; dword boundary
Do_CRC_byte
dec ecx
jnz align_loop
aligned_now:
ENDIF ; !NO_32_BIT_LOADS
mov edx,ecx ; save len in edx
and edx,000000007H ; edx = len % 8
shr ecx,3 ; ecx = len / 8
jz SHORT No_Eights
IFNDEF NO_ALIGN
; align loop head at start of 486 internal cache line !!
align 16
ENDIF
Next_Eight:
IFNDEF NO_32_BIT_LOADS
Do_CRC_dword
Do_CRC_dword
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
dec ecx
jnz Next_Eight
No_Eights:
mov ecx,edx
ENDIF ; NO_UNROLLED_LOOPS
IFNDEF NO_JECXZ_SUPPORT
jecxz bail ;> if (len)
ELSE
test ecx,ecx ;> if (len)
jz SHORT bail
ENDIF
IFNDEF NO_ALIGN
; align loop head at start of 486 internal cache line !!
align 16
ENDIF
loupe: ;> do {
Do_CRC_byte ; c = CRC32(c, *buf++);
dec ecx ;> } while (--len);
jnz loupe
bail: ;> }
not eax ;> return ~c;
fine:
pop ecx
pop edx
pop ebx
pop esi
pop edi
STD_LEAVE
ret
_crc32 endp
_TEXT ends
;
ENDIF ; !USE_ZLIB
;
end

View File

@@ -0,0 +1,215 @@
/* crc_i386.c -- Microsoft 32-bit C/C++ adaptation of crc_i386.asm
* Created by Rodney Brown from crc_i386.asm, modified by Chr. Spieler.
* Last revised: 22-Mai-1998
*
* Original coded (in crc_i386.asm) and put into the public domain
* by Paul Kienitz and Christian Spieler.
*
* Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
* fixed to assemble with masm by not using .model directive which makes
* assumptions about segment alignment. Also,
* avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
* than lodsb, and other misc. changes resulting in the following performance
* increases:
*
* unrolled loops NO_UNROLLED_LOOPS
* *8 >8 <8 *8 >8 <8
*
* +54% +42% +35% +82% +52% +25%
*
* first item in each table is input buffer length, even multiple of 8
* second item in each table is input buffer length, > 8
* third item in each table is input buffer length, < 8
*
* Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
* Incorporated Rodney Brown's 32-bit-reads optimization as found in the
* UNIX AS source crc_i386.S. This new code can be disabled by defining
* the macro symbol NO_32_BIT_LOADS.
*
* Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
* Incorporated 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 macro symbol __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 ...)
*
* Revised 16-Nov-97, Chr. Spieler: Made code compatible with Borland C++
* 32-bit, removed unneeded kludge for potentially unknown movzx mnemonic,
* confirmed correct working with MS VC++ (32-bit).
*
* Revised 22-Mai-98, Peter Kunath, Chr. Spieler : The 16-Nov-97 revision broke
* MSVC 5.0. Inside preprocessor macros, each instruction is enclosed in its
* own __asm {...} construct. For MSVC, a "#pragma warning" was added to
* shut up the "no return value" warning message.
*
* FLAT memory model assumed.
*
* The loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
* This results in shorter code at the expense of reduced performance.
*
*/
#include "zip.h"
#ifndef USE_ZLIB
#ifndef ZCONST
# define ZCONST const
#endif
/* Select wether the following inline-assember code is supported. */
#if (defined(_MSC_VER) && _MSC_VER >= 700)
#if (defined(_M_IX86) && _M_IX86 >= 300)
# define MSC_INLINE_ASM_32BIT_SUPPORT
/* Disable warning for no return value, typical of asm functions */
# pragma warning( disable : 4035 )
#endif
#endif
#if (defined(__BORLANDC__) && __BORLANDC__ >= 452)
# define MSC_INLINE_ASM_32BIT_SUPPORT
#endif
#ifdef MSC_INLINE_ASM_32BIT_SUPPORT
/* This code is intended for Microsoft C/C++ (32-bit) compatible compilers. */
/*
* 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 dword) "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
#define Do_CRC { \
__asm { mov bl, al }; \
__asm { shr eax, 8 }; \
__asm { xor eax, [edi+ebx*4] }; }
#else /* __686 */
#define Do_CRC { \
__asm { movzx ebx, al }; \
__asm { shr eax, 8 }; \
__asm { xor eax, [edi+ebx*4] }; }
#endif /* ?__686 */
#define Do_CRC_byte { \
__asm { xor al, byte ptr [esi] }; \
__asm { inc esi }; \
Do_CRC; }
#ifndef NO_32_BIT_LOADS
#define Do_CRC_dword { \
__asm { xor eax, dword ptr [esi] }; \
__asm { add esi, 4 }; \
Do_CRC; \
Do_CRC; \
Do_CRC; \
Do_CRC; }
#endif /* !NO_32_BIT_LOADS */
/* ========================================================================= */
ulg crc32(crc, buf, len)
ulg crc; /* crc shift register */
ZCONST uch *buf; /* pointer to bytes to pump through */
extent len; /* number of bytes in buf[] */
/* Run a set of bytes through the crc shift register. If buf is a NULL
pointer, then initialize the crc shift register contents instead.
Return the current crc in either case. */
{
__asm {
push edx
push ecx
mov esi,buf ;/* 2nd arg: uch *buf */
sub eax,eax ;/*> if (!buf) */
test esi,esi ;/*> return 0; */
jz fine ;/*> else { */
call get_crc_table
mov edi,eax
mov eax,crc ;/* 1st arg: ulg crc */
#ifndef __686
sub ebx,ebx ;/* ebx=0; => bl usable as a dword */
#endif
mov ecx,len ;/* 3rd arg: extent len */
not eax ;/*> c = ~crc; */
#ifndef NO_UNROLLED_LOOPS
# ifndef NO_32_BIT_LOADS
test ecx,ecx
je bail
align_loop:
test esi,3 ;/* align buf pointer on next */
jz aligned_now ;/* dword boundary */
}
Do_CRC_byte ;
__asm {
dec ecx
jnz align_loop
aligned_now:
# endif /* !NO_32_BIT_LOADS */
mov edx,ecx ;/* save len in edx */
and edx,000000007H ;/* edx = len % 8 */
shr ecx,3 ;/* ecx = len / 8 */
jz No_Eights
; align loop head at start of 486 internal cache line !!
align 16
Next_Eight:
}
# ifndef NO_32_BIT_LOADS
Do_CRC_dword ;
Do_CRC_dword ;
# 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 */
__asm {
dec ecx
jnz Next_Eight
No_Eights:
mov ecx,edx
#endif /* NO_UNROLLED_LOOPS */
#ifndef NO_JECXZ_SUPPORT
jecxz bail ;/*> if (len) */
#else
test ecx,ecx ;/*> if (len) */
jz bail
#endif
; align loop head at start of 486 internal cache line !!
align 16
loupe: ;/*> do { */
}
Do_CRC_byte ;/* c = CRC32(c, *buf++); */
__asm {
dec ecx ;/*> } while (--len); */
jnz loupe
bail: ;/*> } */
not eax ;/*> return ~c; */
fine:
pop ecx
pop edx
}
#ifdef NEED_RETURN
return _EAX;
#endif
}
#endif /* MSC_INLINE_ASM_32BIT_SUPPORT */
#if (defined(_MSC_VER) && _MSC_VER >= 700)
#if (defined(_M_IX86) && _M_IX86 >= 300)
/* Reenable missing return value warning */
# pragma warning( default : 4035 )
#endif
#endif
#endif /* !USE_ZLIB */

View File

@@ -0,0 +1,108 @@
; crc_lcc.asm, optimized CRC calculation function for Zip and UnZip, not
; copyrighted by Paul Kienitz and Christian Spieler. Last revised 25 Mar 98.
;
; The code in this file has been copied verbatim from crc_i386.{asm|S};
; only the assembler syntax and metacommands have been adapted to
; the habits of the free LCC-Win32 C compiler package.
; This version of the code uses the "optimized for i686" variant of
; crc_i386.{asm|S}.
;
; For more information (and a revision log), look into the original
; source files.
;
.text
.file "crc32.c"
.text
.type _crc32,function
_crc32:
pushl %ebp
movl %esp,%ebp
pushl %ecx
pushl %ebx
pushl %esi
pushl %edi
.line 34
.line 37
movl 12(%ebp),%esi
subl %eax,%eax
testl %esi,%esi
jz _$3
.line 39
call _get_crc_table
movl %eax,%edi
.line 41
movl 8(%ebp),%eax
movl 16(%ebp),%ecx
notl %eax
testl %ecx,%ecx
jz _$4
_$5:
testl $3,%esi
jz _$6
xorb (%esi),%al
incl %esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
decl %ecx
jnz _$5
_$6:
movl %ecx,%edx
andl $7,%edx
shrl $3,%ecx
jz _$8
_$7:
xorl (%esi),%eax
addl $4,%esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
xorl (%esi),%eax
addl $4,%esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
decl %ecx
jnz _$7
_$8:
movl %edx,%ecx
jecxz _$4
_$9:
xorb (%esi),%al
incl %esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
decl %ecx
jnz _$9
_$4:
xorl $0xffffffff,%eax
_$3:
.line 52
popl %edi
popl %esi
popl %ebx
leave
ret
_$34:
.size _crc32,_$34-_crc32
.globl _crc32
.extern _get_crc_table

View File

@@ -0,0 +1,219 @@
/* crctab.c -- supply the CRC table needed for CRC-32 calculations.
* Copyright (C) 1995 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* $Id$ */
/*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The table is simply the CRC of all possible eight bit values. This is all
the information needed to generate CRC's on data a byte at a time for all
combinations of CRC register values and incoming bytes.
*/
#define __CRCTAB_C /* identifies this source module */
#include "zip.h"
#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
#ifndef ZCONST
# define ZCONST const
#endif
#ifdef DYNAMIC_CRC_TABLE
/* =========================================================================
* Make the crc table. This function is needed only if you want to compute
* the table dynamically.
*/
local void make_crc_table OF((void));
#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
error: Dynamic allocation of CRC table not safe with reentrant code.
#endif /* DYNALLOC_CRCTAB && REENTRANT */
#ifdef DYNALLOC_CRCTAB
local ulg near *crc_table = NULL;
# if 0 /* not used, since sizeof("near *") <= sizeof(int) */
/* Use this section when access to a "local int" is faster than access to
a "local pointer" (e.g.: i86 16bit code with far pointers). */
local int crc_table_empty = 1;
# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0)
# define MARK_CRCTAB_FILLED crc_table_empty = 0
# define MARK_CRCTAB_EMPTY crc_table_empty = 1
# else
/* Use this section on systems where the size of pointers and ints is
equal (e.g.: all 32bit systems). */
# define CRC_TABLE_IS_EMPTY (crc_table == NULL)
# define MARK_CRCTAB_FILLED crc_table = crctab_p
# define MARK_CRCTAB_EMPTY crc_table = NULL
# endif
#else /* !DYNALLOC_CRCTAB */
local ulg near crc_table[256];
local int crc_table_empty = 1;
# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0)
# define MARK_CRCTAB_FILLED crc_table_empty = 0
#endif /* ?DYNALLOC_CRCTAB */
local void make_crc_table()
{
ulg c; /* crc shift register */
int n; /* counter for all possible eight bit values */
int k; /* byte being shifted into crc apparatus */
#ifdef DYNALLOC_CRCTAB
ulg near *crctab_p; /* temporary pointer to allocated crc_table area */
#else /* !DYNALLOC_CRCTAB */
# define crctab_p crc_table
#endif /* DYNALLOC_CRCTAB */
#ifdef COMPUTE_XOR_PATTERN
/* This piece of code has been left here to explain how the XOR pattern
* used in the creation of the crc_table values can be recomputed.
* For production versions of this function, it is more efficient to
* supply the resultant pattern at compile time.
*/
ulg xor; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static uch p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */
xor = 0L;
for (i = 0; i < sizeof(p)/sizeof(uch); i++)
xor |= 1L << (31 - p[i]);
#else
# define xor 0xedb88320L
#endif
#ifdef DYNALLOC_CRCTAB
crctab_p = (ulg near *) nearmalloc (256*sizeof(ulg));
if (crctab_p == NULL) {
ziperr(ZE_MEM, "crc_table allocation");
}
#endif /* DYNALLOC_CRCTAB */
for (n = 0; n < 256; n++) {
c = (ulg)n;
for (k = 8; k; k--)
c = c & 1 ? xor ^ (c >> 1) : c >> 1;
crctab_p[n] = c;
}
MARK_CRCTAB_FILLED;
}
#else /* !DYNAMIC_CRC_TABLE */
#ifdef DYNALLOC_CRCTAB
error: Inconsistent flags, DYNALLOC_CRCTAB without DYNAMIC_CRC_TABLE.
#endif
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
local ZCONST ulg near crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#endif /* ?DYNAMIC_CRC_TABLE */
/* use "OF((void))" here to work around a Borland TC++ 1.0 problem */
#ifdef USE_ZLIB
ZCONST uLongf *get_crc_table OF((void))
#else
ZCONST ulg near *get_crc_table OF((void))
#endif
{
#ifdef DYNAMIC_CRC_TABLE
if (CRC_TABLE_IS_EMPTY)
make_crc_table();
#endif
#ifdef USE_ZLIB
return (ZCONST uLongf *)crc_table;
#else
return (ZCONST ulg near *)crc_table;
#endif
}
#ifdef DYNALLOC_CRCTAB
void free_crc_table()
{
if (!CRC_TABLE_IS_EMPTY)
{
nearfree((ulg near *)crc_table);
MARK_CRCTAB_EMPTY;
}
}
#endif
#endif /* !USE_ZLIB || USE_OWN_CRCTAB */

View File

@@ -0,0 +1,12 @@
/*
crypt.c (dummy version) by Info-ZIP. Last revised: 15 Aug 98
This is a non-functional version of Info-ZIP's crypt.c encryption/
decryption code for Zip, ZipCloak, UnZip and fUnZip. This file is
not copyrighted and may be distributed freely. :-) See the "WHERE"
file for sites from which to obtain the full encryption/decryption
sources (zcrypt28.zip or later).
*/
/* something "externally visible" to shut up compiler/linker warnings */
int zcr_dummy;

View File

@@ -0,0 +1,314 @@
/*----------------------------------------------------------------*
| envargs - add default options from environment to command line
|----------------------------------------------------------------
| Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
| This program is in the public domain.
|----------------------------------------------------------------
| Minor program notes:
| 1. Yes, the indirection is a tad complex
| 2. Parentheses were added where not needed in some cases
| to make the action of the code less obscure.
|----------------------------------------------------------------
| UnZip notes: 24 May 92 ("v1.4"):
| 1. #include "unzip.h" for prototypes (24 May 92)
| 2. changed ch to type char (24 May 92)
| 3. added an ifdef to avoid Borland warnings (24 May 92)
| 4. included Rich Wales' mksargs() routine (for MS-DOS, maybe
| OS/2? NT?) (4 Dec 93)
| 5. added alternate-variable string envstr2 (21 Apr 94)
| 6. added support for quoted arguments (6 Jul 96)
*----------------------------------------------------------------*/
#define ENVARGS_C
#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef __EMX__ /* emx isspace() returns TRUE on extended ASCII !! */
# define ISspace(c) ((c) & 0x80 ? 0 : isspace((unsigned)c))
#else
# define ISspace(c) isspace((unsigned)c)
#endif /* ?__EMX__ */
static int count_args OF((ZCONST char *));
static void mem_err OF((__GPRO));
static ZCONST char Far NoMemArguments[] =
"envargs: cannot get memory for arguments";
void envargs(__G__ Pargc, Pargv, envstr, envstr2)
__GDEF
int *Pargc;
char ***Pargv;
ZCONST char *envstr, *envstr2;
{
#ifndef RISCOS
char *getenv();
#endif
char *envptr; /* value returned by getenv */
char *bufptr; /* copy of env info */
int argc = 0; /* internal arg count */
register int ch; /* spare temp value */
char **argv; /* internal arg vector */
char **argvect; /* copy of vector address */
/* see if anything in the environment */
if ((envptr = getenv(envstr)) != (char *)NULL) /* usual var */
while (ISspace(*envptr)) /* must discard leading spaces */
envptr++;
if (envptr == (char *)NULL || *envptr == '\0')
if ((envptr = getenv(envstr2)) != (char *)NULL) /* alternate var */
while (ISspace(*envptr))
envptr++;
if (envptr == (char *)NULL || *envptr == '\0')
return;
bufptr = malloc(1 + strlen(envptr));
if (bufptr == (char *)NULL)
mem_err(__G);
#if (defined(WIN32) || defined(WINDLL))
# ifdef WIN32
if (IsWinNT()) {
/* SPC: don't know codepage of 'real' WinNT console */
strcpy(bufptr, envptr);
} else {
/* Win95 environment is DOS and uses OEM character coding */
OEM_TO_INTERN(envptr, bufptr);
}
# else /* !WIN32 */
/* DOS environment uses OEM codepage */
OEM_TO_INTERN(envptr, bufptr);
# endif
#else /* !(WIN32 || WINDLL) */
strcpy(bufptr, envptr);
#endif /* ?(WIN32 || WINDLL) */
/* count the args so we can allocate room for them */
argc = count_args(bufptr);
/* allocate a vector large enough for all args */
argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
if (argv == (char **)NULL) {
free(bufptr);
mem_err(__G);
}
argvect = argv;
/* copy the program name first, that's always true */
*(argv++) = *((*Pargv)++);
/* copy the environment args next, may be changed */
do {
#if defined(AMIGA) || defined(UNIX)
if (*bufptr == '"') {
char *argstart = ++bufptr;
*(argv++) = argstart;
for (ch = *bufptr; ch != '\0' && ch != '\"'; ch = *(++bufptr))
if (ch == '\\' && bufptr[1] != '\0')
++bufptr; /* skip char after backslash */
if (ch != '\0')
*(bufptr++) = '\0'; /* overwrite trailing " */
/* remove escape characters */
while ((argstart = strchr(argstart, '\\')) != (char *)NULL) {
strcpy(argstart, argstart + 1);
if (*argstart)
++argstart;
}
} else {
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
++bufptr;
if (ch != '\0')
*(bufptr++) = '\0';
}
#else
#ifdef DOS_FLX_OS2_W32
/* we do not support backslash-quoting of quotes in quoted
* strings under DOS_OS2_W32, because backslashes are directory
* separators and double quotes are illegal in filenames */
if (*bufptr == '"') {
*(argv++) = ++bufptr;
while ((ch = *bufptr) != '\0' && ch != '\"')
++bufptr;
if (ch != '\0')
*(bufptr++) = '\0';
} else {
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
++bufptr;
if (ch != '\0')
*(bufptr++) = '\0';
}
#else
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
++bufptr;
if (ch != '\0')
*(bufptr++) = '\0';
#endif /* ?DOS_FLX_OS2_W32 */
#endif /* ?(AMIGA || UNIX) */
while ((ch = *bufptr) != '\0' && ISspace(ch))
++bufptr;
} while (ch);
/* now save old argc and copy in the old args */
argc += *Pargc;
while (--(*Pargc))
*(argv++) = *((*Pargv)++);
/* finally, add a NULL after the last arg, like Unix */
*argv = (char *)NULL;
/* save the values and return */
*Pargv = argvect;
*Pargc = argc;
}
static int count_args(s)
ZCONST char *s;
{
int count = 0;
char ch;
do {
/* count and skip args */
++count;
#if defined(AMIGA) || defined(UNIX)
if (*s == '\"') {
for (ch = *(++s); ch != '\0' && ch != '\"'; ch = *(++s))
if (ch == '\\' && s[1] != '\0')
++s;
if (*s)
++s; /* trailing quote */
} else
#else
#ifdef DOS_FLX_OS2_W32
if (*s == '\"') {
++s; /* leading quote */
while ((ch = *s) != '\0' && ch != '\"')
++s;
if (*s)
++s; /* trailing quote */
} else
#endif /* DOS_FLX_OS2_W32 */
#endif /* ?(AMIGA || UNIX) */
while ((ch = *s) != '\0' && !ISspace(ch)) /* note else-clauses above */
++s;
while ((ch = *s) != '\0' && ISspace(ch))
++s;
} while (ch);
return count;
}
static void mem_err(__G)
__GDEF
{
perror(LoadFarString(NoMemArguments));
DESTROYGLOBALS()
EXIT(PK_MEM);
}
#ifdef TEST
main(argc, argv)
int argc;
char **argv;
{
int i;
pipeit("Orig argv: %p\n", argv);
dump_args(argc, argv);
envargs(__G__ &argc, &argv, "ENVTEST");
pipeit(" New argv: %p\n", argv);
dump_args(argc, argv);
}
dump_args(argc, argv)
int argc;
char *argv[];
{
int i;
pipeit("\nDump %d args:\n", argc);
for (i = 0; i < argc; ++i)
pipeit("%3d %s\n", i, argv[i]);
}
#endif /* TEST */
#ifdef MSDOS /* DOS_OS2? DOS_OS2_W32? */
/*
* void mksargs(int *argcp, char ***argvp)
*
* Substitutes the extended command line argument list produced by
* the MKS Korn Shell in place of the command line info from DOS.
*
* The MKS shell gets around DOS's 128-byte limit on the length of
* a command line by passing the "real" command line in the envi-
* ronment. The "real" arguments are flagged by prepending a tilde
* (~) to each one.
*
* This "mksargs" routine creates a new argument list by scanning
* the environment from the beginning, looking for strings begin-
* ning with a tilde character. The new list replaces the original
* "argv" (pointed to by "argvp"), and the number of arguments
* in the new list replaces the original "argc" (pointed to by
* "argcp").
*
* Rich Wales
*/
void mksargs(argcp, argvp)
int *argcp;
char ***argvp;
{
#ifndef MSC /* declared differently in MSC 7.0 headers, at least */
#ifndef __WATCOMC__
extern char **environ; /* environment */
#endif
#endif
char **envp; /* pointer into environment */
char **newargv; /* new argument list */
char **argp; /* pointer into new arg list */
int newargc; /* new argument count */
/* sanity check */
if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
return;
/* find out how many environment arguments there are */
for (envp = environ, newargc = 0; *envp != NULL && (*envp)[0] == '~';
envp++, newargc++)
;
if (newargc == 0)
return; /* no environment arguments */
/* set up new argument list */
newargv = (char **) malloc(sizeof(char **) * (newargc+1));
if (newargv == NULL)
return; /* malloc failed */
for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
*argp++ = &(*envp++)[1])
;
*argp = NULL; /* null-terminate the list */
/* substitute new argument list in place of old one */
*argcp = newargc;
*argvp = newargv;
}
#endif /* MSDOS */

View File

@@ -0,0 +1,871 @@
/* explode.c -- put in the public domain by Mark Adler
version c15, 6 July 1996 */
/* 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
---- --------- -------------- ------------------------------------
c1 30 Mar 92 M. Adler explode that uses huft_build from inflate
(this gives over a 70% speed improvement
over the original unimplode.c, which
decoded a bit at a time)
c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k.
c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG
c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy()
c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing
the 32K window size for specialized
applications.
c6 31 May 92 M. Adler added typecasts to eliminate some warnings
c7 27 Jun 92 G. Roelofs added more typecasts.
c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch.
c9 19 Jul 93 J. Bush added more typecasts (to return values);
made l[256] array static for Amiga.
c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added
buf and unshrink arguments to flush();
undef'd various macros at end for Turbo C;
removed NEXTBYTE macro (now in unzip.h)
and bytebuf variable (not used); changed
memset() to memzero().
c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation.
c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines
to avoid bug in Encore compiler.
c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix)
c14 22 Nov 95 S. Maxwell removed unnecessary "static" on auto array
c15 6 Jul 96 W. Haidinger added ulg typecasts to flush() calls.
c16 8 Feb 98 C. Spieler added ZCONST modifiers to const tables
and #ifdef DEBUG around debugging code.
c16b 25 Mar 98 C. Spieler modified DLL code for slide redirection.
*/
/*
Explode imploded (PKZIP method 6 compressed) data. This compression
method searches for as much of the current string of bytes (up to a length
of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches
(of at least length 2 or 3), it codes the next byte. Otherwise, it codes
the length of the matched string and its distance backwards from the
current position. Single bytes ("literals") are preceded by a one (a
single bit) and are either uncoded (the eight bits go directly into the
compressed stream for a total of nine bits) or Huffman coded with a
supplied literal code tree. If literals are coded, then the minimum match
length is three, otherwise it is two.
There are therefore four kinds of imploded streams: 8K search with coded
literals (min match = 3), 4K search with coded literals (min match = 3),
8K with uncoded literals (min match = 2), and 4K with uncoded literals
(min match = 2). The kind of stream is identified in two bits of a
general purpose bit flag that is outside of the compressed stream.
Distance-length pairs for matched strings are preceded by a zero bit (to
distinguish them from literals) and are always coded. The distance comes
first and is either the low six (4K) or low seven (8K) bits of the
distance (uncoded), followed by the high six bits of the distance coded.
Then the length is six bits coded (0..63 + min match length), and if the
maximum such length is coded, then it's followed by another eight bits
(uncoded) to be added to the coded length. This gives a match length
range of 2..320 or 3..321 bytes.
The literal, length, and distance codes are all represented in a slightly
compressed form themselves. What is sent are the lengths of the codes for
each value, which is sufficient to construct the codes. Each byte of the
code representation is the code length (the low four bits representing
1..16), and the number of values sequentially with that length (the high
four bits also representing 1..16). There are 256 literal code values (if
literals are coded), 64 length code values, and 64 distance code values,
in that order at the beginning of the compressed stream. Each set of code
values is preceded (redundantly) with a byte indicating how many bytes are
in the code description that follows, in the range 1..256.
The codes themselves are decoded using tables made by huft_build() from
the bit lengths. That routine and its comments are in the inflate.c
module.
*/
#define UNZIP_INTERNAL
#include "unzip.h" /* must supply slide[] (uch) array and NEXTBYTE macro */
#ifndef WSIZE
# define WSIZE 0x8000 /* window size--must be a power of two, and */
#endif /* at least 8K for zip's implode method */
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
# define wsize G._wsize
#else
# define wsize WSIZE
#endif
/* routines here */
static int get_tree OF((__GPRO__ unsigned *l, unsigned n));
static int explode_lit8 OF((__GPRO__ struct huft *tb, struct huft *tl,
struct huft *td, int bb, int bl, int bd));
static int explode_lit4 OF((__GPRO__ struct huft *tb, struct huft *tl,
struct huft *td, int bb, int bl, int bd));
static int explode_nolit8 OF((__GPRO__ struct huft *tl, struct huft *td,
int bl, int bd));
static int explode_nolit4 OF((__GPRO__ struct huft *tl, struct huft *td,
int bl, int bd));
int explode OF((__GPRO));
/* The implode algorithm uses a sliding 4K or 8K byte window on the
uncompressed stream to find repeated byte strings. This is implemented
here as a circular buffer. The index is updated simply by incrementing
and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K
buffer of inflate is used, and it works just as well to always have
a 32K circular buffer, so the index is anded with 0x7fff. This is
done to allow the window to also be used as the output buffer. */
/* This must be supplied in an external module useable like "uch slide[8192];"
or "uch *slide;", where the latter would be malloc'ed. In unzip, slide[]
is actually a 32K area for use by inflate, which uses a 32K sliding window.
*/
/* Tables for length and distance */
static ZCONST ush cplen2[] =
{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65};
static ZCONST ush cplen3[] =
{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66};
static ZCONST ush extra[] =
{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, 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,
8};
static ZCONST ush cpdist4[] =
{1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705,
769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473,
1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177,
2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881,
2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585,
3649, 3713, 3777, 3841, 3905, 3969, 4033};
static ZCONST ush cpdist8[] =
{1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281,
1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689,
2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097,
4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505,
5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913,
7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065};
/* Macros for inflate() bit peeking and grabbing.
The usage is:
NEEDBITS(j)
x = b & mask_bits[j];
DUMPBITS(j)
where NEEDBITS makes sure that b has at least j bits in it, and
DUMPBITS removes the bits from b. The macros use the variable k
for the number of bits in b. Normally, b and k are register
variables for speed.
*/
#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(n) {b>>=(n);k-=(n);}
static int get_tree(__G__ l, n)
__GDEF
unsigned *l; /* bit lengths */
unsigned n; /* number expected */
/* Get the bit lengths for a code representation from the compressed
stream. If get_tree() returns 4, then there is an error in the data.
Otherwise zero is returned. */
{
unsigned i; /* bytes remaining in list */
unsigned k; /* lengths entered */
unsigned j; /* number of codes */
unsigned b; /* bit length for those codes */
/* get bit lengths */
i = NEXTBYTE + 1; /* length/count pairs to read */
k = 0; /* next code */
do {
b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */
j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */
if (k + j > n)
return 4; /* don't overflow l[] */
do {
l[k++] = b;
} while (--j);
} while (--i);
return k != n ? 4 : 0; /* should have read n of them */
}
static int explode_lit8(__G__ tb, tl, td, bb, bl, bd)
__GDEF
struct huft *tb, *tl, *td; /* literal, length, and distance tables */
int bb, bl, bd; /* number of bits decoded by those */
/* Decompress the imploded data using coded literals and an 8K sliding
window. */
{
long s; /* bytes to decompress */
register unsigned e; /* table entry flag/number of extra bits */
unsigned n, d; /* length and index for copy */
unsigned w; /* current window position */
struct huft *t; /* pointer to table entry */
unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
unsigned u; /* true if unflushed */
/* explode the coded data */
b = k = w = 0; /* initialize bit buffer, window */
u = 1; /* buffer unflushed */
mb = mask_bits[bb]; /* precompute masks for speed */
ml = mask_bits[bl];
md = mask_bits[bd];
s = G.ucsize;
while (s > 0) /* do until ucsize bytes uncompressed */
{
NEEDBITS(1)
if (b & 1) /* then literal--decode it */
{
DUMPBITS(1)
s--;
NEEDBITS((unsigned)bb) /* get coded literal */
if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
redirSlide[w++] = (uch)t->v.n;
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
}
else /* else distance/length */
{
DUMPBITS(1)
NEEDBITS(7) /* get distance low bits */
d = (unsigned)b & 0x7f;
DUMPBITS(7)
NEEDBITS((unsigned)bd) /* get coded distance high bits */
if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
d = w - d - t->v.n; /* construct offset */
NEEDBITS((unsigned)bl) /* get coded length */
if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
n = t->v.n;
if (e) /* get length extra bits */
{
NEEDBITS(8)
n += (unsigned)b & 0xff;
DUMPBITS(8)
}
/* do the copy */
s -= n;
do {
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide) {
/* &= w/ wsize not needed and wrong if redirect */
if (d >= wsize)
return 1;
n -= (e = (e = wsize - (d > w ? d : w)) > n ? n : e);
} else
#endif
n -= (e = (e = wsize - ((d &= wsize-1) > w ? d : w)) > n ? n : e);
if (u && w <= d)
{
memzero(redirSlide + w, e);
w += e;
d += e;
}
else
#ifndef NOMEMCPY
if (w - d >= e) /* (this test assumes unsigned comparison) */
{
memcpy(redirSlide + w, redirSlide + d, e);
w += e;
d += e;
}
else /* do it slow to avoid memcpy() overlap */
#endif /* !NOMEMCPY */
do {
redirSlide[w++] = redirSlide[d++];
} while (--e);
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
} while (n);
}
}
/* flush out redirSlide */
flush(__G__ redirSlide, (ulg)w, 0);
if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */
{ /* sometimes read one too many: k>>3 compensates */
G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3);
return 5;
}
return 0;
}
static int explode_lit4(__G__ tb, tl, td, bb, bl, bd)
__GDEF
struct huft *tb, *tl, *td; /* literal, length, and distance tables */
int bb, bl, bd; /* number of bits decoded by those */
/* Decompress the imploded data using coded literals and a 4K sliding
window. */
{
long s; /* bytes to decompress */
register unsigned e; /* table entry flag/number of extra bits */
unsigned n, d; /* length and index for copy */
unsigned w; /* current window position */
struct huft *t; /* pointer to table entry */
unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
unsigned u; /* true if unflushed */
/* explode the coded data */
b = k = w = 0; /* initialize bit buffer, window */
u = 1; /* buffer unflushed */
mb = mask_bits[bb]; /* precompute masks for speed */
ml = mask_bits[bl];
md = mask_bits[bd];
s = G.ucsize;
while (s > 0) /* do until ucsize bytes uncompressed */
{
NEEDBITS(1)
if (b & 1) /* then literal--decode it */
{
DUMPBITS(1)
s--;
NEEDBITS((unsigned)bb) /* get coded literal */
if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
redirSlide[w++] = (uch)t->v.n;
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
}
else /* else distance/length */
{
DUMPBITS(1)
NEEDBITS(6) /* get distance low bits */
d = (unsigned)b & 0x3f;
DUMPBITS(6)
NEEDBITS((unsigned)bd) /* get coded distance high bits */
if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
d = w - d - t->v.n; /* construct offset */
NEEDBITS((unsigned)bl) /* get coded length */
if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
n = t->v.n;
if (e) /* get length extra bits */
{
NEEDBITS(8)
n += (unsigned)b & 0xff;
DUMPBITS(8)
}
/* do the copy */
s -= n;
do {
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide) {
/* &= w/ wsize not needed and wrong if redirect */
if (d >= wsize)
return 1;
n -= (e = (e = wsize - (d > w ? d : w)) > n ? n : e);
} else
#endif
n -= (e = (e = wsize - ((d &= wsize-1) > w ? d : w)) > n ? n : e);
if (u && w <= d)
{
memzero(redirSlide + w, e);
w += e;
d += e;
}
else
#ifndef NOMEMCPY
if (w - d >= e) /* (this test assumes unsigned comparison) */
{
memcpy(redirSlide + w, redirSlide + d, e);
w += e;
d += e;
}
else /* do it slow to avoid memcpy() overlap */
#endif /* !NOMEMCPY */
do {
redirSlide[w++] = redirSlide[d++];
} while (--e);
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
} while (n);
}
}
/* flush out redirSlide */
flush(__G__ redirSlide, (ulg)w, 0);
if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */
{ /* sometimes read one too many: k>>3 compensates */
G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3);
return 5;
}
return 0;
}
static int explode_nolit8(__G__ tl, td, bl, bd)
__GDEF
struct huft *tl, *td; /* length and distance decoder tables */
int bl, bd; /* number of bits decoded by tl[] and td[] */
/* Decompress the imploded data using uncoded literals and an 8K sliding
window. */
{
long s; /* bytes to decompress */
register unsigned e; /* table entry flag/number of extra bits */
unsigned n, d; /* length and index for copy */
unsigned w; /* current window position */
struct huft *t; /* pointer to table entry */
unsigned ml, md; /* masks for bl and bd bits */
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
unsigned u; /* true if unflushed */
/* explode the coded data */
b = k = w = 0; /* initialize bit buffer, window */
u = 1; /* buffer unflushed */
ml = mask_bits[bl]; /* precompute masks for speed */
md = mask_bits[bd];
s = G.ucsize;
while (s > 0) /* do until ucsize bytes uncompressed */
{
NEEDBITS(1)
if (b & 1) /* then literal--get eight bits */
{
DUMPBITS(1)
s--;
NEEDBITS(8)
redirSlide[w++] = (uch)b;
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
DUMPBITS(8)
}
else /* else distance/length */
{
DUMPBITS(1)
NEEDBITS(7) /* get distance low bits */
d = (unsigned)b & 0x7f;
DUMPBITS(7)
NEEDBITS((unsigned)bd) /* get coded distance high bits */
if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
d = w - d - t->v.n; /* construct offset */
NEEDBITS((unsigned)bl) /* get coded length */
if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
n = t->v.n;
if (e) /* get length extra bits */
{
NEEDBITS(8)
n += (unsigned)b & 0xff;
DUMPBITS(8)
}
/* do the copy */
s -= n;
do {
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide) {
/* &= w/ wsize not needed and wrong if redirect */
if (d >= wsize)
return 1;
n -= (e = (e = wsize - (d > w ? d : w)) > n ? n : e);
} else
#endif
n -= (e = (e = wsize - ((d &= wsize-1) > w ? d : w)) > n ? n : e);
if (u && w <= d)
{
memzero(redirSlide + w, e);
w += e;
d += e;
}
else
#ifndef NOMEMCPY
if (w - d >= e) /* (this test assumes unsigned comparison) */
{
memcpy(redirSlide + w, redirSlide + d, e);
w += e;
d += e;
}
else /* do it slow to avoid memcpy() overlap */
#endif /* !NOMEMCPY */
do {
redirSlide[w++] = redirSlide[d++];
} while (--e);
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
} while (n);
}
}
/* flush out redirSlide */
flush(__G__ redirSlide, (ulg)w, 0);
if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */
{ /* sometimes read one too many: k>>3 compensates */
G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3);
return 5;
}
return 0;
}
static int explode_nolit4(__G__ tl, td, bl, bd)
__GDEF
struct huft *tl, *td; /* length and distance decoder tables */
int bl, bd; /* number of bits decoded by tl[] and td[] */
/* Decompress the imploded data using uncoded literals and a 4K sliding
window. */
{
long s; /* bytes to decompress */
register unsigned e; /* table entry flag/number of extra bits */
unsigned n, d; /* length and index for copy */
unsigned w; /* current window position */
struct huft *t; /* pointer to table entry */
unsigned ml, md; /* masks for bl and bd bits */
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
unsigned u; /* true if unflushed */
/* explode the coded data */
b = k = w = 0; /* initialize bit buffer, window */
u = 1; /* buffer unflushed */
ml = mask_bits[bl]; /* precompute masks for speed */
md = mask_bits[bd];
s = G.ucsize;
while (s > 0) /* do until ucsize bytes uncompressed */
{
NEEDBITS(1)
if (b & 1) /* then literal--get eight bits */
{
DUMPBITS(1)
s--;
NEEDBITS(8)
redirSlide[w++] = (uch)b;
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
DUMPBITS(8)
}
else /* else distance/length */
{
DUMPBITS(1)
NEEDBITS(6) /* get distance low bits */
d = (unsigned)b & 0x3f;
DUMPBITS(6)
NEEDBITS((unsigned)bd) /* get coded distance high bits */
if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
d = w - d - t->v.n; /* construct offset */
NEEDBITS((unsigned)bl) /* get coded length */
if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
do {
if (e == 99)
return 1;
DUMPBITS(t->b)
e -= 16;
NEEDBITS(e)
} while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
DUMPBITS(t->b)
n = t->v.n;
if (e) /* get length extra bits */
{
NEEDBITS(8)
n += (unsigned)b & 0xff;
DUMPBITS(8)
}
/* do the copy */
s -= n;
do {
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide) {
/* &= w/ wsize not needed and wrong if redirect */
if (d >= wsize)
return 1;
n -= (e = (e = wsize - (d > w ? d : w)) > n ? n : e);
} else
#endif
n -= (e = (e = wsize - ((d &= wsize-1) > w ? d : w)) > n ? n : e);
if (u && w <= d)
{
memzero(redirSlide + w, e);
w += e;
d += e;
}
else
#ifndef NOMEMCPY
if (w - d >= e) /* (this test assumes unsigned comparison) */
{
memcpy(redirSlide + w, redirSlide + d, e);
w += e;
d += e;
}
else /* do it slow to avoid memcpy() overlap */
#endif /* !NOMEMCPY */
do {
redirSlide[w++] = redirSlide[d++];
} while (--e);
if (w == wsize)
{
flush(__G__ redirSlide, (ulg)w, 0);
w = u = 0;
}
} while (n);
}
}
/* flush out redirSlide */
flush(__G__ redirSlide, (ulg)w, 0);
if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */
{ /* sometimes read one too many: k>>3 compensates */
G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3);
return 5;
}
return 0;
}
int explode(__G)
__GDEF
/* Explode an imploded compressed stream. Based on the general purpose
bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding
window. Construct the literal (if any), length, and distance codes and
the tables needed to decode them (using huft_build() from inflate.c),
and call the appropriate routine for the type of data in the remainder
of the stream. The four routines are nearly identical, differing only
in whether the literal is decoded or simply read in, and in how many
bits are read in, uncoded, for the low distance bits. */
{
unsigned r; /* return codes */
struct huft *tb; /* literal code table */
struct huft *tl; /* length code table */
struct huft *td; /* distance code table */
int bb; /* bits for tb */
int bl; /* bits for tl */
int bd; /* bits for td */
unsigned l[256]; /* bit lengths for codes */
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide)
wsize = G.redirect_size, redirSlide = G.redirect_buffer;
else
wsize = WSIZE, redirSlide = slide;
#endif
/* Tune base table sizes. Note: I thought that to truly optimize speed,
I would have to select different bl, bd, and bb values for different
compressed file sizes. I was surprised to find out that the values of
7, 7, and 9 worked best over a very wide range of sizes, except that
bd = 8 worked marginally better for large compressed sizes. */
bl = 7;
bd = (G.csize + G.incnt) > 200000L ? 8 : 7;
/* With literal tree--minimum match length is 3 */
#ifdef DEBUG
G.hufts = 0; /* initialize huft's malloc'ed */
#endif
if (G.lrec.general_purpose_bit_flag & 4)
{
bb = 9; /* base table size for literals */
if ((r = get_tree(__G__ l, 256)) != 0)
return (int)r;
if ((r = huft_build(__G__ l, 256, 256, NULL, NULL, &tb, &bb)) != 0)
{
if (r == 1)
huft_free(tb);
return (int)r;
}
if ((r = get_tree(__G__ l, 64)) != 0)
return (int)r;
if ((r = huft_build(__G__ l, 64, 0, cplen3, extra, &tl, &bl)) != 0)
{
if (r == 1)
huft_free(tl);
huft_free(tb);
return (int)r;
}
if ((r = get_tree(__G__ l, 64)) != 0)
return (int)r;
if (G.lrec.general_purpose_bit_flag & 2) /* true if 8K */
{
if ((r = huft_build(__G__ l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
{
if (r == 1)
huft_free(td);
huft_free(tl);
huft_free(tb);
return (int)r;
}
r = explode_lit8(__G__ tb, tl, td, bb, bl, bd);
}
else /* else 4K */
{
if ((r = huft_build(__G__ l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
{
if (r == 1)
huft_free(td);
huft_free(tl);
huft_free(tb);
return (int)r;
}
r = explode_lit4(__G__ tb, tl, td, bb, bl, bd);
}
huft_free(td);
huft_free(tl);
huft_free(tb);
}
else
/* No literal tree--minimum match length is 2 */
{
if ((r = get_tree(__G__ l, 64)) != 0)
return (int)r;
if ((r = huft_build(__G__ l, 64, 0, cplen2, extra, &tl, &bl)) != 0)
{
if (r == 1)
huft_free(tl);
return (int)r;
}
if ((r = get_tree(__G__ l, 64)) != 0)
return (int)r;
if (G.lrec.general_purpose_bit_flag & 2) /* true if 8K */
{
if ((r = huft_build(__G__ l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
{
if (r == 1)
huft_free(td);
huft_free(tl);
return (int)r;
}
r = explode_nolit8(__G__ tl, td, bl, bd);
}
else /* else 4K */
{
if ((r = huft_build(__G__ l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
{
if (r == 1)
huft_free(td);
huft_free(tl);
return (int)r;
}
r = explode_nolit4(__G__ tl, td, bl, bd);
}
huft_free(td);
huft_free(tl);
}
Trace((stderr, "<%u > ", G.hufts));
return (int)r;
}
/* so explode.c and inflate.c can be compiled together into one object: */
#undef NEXTBYTE
#undef NEEDBITS
#undef DUMPBITS

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,468 @@
/* funzip.c -- put in the public domain by Mark Adler */
#define VERSION "3.93 of 21 November 1998"
/* 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
*/
/*
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 zcrypt21.zip or later must be used.
*/
#define FUNZIP
#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 */
/* 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))
/* Function prototypes */
void err OF((int, char *));
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 */
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);
}
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;
}
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 */
#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
G.area.Slide = (uch *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
#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_H68_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_H68_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_OS2_W32
#if (defined(__HIGHC__) && !defined(FLEXOS))
setmode(stdout, _BINARY);
#else
setmode(1, O_BINARY);
#endif
#endif /* DOS_FLX_H68_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");
if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
err(3, "first entry not deflated or stored--cannot unpack");
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 (h[GZPHOW] != DEFLATED)
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)) != 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 (++G.outcnt == WSIZE) /* do FlushOutput() */
{
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);
}

View File

@@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------
globals.c
Routines to allocate and initialize globals, with or without threads.
Contents: registerGlobalPointer()
deregisterGlobalPointer()
getGlobalPointer()
globalsCtor()
---------------------------------------------------------------------------*/
#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
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_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
G.echofd = -1;
#endif /* !(MACOS || ATARI || VMS) */
#endif /* !(DOS_FLX_H68_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

644
utils/Install/sfxzip/list.c Normal file
View File

@@ -0,0 +1,644 @@
/*---------------------------------------------------------------------------
list.c
This file contains the non-ZipInfo-specific listing routines for UnZip.
Contains: list_files()
get_time_stamp() [optional feature]
ratio()
fnprint()
---------------------------------------------------------------------------*/
#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef WINDLL
# ifdef POCKET_UNZIP
# include "wince/intrface.h"
# else
# include "windll/windll.h"
# endif
#endif
#ifdef TIMESTAMP
static int fn_is_dir OF((__GPRO));
#endif
#ifndef WINDLL
static ZCONST char Far CompFactorStr[] = "%c%d%%";
static ZCONST char Far CompFactor100[] = "100%%";
#ifdef OS2_EAS
static ZCONST char Far HeadersS[] =
" Length EAs ACLs Date Time Name";
static ZCONST char Far HeadersS1[] =
" -------- --- ---- ---- ---- ----";
#else
static ZCONST char Far HeadersS[] = " Length Date Time Name";
static ZCONST char Far HeadersS1[] = " -------- ---- ---- ----";
#endif
static ZCONST char Far HeadersL[] =
" Length Method Size Ratio Date Time CRC-32 Name";
static ZCONST char Far HeadersL1[] =
"-------- ------ ------- ----- ---- ---- ------ ----";
static ZCONST char Far *Headers[][2] =
{ {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
static ZCONST char Far CaseConversion[] =
"%s (\"^\" ==> case\n%s conversion)\n";
static ZCONST char Far LongHdrStats[] =
"%8lu %-7s%8lu %4s %02u-%02u-%02u %02u:%02u %08lx %c";
static ZCONST char Far LongFileTrailer[] =
"-------- ------- --- \
-------\n%8lu %8lu %4s %u file%s\n";
#ifdef OS2_EAS
static ZCONST char Far ShortHdrStats[] =
"%9lu %6lu %6lu %02u-%02u-%02u %02u:%02u %c";
static ZCONST char Far ShortFileTrailer[] = " -------- ----- ----- \
-------\n%9lu %6lu %6lu %u file%s\n";
static ZCONST char Far OS2ExtAttrTrailer[] =
"%ld file%s %ld bytes of OS/2 extended attributes attached.\n";
static ZCONST char Far OS2ACLTrailer[] =
"%ld file%s %ld bytes of access control lists attached.\n";
#else
static ZCONST char Far ShortHdrStats[] =
"%9lu %02u-%02u-%02u %02u:%02u %c";
static ZCONST char Far ShortFileTrailer[] =
" -------- -------\n%9lu %u file%s\n";
#endif /* ?OS2_EAS */
#endif /* !WINDLL */
/*************************/
/* Function list_files() */
/*************************/
int list_files(__G) /* return PK-type error code */
__GDEF
{
int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
#ifndef WINDLL
char sgn, cfactorstr[10];
int longhdr=(uO.vflag>1);
#endif
int date_format;
unsigned j, methnum, members=0;
#ifdef USE_EF_UT_TIME
iztimes z_utime;
struct tm *t;
#endif
unsigned yr, mo, dy, hh, mm;
ulg csiz, tot_csize=0L, tot_ucsize=0L;
#ifdef OS2_EAS
ulg ea_size, tot_easize=0L, tot_eafiles=0L;
ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
#endif
min_info info;
char methbuf[8];
static ZCONST char dtype[]="NXFS"; /* see zi_short() */
static ZCONST char Far method[NUM_METHODS+1][8] =
{"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
"Implode", "Token", "Defl:#", "EnhDefl", "ImplDCL", "Unk:###"};
/*---------------------------------------------------------------------------
Unlike extract_or_test_files(), this routine confines itself to the cen-
tral directory. Thus its structure is somewhat simpler, since we can do
just a single loop through the entire directory, listing files as we go.
So to start off, print the heading line and then begin main loop through
the central directory. The results will look vaguely like the following:
Length Method Size Ratio Date Time CRC-32 Name ("^" ==> case
-------- ------ ------- ----- ---- ---- ------ ---- conversion)
44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 ^dos-file.ext
16717 Defl:X 5252 69% 11-03-97 06:40 1ce0f189 WHERE
-------- ------- --- -------
64159 20502 68% 3 files
---------------------------------------------------------------------------*/
G.pInfo = &info;
date_format = DATE_FORMAT;
#ifndef WINDLL
if (uO.qflag < 2) {
if (uO.L_flag)
Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
LoadFarStringSmall(Headers[longhdr][0]),
LoadFarStringSmall2(Headers[longhdr][1])));
else
Info(slide, 0, ((char *)slide, "%s\n%s\n",
LoadFarString(Headers[longhdr][0]),
LoadFarStringSmall(Headers[longhdr][1])));
}
#endif /* !WINDLL */
for (j = 0; j++ < (unsigned)G.ecrec.total_entries_central_dir;) {
if (readbuf(__G__ G.sig, 4) == 0)
return PK_EOF;
if (strncmp(G.sig, central_hdr_sig, 4)) { /* just to make sure */
Info(slide, 0x401, ((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
return PK_BADERR; /* sig not found */
}
/* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
return error; /* only PK_EOF defined */
/*
* We could DISPLAY the filename instead of storing (and possibly trun-
* cating, in the case of a very long name) and printing it, but that
* has the disadvantage of not allowing case conversion--and it's nice
* to be able to see in the listing precisely how you have to type each
* filename in order for unzip to consider it a match. Speaking of
* which, if member names were specified on the command line, check in
* with match() to see if the current file is one of them, and make a
* note of it if it is.
*/
if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
PK_COOL) /* ^--(uses pInfo->lcflag) */
{
error_in_archive = error;
if (error > PK_WARN) /* fatal: can't continue */
return error;
}
if (G.extra_field != (uch *)NULL) {
free(G.extra_field);
G.extra_field = (uch *)NULL;
}
if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
!= 0)
{
error_in_archive = error;
if (error > PK_WARN) /* fatal */
return error;
}
if (!G.process_all_files) { /* check if specified on command line */
unsigned i;
do_this_file = FALSE;
for (i = 0; i < G.filespecs; i++)
if (match(G.filename, G.pfnames[i], uO.C_flag)) {
do_this_file = TRUE;
break; /* found match, so stop looping */
}
if (do_this_file) { /* check if this is an excluded file */
for (i = 0; i < G.xfilespecs; i++)
if (match(G.filename, G.pxnames[i], uO.C_flag)) {
do_this_file = FALSE; /* ^-- ignore case in match */
break;
}
}
}
/*
* If current file was specified on command line, or if no names were
* specified, do the listing for this file. Otherwise, get rid of the
* file comment and go back for the next file.
*/
if (G.process_all_files || do_this_file) {
#ifdef OS2DLL
/* this is used by UzpFileTree() to allow easy processing of lists
* of zip directory contents */
if (G.processExternally) {
if ((G.processExternally)(G.filename, &G.crec))
break;
++members;
} else {
#endif
#ifdef OS2_EAS
{
uch *ef_ptr = G.extra_field;
int ef_size, ef_len = G.crec.extra_field_length;
ea_size = acl_size = 0;
while (ef_len >= EB_HEADSIZE) {
ef_size = makeword(&ef_ptr[EB_LEN]);
switch (makeword(&ef_ptr[EB_ID])) {
case EF_OS2:
ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
break;
case EF_ACL:
acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
break;
}
ef_ptr += (ef_size + EB_HEADSIZE);
ef_len -= (ef_size + EB_HEADSIZE);
}
}
#endif
#ifdef USE_EF_UT_TIME
if (G.extra_field &&
#ifdef IZ_CHECK_TZ
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
G.crec.last_mod_dos_datetime, &z_utime, NULL)
& EB_UT_FL_MTIME))
{
TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0, Mac */
t = localtime(&(z_utime.mtime));
} else
t = (struct tm *)NULL;
if (t != (struct tm *)NULL) {
mo = (unsigned)(t->tm_mon + 1);
dy = (unsigned)(t->tm_mday);
yr = (unsigned)(t->tm_year % 100);
hh = (unsigned)(t->tm_hour);
mm = (unsigned)(t->tm_min);
} else
#endif /* USE_EF_UT_TIME */
{
yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
+ 80) % (unsigned)100);
mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
}
/* permute date so it displays according to nat'l convention
* ('methnum' is not yet set, it is used as temporary buffer) */
switch (date_format) {
case DF_YMD:
methnum = (unsigned)mo;
mo = yr; yr = dy; dy = (ush)methnum;
break;
case DF_DMY:
methnum = (unsigned)mo;
mo = dy; dy = (ush)methnum;
}
csiz = G.crec.csize;
if (G.crec.general_purpose_bit_flag & 1)
csiz -= 12; /* if encrypted, don't count encryption header */
if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
#ifndef WINDLL
sgn = '-';
#endif
cfactor = (-cfactor + 5) / 10;
} else {
#ifndef WINDLL
sgn = ' ';
#endif
cfactor = (cfactor + 5) / 10;
}
methnum = MIN(G.crec.compression_method, NUM_METHODS);
zfstrcpy(methbuf, method[methnum]);
if (methnum == DEFLATED) {
methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
} else if (methnum >= NUM_METHODS) {
sprintf(&methbuf[4], "%03u", G.crec.compression_method);
}
#if 0 /* GRR/Euro: add this? */
#if defined(DOS_FLX_OS2_W32) || defined(UNIX)
for (p = G.filename; *p; ++p)
if (!isprint(*p))
*p = '?'; /* change non-printable chars to '?' */
#endif /* DOS_FLX_OS2_W32 || UNIX */
#endif /* 0 */
#ifdef WINDLL
/* send data to application for formatting and printing */
(*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize, csiz,
(ush)cfactor, mo, dy, yr, hh, mm,
(char)(G.pInfo->lcflag ? '^' : ' '),
(LPSTR)fnfilter(G.filename, slide), (LPSTR)methbuf, G.crec.crc32,
(char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
#else /* !WINDLL */
if (cfactor == 100)
sprintf(cfactorstr, LoadFarString(CompFactor100));
else
sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr)
Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
G.crec.ucsize, methbuf, csiz, cfactorstr, mo, dy,
yr, hh, mm, G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
else
#ifdef OS2_EAS
Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
G.crec.ucsize, ea_size, acl_size,
mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
#else
Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
G.crec.ucsize,
mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
#endif
/* fnprint(__G);*/
#endif /* ?WINDLL */
if ((error = do_string(__G__ G.crec.file_comment_length,
QCOND? DISPL_8 : SKIP)) != 0)
{
error_in_archive = error; /* might be just warning */
if (error > PK_WARN) /* fatal */
return error;
}
tot_ucsize += G.crec.ucsize;
tot_csize += csiz;
++members;
#ifdef OS2_EAS
if (ea_size) {
tot_easize += ea_size;
++tot_eafiles;
}
if (acl_size) {
tot_aclsize += acl_size;
++tot_aclfiles;
}
#endif
#ifdef OS2DLL
} /* end of "if (G.processExternally) {...} else {..." */
#endif
} else { /* not listing this file */
SKIP_(G.crec.file_comment_length)
}
} /* end for-loop (j: files in central directory) */
/*---------------------------------------------------------------------------
Print footer line and totals (compressed size, uncompressed size, number
of members in zipfile).
---------------------------------------------------------------------------*/
if (uO.qflag < 2
#ifdef OS2DLL
&& !G.processExternally
#endif
) {
if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
#ifndef WINDLL
sgn = '-';
#endif
cfactor = (-cfactor + 5) / 10;
} else {
#ifndef WINDLL
sgn = ' ';
#endif
cfactor = (cfactor + 5) / 10;
}
#ifdef WINDLL
/* pass the totals back to the calling application */
G.lpUserFunctions->TotalSizeComp = tot_csize;
G.lpUserFunctions->TotalSize = tot_ucsize;
G.lpUserFunctions->CompFactor = cfactor;
G.lpUserFunctions->NumMembers = members;
#else /* !WINDLL */
if (cfactor == 100)
sprintf(cfactorstr, LoadFarString(CompFactor100));
else
sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr) {
Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
tot_ucsize, tot_csize, cfactorstr, members, members==1? "":"s"));
#ifdef OS2_EAS
if (tot_easize || tot_aclsize)
Info(slide, 0, ((char *)slide, "\n"));
if (tot_eafiles && tot_easize)
Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
tot_easize));
if (tot_aclfiles && tot_aclsize)
Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
tot_aclfiles, tot_aclfiles == 1? " has" : "s have a total of",
tot_aclsize));
#endif /* OS2_EAS */
} else
#ifdef OS2_EAS
Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
tot_ucsize, tot_easize, tot_aclsize, members, members == 1?
"" : "s"));
#else
Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
tot_ucsize, members, members == 1? "" : "s"));
#endif /* OS2_EAS */
#endif /* ?WINDLL */
}
/*---------------------------------------------------------------------------
Double check that we're back at the end-of-central-directory record.
---------------------------------------------------------------------------*/
if (readbuf(__G__ G.sig, 4) == 0) /* disk error? */
return PK_EOF;
if (strncmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN; /* didn't find sig */
}
if (members == 0 && error_in_archive <= PK_WARN)
error_in_archive = PK_FIND;
return error_in_archive;
} /* end function list_files() */
#ifdef TIMESTAMP
/************************/
/* Function fn_is_dir() */
/************************/
static int fn_is_dir(__G) /* returns TRUE if G.filename is directory */
__GDEF
{
extent fn_len = strlen(G.filename);
register char endc;
return fn_len > 0 &&
((endc = G.filename[fn_len-1]) == '/' ||
(G.pInfo->hostnum == FS_FAT_ && !strchr(G.filename, '/') &&
endc == '\\'));
}
/*****************************/
/* Function get_time_stamp() */
/*****************************/
int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
__GDEF
time_t *last_modtime;
unsigned *nmember;
{
int do_this_file=FALSE, error, error_in_archive=PK_COOL;
unsigned j;
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
min_info info;
/*---------------------------------------------------------------------------
Unlike extract_or_test_files() but like list_files(), this function works
on information in the central directory alone. Thus we have a single,
large loop through the entire directory, searching for the latest time
stamp.
---------------------------------------------------------------------------*/
*last_modtime = 0L; /* assuming no zipfile data older than 1970 */
*nmember = 0;
G.pInfo = &info;
for (j = 0; j++ < (unsigned)G.ecrec.total_entries_central_dir;) {
if (readbuf(__G__ G.sig, 4) == 0)
return PK_EOF;
if (strncmp(G.sig, central_hdr_sig, 4)) { /* just to make sure */
Info(slide, 0x401, ((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
return PK_BADERR;
}
/* process_cdir_file_hdr() sets pInfo->lcflag: */
if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
return error; /* only PK_EOF defined */
if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
{ /* ^-- (uses pInfo->lcflag) */
error_in_archive = error;
if (error > PK_WARN) /* fatal: can't continue */
return error;
}
if (G.extra_field != (uch *)NULL) {
free(G.extra_field);
G.extra_field = (uch *)NULL;
}
if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
!= 0)
{
error_in_archive = error;
if (error > PK_WARN) /* fatal */
return error;
}
if (!G.process_all_files) { /* check if specified on command line */
unsigned i;
do_this_file = FALSE;
for (i = 0; i < G.filespecs; i++)
if (match(G.filename, G.pfnames[i], uO.C_flag)) {
do_this_file = TRUE;
break; /* found match, so stop looping */
}
if (do_this_file) { /* check if this is an excluded file */
for (i = 0; i < G.xfilespecs; i++)
if (match(G.filename, G.pxnames[i], uO.C_flag)) {
do_this_file = FALSE; /* ^-- ignore case in match */
break;
}
}
}
/* If current file was specified on command line, or if no names were
* specified, check the time for this file. Either way, get rid of the
* file comment and go back for the next file.
* Directory entries are always ignored, to stay compatible with both
* Zip and PKZIP.
*/
if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
#ifdef USE_EF_UT_TIME
if (G.extra_field &&
#ifdef IZ_CHECK_TZ
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
G.crec.last_mod_dos_datetime, &z_utime, NULL)
& EB_UT_FL_MTIME))
{
if (*last_modtime < z_utime.mtime)
*last_modtime = z_utime.mtime;
} else
#endif /* USE_EF_UT_TIME */
{
time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
if (*last_modtime < modtime)
*last_modtime = modtime;
}
++*nmember;
}
SKIP_(G.crec.file_comment_length)
} /* end for-loop (j: files in central directory) */
/*---------------------------------------------------------------------------
Double check that we're back at the end-of-central-directory record.
---------------------------------------------------------------------------*/
if (readbuf(__G__ G.sig, 4) == 0)
return PK_EOF;
if (strncmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN;
}
if (*nmember == 0 && error_in_archive <= PK_WARN)
error_in_archive = PK_FIND;
return error_in_archive;
} /* end function get_time_stamp() */
#endif /* TIMESTAMP */
/********************/
/* Function ratio() */ /* also used by ZipInfo routines */
/********************/
int ratio(uc, c)
ulg uc, c;
{
ulg denom;
if (uc == 0)
return 0;
if (uc > 2000000L) { /* risk signed overflow if multiply numerator */
denom = uc / 1000L;
return ((uc >= c) ?
(int) ((uc-c + (denom>>1)) / denom) :
-((int) ((c-uc + (denom>>1)) / denom)));
} else { /* ^^^^^^^^ rounding */
denom = uc;
return ((uc >= c) ?
(int) ((1000L*(uc-c) + (denom>>1)) / denom) :
-((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
} /* ^^^^^^^^ rounding */
}
/************************/
/* Function fnprint() */ /* also used by ZipInfo routines */
/************************/
void fnprint(__G) /* print filename (after filtering) and newline */
__GDEF
{
char *name = fnfilter(G.filename, slide);
(*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
(*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
} /* end function fnprint() */

View File

@@ -0,0 +1,142 @@
#==============================================================================
# Makefile for UnZip, UnZipSFX and fUnZip: Unix and MS-DOS ("real" makes only)
# Version: 5.4 19 November 1998
#==============================================================================
# INSTRUCTIONS (such as they are):
#
# "make sunos" -- makes UnZip in current directory on a generic SunOS 4.x Sun
# "make list" -- lists all supported systems (targets)
# "make help" -- provides pointers on what targets to try if problems occur
# "make wombat" -- chokes and dies if you haven't added the specifics for your
# Wombat 68000 (or whatever) to the systems list
#
# CF are flags for the C compiler. LF are flags for the loader. LF2 are more
# flags for the loader, if they need to be at the end of the line instead of at
# the beginning (for example, some libraries). FL and FL2 are the corre-
# sponding flags for fUnZip. LOCAL_UNZIP is an environment variable that can
# be used to add default C flags to your compile without editing the Makefile
# (e.g., -DDEBUG_STRUC, or -FPi87 on PCs using Microsoft C).
#
# Some versions of make do not define the macro "$(MAKE)"; this is rare, but
# if things don't work, try using "make" instead of "$(MAKE)" in your system's
# makerule. Or try adding the following line to your .login file:
# setenv MAKE "make"
# (That never works--makes that are too stupid to define MAKE are also too
# stupid to look in the environment--but try it anyway for kicks. :-) )
#
# Memcpy and memset are provided for those systems that don't have them; they
# are in fileio.c and will be used if -DZMEM is included in CF. These days
# almost all systems have them.
#
# Be sure to test your new UnZip (and UnZipSFX and fUnZip); successful compila-
# tion does not always imply a working program.
#####################
# MACRO DEFINITIONS #
#####################
# Defaults most systems use (use LOCAL_UNZIP in environment to add flags,
# such as -DDOSWILD).
# UnZip flags
CC = cc# try using "gcc" target rather than changing this (CC and LD
LD = $(CC)# must match, else "unresolved symbol: ___main" is possible)
AS = as
LOC = $(LOCAL_UNZIP)
AF = $(LOC)
CF = -O -g -I. -I.. -I../inczip $(LOC) -I/usr/local//include -I/usr/X11R6/include -I/usr/local/lib/glib/include -DSTRICT -D__WXGTK__ -DGTK_NO_CHECK_CASTS -D_REENTRANT -D_IODBC_ -Wall
LF = -o sfx -L/usr/local/lib -L/usr/X11R6/lib -L/usr -lwx_gtk -lpng -ljpeg -lstdc++ -lgcc -lc_r -lgtk -lgdk -lgmodule -lglib -lXext -lX11 -lm -lgthread
LF2 = -s
# general-purpose stuff
#CP = cp
CP = ln
LN = ln
RM = rm -f
CHMOD = chmod
BINPERMS = 755
MANPERMS = 644
STRIP = strip
E =
O = .o
M = unix
SHELL = /bin/sh
# defaults for crc32 stuff and system dependent headers
CRC32 = crc32
# object files
OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O envargs$O explode$O
OBJS2 = extract$O fileio$O globals$O inflate$O list$O match$O
OBJS3 = process$O ttyio$O unreduce$O unshrink$O zipinfo$O
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $M$O install$O wxmain$O instsup$O
UNZIP_H = ../inczip/unzip.h ../inczip/unzpriv.h ../inczip/globals.h
# installation
# (probably can change next two to `install' and `install -d' if you have it)
INSTALL = cp
INSTALL_D = mkdir -p
###############################################
# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES #
###############################################
# this is for GNU make; comment out and notify zip-bugs if it causes errors
.SUFFIXES: .c .o .obj .pic.o
# yes, we should be able to use the $O macro to combine these two, but it
# fails on some brain-damaged makes (e.g., AIX's)...no big deal
.c.o:
$(CC) -c $(CF) $*.c
.c.obj:
$(CC) -c $(CF) $*.c
.c.pic.o:
$(CC) -c $(CF) -o $@ $*.c
all: sfx
# EDIT HERE FOR PARALLEL MAKES on Sequent (and others?)--screws up MS-DOS
# make utilities if default: change "unzip$E:" to "unzip$E:&"
sfx$E: $(OBJS) # add `&' for parallel makes
$(LD) $(LF) $(OBJS)
crc32$O: crc32.c $(UNZIP_H) ../inczip/zip.h
crctab$O: crctab.c $(UNZIP_H) ../inczip/zip.h
crypt$O: crypt.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
envargs$O: envargs.c $(UNZIP_H)
explode$O: explode.c $(UNZIP_H)
extract$O: extract.c $(UNZIP_H) ../inczip/crypt.h
fileio$O: fileio.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/ebcdic.h
funzip$O: funzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/tables.h
globals$O: globals.c $(UNZIP_H)
inflate$O: inflate.c ../inczip/inflate.h $(UNZIP_H)
list$O: list.c $(UNZIP_H)
match$O: match.c $(UNZIP_H)
process$O: process.c $(UNZIP_H)
ttyio$O: ttyio.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
unreduce$O: unreduce.c $(UNZIP_H)
unshrink$O: unshrink.c $(UNZIP_H)
unzip$O: unzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/version.h ../inczip/consts.h
zipinfo$O: zipinfo.c $(UNZIP_H)
unix$O: unix.c $(UNZIP_H) ../inczip/version.h # Unix only
$(CC) -c $(CF) unix.c
install$O: ../install.c
$(CC) -c $(CF) ../install.c
wxmain$O: ../wxmain.cpp
$(CC) -c $(CF) ../wxmain.cpp
instsup$O: ../instsup.cpp
$(CC) -c $(CF) ../instsup.cpp

View File

@@ -0,0 +1,135 @@
# Makefile for UnZip(SFX) and fUnZip for Borland C++ for Windows 95/NT
# Version: 5.4 and later Alvin Koh, Jim Knoble, Christian Spieler, etc.
# Adapted from the MS-DOS makefile by E-Yen Tan
#
# Last revised: 24 Nov 98
#
#
# Optional nonstandard preprocessor flags (as -DCHECK_EOF or -DDOS_WILD)
# should be added to the environment via "set LOCAL_UNZIP=-DFOO" or added
# to the declaration of LOC here:
LOC = $(LOCAL_UNZIP)
# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
CPU_TYP = 4
# (De)Select inclusion of optimized assembler CRC32 routine:
USE_ASMCRC = 0
# If you have bcc32i, you should define:
# CC = bcc32i
# This compiler generates a faster code.
CC = bcc32
AS = tasm32
!if $(USE_ASMCRC)
ASMFLG = -DASM_CRC
ASMOBJS = crc_i386.obj
!else
ASMFLG =
ASMOBJS =
!endif
!if $(UNCLEAN)
DIRT = -DUSE_SMITH_CODE -DUSE_UNSHRINK
!else
DIRT =
!endif
# compiler flags
ASCPUFLAG = __$(CPU_TYP)86
!if $(CPU_TYP) != 0
CC_CPUFLG = -$(CPU_TYP)
!endif
ASFLAGS = -ml -m2 -w0 -D$(ASCPUFLAG) $(LOC)
CFLAGS = -Od -w- $(CC_CPUFLG) -ff- -k- -P-.C -I. -I.. -I../inczip -I../../../include $(ASMFLG) $(LOC) $(DIRT) -v -D__WXMSW__ -DWXDEBUG=1 -D__WXDEBUG__ -DUSE_DEFINE -DWIN32 -D__WIN95__ -D__WINDOWS__ -I$(WXDIR)\include
LDFLAGS = -L$(WXWIN)\lib -aa -c # for bcc
LINK = ilink32
LIBS = wx32 cw32mt import32 ole2w32 winpng zlib jpeg xpm tiff
UNFLAGS = $(CFLAGS)
# implicit rules
.asm.obj:
$(AS) $(ASFLAGS) $<
.c.obj:
$(CC) -c $(UNFLAGS) {$< }
# list macros
OBJU1 = unzip.obj crc32.obj crctab.obj crypt.obj envargs.obj explode.obj
OBJU2 = extract.obj fileio.obj globals.obj inflate.obj list.obj match.obj
OBJU3 = process.obj ttyio.obj unreduce.obj unshrink.obj zipinfo.obj
OBJUS = win32.obj nt.obj install.obj wxmain.obj instsup.obj $(ASMOBJS)
OBJU = $(OBJU1) $(OBJU2) $(OBJU3) $(OBJUS)
UNZIP_H = ../inczip/unzip.h ../inczip/unzpriv.h ../inczip/globals.h ../inczip/w32cfg.h
# explicit rules
all: sfx.exe
sfx.exe: $(OBJU) sfx.res
$(LINK) $(LDFLAGS) @&&!
c0w32.obj $(OBJU)
sfx.exe
nul
$(LIBS)
sfx.res
!
clean:
-erase *.obj
-erase *.exe
-erase *.res
-erase *.map
-erase *.rws
-erase *.tds
-erase *.il?
# individual file dependencies
crc32.obj: crc32.c $(UNZIP_H) ../inczip/zip.h
crctab.obj: crctab.c $(UNZIP_H) ../inczip/zip.h
crypt.obj: crypt.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
envargs.obj: envargs.c $(UNZIP_H)
explode.obj: explode.c $(UNZIP_H)
extract.obj: extract.c $(UNZIP_H) ../inczip/crypt.h
fileio.obj: fileio.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/ebcdic.h
globals.obj: globals.c $(UNZIP_H)
inflate.obj: inflate.c ../inczip/inflate.h $(UNZIP_H)
list.obj: list.c $(UNZIP_H)
match.obj: match.c $(UNZIP_H)
process.obj: process.c $(UNZIP_H)
ttyio.obj: ttyio.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
unreduce.obj: unreduce.c $(UNZIP_H)
unshrink.obj: unshrink.c $(UNZIP_H)
unzip.obj: unzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/version.h ../inczip/consts.h
zipinfo.obj: zipinfo.c $(UNZIP_H)
#crc_i386.obj: win32/crc_i386.asm
# $(AS) $(ASFLAGS) win32\crc_i386.asm, $*.obj ;
win32.obj: win32.c $(UNZIP_H)
$(CC) -c $(UNFLAGS) win32.c
nt.obj: nt.c $(UNZIP_H)
$(CC) -c $(UNFLAGS) nt.c
install.obj: ../install.c $(UNZIP_H)
$(CC) -c $(UNFLAGS) ../install.c
wxmain.obj: ../wxmain.cpp $(UNZIP_H)
$(CC) -P- -c $(UNFLAGS) ../wxmain.cpp
instsup.obj: ../instsup.cpp $(UNZIP_H)
$(CC) -P- -c $(UNFLAGS) ../instsup.cpp
sfx.res : sfx.rc $(WXWIN)\include\wx\msw\wx.rc
brc32 -r /i$(BCCDIR)\include /i$(WXWIN)\include /i$(WXWIN)\contrib\include sfx

View File

@@ -0,0 +1,164 @@
# Makefile for UnZip, fUnZip and UnZipSFX for native Win32-Intel ports of gcc.
# Currently supported implementations: Cygnus/Win32 and MinGW32.
#
# First version: Cosmin Truta <cosmint@cs.ubbcluj.ro>, Dec 1997.
# Last revision: Christian Spieler, 29-Apr-1998
#
# To use, do "make -f win32/makefile.gcc".
### Optional section
# Optional nonstandard preprocessor flags (as -DUSE_ZLIB or -DUSE_SMITH_CODE)
# should be added to the environment via "set LOCAL_UNZIP=-DFOO" or added
# to the declaration of LOCFLAGS here:
LOCFLAGS = $(LOCAL_UNZIP)
### Compiler-specific section
# ------------ GNU C ------------
CC = gcc
#AS = as
AS = $(CC)
#LD = ld
LD = $(CC)
# Quiet
CC_QUIET_OPT =
AS_QUIET_OPT = $(CC_QUIET_OPT)
LD_QUIET_OPT = $(CC_QUIET_OPT)
# Warnings
CC_WARN_OPT = -Wall
AS_WARN_OPT = $(CC_WARN_OPT)
LD_WARN_OPT =
# Debug version
CC_DEBUG_OPT = -g
AS_DEBUG_OPT = $(CC_DEBUG_OPT)
LD_DEBUG_OPT = $(CC_DEBUG_OPT)
# Release version
CC_RELEASE_OPT =
AS_RELEASE_OPT =
#LD_RELEASE_OPT = -s
# Smallest code
CC_SIZE_OPT = -O1
# Fastest code
CC_SPEED_OPT = -O2
# Output object file name
CC_OUT_OPT = -o
# Other specific options
#CC_SPECIFIC_OPT = -c -DASM_CRC -DWIN32 -mno-cygwin
CC_SPECIFIC_OPT = -c -DWIN32 -I../inczip -g -I.. -D_X86_=1 -DWIN32 -D_WIN32 -DWINVER=0x0400 -D__WIN95__ -D__GNUWIN32__ -D__WIN32__ -I../../../include -I../../../src/png -I../../../src/jpeg -I../../../src/zlib -I../../../include/wx/msw/gnuwin32 -DSTRICT -D__WXMSW__ -D__WINDOWS__ -D__WXDEBUG__ -Wall -fno-pcc-struct-return -O2 -fno-rtti -fno-exceptions
AS_SPECIFIC_OPT = -c
LD_SPECIFIC_OPT = -Wl,--subsystem,windows -mwindows -L../../../lib -o $@
# Libraries for the debug & release version
LD_RELEASE_LIBS = ../../../lib/libwx.a -lpng -ljpeg -lzlib -lxpm -lstdc++ -lgcc -lwinspool -lwinmm -lshell32 -lcomctl32 -lctl3d32 -lodbc32 -ladvapi32 -lole32 -loleaut32 -luuid -lodbc32 -lwsock32
LD_DEBUG_LIBS = $(LD_RELEASE_LIBS)
### System-specific section
# Suffixes
OBJ = .o
EXE = .exe
.SUFFIXES: .c .S $(OBJ) $(EXE)
# Commands
RM = rm -f
### General section
CFLAGS = $(CC_SPECIFIC_OPT) $(CC_QUIET_OPT) $(CC_WARN_OPT) $(LOCFLAGS) \
$(CC_OUT_OPT) $@
ASFLAGS = $(AS_SPECIFIC_OPT) $(AS_QUIET_OPT) $(AS_WARN_OPT) $(LOCFLAGS)
LDFLAGS = $(LD_SPECIFIC_OPT) $(LD_QUIET_OPT) $(LD_WARN_OPT)
# To build with debug info, use 'make DEBUG=1'.
ifdef DEBUG
CVER = $(CC_DEBUG_OPT)
ASVER = $(AS_DEBUG_OPT)
LDVER = $(LD_DEBUG_OPT)
GENFLAGS =
FFLAGS = -DFUNZIP
SFXFLAGS = -DSFX
LDLIBS = $(LD_DEBUG_LIBS)
else
CVER = $(CC_RELEASE_OPT)
ASVER = $(AS_RELEASE_OPT)
LDVER = $(LD_RELEASE_OPT)
GENFLAGS = $(CC_SPEED_OPT)
FFLAGS = $(CC_SPEED_OPT) -DFUNZIP
SFXFLAGS = $(CC_SIZE_OPT) -DSFX
LDLIBS = $(LD_RELEASE_LIBS)
endif
# Object files
OBJA = crc_i386$(OBJ) install$(OBJ) wxmain$(OBJ) instsup$(OBJ)
OBJS1 = unzip$(OBJ) crc32$(OBJ) crctab$(OBJ) crypt$(OBJ) envargs$(OBJ)
OBJS2 = explode$(OBJ) extract$(OBJ) fileio$(OBJ) globals$(OBJ) inflate$(OBJ)
OBJS3 = list$(OBJ) match$(OBJ) process$(OBJ) ttyio$(OBJ) unreduce$(OBJ)
OBJS4 = unshrink$(OBJ) zipinfo$(OBJ) win32$(OBJ) nt$(OBJ)
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJA)
UNZIP_H = ../inczip/unzip.h ../inczip/unzpriv.h ../inczip/globals.h ../inczip/w32cfg.h
# Default target is all the executables
unzips: sfx$(EXE)
sfx$(EXE): $(OBJS)
$(LD) $(LDFLAGS) $(LDVER) $(OBJS) $(LDLIBS)
# How to compile sources
.c$(OBJ):
$(CC) $(CFLAGS) $(CVER) $(GENFLAGS) $<
.S$(OBJ):
$(AS) $(ASFLAGS) $(ASVER) $(GENFLAGS) $<
# Dependencies
crc32$(OBJ): crc32.c $(UNZIP_H) ../inczip/zip.h
crctab$(OBJ): crctab.c $(UNZIP_H) ../inczip/zip.h
crypt$(OBJ): crypt.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
envargs$(OBJ): envargs.c $(UNZIP_H)
explode$(OBJ): explode.c $(UNZIP_H)
extract$(OBJ): extract.c $(UNZIP_H) ../inczip/crypt.h
fileio$(OBJ): fileio.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/ebcdic.h
funzip$(OBJ): funzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/tables.h
globals$(OBJ): globals.c $(UNZIP_H)
inflate$(OBJ): inflate.c ../inczip/inflate.h $(UNZIP_H)
list$(OBJ): list.c $(UNZIP_H)
match$(OBJ): match.c $(UNZIP_H)
process$(OBJ): process.c $(UNZIP_H)
ttyio$(OBJ): ttyio.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
unreduce$(OBJ): unreduce.c $(UNZIP_H)
unshrink$(OBJ): unshrink.c $(UNZIP_H)
unzip$(OBJ): unzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/version.h ../inczip/consts.h
zipinfo$(OBJ): zipinfo.c $(UNZIP_H)
crc_i386$(OBJ): crc_i386.S
win32$(OBJ): win32.c $(UNZIP_H) ../inczip/nt.h
nt$(OBJ): nt.c ../inczip/nt.h
install$(OBJ): ../install.c
$(CC) $(CFLAGS) $(CVER) $(GENFLAGS) $<
wxmain$(OBJ): ../wxmain.cpp
$(CC) $(CFLAGS) $(CVER) $(GENFLAGS) $<
instsup$(OBJ): ../instsup.cpp
$(CC) $(CFLAGS) $(CVER) $(GENFLAGS) $<
clean:
$(RM) *$(OBJ)
$(RM) *$(EXE)

View File

@@ -0,0 +1,142 @@
#==============================================================================
# Makefile for UnZip, UnZipSFX and fUnZip: Unix and MS-DOS ("real" makes only)
# Version: 5.4 19 November 1998
#==============================================================================
# INSTRUCTIONS (such as they are):
#
# "make sunos" -- makes UnZip in current directory on a generic SunOS 4.x Sun
# "make list" -- lists all supported systems (targets)
# "make help" -- provides pointers on what targets to try if problems occur
# "make wombat" -- chokes and dies if you haven't added the specifics for your
# Wombat 68000 (or whatever) to the systems list
#
# CF are flags for the C compiler. LF are flags for the loader. LF2 are more
# flags for the loader, if they need to be at the end of the line instead of at
# the beginning (for example, some libraries). FL and FL2 are the corre-
# sponding flags for fUnZip. LOCAL_UNZIP is an environment variable that can
# be used to add default C flags to your compile without editing the Makefile
# (e.g., -DDEBUG_STRUC, or -FPi87 on PCs using Microsoft C).
#
# Some versions of make do not define the macro "$(MAKE)"; this is rare, but
# if things don't work, try using "make" instead of "$(MAKE)" in your system's
# makerule. Or try adding the following line to your .login file:
# setenv MAKE "make"
# (That never works--makes that are too stupid to define MAKE are also too
# stupid to look in the environment--but try it anyway for kicks. :-) )
#
# Memcpy and memset are provided for those systems that don't have them; they
# are in fileio.c and will be used if -DZMEM is included in CF. These days
# almost all systems have them.
#
# Be sure to test your new UnZip (and UnZipSFX and fUnZip); successful compila-
# tion does not always imply a working program.
#####################
# MACRO DEFINITIONS #
#####################
# Defaults most systems use (use LOCAL_UNZIP in environment to add flags,
# such as -DDOSWILD).
# UnZip flags
CC = cc# try using "gcc" target rather than changing this (CC and LD
LD = $(CC)# must match, else "unresolved symbol: ___main" is possible)
AS = as
LOC = $(LOCAL_UNZIP)
AF = $(LOC)
CF = -O -g -I. -I.. -I../inczip $(LOC) -I/usr/local//include -I/usr/X11R6/include -I/usr/local/lib/glib/include -DSTRICT -D__WXGTK__ -DGTK_NO_CHECK_CASTS -D_REENTRANT -D_IODBC_ -Wall
LF = -o sfx -L/usr/local/lib -L/usr/X11R6/lib -L/usr -lwx_gtk -lpng -ljpeg -lstdc++ -lgcc -lc_r -lgtk -lgdk -lgmodule -lglib -lXext -lX11 -lm -lgthread
LF2 = -s
# general-purpose stuff
#CP = cp
CP = ln
LN = ln
RM = rm -f
CHMOD = chmod
BINPERMS = 755
MANPERMS = 644
STRIP = strip
E =
O = .o
M = unix
SHELL = /bin/sh
# defaults for crc32 stuff and system dependent headers
CRC32 = crc32
# object files
OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O envargs$O explode$O
OBJS2 = extract$O fileio$O globals$O inflate$O list$O match$O
OBJS3 = process$O ttyio$O unreduce$O unshrink$O zipinfo$O
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $M$O install$O wxmain$O instsup$O
UNZIP_H = ../inczip/unzip.h ../inczip/unzpriv.h ../inczip/globals.h
# installation
# (probably can change next two to `install' and `install -d' if you have it)
INSTALL = cp
INSTALL_D = mkdir -p
###############################################
# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES #
###############################################
# this is for GNU make; comment out and notify zip-bugs if it causes errors
.SUFFIXES: .c .o .obj .pic.o
# yes, we should be able to use the $O macro to combine these two, but it
# fails on some brain-damaged makes (e.g., AIX's)...no big deal
.c.o:
$(CC) -c $(CF) $*.c
.c.obj:
$(CC) -c $(CF) $*.c
.c.pic.o:
$(CC) -c $(CF) -o $@ $*.c
all: sfx
# EDIT HERE FOR PARALLEL MAKES on Sequent (and others?)--screws up MS-DOS
# make utilities if default: change "unzip$E:" to "unzip$E:&"
sfx$E: $(OBJS) # add `&' for parallel makes
$(LD) $(LF) $(OBJS)
crc32$O: crc32.c $(UNZIP_H) ../inczip/zip.h
crctab$O: crctab.c $(UNZIP_H) ../inczip/zip.h
crypt$O: crypt.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
envargs$O: envargs.c $(UNZIP_H)
explode$O: explode.c $(UNZIP_H)
extract$O: extract.c $(UNZIP_H) ../inczip/crypt.h
fileio$O: fileio.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/ebcdic.h
funzip$O: funzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/ttyio.h ../inczip/tables.h
globals$O: globals.c $(UNZIP_H)
inflate$O: inflate.c ../inczip/inflate.h $(UNZIP_H)
list$O: list.c $(UNZIP_H)
match$O: match.c $(UNZIP_H)
process$O: process.c $(UNZIP_H)
ttyio$O: ttyio.c $(UNZIP_H) ../inczip/zip.h ../inczip/crypt.h ../inczip/ttyio.h
unreduce$O: unreduce.c $(UNZIP_H)
unshrink$O: unshrink.c $(UNZIP_H)
unzip$O: unzip.c $(UNZIP_H) ../inczip/crypt.h ../inczip/version.h ../inczip/consts.h
zipinfo$O: zipinfo.c $(UNZIP_H)
unix$O: unix.c $(UNZIP_H) ../inczip/version.h # Unix only
$(CC) -c $(CF) unix.c
install$O: ../install.c
$(CC) -c $(CF) ../install.c
wxmain$O: ../wxmain.cpp
$(CC) -c $(CF) ../wxmain.cpp
instsup$O: ../instsup.cpp
$(CC) -c $(CF) ../instsup.cpp

View File

@@ -0,0 +1,670 @@
# Makefile for UnZip, UnZipSFX and fUnZip 24 November 1998
#
# supported compilers:
# - Microsoft C, version 6.00 or higher, for use under OS/2 1.x (16-bit)
# - Watcom C/C++, version 9.0+, for use under OS/2 1.x or 2.x+ (16/32-bit)
# - emx+gcc, version 0.9c or higher, for use under OS/2 2.x+ (32-bit)
# - IBM C Set++, for use under OS/2 2.x+ (32-bit)
# - Borland C++, for use under OS/2 2.x+ (32-bit)
# - Metaware High C/C++, for use under OS/2 2.x+ (32-bit)
#
# supported cross-compilers:
# - Microsoft C, version 6.0 or 7.0, for use under DOS (16-bit)
# - Watcom C/C++, version 9.0+, for use under DOS/Win95/NT (16/32-bit)
# - GNU gcc (emx), version 0.9c or higher, for use under DOS/Win95/NT (32-bit)
#
# supported assemblers:
# - Microsoft MASM 6.00 with Microsoft C
# - Watcom WASM with Watcom C/C++
# - GNU as with GNU gcc
# To use MASM 5.x instead of MASM 6.00:
# - set AS="masm -t -Ml"
# - set ASEOL=";"
# To use, enter "{d,n}make -f os2/makefile.os2" (this makefile depends on its
# name being "makefile.os2", and it must be in the os2 subdirectory).
# Notes on Microsoft C 6.00 compilation for OS/2:
#
# The resulting programs can be used under OS/2 protected mode only, not
# under DOS. A larger stack has to be used for OS/2 because system calls
# use more stack than under DOS; 8k is recommended by Microsoft.
# Notes on IBM C Set++, Watcom C/C++, Borland C++ or emx+gcc compilation:
#
# The resulting programs can be used under protected mode of OS/2 2.x or
# higher only, not under OS/2 1.x and not under DOS.
#
# The NFLAGS macro is used to work around an optimization bug in the IBM
# C++ Set compiler; this is fixed by CSD #4, so NFLAGS="" can be used for
# all targets below.
# Notes on Watcom C/C++ compilation for DOS with the PMODE/W extender:
#
# You need to add the following section to your \watcom\binb\wlsystem.lnk
# file and also need to copy pmodew.exe to the same directory:
#
# system begin pmodew
# option osname='PMODE/W'
# libpath %WATCOM%\lib386
# libpath %WATCOM%\lib386\dos
# op stub=pmodew.exe
# format os2 le
# end
#
# PMODE/W 1.16 or higher is required. See also msdos/README for important
# notes about PMODE/W bugs.
default:
@echo "Enter `$(MAKE) -f os2/makefile.os2 target' from the main"
@echo "UnZip directory, where target is one of:"
@echo " msc mscdebug mscdos ibm ibmdyn ibmdebug ibmprof"
@echo " ibmdll ibmdyndll ibmdebugdll ibmprofdll"
@echo " metaware borland gcc gccdyn gccdebug gccdos gccwin32"
@echo " watcom watcom16 watcomdos watcom16dos pmodew watcomwin32"
# MS C 6.00 for OS/2, 16-bit (should figure out way to split unzip/funzip
# compiles so former is always large model and latter always small model...)
msc:
$(MAKE) -f os2/makefile.os2 all \
CC="cl -nologo -AL -Ocegit -Gs -I. $(FP)" \
CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="ml -nologo -c -Zm -Cp" \
ASFLAGS="-D__LARGE__ -D__286" \
LDFLAGS="-F 2000 -Lp -Fe" \
LDFLAGS2="-link /noe" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i86" \
CRC32F="crc_i86" \
CRC32X="crc_i86" \
DEF="os2\unzip.def"
# MS C 6.00 for OS/2, debug version
mscdebug:
$(MAKE) -f os2/makefile.os2 all \
CC="cl -nologo -AL -Zi -Od -I. $(FP)" \
CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="ml -nologo -c -Zim -Cp" \
ASFLAGS="-D__LARGE__ -D__286" \
LDFLAGS="-F 2000 -Lp -Fe" \
LDFLAGS2="-link /noe" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i86" \
CRC32F="crc_i86" \
CRC32X="crc_i86" \
DEF="os2\unzip.def"
# cross-compilation for MS-DOS with MS C 6.00 (same comment as above...formerly;
# now unzip is medium model again, with [almost] all strings in far memory)
mscdos:
$(MAKE) -f os2/makefile.os2 all \
CC="cl -nologo -AM -Oaict -Gs -I. $(FP)" \
CFLAGS="-Zp1 -W3 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="ml -nologo -c -Zm -Cp" \
ASFLAGS="-D__MEDIUM__" \
LDFLAGS="-F 0C00 -Lr -Fe" \
LDFLAGS2="-link /noe /exe" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i86" \
CRC32F="crc_i86" \
CRC32X="crc_i86" \
OBJU2="msdos.obj" \
OBJX2="msdos_.obj" \
OSDEP_H="msdos/doscfg.h"
# IBM C Set, statically linked runtime
ibm:
$(MAKE) -f os2/makefile.os2 all \
CC="icc -Q -O -Gs -I." \
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-B/ST:0x50000 -Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DEF="os2\unzip.def"
# IBM C Set, dynamically linked runtime
ibmdyn:
$(MAKE) -f os2/makefile.os2 all \
CC="icc -Q -O -Gs -Gd -I." \
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-B/ST:0x50000 -Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DEF="os2\unzip.def"
# IBM C Set, debug version
ibmdebug:
$(MAKE) -f os2/makefile.os2 all \
CC="icc -Q -Ti -I." \
CFLAGS="-Sm -Sp1 -D__DEBUG_ALLOC__ -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-B/ST:0x50000 -Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DEF="os2\unzip.def"
# IBM C Set, profiling version for PROFIT
ibmprof:
$(MAKE) -f os2/makefile.os2 all \
CC="icc -Q -O -Gs -Gh -Ti -I." \
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-B/ST:0x50000 -Fe" \
LDFLAGS2="cppopa3.obj" \
OUT="-Fo" \
OBJ=".obj" \
DEF="os2\unzip.def"
# IBM C Set, statically linked runtime
ibmdll:
$(MAKE) -f os2/makefile.os2 dll \
CC="icc -Q -O -Gs -I." \
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \
LDFLAGS="-Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DLLDEF="os2\rexxapi.def" \
STUBDEF="os2\stub.def" \
DEF="os2\unzip.def" \
APILIB="REXX.lib"
# IBM C Set, dynamically linked runtime
ibmdyndll:
$(MAKE) -f os2/makefile.os2 dll \
CC="icc -Q -O -Gs -Gd -I." \
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \
LDFLAGS="-Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DLLDEF="os2\rexxapi.def" \
STUBDEF="os2\stub.def" \
DEF="os2\unzip.def" \
APILIB="REXX.lib"
# IBM C Set, debug version
ibmdebugdll:
$(MAKE) -f os2/makefile.os2 dll \
CC="icc -Q -Ti -I." \
CFLAGS="-Sm -Sp1 -D__DEBUG_ALLOC__ -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \
LDFLAGS="-Fe" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
DLLDEF="os2\rexxapi.def" \
STUBDEF="os2\stub.def" \
DEF="os2\unzip.def" \
APILIB="REXX.lib"
# IBM C Set, profiling version for PROFIT
ibmprofdll:
$(MAKE) -f os2/makefile.os2 dll \
CC="icc -Q -O -Gs -Gh -Ti -I." \
CFLAGS="-Gm -Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \
LDFLAGS="-Fe" \
LDFLAGS2="profit.obj" \
OUT="-Fo" \
OBJ=".obj" \
DLLDEF="os2\rexxapi.def" \
STUBDEF="os2\stub.def" \
DEF="os2\unzip.def" \
APILIB="REXX.lib"
# Watcom C/386 9.0 or higher
watcom:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl386 -bt=os2v2 -zq -Ox -s -I." \
CFLAGS="-Zp1 -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=os2v2 -zq -3 -mf" \
ASFLAGS="" \
LDFLAGS="-k0x50000 -x -l=os2v2 -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i386" \
CRC32F="crc_i386" \
CRC32X="crc_i386" \
DEF="" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# Watcom C/286 9.0 or higher
watcom16:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl -bt=os2 -zq -ml -Ox -s -I." \
CFLAGS="-Zp1 -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=os2 -zq -2 -ml" \
ASFLAGS="" \
LDFLAGS="-k0x2000 -x -l=os2 -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i86" \
CRC32F="crc_i86" \
CRC32X="crc_i86" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# Watcom C/386 9.0 or higher, crosscompilation for DOS, DOS4GW extender
watcomdos:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl386 -bt=dos4g -zq -Ox -s -I." \
CFLAGS="-Zp1 -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=dos4g -zq -3 -mf" \
ASFLAGS="" \
LDFLAGS="-k0x50000 -x -l=dos4g -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i386" \
CRC32F="crc_i386" \
CRC32X="crc_i386" \
OBJU2="msdos.obj" \
OBJX2="msdos_.obj" \
OSDEP_H="msdos/doscfg.h" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# Watcom C/386 9.0 or higher, crosscompilation for DOS, PMODE/W extender
pmodew:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl386 -bt=dos4g -zq -Ox -s -I." \
CFLAGS="-Zp1 -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=dos4g -zq -3 -mf" \
ASFLAGS="" \
LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
CRC32="crc_i386" \
CRC32F="crc_i386" \
CRC32X="crc_i386" \
OBJU2="msdos.obj" \
OBJX2="msdos_.obj" \
OSDEP_H="msdos/doscfg.h" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# Watcom C/286 9.0 or higher, crosscompilation for DOS
watcom16dos:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl -bt=dos -zq -ml -Ox -s -I." \
CFLAGS="-Zp1 -DMSDOS $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=dos -0 -mm" \
ASFLAGS="-D__MEDIUM__" \
LDFLAGS="-k0xC00 -x -l=dos -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
OBJU2="msdos.obj" \
OBJX2="msdos_.obj" \
OSDEP_H="msdos/doscfg.h" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# Watcom C/386 9.0 or higher, crosscompilation for Win95/NT
watcomwin32:
$(MAKE) -f os2/makefile.os2 all \
CC="wcl386 -bt=NT -zq -Ox -s -I." \
CFLAGS="-Zp1 -DWIN32 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="wasm -bt=NT -zq -3 -mf" \
ASFLAGS="" \
LDFLAGS="-k0x50000 -x -l=NT -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
OBJU2="win32.obj nt.obj" \
OBJX2="win32_.obj nt_.obj" \
CRC32="crc_i386" \
CRC32F="crc_i386" \
CRC32X="crc_i386" \
DEF="" \
DIRSEP="\\" \
AS_DIRSEP="\\"
# MetaWare High C/C++ 3.2
metaware:
$(MAKE) -f os2/makefile.os2 all \
CC="hc -O2 -I." \
CFLAGS="-D__32BIT__ -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-o " \
LDFLAGS2="" \
OUT="-o ./" \
OBJ=".obj" \
DEF="-Hdef=os2\unzip.def"
# Borland C++
borland:
$(MAKE) -f os2/makefile.os2 all \
CC="bcc -O -I. -Ios2" \
CFLAGS="-w- -D__cdecl -D__32BIT__ -DOS2 $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
LDFLAGS="-e" \
LDFLAGS2="" \
OUT="-o" \
OBJ=".obj" \
DEF="-sDos2\unzip.def"
# emx, gcc, OMF format, statically linked C runtime
gcc:
$(MAKE) -f os2/makefile.os2 all \
CC="gcc -Zomf -O -I." \
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="gcc -Zomf" \
ASFLAGS="-Di386" \
LDFLAGS="-o ./" \
LDFLAGS2="-Zsmall-conv -Zstack 320 -Zsys -s" \
OUT="-o" \
OBJ=".obj" \
CRC32="crc_gcc" \
CRC32F="crc_gcc" \
CRC32X="crc_gcc" \
DEF="os2/unzip.def"
# emx, gcc, OMF format, dynamically linked C runtime
gccdyn:
$(MAKE) -f os2/makefile.os2 all \
CC="gcc -Zomf -O -I." \
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="gcc -Zomf" \
ASFLAGS="-Di386" \
LDFLAGS="-o ./" \
LDFLAGS2="-Zstack 320 -Zcrtdll -s" \
OUT="-o" \
OBJ=".obj" \
CRC32="crc_gcc" \
CRC32F="crc_gcc" \
CRC32X="crc_gcc" \
DEF="os2/unzip.def"
# emx, gcc, a.out format, with debug info for gdb
gccdebug:
$(MAKE) -f os2/makefile.os2 all \
CC="gcc -g -I." \
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="gcc -g" \
ASFLAGS="-Di386" \
LDFLAGS="-o ./" \
LDFLAGS2="-Zsmall-conv" \
OUT="-o" \
OBJ=".o" \
CRC32="crc_gcc" \
CRC32F="crc_gcc" \
CRC32X="crc_gcc"
# emx, gcc, a.out format, cross-compilation for MS-DOS
gccdos:
$(MAKE) -f os2/makefile.os2 all \
CC="gcc -O -I." \
CFLAGS="-Wall -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="gcc" \
ASFLAGS="-Di386" \
LDFLAGS="-o ./" \
LDFLAGS2="-Zsmall-conv -s" \
OUT="-o" \
OBJ=".o" \
CRC32="crc_gcc" \
CRC32F="crc_gcc" \
CRC32X="crc_gcc" \
OBJU2="msdos.o" \
OBJX2="msdos_.o" \
OSDEP_H="msdos/doscfg.h"
# emx, gcc, RSXNT, cross-compilation for Win32, statically linked C runtime
gccwin32:
$(MAKE) -f os2/makefile.os2 all \
CC="gcc -Zwin32 -O2 -I." \
CFLAGS="-Wall -DWIN32 -DASM_CRC $(LOCAL_UNZIP)" \
NFLAGS="" \
DLLFLAG="" \
AS="gcc" \
ASFLAGS="-Di386" \
LDFLAGS="-Zsys -o ./" \
LDFLAGS2="-ladvapi32 -Zsmall-conv -s" \
OUT="-o" \
OBJ=".o" \
CRC32="crc_gcc" \
CRC32F="crc_gcc" \
CRC32X="crc_gcc" \
OBJU2="win32.o nt.o" \
OBJX2="win32_.o nt_.o" \
OBJF2="win32f.o" \
OSDEP_H="win32/w32cfg.h"
# variables
# LOCAL_UNZIP = -DREENTRANT
# default settings for target dependent macros:
DIRSEP = /
AS_DIRSEP = /
OSDEP_H = os2/os2data.h os2/os2cfg.h
CRC32 = crc32
CRC32F = crc32f
CRC32X = crc32_
OBJU = unzip$(OBJ) $(CRC32)$(OBJ) crctab$(OBJ) crypt$(OBJ) envargs$(OBJ) \
explode$(OBJ) extract$(OBJ) fileio$(OBJ) globals$(OBJ) \
inflate$(OBJ) list$(OBJ) match$(OBJ) process$(OBJ) ttyio$(OBJ) \
unreduce$(OBJ) unshrink$(OBJ) zipinfo$(OBJ)
OBJU2 = os2$(OBJ) os2acl$(OBJ)
OBJX = unzipsf_$(OBJ) $(CRC32X)$(OBJ) crctab_$(OBJ) crypt_$(OBJ) \
extract_$(OBJ) fileio_$(OBJ) globals_$(OBJ) inflate_$(OBJ) \
match_$(OBJ) process_$(OBJ) ttyio_$(OBJ)
OBJX2 = os2_$(OBJ) os2acl_$(OBJ)
OBJDLL= api$(OBJ) apihelp$(OBJ) rexxhelp$(OBJ) rexxapi$(OBJ)
OBJF = funzip$(OBJ) $(CRC32F)$(OBJ) cryptf$(OBJ) inflatef$(OBJ) \
globalsf$(OBJ) ttyiof$(OBJ)
OBJF2 =
UNZIP_H = unzip.h unzpriv.h globals.h $(OSDEP_H)
# rules
.SUFFIXES: .c .asm $(OBJ)
.c$(OBJ):
$(CC) -c $(CFLAGS) $(DLLFLAG) $<
.asm$(OBJ):
$(AS) $(ASFLAGS) $< $(ASEOL)
# targets
all: unzip.exe funzip.exe unzipsfx.exe
dll: unzip32.dll unzip.stb funzip.exe unzipsfx.exe
unzip.exe: $(OBJU) $(OBJU2)
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJU) $(OBJU2) $(LDFLAGS2)
funzip.exe: $(OBJF) $(OBJF2)
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJF) $(OBJF2) $(LDFLAGS2)
unzipsfx.exe: $(OBJX) $(OBJX2)
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJX) $(OBJX2) $(LDFLAGS2)
unzip32.dll: $(DLLDEF) $(OBJU) $(OBJU2) $(OBJDLL)
$(CC) $(DLLFLAG) $(LDFLAGS)$@ $(DLLDEF) $(OBJU) $(OBJDLL) $(OBJU2) $(APILIB) $(LDFLAGS2)
unzip.stb: unzipstb$(OBJ) $(STUBDEF)
$(CC) $(LDFLAGS)$@ $(STUBDEF) unzipstb$(OBJ) $(LDFLAGS2)
copy unzip.stb unzip.exe
# dependencies
apihelp$(OBJ): apihelp.c $(UNZIP_H) version.h
crc32$(OBJ): crc32.c $(UNZIP_H) zip.h
crctab$(OBJ): crctab.c $(UNZIP_H) zip.h
envargs$(OBJ): envargs.c $(UNZIP_H)
explode$(OBJ): explode.c $(UNZIP_H)
extract$(OBJ): extract.c $(UNZIP_H) crypt.h
fileio$(OBJ): fileio.c $(UNZIP_H) crypt.h ttyio.h ebcdic.h
globals$(OBJ): globals.c $(UNZIP_H)
inflate$(OBJ): inflate.c $(UNZIP_H)
list$(OBJ): list.c $(UNZIP_H)
match$(OBJ): match.c $(UNZIP_H)
process$(OBJ): process.c $(UNZIP_H)
ttyio$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h
unreduce$(OBJ): unreduce.c $(UNZIP_H)
unshrink$(OBJ): unshrink.c $(UNZIP_H)
unzip$(OBJ): unzip.c $(UNZIP_H) crypt.h version.h consts.h
api$(OBJ): api.c $(UNZIP_H) version.h
zipinfo$(OBJ): zipinfo.c $(UNZIP_H)
funzip$(OBJ): funzip.c $(UNZIP_H) crypt.h ttyio.h tables.h # funzip only
$(CC) -c $(CFLAGS) funzip.c
unzipstb$(OBJ): unzipstb.c # DLL version
$(CC) -c $(CFLAGS) unzipstb.c
msdos$(OBJ): msdos/msdos.c $(UNZIP_H) version.h # DOS only
$(CC) -c $(CFLAGS) msdos$(DIRSEP)msdos.c
msdos_$(OBJ): msdos/msdos.c $(UNZIP_H) # DOS unzipsfx
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ msdos$(DIRSEP)msdos.c
win32$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h version.h # Win32 only
$(CC) -c $(CFLAGS) win32$(DIRSEP)win32.c
nt$(OBJ): win32/nt.c $(UNZIP_H) win32/nt.h # Win32 only
$(CC) -c $(CFLAGS) win32$(DIRSEP)nt.c
win32_$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h # Win32 unzipsfx
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ win32$(DIRSEP)win32.c
nt_$(OBJ): win32/nt.c $(UNZIP_H) win32/nt.h # Win32 unzipsfx
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ win32$(DIRSEP)nt.c
win32f$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h # Win32 funzip
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ win32$(DIRSEP)win32.c
os2$(OBJ): os2/os2.c $(UNZIP_H) version.h # OS/2 only
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)os2.c
os2_$(OBJ): os2/os2.c $(UNZIP_H) # OS/2 unzipsfx
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ os2$(DIRSEP)os2.c
os2acl$(OBJ): os2/os2acl.c $(UNZIP_H) version.h # OS/2 only
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)os2acl.c
os2acl_$(OBJ): os2/os2acl.c $(UNZIP_H) version.h # OS/2 unzipsfx
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ os2$(DIRSEP)os2acl.c
rexxhelp$(OBJ): os2/rexxhelp.c # OS/2 DLL only
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)rexxhelp.c
rexxapi$(OBJ): os2/rexxapi.c # OS/2 DLL only
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)rexxapi.c
crc_i86$(OBJ): msdos/crc_i86.asm # 16bit only
$(AS) $(ASFLAGS) msdos$(AS_DIRSEP)crc_i86.asm $(ASEOL)
crc_i386$(OBJ): win32/crc_i386.asm # 32bit, MASM
$(AS) $(ASFLAGS) win32$(AS_DIRSEP)crc_i386.asm $(ASEOL)
crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
$(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
# NFLAGS are solely used as work-around for optimization bug in IBM C++ Set
crypt$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $(DLLFLAG) $(NFLAGS) crypt.c
cryptf$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h ttyio.h # funzip only
$(CC) -c $(CFLAGS) $(NFLAGS) -DFUNZIP $(OUT)$@ crypt.c
crc32f$(OBJ): crc32.c $(UNZIP_H) zip.h # funzip only
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ crc32.c
globalsf$(OBJ): globals.c $(UNZIP_H) # funzip only
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ globals.c
inflatef$(OBJ): inflate.c inflate.h $(UNZIP_H) crypt.h # funzip only
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ inflate.c
ttyiof$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h # funzip only
$(CC) -c $(CFLAGS) $(NFLAGS) -DFUNZIP $(OUT)$@ ttyio.c
crc32_$(OBJ): crc32.c $(UNZIP_H) zip.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ crc32.c
crctab_$(OBJ): crctab.c $(UNZIP_H) zip.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ crctab.c
crypt_$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h ttyio.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ crypt.c
extract_$(OBJ): extract.c $(UNZIP_H) crypt.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ extract.c
fileio_$(OBJ): fileio.c $(UNZIP_H) crypt.h ttyio.h ebcdic.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ fileio.c
globals_$(OBJ): globals.c $(UNZIP_H) # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ globals.c
inflate_$(OBJ): inflate.c inflate.h $(UNZIP_H) crypt.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ inflate.c
match_$(OBJ): match.c $(UNZIP_H) # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ match.c
process_$(OBJ): process.c $(UNZIP_H) # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ process.c
ttyio_$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ ttyio.c
unzipsf_$(OBJ): unzip.c $(UNZIP_H) crypt.h version.h consts.h # unzipsfx only
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ unzip.c

View File

@@ -0,0 +1,294 @@
/*---------------------------------------------------------------------------
match.c
The match() routine recursively compares a string to a "pattern" (regular
expression), returning TRUE if a match is found or FALSE if not. This
version is specifically for use with unzip.c: as did the previous match()
routines from SEA and J. Kercheval, it leaves the case (upper, lower, or
mixed) of the string alone, but converts any uppercase characters in the
pattern to lowercase if indicated by the global var pInfo->lcflag (which
is to say, string is assumed to have been converted to lowercase already,
if such was necessary).
GRR: reversed order of text, pattern in matche() (now same as match());
added ignore_case/ic flags, Case() macro.
PaulK: replaced matche() with recmatch() from Zip, modified to have an
ignore_case argument; replaced test frame with simpler one.
---------------------------------------------------------------------------
Copyright on recmatch() from Zip's util.c (although recmatch() was almost
certainly written by Mark Adler...ask me how I can tell :-) ):
Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
Kai Uwe Rommel and Igor Mandrichenko.
Permission is granted to any individual or institution to use, copy,
or redistribute this software so long as all of the original files are
included unmodified, that it is not sold for profit, and that this copy-
right notice is retained.
---------------------------------------------------------------------------
Match the pattern (wildcard) against the string (fixed):
match(string, pattern, ignore_case);
returns TRUE if string matches pattern, FALSE otherwise. In the pattern:
`*' matches any sequence of characters (zero or more)
`?' matches any single character
[SET] matches any character in the specified set,
[!SET] or [^SET] matches any character not in the specified set.
A set is composed of characters or ranges; a range looks like ``character
hyphen character'' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
characters allowed in the [..] pattern construct. Other characters are
allowed (i.e., 8-bit characters) if your system will support them.
To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
side or outside a [..] construct, and match the character exactly, precede
it with a ``\'' (backslash).
Note that "*.*" and "*." are treated specially under MS-DOS if DOSWILD is
defined. See the DOSWILD section below for an explanation. Note also
that with VMSWILD defined, '%' is used instead of '?', and sets (ranges)
are delimited by () instead of [].
---------------------------------------------------------------------------*/
/* define ToLower() in here (for Unix, define ToLower to be macro (using
* isupper()); otherwise just use tolower() */
#define UNZIP_INTERNAL
#include "unzip.h"
#if 0 /* this is not useful until it matches Amiga names insensitively */
#ifdef AMIGA /* some other platforms might also want to use this */
# define ANSI_CHARSET /* MOVE INTO UNZIP.H EVENTUALLY */
#endif
#endif /* 0 */
#ifdef ANSI_CHARSET
# ifdef ToLower
# undef ToLower
# endif
/* uppercase letters are values 41 thru 5A, C0 thru D6, and D8 thru DE */
# define IsUpper(c) (c>=0xC0 ? c<=0xDE && c!=0xD7 : c>=0x41 && c<=0x5A)
# define ToLower(c) (IsUpper((uch) c) ? (unsigned) c | 0x20 : (unsigned) c)
#endif
#define Case(x) (ic? ToLower(x) : (x))
#ifdef VMSWILD
# define WILDCHAR '%'
# define BEG_RANGE '('
# define END_RANGE ')'
#else
# define WILDCHAR '?'
# define BEG_RANGE '['
# define END_RANGE ']'
#endif
#if 0 /* GRR: add this to unzip.h someday... */
#if !(defined(MSDOS) && defined(DOSWILD))
#define match(s,p,ic) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic) == 1)
int recmatch OF((ZCONST uch *pattern, ZCONST uch *string, int ignore_case));
#endif
#endif /* 0 */
static int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
int ignore_case));
/* match() is a shell to recmatch() to return only Boolean values. */
int match(string, pattern, ignore_case)
ZCONST char *string, *pattern;
int ignore_case;
{
#if (defined(MSDOS) && defined(DOSWILD))
char *dospattern;
int j = strlen(pattern);
/*---------------------------------------------------------------------------
Optional MS-DOS preprocessing section: compare last three chars of the
wildcard to "*.*" and translate to "*" if found; else compare the last
two characters to "*." and, if found, scan the non-wild string for dots.
If in the latter case a dot is found, return failure; else translate the
"*." to "*". In either case, continue with the normal (Unix-like) match
procedure after translation. (If not enough memory, default to normal
match.) This causes "a*.*" and "a*." to behave as MS-DOS users expect.
---------------------------------------------------------------------------*/
if ((dospattern = (char *)malloc(j+1)) != NULL) {
strcpy(dospattern, pattern);
if (!strcmp(dospattern+j-3, "*.*")) {
dospattern[j-2] = '\0'; /* nuke the ".*" */
} else if (!strcmp(dospattern+j-2, "*.")) {
char *p = strchr(string, '.');
if (p) { /* found a dot: match fails */
free(dospattern);
return 0;
}
dospattern[j-1] = '\0'; /* nuke the end "." */
}
j = recmatch((uch *)dospattern, (uch *)string, ignore_case);
free(dospattern);
return j == 1;
} else
#endif /* MSDOS && DOSWILD */
return recmatch((uch *)pattern, (uch *)string, ignore_case) == 1;
}
static int recmatch(p, s, ic)
ZCONST uch *p; /* sh pattern to match */
ZCONST uch *s; /* string to which to match it */
int ic; /* true for case insensitivity */
/* Recursively compare the sh pattern p with the string s and return 1 if
* they match, and 0 or 2 if they don't or if there is a syntax error in the
* pattern. This routine recurses on itself no more deeply than the number
* of characters in the pattern. */
{
unsigned int c; /* pattern char or start of range in [-] loop */
/* Get first character, the pattern for new recmatch calls follows */
c = *p++;
/* If that was the end of the pattern, match if string empty too */
if (c == 0)
return *s == 0;
/* '?' (or '%') matches any character (but not an empty string) */
if (c == WILDCHAR)
return *s ? recmatch(p, s + 1, ic) : 0;
/* '*' matches any number of characters, including zero */
#ifdef AMIGA
if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
c = '*', p++;
#endif /* AMIGA */
if (c == '*') {
if (*p == 0)
return 1;
for (; *s; s++)
if ((c = recmatch(p, s, ic)) != 0)
return (int)c;
return 2; /* 2 means give up--match will return false */
}
/* Parse and process the list of characters and ranges in brackets */
if (c == BEG_RANGE) {
int e; /* flag true if next char to be taken literally */
ZCONST uch *q; /* pointer to end of [-] group */
int r; /* flag true to match anything but the range */
if (*s == 0) /* need a character to match */
return 0;
p += (r = (*p == '!' || *p == '^')); /* see if reverse */
for (q = p, e = 0; *q; q++) /* find closing bracket */
if (e)
e = 0;
else
if (*q == '\\') /* GRR: change to ^ for MS-DOS, OS/2? */
e = 1;
else if (*q == END_RANGE)
break;
if (*q != END_RANGE) /* nothing matches if bad syntax */
return 0;
for (c = 0, e = *p == '-'; p < q; p++) { /* go through the list */
if (e == 0 && *p == '\\') /* set escape flag if \ */
e = 1;
else if (e == 0 && *p == '-') /* set start of range if - */
c = *(p-1);
else {
unsigned int cc = Case(*s);
if (*(p+1) != '-')
for (c = c ? c : *p; c <= *p; c++) /* compare range */
if ((unsigned)Case(c) == cc) /* typecast for MSC bug */
return r ? 0 : recmatch(q + 1, s + 1, ic);
c = e = 0; /* clear range, escape flags */
}
}
return r ? recmatch(q + 1, s + 1, ic) : 0; /* bracket match failed */
}
/* if escape ('\'), just compare next character */
if (c == '\\' && (c = *p++) == 0) /* if \ at end, then syntax error */
return 0;
/* just a character--compare it */
#ifdef QDOS
return QMatch(Case((uch)c), Case(*s)) ? recmatch(p, ++s, ic) : 0;
#else
return Case((uch)c) == Case(*s) ? recmatch(p, ++s, ic) : 0;
#endif
} /* end function recmatch() */
int iswild(p) /* originally only used for stat()-bug workaround in */
ZCONST char *p; /* VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
{ /* now used in process_zipfiles() as well */
for (; *p; ++p)
if (*p == '\\' && *(p+1))
++p;
#ifdef VMS
else if (*p == '%' || *p == '*')
#else /* !VMS */
#ifdef AMIGA
else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
#else /* !AMIGA */
else if (*p == '?' || *p == '*' || *p == '[')
#endif /* ?AMIGA */
#endif /* ?VMS */
#ifdef QDOS
return (int)p;
#else
return TRUE;
#endif
return FALSE;
} /* end function iswild() */
#ifdef TEST_MATCH
#define put(s) {fputs(s,stdout); fflush(stdout);}
void main()
{
char pat[256], str[256];
for (;;) {
put("Pattern (return to exit): ");
gets(pat);
if (!pat[0])
break;
for (;;) {
put("String (return for new pattern): ");
gets(str);
if (!str[0])
break;
pipeit("Case sensitive: %s insensitive: %s\n",
match(str, pat, 0) ? "YES" : "NO",
match(str, pat, 1) ? "YES" : "NO");
}
}
EXIT(0);
}
#endif /* TEST_MATCH */

659
utils/Install/sfxzip/nt.c Normal file
View File

@@ -0,0 +1,659 @@
/*
Copyright (c) 1996 Scott Field
Module Name:
nt.c
Abstract:
This module implements WinNT security descriptor operations for the
Win32 Info-ZIP project. Operation such as setting file security,
using/querying local and remote privileges, and queuing of operations
is performed here. The contents of this module are only relevant
when the code is running on Windows NT, and the target volume supports
persistent Acl storage.
User privileges that allow accessing certain privileged aspects of the
security descriptor (such as the Sacl) are only used if the user specified
to do so.
Author:
Scott Field (sfield@microsoft.com)
Last revised: 18 Jan 97
*/
#define WIN32_LEAN_AND_MEAN
#define UNZIP_INTERNAL
#include "unzip.h"
#include <windows.h>
#ifdef __RSXNT__
# include "rsxntwin.h"
#endif
#include "nt.h"
#ifdef NTSD_EAS /* This file is only needed for NTSD handling */
/* Borland C++ does not define FILE_SHARE_DELETE. Others also? */
#ifndef FILE_SHARE_DELETE
# define FILE_SHARE_DELETE 0x00000004
#endif
/* private prototypes */
static BOOL Initialize(VOID);
#if 0 /* currently unused */
static BOOL Shutdown(VOID);
#endif
static BOOL DeferSet(char *resource, PVOLUMECAPS VolumeCaps, uch *buffer);
static VOID GetRemotePrivilegesSet(CHAR *FileName, PDWORD dwRemotePrivileges);
static VOID InitLocalPrivileges(VOID);
BOOL bInitialized = FALSE; /* module level stuff initialized? */
HANDLE hInitMutex = NULL; /* prevent multiple initialization */
BOOL g_bRestorePrivilege = FALSE; /* for local set file security override */
BOOL g_bSaclPrivilege = FALSE; /* for local set sacl operations, only when
restore privilege not present */
/* our single cached volume capabilities structure that describes the last
volume root we encountered. A single entry like this works well in the
zip/unzip scenario for a number of reasons:
1. typically one extraction path during unzip.
2. typically process one volume at a time during zip, and then move
on to the next.
3. no cleanup code required and no memory leaks.
4. simple code.
This approach should be reworked to a linked list approach if we expect to
be called by many threads which are processing a variety of input/output
volumes, since lock contention and stale data may become a bottleneck. */
VOLUMECAPS g_VolumeCaps;
CRITICAL_SECTION VolumeCapsLock;
/* our deferred set structure linked list element, used for making a copy
of input data which is used at a later time to process the original input
at a time when it makes more sense. eg, applying security to newly created
directories, after all files have been placed in such directories. */
CRITICAL_SECTION SetDeferLock;
typedef struct _DEFERRED_SET {
struct _DEFERRED_SET *Next;
uch *buffer; /* must point to DWORD aligned block */
PVOLUMECAPS VolumeCaps;
char *resource;
} DEFERRED_SET, *PDEFERRED_SET, *LPDEFERRED_SET;
PDEFERRED_SET pSetHead = NULL;
PDEFERRED_SET pSetTail;
static BOOL Initialize(VOID)
{
HANDLE hMutex;
HANDLE hOldMutex;
if(bInitialized) return TRUE;
hMutex = CreateMutex(NULL, TRUE, NULL);
if(hMutex == NULL) return FALSE;
hOldMutex = (HANDLE)InterlockedExchange((LPLONG)&hInitMutex, (LONG)hMutex);
if(hOldMutex != NULL) {
/* somebody setup the mutex already */
InterlockedExchange((LPLONG)&hInitMutex, (LONG)hOldMutex);
CloseHandle(hMutex); /* close new, un-needed mutex */
/* wait for initialization to complete and return status */
WaitForSingleObject(hOldMutex, INFINITE);
ReleaseMutex(hOldMutex);
return bInitialized;
}
/* initialize module level resources */
InitializeCriticalSection( &SetDeferLock );
InitializeCriticalSection( &VolumeCapsLock );
memset(&g_VolumeCaps, 0, sizeof(VOLUMECAPS));
InitLocalPrivileges();
bInitialized = TRUE;
ReleaseMutex(hMutex); /* release correct mutex */
return TRUE;
}
#if 0 /* currently not used ! */
static BOOL Shutdown(VOID)
{
/* really need to free critical sections, disable enabled privilges, etc,
but doing so brings up possibility of race conditions if those resources
are about to be used. The easiest way to handle this is let these
resources be freed when the process terminates... */
return TRUE;
}
#endif /* never */
static BOOL DeferSet(char *resource, PVOLUMECAPS VolumeCaps, uch *buffer)
{
PDEFERRED_SET psd;
DWORD cbDeferSet;
DWORD cbResource;
DWORD cbBuffer;
if(!bInitialized) if(!Initialize()) return FALSE;
cbResource = lstrlenA(resource) + 1;
cbBuffer = GetSecurityDescriptorLength((PSECURITY_DESCRIPTOR)buffer);
cbDeferSet = sizeof(DEFERRED_SET) + cbBuffer + sizeof(VOLUMECAPS) +
cbResource;
psd = (PDEFERRED_SET)HeapAlloc(GetProcessHeap(), 0, cbDeferSet);
if(psd == NULL) return FALSE;
psd->Next = NULL;
psd->buffer = (uch *)(psd+1);
psd->VolumeCaps = (PVOLUMECAPS)((char *)psd->buffer + cbBuffer);
psd->resource = (char *)((char *)psd->VolumeCaps + sizeof(VOLUMECAPS));
memcpy(psd->buffer, buffer, cbBuffer);
memcpy(psd->VolumeCaps, VolumeCaps, sizeof(VOLUMECAPS));
psd->VolumeCaps->bProcessDefer = TRUE;
memcpy(psd->resource, resource, cbResource);
/* take defer lock */
EnterCriticalSection( &SetDeferLock );
/* add element at tail of list */
if(pSetHead == NULL) {
pSetHead = psd;
} else {
pSetTail->Next = psd;
}
pSetTail = psd;
/* release defer lock */
LeaveCriticalSection( &SetDeferLock );
return TRUE;
}
BOOL ProcessDefer(PDWORD dwDirectoryCount, PDWORD dwBytesProcessed,
PDWORD dwDirectoryFail, PDWORD dwBytesFail)
{
PDEFERRED_SET This;
PDEFERRED_SET Next;
*dwDirectoryCount = 0;
*dwBytesProcessed = 0;
*dwDirectoryFail = 0;
*dwBytesFail = 0;
if(!bInitialized) return TRUE; /* nothing to do */
EnterCriticalSection( &SetDeferLock );
This = pSetHead;
while(This) {
if(SecuritySet(This->resource, This->VolumeCaps, This->buffer)) {
(*dwDirectoryCount)++;
*dwBytesProcessed +=
GetSecurityDescriptorLength((PSECURITY_DESCRIPTOR)This->buffer);
} else {
(*dwDirectoryFail)++;
*dwBytesFail +=
GetSecurityDescriptorLength((PSECURITY_DESCRIPTOR)This->buffer);
}
Next = This->Next;
HeapFree(GetProcessHeap(), 0, This);
This = Next;
}
pSetHead = NULL;
LeaveCriticalSection( &SetDeferLock );
return TRUE;
}
BOOL ValidateSecurity(uch *securitydata)
{
PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata;
PACL pAcl;
PSID pSid;
BOOL bAclPresent;
BOOL bDefaulted;
if(!IsWinNT()) return TRUE; /* don't do anything if not on WinNT */
if(!IsValidSecurityDescriptor(sd)) return FALSE;
/* verify Dacl integrity */
if(!GetSecurityDescriptorDacl(sd, &bAclPresent, &pAcl, &bDefaulted))
return FALSE;
if(bAclPresent) {
if(!IsValidAcl(pAcl)) return FALSE;
}
/* verify Sacl integrity */
if(!GetSecurityDescriptorSacl(sd, &bAclPresent, &pAcl, &bDefaulted))
return FALSE;
if(bAclPresent) {
if(!IsValidAcl(pAcl)) return FALSE;
}
/* verify owner integrity */
if(!GetSecurityDescriptorOwner(sd, &pSid, &bDefaulted))
return FALSE;
if(pSid != NULL) {
if(!IsValidSid(pSid)) return FALSE;
}
/* verify group integrity */
if(!GetSecurityDescriptorGroup(sd, &pSid, &bDefaulted))
return FALSE;
if(pSid != NULL) {
if(!IsValidSid(pSid)) return FALSE;
}
return TRUE;
}
static VOID GetRemotePrivilegesSet(char *FileName, PDWORD dwRemotePrivileges)
{
HANDLE hFile;
*dwRemotePrivileges = 0;
/* see if we have the SeRestorePrivilege */
hFile = CreateFileA(
FileName,
ACCESS_SYSTEM_SECURITY | WRITE_DAC | WRITE_OWNER | READ_CONTROL,
FILE_SHARE_READ | FILE_SHARE_DELETE, /* no sd updating allowed here */
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
if(hFile != INVALID_HANDLE_VALUE) {
/* no remote way to determine SeRestorePrivilege -- just try a
read/write to simulate it */
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION |
SACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION;
PSECURITY_DESCRIPTOR sd;
DWORD cbBuf = 0;
GetKernelObjectSecurity(hFile, si, NULL, cbBuf, &cbBuf);
if(ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
if((sd = HeapAlloc(GetProcessHeap(), 0, cbBuf)) != NULL) {
if(GetKernelObjectSecurity(hFile, si, sd, cbBuf, &cbBuf)) {
if(SetKernelObjectSecurity(hFile, si, sd))
*dwRemotePrivileges |= OVERRIDE_RESTORE;
}
HeapFree(GetProcessHeap(), 0, sd);
}
}
CloseHandle(hFile);
} else {
/* see if we have the SeSecurityPrivilege */
/* note we don't need this if we have SeRestorePrivilege */
hFile = CreateFileA(
FileName,
ACCESS_SYSTEM_SECURITY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* max */
NULL,
OPEN_EXISTING,
0,
NULL
);
if(hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
*dwRemotePrivileges |= OVERRIDE_SACL;
}
}
}
BOOL GetVolumeCaps(
char *rootpath, /* filepath, or NULL */
char *name, /* filename associated with rootpath */
PVOLUMECAPS VolumeCaps /* result structure describing capabilities */
)
{
char TempRootPath[MAX_PATH + 1];
DWORD cchTempRootPath = 0;
BOOL bSuccess = TRUE; /* assume success until told otherwise */
if(!bInitialized) if(!Initialize()) return FALSE;
/* process the input path to produce a consistent path suitable for
compare operations and also suitable for certain picky Win32 API
that don't like forward slashes */
if(rootpath != NULL && rootpath[0] != '\0') {
DWORD i;
cchTempRootPath = lstrlen(rootpath);
if(cchTempRootPath > MAX_PATH) return FALSE;
/* copy input, converting forward slashes to back slashes as we go */
for(i = 0 ; i <= cchTempRootPath ; i++) {
if(rootpath[i] == '/') TempRootPath[i] = '\\';
else TempRootPath[i] = rootpath[i];
}
/* check for UNC and Null terminate or append trailing \ as
appropriate */
/* possible valid UNCs we are passed follow:
\\machine\foo\bar (path is \\machine\foo\)
\\machine\foo (path is \\machine\foo\)
\\machine\foo\
\\.\c$\ (FIXFIX: Win32API doesn't like this - GetComputerName())
LATERLATER: handling mounted DFS drives in the future will require
slightly different logic which isn't available today.
This is required because directories can point at
different servers which have differing capabilities.
*/
if(TempRootPath[0] == '\\' && TempRootPath[1] == '\\') {
DWORD slash = 0;
for(i = 2 ; i < cchTempRootPath ; i++) {
if(TempRootPath[i] == '\\') {
slash++;
if(slash == 2) {
i++;
TempRootPath[i] = '\0';
cchTempRootPath = i;
break;
}
}
}
/* if there was only one slash found, just tack another onto the
end */
if(slash == 1 && TempRootPath[cchTempRootPath] != '\\') {
TempRootPath[cchTempRootPath] = TempRootPath[0]; /* '\' */
TempRootPath[cchTempRootPath+1] = '\0';
cchTempRootPath++;
}
} else {
if(TempRootPath[1] == ':') {
/* drive letter specified, truncate to root */
TempRootPath[2] = '\\';
TempRootPath[3] = '\0';
cchTempRootPath = 3;
} else {
/* must be file on current drive */
TempRootPath[0] = '\0';
cchTempRootPath = 0;
}
}
} /* if path != NULL */
/* grab lock protecting cached entry */
EnterCriticalSection( &VolumeCapsLock );
if(!g_VolumeCaps.bValid ||
lstrcmpi(g_VolumeCaps.RootPath, TempRootPath) != 0)
{
/* no match found, build up new entry */
DWORD dwFileSystemFlags;
DWORD dwRemotePrivileges = 0;
BOOL bRemote = FALSE;
/* release lock during expensive operations */
LeaveCriticalSection( &VolumeCapsLock );
bSuccess = GetVolumeInformation(
(TempRootPath[0] == '\0') ? NULL : TempRootPath,
NULL, 0,
NULL, NULL,
&dwFileSystemFlags,
NULL, 0);
/* only if target volume supports Acls, and we were told to use
privileges do we need to go out and test for the remote case */
if(bSuccess && (dwFileSystemFlags & FS_PERSISTENT_ACLS) &&
VolumeCaps->bUsePrivileges)
{
if(GetDriveType( (TempRootPath[0] == '\0') ? NULL : TempRootPath )
== DRIVE_REMOTE)
{
bRemote = TRUE;
/* make a determination about our remote capabilities */
GetRemotePrivilegesSet(name, &dwRemotePrivileges);
}
}
/* always take the lock again, since we release it below */
EnterCriticalSection( &VolumeCapsLock );
/* replace the existing data if successful */
if(bSuccess) {
lstrcpynA(g_VolumeCaps.RootPath, TempRootPath, cchTempRootPath+1);
g_VolumeCaps.bProcessDefer = FALSE;
g_VolumeCaps.dwFileSystemFlags = dwFileSystemFlags;
g_VolumeCaps.bRemote = bRemote;
g_VolumeCaps.dwRemotePrivileges = dwRemotePrivileges;
g_VolumeCaps.bValid = TRUE;
}
}
if(bSuccess) {
/* copy input elements */
g_VolumeCaps.bUsePrivileges = VolumeCaps->bUsePrivileges;
g_VolumeCaps.dwFileAttributes = VolumeCaps->dwFileAttributes;
/* give caller results */
memcpy(VolumeCaps, &g_VolumeCaps, sizeof(VOLUMECAPS));
} else {
g_VolumeCaps.bValid = FALSE;
}
LeaveCriticalSection( &VolumeCapsLock ); /* release lock */
return bSuccess;
}
BOOL SecuritySet(char *resource, PVOLUMECAPS VolumeCaps, uch *securitydata)
{
HANDLE hFile;
DWORD dwDesiredAccess = 0;
DWORD dwFlags = 0;
PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata;
SECURITY_DESCRIPTOR_CONTROL sdc;
SECURITY_INFORMATION RequestedInfo = 0;
DWORD dwRev;
BOOL bRestorePrivilege = FALSE;
BOOL bSaclPrivilege = FALSE;
BOOL bSuccess;
if(!bInitialized) if(!Initialize()) return FALSE;
/* defer directory processing */
if(VolumeCaps->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if(!VolumeCaps->bProcessDefer) {
return DeferSet(resource, VolumeCaps, securitydata);
} else {
/* opening a directory requires FILE_FLAG_BACKUP_SEMANTICS */
dwFlags |= FILE_FLAG_BACKUP_SEMANTICS;
}
}
/* evaluate the input security desriptor and act accordingly */
if(!IsValidSecurityDescriptor(sd))
return FALSE;
if(!GetSecurityDescriptorControl(sd, &sdc, &dwRev))
return FALSE;
/* setup privilege usage based on if told we can use privileges, and if so,
what privileges we have */
if(VolumeCaps->bUsePrivileges) {
if(VolumeCaps->bRemote) {
/* use remotely determined privileges */
if(VolumeCaps->dwRemotePrivileges & OVERRIDE_RESTORE)
bRestorePrivilege = TRUE;
if(VolumeCaps->dwRemotePrivileges & OVERRIDE_SACL)
bSaclPrivilege = TRUE;
} else {
/* use local privileges */
bRestorePrivilege = g_bRestorePrivilege;
bSaclPrivilege = g_bSaclPrivilege;
}
}
/* if a Dacl is present write Dacl out */
/* if we have SeRestorePrivilege, write owner and group info out */
if(sdc & SE_DACL_PRESENT) {
dwDesiredAccess |= WRITE_DAC;
RequestedInfo |= DACL_SECURITY_INFORMATION;
if(bRestorePrivilege) {
dwDesiredAccess |= WRITE_OWNER;
RequestedInfo |= (OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION);
}
}
/* if a Sacl is present and we have either SeRestorePrivilege or
SeSystemSecurityPrivilege try to write Sacl out */
if((sdc & SE_SACL_PRESENT) && (bRestorePrivilege || bSaclPrivilege)) {
dwDesiredAccess |= ACCESS_SYSTEM_SECURITY;
RequestedInfo |= SACL_SECURITY_INFORMATION;
}
if(RequestedInfo == 0) /* nothing to do */
return FALSE;
if(bRestorePrivilege)
dwFlags |= FILE_FLAG_BACKUP_SEMANTICS;
hFile = CreateFileA(
resource,
dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,/* max sharing */
NULL,
OPEN_EXISTING,
dwFlags,
NULL
);
if(hFile == INVALID_HANDLE_VALUE)
return FALSE;
bSuccess = SetKernelObjectSecurity(hFile, RequestedInfo, sd);
CloseHandle(hFile);
return bSuccess;
}
static VOID InitLocalPrivileges(VOID)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
/* try to enable some interesting privileges that give us the ability
to get some security information that we normally cannot.
note that enabling privileges is only relevant on the local machine;
when accessing files that are on a remote machine, any privileges
that are present on the remote machine get enabled by default. */
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
return;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) {
/* try to enable SeRestorePrivilege; if this succeeds, we can write
all aspects of the security descriptor */
if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
GetLastError() == ERROR_SUCCESS) g_bRestorePrivilege = TRUE;
}
/* try to enable SeSystemSecurityPrivilege, if SeRestorePrivilege not
present; if this succeeds, we can write the Sacl */
if(!g_bRestorePrivilege &&
LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid)) {
if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
GetLastError() == ERROR_SUCCESS) g_bSaclPrivilege = TRUE;
}
CloseHandle(hToken);
}
#endif /* NTSD_EAS */

2187
utils/Install/sfxzip/os2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,384 @@
/* os2acl.c - access to OS/2 (LAN Server) ACLs
*
* Author: Kai Uwe Rommel <rommel@ars.de>
* Created: Mon Aug 08 1994
*
* This code is in the public domain.
*/
/*
* supported 32-bit compilers:
* - emx+gcc
* - IBM C Set++ 2.1 or newer
* - Watcom C/C++ 10.0 or newer
*
* supported 16-bit compilers:
* - MS C 6.00A
* - Watcom C/C++ 10.0 or newer
*
* supported OS/2 LAN environments:
* - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server)
* - IBM Peer 1.0 (Warp Connect)
*/
#ifdef KUR
static char *rcsid =
"$Id$";
static char *rcsrev = "$Revision$";
#endif
/*
* $Log$
* Revision 1.2 2000/07/15 19:50:50 cvsuser
* merged 2.2 branch
*
* Revision 1.1.2.1 2000/04/11 12:38:06 BS
* Added wxInstall a self extracting installation program using wxWindows.
*
* Revision 1.3 1996/04/03 19:18:27 rommel
* minor fixes
*
* Revision 1.2 1996/03/30 22:03:52 rommel
* avoid frequent dynamic allocation for every call
* streamlined code
*
* Revision 1.1 1996/03/30 09:35:00 rommel
* Initial revision
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#define INCL_NOPM
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#include "os2/os2acl.h"
#define UNLEN 20
#if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__)
#define __32BIT__
#endif
#ifdef __32BIT__
typedef ULONG U_INT;
#ifdef __EMX__
#define PSTR16 _far16ptr
#define PTR16(x) _emx_32to16(x)
#else /* other 32-bit */
#define PSTR16 PCHAR16
#define PTR16(x) ((PCHAR16)(x))
#endif
#else /* 16-bit */
typedef USHORT U_INT;
#define PSTR16 PSZ
#define PTR16(x) (x)
#endif
typedef struct access_list
{
char acl_ugname[UNLEN+1];
char acl_pad;
USHORT acl_access;
}
ACCLIST;
typedef struct access_info
{
PSTR16 acc_resource_name;
USHORT acc_attr;
USHORT acc_count;
}
ACCINFO;
static ACCINFO *ai;
static char *path, *data;
#ifdef __32BIT__
#ifdef __EMX__
static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail)
{
return (USHORT)
(_THUNK_PROLOG (4+4+2+4+2+4);
_THUNK_FLAT (pszServer);
_THUNK_FLAT (pszResource);
_THUNK_SHORT (sLevel);
_THUNK_FLAT (pbBuffer);
_THUNK_SHORT (cbBuffer);
_THUNK_FLAT (pcbTotalAvail);
_THUNK_CALLI (_emx_32to16(_NetAccessGetInfo)));
}
USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum)
{
return (USHORT)
(_THUNK_PROLOG (4+4+2+4+2+2);
_THUNK_FLAT (pszServer);
_THUNK_FLAT (pszResource);
_THUNK_SHORT (sLevel);
_THUNK_FLAT (pbBuffer);
_THUNK_SHORT (cbBuffer);
_THUNK_SHORT (sParmNum);
_THUNK_CALLI (_emx_32to16(_NetAccessSetInfo)));
}
USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel,
PVOID pbBuffer, USHORT cbBuffer)
{
return (USHORT)
(_THUNK_PROLOG (4+2+4+2);
_THUNK_FLAT (pszServer);
_THUNK_SHORT (sLevel);
_THUNK_FLAT (pbBuffer);
_THUNK_SHORT (cbBuffer);
_THUNK_CALLI (_emx_32to16(_NetAccessAdd)));
}
#else /* other 32-bit */
APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail);
APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum);
APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer,
USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer);
#define _NetAccessGetInfo NetAccessGetInfo
#define _NetAccessSetInfo NetAccessSetInfo
#define _NetAccessAdd NetAccessAdd
#if !defined(__IBMC__) || !defined(__TILED__)
#define _tmalloc malloc
#define _tfree free
#endif
#endif
#else /* 16-bit */
USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer,
USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
#define _NetAccessGetInfo NetAccessGetInfo
#define _NetAccessSetInfo NetAccessSetInfo
#define _NetAccessAdd NetAccessAdd
#define _tmalloc malloc
#define _tfree free
#define DosQueryProcAddr(handle, ord, name, funcptr) \
DosGetProcAddr(handle, name, funcptr)
#define DosQueryCurrentDir DosQCurDir
#define DosQueryCurrentDisk DosQCurDisk
#endif
static BOOL acl_init(void)
{
static BOOL initialized, netapi_avail;
HMODULE netapi;
char buf[256];
if (initialized)
return netapi_avail;
initialized = TRUE;
if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi))
return FALSE;
if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) ||
DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) ||
DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd))
return FALSE;
#if defined(__WATCOMC__) && defined(__386__)
NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo;
NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo;
NetAccessAdd = (PVOID) (ULONG) (PVOID16) NetAccessAdd;
#endif
if ((path = _tmalloc(CCHMAXPATH)) == NULL)
return FALSE;
if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL)
return FALSE;
if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL)
return -1;
netapi_avail = TRUE;
return netapi_avail;
}
static void acl_mkpath(char *buffer, const char *source)
{
char *ptr;
static char cwd[CCHMAXPATH];
static U_INT cwdlen;
U_INT cdrive;
ULONG drivemap;
if (isalpha(source[0]) && source[1] == ':')
buffer[0] = 0; /* fully qualified names */
else
{
if (cwd[0] == 0)
{
DosQueryCurrentDisk(&cdrive, &drivemap);
cwd[0] = (char)(cdrive + '@');
cwd[1] = ':';
cwd[2] = '\\';
cwdlen = sizeof(cwd) - 3;
DosQueryCurrentDir(0, cwd + 3, &cwdlen);
cwdlen = strlen(cwd);
}
if (source[0] == '/' || source[0] == '\\')
{
if (source[1] == '/' || source[1] == '\\')
buffer[0] = 0; /* UNC names */
else
{
strncpy(buffer, cwd, 2);
buffer[2] = 0;
}
}
else
{
strcpy(buffer, cwd);
if (cwd[cwdlen - 1] != '\\' && cwd[cwdlen - 1] != '/')
strcat(buffer, "/");
}
}
strcat(buffer, source);
for (ptr = buffer; *ptr; ptr++)
if (*ptr == '/')
*ptr = '\\';
if (ptr[-1] == '\\')
ptr[-1] = 0;
strupr(buffer);
}
static int acl_bin2text(char *data, char *text)
{
ACCINFO *ai;
ACCLIST *al;
U_INT cnt, offs;
ai = (ACCINFO *) data;
al = (ACCLIST *) (data + sizeof(ACCINFO));
offs = sprintf(text, "ACL1:%X,%d\n",
ai -> acc_attr, ai -> acc_count);
for (cnt = 0; cnt < ai -> acc_count; cnt++)
offs += sprintf(text + offs, "%s,%X\n",
al[cnt].acl_ugname, al[cnt].acl_access);
return strlen(text);
}
int acl_get(char *server, const char *resource, char *buffer)
{
USHORT datalen;
PSZ srv = NULL;
int rc;
if (!acl_init())
return -1;
if (server)
srv = server;
acl_mkpath(path, resource);
datalen = 0;
rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen);
if (rc == 0)
acl_bin2text(data, buffer);
return rc;
}
static int acl_text2bin(char *data, char *text, char *path)
{
ACCINFO *ai;
ACCLIST *al;
char *ptr, *ptr2;
U_INT cnt;
ai = (ACCINFO *) data;
ai -> acc_resource_name = PTR16(path);
if (sscanf(text, "ACL1:%hX,%hd",
&ai -> acc_attr, &ai -> acc_count) != 2)
return ERROR_INVALID_PARAMETER;
al = (ACCLIST *) (data + sizeof(ACCINFO));
ptr = strchr(text, '\n') + 1;
for (cnt = 0; cnt < ai -> acc_count; cnt++)
{
ptr2 = strchr(ptr, ',');
strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr);
al[cnt].acl_ugname[ptr2 - ptr] = 0;
sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access);
ptr = strchr(ptr, '\n') + 1;
}
return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST);
}
int acl_set(char *server, const char *resource, char *buffer)
{
USHORT datalen;
PSZ srv = NULL;
if (!acl_init())
return -1;
if (server)
srv = server;
acl_mkpath(path, resource);
ai -> acc_resource_name = PTR16(path);
ai -> acc_attr = 0;
ai -> acc_count = 0;
NetAccessAdd(srv, 1, ai, sizeof(ACCINFO));
/* Ignore any errors, most probably because ACL already exists. */
/* In any such case, try updating the existing ACL. */
datalen = acl_text2bin(data, buffer, path);
return NetAccessSetInfo(srv, path, 1, data, datalen, 0);
}
/* end of os2acl.c */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,886 @@
/**********************************************************************
* REXXAPI.C *
* *
* This program adds a ZIP engine directly to the REXX language. *
* The functions are: *
* UZDropFuncs -- Makes all functions in this package *
* unknown to REXX. *
* UZLoadFuncs -- Makes all functions in this package *
* known to REXX so REXX programs may *
* call them. *
* UZFileTree -- Searches for files matching a given *
* filespec, including files in *
* subdirectories. *
* UZUnZip -- Unzip command-line entry point. *
* This is functionally equivalent to *
* using Unzip as an external program. *
* UZUnZipToVar -- Unzip one file to a variable *
* UZUnZipToStem -- Unzip files to a variable array *
* UZVer -- Returns the Unzip version number *
* *
**********************************************************************/
/* Include files */
#ifdef OS2DLL
#define INCL_DOS
#define INCL_DOSMEMMGR
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define UNZIP_INTERNAL
#include "../unzip.h"
#include "../version.h"
/*********************************************************************/
/* Various definitions used by various functions. */
/*********************************************************************/
RexxFunctionHandler UZDropFuncs;
RexxFunctionHandler UZLoadFuncs;
RexxFunctionHandler UZFileTree;
RexxFunctionHandler UZUnZip;
RexxFunctionHandler UZUnZipToVar;
RexxFunctionHandler UZUnZipToStem;
RexxFunctionHandler UZVer;
RexxFunctionHandler UZAPIVer;
int SetOutputVar(__GPRO__ const char *name);
int SetOutputVarStem(__GPRO__ const char *name);
int SetOutputVarLength(__GPRO);
int WriteToVariable(__GPRO__ const char *name, char *buffer, int len);
int PrintToSubVariable(__GPRO__ int idx, const char *format,...);
int PrintToVariable(__GPRO__ const char *name, const char *format,...);
int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr);
int TextSetNext(__GPRO__ char *format, int len, int all);
#define EZRXSTRING(r,p) {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);}
/*********************************************************************/
/* RxFncTable */
/* Array of names of the UNZIPAPI functions. */
/* This list is used for registration and deregistration. */
/*********************************************************************/
static PSZ RxFncTable[] =
{
"UZDropFuncs",
"UZLoadFuncs",
"UZFileSearch",
"UZFileTree",
"UZUnZip",
"UZUnZipToVar",
"UZUnZipToStem",
"UZVer",
};
/*********************************************************************/
/* Numeric Error Return Strings */
/*********************************************************************/
#define NO_UTIL_ERROR "0" /* No error whatsoever */
#define ERROR_NOMEM "2" /* Insufficient memory */
/*********************************************************************/
/* Numeric Return calls */
/*********************************************************************/
#define INVALID_ROUTINE 40 /* Raise Rexx error */
#define VALID_ROUTINE 0 /* Successful completion */
/*********************************************************************/
/* Some useful macros */
/*********************************************************************/
#define BUILDRXSTRING(t, s) { \
strcpy((t)->strptr,(s));\
(t)->strlength = strlen((s)); \
}
/*********************************************************************/
/**************** UNZIPAPI Supporting Functions ********************/
/**************** UNZIPAPI Supporting Functions ********************/
/**************** UNZIPAPI Supporting Functions ********************/
/*********************************************************************/
int RexxReturn(__GPRO__ int nodefault, RXSTRING *retstr)
{
int ret = G.os2.rexx_error;
if (G.filenotfound)
G.os2.rexx_mes = "file not found";
if (*G.os2.rexx_mes != '0') {
if (retstr->strlength > 255) {
DosFreeMem(retstr->strptr);
retstr->strptr = NULL;
}
} else if (nodefault)
goto noBuild;
BUILDRXSTRING(retstr, G.os2.rexx_mes);
noBuild:
DESTROYGLOBALS();
return ret;
}
/* Get a variable from REXX, return 0 if OK */
int GetVariable(__GPRO__ const char *name)
{
G.os2.request.shvnext = NULL;
EZRXSTRING(G.os2.request.shvname, name);
G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
G.os2.request.shvvalue.strptr = G.os2.buffer;
G.os2.request.shvvalue.strlength = IBUF_LEN;
G.os2.request.shvvaluelen = IBUF_LEN;
G.os2.request.shvcode = RXSHV_SYFET;
G.os2.request.shvret = 0;
switch (RexxVariablePool(&G.os2.request)) {
case RXSHV_MEMFL:
G.os2.rexx_mes = ERROR_NOMEM;
break;
case RXSHV_BADN:
case RXSHV_NEWV:
G.os2.request.shvvaluelen = 0;
case RXSHV_OK:
*(G.os2.buffer+G.os2.request.shvvaluelen) = 0;
return G.os2.request.shvvaluelen;
}
return 0;
}
/* Get REXX compound variable */
/* Stem must exist in G.os2.getvar_buf w/ length in G.os2.getvar_len */
int GetVariableIndex(__GPRO__ int index)
{
sprintf(G.os2.getvar_buf+G.os2.getvar_len,"%d",index);
return GetVariable(__G__ G.os2.getvar_buf);
}
/* Transfer REXX array to standard C string array */
/* Returns number of elements */
/* User is responsible for calling KillStringArray */
int CompoundToStringArray(__GPRO__ char ***pointer, const char *name)
{
int count;
int total;
char **trav;
G.os2.getvar_len = strlen(name);
memcpy(G.os2.getvar_buf,name,G.os2.getvar_len+1);
if (*(G.os2.getvar_buf+G.os2.getvar_len-1) != '.')
*(G.os2.getvar_buf+G.os2.getvar_len++) = '.', *(G.os2.getvar_buf+G.os2.getvar_len) = 0;
if (GetVariableIndex(__G__ 0))
return 0;
total = atoi(G.os2.buffer);
*pointer = (char **)malloc((total+1)<<2);
trav = *pointer;
for (count = 1; count <= total; count++) {
GetVariableIndex(__G__ count);
trav[count-1] = (char *)malloc(strlen(G.os2.buffer)+1);
strcpy(trav[count-1],G.os2.buffer);
}
trav[count-1] = NULL;
return total;
}
/* Kill string array created by CompoundToStringArray */
void KillStringArray(char **pointer)
{
char **trav=pointer;
while (*trav != NULL) {
free(*trav);
trav++;
}
free(pointer);
}
/*************************************************************************
* Function: UZDropFuncs *
* *
* Syntax: call UZDropFuncs *
* *
* Return: NO_UTIL_ERROR - Successful. *
*************************************************************************/
ULONG UZDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
INT entries; /* Num of entries */
INT j; /* Counter */
if (numargs != 0) /* no arguments for this */
return INVALID_ROUTINE; /* raise an error */
retstr->strlength = 0; /* return a null string result*/
entries = sizeof(RxFncTable)/sizeof(PSZ);
for (j = 0; j < entries; j++)
RexxDeregisterFunction(RxFncTable[j]);
return VALID_ROUTINE; /* no error on call */
}
/*************************************************************************
* Function: UZFileTree *
* *
* Syntax: call UZFileTree zipfile, stem[, include-filespec] *
* [, exclude-filespec][, options] *
* *
* Params: zipfile - Name of zip file to search. *
* stem - Name of stem var to store results in. *
* include - Filespec to search for (may include * and ?). *
* exclude - Filespec to exclude (may include * and ?). *
* options - Either of the following: *
* 'F' - Give file statistics. *
* Length Date Time Name *
* 'Z' - Give zip statistics, too. *
* Length Method Size Ratio Date Time CRC-32 Name*
* Default is to return only filenames *
* *
* Return: NO_UTIL_ERROR - Successful. *
* ERROR_NOMEM - Out of memory. *
*************************************************************************/
ULONG UZFileTree(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
/* validate arguments */
char *incname[2];
char *excname[2];
CONSTRUCTGLOBALS();
if (numargs < 2 || numargs > 5 ||
!RXVALIDSTRING(args[0]) ||
!RXVALIDSTRING(args[1]) ||
args[0].strlength > 255) {
DESTROYGLOBALS();
return INVALID_ROUTINE; /* Invalid call to routine */
}
/* initialize data area */
SetOutputVarStem(__G__ args[1].strptr);
G.wildzipfn = args[0].strptr;
G.process_all_files = TRUE;
uO.lflag = 1;
uO.zipinfo_mode = TRUE;
uO.C_flag = 1;
G.extract_flag = FALSE;
uO.qflag = 2;
if (numargs >= 3 && /* check third option */
!RXNULLSTRING(args[2]) &&
args[2].strlength > 0) { /* a zero length string isn't */
if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
G.pfnames = incname;
incname[0] = args[2].strptr;
incname[1] = NULL;
G.filespecs = 1;
}
G.process_all_files = FALSE;
}
if (numargs >= 4 && /* check third option */
!RXNULLSTRING(args[3]) &&
args[3].strlength > 0) { /* a zero length string isn't */
if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
G.pxnames = excname;
excname[0] = args[3].strptr;
excname[1] = NULL;
G.xfilespecs = 1;
}
G.process_all_files = FALSE;
}
if (numargs == 5 && /* check third option */
!RXNULLSTRING(args[4]) &&
args[4].strlength > 0) { /* a zero length string isn't */
int first = *args[4].strptr & 0x5f;
if (first == 'Z')
uO.vflag = 2, uO.lflag = 0, uO.zipinfo_mode = FALSE;
else if (first == 'F')
uO.vflag = 1, uO.lflag = 0, uO.zipinfo_mode = FALSE;
}
process_zipfiles(__G);
SetOutputVarLength(__G);
if (G.filespecs > 0 && G.pfnames != incname)
KillStringArray(G.pfnames);
if (G.xfilespecs > 0 && G.pxnames != excname)
KillStringArray(G.pxnames);
return RexxReturn(__G__ 0,retstr); /* no error on call */
}
/*************************************************************************
* Function: UZUnZipToVar *
* *
* Syntax: call UZUnZipToVar zipfile, filespec [, stem] *
* *
* Params: zipfile - Name of zip file to search. *
* filespec - File to extract *
* stem - If you specify a stem variable, the file will be *
* extracted to the variable, one line per index *
* In this case, 0 will be returned *
* *
* Return: Extracted file *
* ERROR_NOMEM - Out of memory. *
*************************************************************************/
ULONG UZUnZipToVar(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
CONSTRUCTGLOBALS();
UzpBuffer *ub = (UzpBuffer *)retstr;
/* validate arguments */
if (numargs < 2 || numargs > 3 ||
!RXVALIDSTRING(args[0]) ||
!RXVALIDSTRING(args[1]) ||
args[0].strlength == 0 ||
args[1].strlength == 0) {
DESTROYGLOBALS();
return INVALID_ROUTINE; /* Invalid call to routine */
}
uO.C_flag = 1;
G.redirect_data=1;
if (numargs == 3) {
if (!RXVALIDSTRING(args[2]) ||
RXNULLSTRING(args[1]) ||
args[2].strlength == 0) {
DESTROYGLOBALS();
return INVALID_ROUTINE; /* Invalid call to routine */
}
SetOutputVarStem(__G__ args[2].strptr);
G.redirect_text = 0;
G.redirect_data++;
}
unzipToMemory(__G__ args[0].strptr, args[1].strptr,
G.redirect_data==1 ? ub : NULL);
return RexxReturn(__G__ G.redirect_data==1,retstr);
}
/*************************************************************************
* Function: UZUnZipToStem *
* *
* Syntax: call UZUnZipToStem zipfile, stem[, include-filespec] *
* [, exclude-filespec][, mode] *
* *
* Params: zipfile - Name of zip file to search. *
* stem - Name of stem var to store files in. *
* include - Filespec to search for (may include * and ?). *
* exclude - Filespec to exclude (may include * and ?). *
* mode - Specifies 'F'lat or 'T'ree mode. Umm, this is *
* hard to explain so I'll give an example, too. *
* Assuming a file unzip.zip containing: *
* unzip.c *
* unshrink.c *
* extract.c *
* os2/makefile.os2 *
* os2/os2.c *
* os2/dll/dll.def *
* os2/dll/unzipapi.c *
* *
* -- In flat mode, each file is stored in *
* stem.fullname i.e. stem."os2/dll/unzipapi.c" *
* A list of files is created in stem.<index> *
* *
* Flat mode returns: *
* stem.0 = 7 *
* stem.1 = unzip.c *
* stem.2 = unshrink.c *
* stem.3 = extract.c *
* stem.4 = os2/makefile.os2 *
* stem.5 = os2/os2.c *
* stem.6 = os2/dll/dll.def *
* stem.7 = os2/dll/unzipapi.c *
* *
* And the following contain the contents of the *
* various programs: *
* stem.unzip.c *
* stem.unshrink.c *
* stem.extract.c *
* stem.os2/makefile.os2 *
* stem.os2/os2.c *
* stem.os2/dll/dll.def *
* stem.os2/dll/unzipapi.c *
* *
* -- In tree mode, slashes are converted to periods*
* in the pathname thus the above file would have*
* been stored in stem.os2.dll.unzipapi.c *
* The index would then be stored in stem.OS2. *
* DLL.<index>. *
* *
* NOTE: All path names are converted to uppercase *
* *
* Tree mode returns: *
* stem.0 = 4 *
* stem.1 = unzip.c *
* stem.2 = unshrink.c *
* stem.3 = extract.c *
* stem.4 = OS2/ *
* *
* stem.OS2.0 = 3 *
* stem.OS2.1 = makefile.os2 *
* stem.OS2.2 = os2.c *
* stem.OS2.3 = DLL/ *
* *
* stem.OS2.DLL.0 = 2 *
* stem.OS2.DLL.1 = def *
* stem.OS2.DLL.2 = unzipapi.c *
* *
* And the following contain the contents of the *
* various programs: *
* stem.unzip.c *
* stem.unshrink.c *
* stem.extract.c *
* stem.OS2.makefile.os2 *
* stem.OS2.os2.c *
* stem.OS2.DLL.dll.def *
* stem.OS2.DLL.unzipapi.c *
* *
* *
* Return: NO_UTIL_ERROR - Successful. *
* ERROR_NOMEM - Out of memory. *
*************************************************************************/
ULONG UZUnZipToStem(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
char *incname[2];
char *excname[2];
CONSTRUCTGLOBALS();
/* validate arguments */
if (numargs < 2 || numargs > 5 ||
!RXVALIDSTRING(args[0]) ||
!RXVALIDSTRING(args[1]) ||
args[0].strlength > 255) {
DESTROYGLOBALS();
return INVALID_ROUTINE; /* Invalid call to routine */
}
/* initialize data area */
G.wildzipfn = args[0].strptr;
G.process_all_files = TRUE;
uO.C_flag = 1;
G.extract_flag = TRUE;
SetOutputVarStem(__G__ args[1].strptr);
G.redirect_data = 3;
G.redirect_text = 0;
if (numargs >= 3 && /* check third option */
!RXNULLSTRING(args[2]) &&
args[2].strlength > 0) { /* a zero length string isn't */
if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
G.pfnames = incname;
incname[0] = args[2].strptr;
incname[1] = NULL;
G.filespecs = 1;
}
G.process_all_files = FALSE;
}
if (numargs >= 4 && /* check third option */
!RXNULLSTRING(args[3]) &&
args[3].strlength > 0) { /* a zero length string isn't */
if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
G.pxnames = excname;
excname[0] = args[3].strptr;
excname[1] = NULL;
G.xfilespecs = 1;
}
G.process_all_files = FALSE;
}
if (numargs == 5 && /* check third option */
!RXNULLSTRING(args[4]) &&
(*args[4].strptr & 0x5f) == 'T') {
G.redirect_data++;
G.os2.request.shvnext = NULL;
EZRXSTRING(G.os2.request.shvname, args[4].strptr);
G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
G.os2.request.shvcode = RXSHV_SYDRO;
G.os2.request.shvret = 0;
RexxVariablePool(&G.os2.request);
}
uO.qflag = 2;
process_zipfiles(__G);
if (G.filespecs > 0 && G.pfnames != incname)
KillStringArray(G.pfnames);
if (G.xfilespecs > 0 && G.pxnames != excname)
KillStringArray(G.pxnames);
if (G.redirect_data == 3)
SetOutputVarLength(__G);
return RexxReturn(__G__ 0,retstr); /* no error on call */
}
/*************************************************************************
* Function: UZLoadFuncs *
* *
* Syntax: call UZLoadFuncs [option] *
* *
* Params: none *
* *
* Return: null string *
*************************************************************************/
ULONG UZLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
INT entries; /* Num of entries */
INT j; /* Counter */
retstr->strlength = 0; /* set return value */
/* check arguments */
if (numargs > 0)
return INVALID_ROUTINE;
entries = sizeof(RxFncTable)/sizeof(PSZ);
for (j = 0; j < entries; j++) {
RexxRegisterFunctionDll(RxFncTable[j],
"UNZIP32", RxFncTable[j]);
}
return VALID_ROUTINE;
}
/*************************************************************************
* Function: UZVer *
* *
* Syntax: call UZVer *
* *
* Return: Version of Unzip *
*************************************************************************/
ULONG UZVer(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
if (numargs > 1) /* validate arg count */
return INVALID_ROUTINE;
if (numargs == 0 || (*args[0].strptr & 0x5f) != 'L')
/* strcpy( retstr->strptr, UZ_VERNUM ); "5.13a BETA" */
sprintf( retstr->strptr, "%d.%d%d%s", UZ_MAJORVER, UZ_MINORVER,
PATCHLEVEL, BETALEVEL );
else
/* strcpy( retstr->strptr, UZ_VERSION ); UZ_VERNUM" of 26 Sep 94" */
sprintf( retstr->strptr, "%d.%d%d%s of %s", UZ_MAJORVER, UZ_MINORVER,
PATCHLEVEL, BETALEVEL, VERSION_DATE );
retstr->strlength = strlen(retstr->strptr);
return VALID_ROUTINE;
}
/*************************************************************************
* Function: UZUnZip *
* *
* Syntax: call UZUnZip *
* *
* Return: Unzip return code *
*************************************************************************/
ULONG UZUnZip(CHAR *name, ULONG numargs, RXSTRING args[],
CHAR *queuename, RXSTRING *retstr)
{
char *argv[30];
char *scan;
int argc=0;
int idx;
CONSTRUCTGLOBALS();
if (numargs < 1 || numargs > 2 ||
args[0].strlength > 255) {
DESTROYGLOBALS();
return INVALID_ROUTINE; /* Invalid call to routine */
}
/* initialize data area */
if (numargs == 2)
SetOutputVarStem(__G__ args[1].strptr);
scan = args[0].strptr;
argv[argc++] = ""; /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */
while (*scan == ' ')
scan++;
argv[argc++] = scan;
while ( (scan = strchr(scan,' ')) != NULL) {
*scan++ = 0;
while (*scan == ' ')
scan++;
argv[argc++] = scan;
}
if (*argv[argc-1] == 0)
argc--;
argv[argc] = 0;
/* GRR: should resetMainFlags() be called in here somewhere? */
sprintf(retstr->strptr, "%d", unzip(__G__ argc, argv)); /* a.k.a. MAIN() */
if (numargs == 2)
SetOutputVarLength(__G);
retstr->strlength = strlen(retstr->strptr);
return RexxReturn(__G__ 1,retstr);
}
int varmessage(__GPRO__ uch *buf, ulg size)
{
if (size > 0)
memcpy(G.os2.buffer+G.os2.putchar_idx,buf,size);
G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, size+G.os2.putchar_idx,0);
return 0;
}
int varputchar(__GPRO__ int c)
{
G.os2.buffer[G.os2.putchar_idx++] = c;
if (c == '\n') {
G.os2.buffer[G.os2.putchar_idx] = 0;
if (G.os2.output_var[0])
G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, G.os2.putchar_idx,0);
else {
G.os2.buffer[--G.os2.putchar_idx] = 0;
puts(G.os2.buffer);
G.os2.putchar_idx = 0;
}
}
return 1;
}
int SetOutputVarStem(__GPRO__ const char *name)
{
int len=strlen(name);
G.redirect_text=1;
G.os2.output_idx = 0;
strcpy(G.os2.output_var, name);
if (len) {
strupr(G.os2.output_var); /* uppercase the name */
if (*(G.os2.output_var+len-1) != '.') {
*(G.os2.output_var+len) = '.';
len++;
*(G.os2.output_var+len) = 0;
}
WriteToVariable(__G__ G.os2.output_var,"",0);
}
G.os2.stem_len = len;
return G.os2.stem_len;
}
int SetOutputVar(__GPRO__ const char *name)
{
int len=strlen(name);
G.redirect_text=1;
G.os2.output_idx = 0;
strcpy(G.os2.output_var, name);
strupr(G.os2.output_var); /* uppercase the name */
if (*(name+len-1) == '.')
G.os2.stem_len = len;
else
G.os2.stem_len = 0;
return G.os2.stem_len;
}
int SetOutputVarLength(__GPRO)
{
if (G.os2.stem_len > 0) {
if (G.os2.putchar_idx)
TextSetNext(__G__ G.os2.buffer,G.os2.putchar_idx,1);
return PrintToSubVariable(__G__ 0,"%d",G.os2.output_idx);
}
return 0;
}
int PrintToVariable(__GPRO__ const char *name, const char *format,...)
{
va_list arg_ptr;
int ret;
va_start(arg_ptr, format);
ret = _PrintToVariable(__G__ name, format, arg_ptr);
va_end(arg_ptr);
return ret;
}
int WriteToVariable(__GPRO__ const char *name, char *buffer, int len)
{
G.os2.request.shvnext = NULL;
EZRXSTRING(G.os2.request.shvname, name);
G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
G.os2.request.shvvalue.strptr = buffer;
G.os2.request.shvvalue.strlength = len;
G.os2.request.shvvaluelen = len;
G.os2.request.shvcode = RXSHV_SET;
G.os2.request.shvret = 0;
switch (RexxVariablePool(&G.os2.request)) {
case RXSHV_BADN:
G.os2.rexx_error = INVALID_ROUTINE;
break;
case RXSHV_MEMFL:
G.os2.rexx_mes = ERROR_NOMEM;
break;
case RXSHV_OK:
return 0;
}
return INVALID_ROUTINE; /* error on non-zero */
}
int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr)
{
int ret = vsprintf(G.os2.buffer, format, arg_ptr);
WriteToVariable(__G__ name, G.os2.buffer, strlen(G.os2.buffer));
return ret;
}
int PrintToSubVariable(__GPRO__ int idx, const char *format, ...)
{
va_list arg_ptr;
int ret;
if (G.os2.stem_len == 0)
return INVALID_ROUTINE; /* error on non-zero */
sprintf(G.os2.output_var+G.os2.stem_len,"%d",idx);
va_start(arg_ptr, format);
ret = _PrintToVariable(__G__ G.os2.output_var, format, arg_ptr);
va_end(arg_ptr);
return ret;
}
int WriteToNextVariable(__GPRO__ char *buffer, int len)
{
if (G.os2.stem_len > 0) {
G.os2.output_idx++;
sprintf(G.os2.output_var+G.os2.stem_len,"%d",G.os2.output_idx);
}
return WriteToVariable(__G__ G.os2.output_var, buffer, len);
}
int TextSetNext(__GPRO__ char *buffer, int len, int all)
{
char *scan = buffer, *next, *base=buffer;
int remaining=len;
int ret;
while ((next = strchr(scan,'\n')) != NULL && remaining > 0) {
if (next > scan && *(next-1) == 0xd)
*(next-1) = 0;
else
*next = 0;
if (WriteToNextVariable(__G__ scan,strlen(scan)))
return 0;
next++;
remaining -= (next-scan);
scan = next;
}
if (remaining > 0)
if (all) {
*(scan+remaining) = 0;
WriteToNextVariable(__G__ scan,remaining);
} else {
memcpy(buffer,scan,remaining);
return remaining;
}
return 0;
}
int finish_REXX_redirect(__GPRO)
{
char *scan, *ptr;
int idx=0, first=1, offset;
if (!G.redirect_size)
return 0;
switch(G.redirect_data) {
case 1:
break;
case 2:
TextSetNext(__G__ G.redirect_buffer, G.redirect_size, 1);
SetOutputVarLength(__G);
DosFreeMem(G.redirect_buffer);
G.redirect_buffer = NULL;
G.redirect_size = 0;
break;
case 3:
WriteToNextVariable(__G__ G.filename,strlen(G.filename));
sprintf(G.os2.output_var+G.os2.stem_len,G.filename);
WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
DosFreeMem(G.redirect_buffer);
G.redirect_buffer = NULL;
G.redirect_size = 0;
break;
case 4:
if ((scan = strrchr(G.filename,'/')) != NULL) {
idx = *scan;
*scan = 0;
strupr(G.filename);
*scan = idx;
}
scan = G.os2.output_var+G.os2.stem_len;
strcpy(scan,G.filename);
while ((scan = strchr(scan,'/')) != NULL)
*scan = '.';
WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
DosFreeMem(G.redirect_buffer);
G.redirect_buffer = NULL;
G.redirect_size = 0;
strcpy(G.os2.getvar_buf, G.os2.output_var);
do {
if ((scan = strrchr(G.filename,'/')) == NULL)
offset = 0;
else
offset = scan-G.filename+1;
if (first || !GetVariable(__G__ G.os2.output_var)) {
ptr = G.os2.getvar_buf+offset+G.os2.stem_len;
*ptr = '0';
*(ptr+1) = 0;
if (!GetVariable(__G__ G.os2.getvar_buf))
idx = 1;
else
idx = atoi(G.os2.buffer)+1;
PrintToVariable(__G__ G.os2.getvar_buf,"%d",idx);
sprintf(ptr,"%d",idx);
if (!first) {
PrintToVariable(__G__ G.os2.output_var,"%d",idx);
idx = strlen(G.filename);
*(G.filename+idx) = '/';
*(G.filename+idx+1) = 0;
}
WriteToVariable(__G__ G.os2.getvar_buf,G.filename+offset,strlen(G.filename+offset));
first=0;
}
if (offset) {
*(G.os2.output_var+G.os2.stem_len+offset-1) = 0;
*scan = 0;
}
} while (offset);
break;
}
return 0;
}
#endif /* OS2DLL */

View File

@@ -0,0 +1,178 @@
/* rexxhelp.c */
#if defined(API_DOC) && defined(OS2DLL)
#define UNZIP_INTERNAL
#include "../unzip.h"
#include "../version.h"
APIDocStruct REXXDetails[] = {
{ "UZDROPFUNCS" , "UZDropFuncs" ,
"call UZDropFuncs",
"Use this function to drop all the loaded UnZip functions.\n"
"\t\tOnce this function is processed by a REXX program, the\n"
"\t\tUnZip functions are not accessible in any OS/2 sessions.\n" },
{ "UZLOADFUNCS" , "UZLoadFuncs" ,
"call UZLoadFuncs",
"Use this function to make all of the UnZip functions\n"
" in this package available to all OS/2 sessions.\n\n"
" Example: call RxFuncAdd 'UZLoadFuncs', 'UNZIPAPI', 'UZLoadFuncs'\n"
" call UZLoadFuncs\n" },
{ "UZFILETREE" , "UZFileTree" ,
"rc = UZFileTree(zipfile, stem, [include], [exclude], [options])\n\n"
" zipfile - Name of ZIP file to search\n"
" stem - Name of the stem variable for results\n"
" Note: stem.0 contains the number of files found.\n"
" include - Optional stem variable specifying a list of files (including\n"
" wildcards) to include. stem.0 must indicate number of items.\n"
" exclude - Optional stem variable specifying a list of files (including\n"
" wildcards) to exclude. stem.0 must indicate number of items.\n"
" NOTE: If lists are not needed, filespec strings may be passed.\n"
" options - One of the following:\n"
" 'O' - Give file names only. This is the default.\n"
" 'F' - Give file statistics in the form:\n"
" Length Date Time Name\n"
" 'Z' - Also give ZIP statistics in the form:\n"
" Length Method Size Ratio Date Time CRC-32 Name",
"Finds all files in the specified ZIP with the specified\n"
" filespec and places their descriptions in a stem variable.\n\n"
" rc: Return codes\n"
" 0 Successful\n"
" 2 Error. Not enough memory.\n\n"
" Examples:\n"
" /* Return a list of all .NDX files in pcboard.qwk */\n"
" rc = UZFileTree('pcboard.qwk', 'stem.', '*.ndx')\n\n"
" /* Return a list of all files except *.NDX and *.DAT */\n"
" exc.0 = 2; exc.1 = '*.ndx'; exc.2 = '*.dat'\n"
" rc = UZFileTree('pcboard.qwk', 'stem.',,'exc.')\n" },
{ "UZUNZIP" , "UZUnZip" ,
"rc = UZUnZip('parameters', [stem])\n\n"
" parameters - The entire list of parameters you would use from\n"
" the command-line\n"
" stem - The name of an optional stem variable where any\n"
" output should be redirected.\n"
" NOTE: If a stem is not specified, all output will\n"
" go to the console.",
"Provide a direct entry point to the command line interface.\n\n"
" rc: UnZip return code\n\n"
" Examples: /* Test the archive 'unzip51s.zip' and return output in stem.*/\n"
" rc = UZUnZip('-t unzip51s.zip','stem.')\n"
" /* Extract the archive, display output on screen */\n"
" call UZUnZip 'doom.zip'\n"
" /* Extract all .NDX files from the archive */\n"
" call UZUnZip 'pcboard.qwk *.ndx','stem.'\n" },
{ "UZUNZIPTOVAR" , "UZUnZipToVar" ,
"rc = UZUnZipToVar('zipfile', 'filename', [stem])\n\n"
" zipfile - Name of ZIP file to search\n"
" filename - Name of file to extract from zipfile\n"
" stem - Optional stem variable to extract the file to.\n"
" If you specify a stem variable, the file will be extracted\n"
" to the variable, one line per index, stem.0 containing a\n"
" line count. In this case, 0 will be returned in rc.\n"
" If NO stem variable is specified, the entire file will be\n"
" extracted to rc.",
"Unzip one file to a variable.\n\n"
" rc: If no stem variable is specified, rc contains the contents of\n"
" the extracted file if successful or an error-code if not.\n"
" If a stem variable IS specified, rc contains 0 if successful.\n"},
/* GRR: "include" and "exclude" used to be identified as stem variables
* (Daniel H bug report)
*/
{ "UZUNZIPTOSTEM", "UZUnZipToStem",
"rc = UZUnZipToStem(zipfile, stem, [include], [exclude], [mode])\n"
" zipfile - Name of ZIP file to search\n"
" stem - Stem variable used to store the extracted files\n"
" include - Optional string variable specifying a list of files (including\n"
" wildcards) to include. stem.0 must indicate number of items.\n"
" exclude - Optional string variable specifying a list of files (including\n"
" wildcards) to exclude. stem.0 must indicate number of items.\n"
" NOTE: If lists are not needed, filespec strings may be passed.\n"
" mode - Optional mode parameter specifies either 'F'lat (the default)\n"
" or 'T'ree mode.\n"
" -- In flat mode, each file is stored in stem.fullname i.e.\n"
" stem.os2/dll/unzipapi.c. A list of files is created in\n"
" stem.<index>\n"
" -- In tree mode, slashes are converted to periods in the\n"
" pathname thus the above file would have been stored in\n"
" stem.OS2.DLL.unzipapi.c and an index stored for each\n"
" directory, i.e. stem.OS2.DLL.<index> = \"unzipapi.c\",\n"
" stem.OS2.<index> = \"DLL/\", stem.<index> = \"OS2/\"",
"Unzip files to a stem variable.\n\n"
" Example: Assuming a file unzip.zip containing:\n"
" unzip.c, unshrink.c, extract.c,\n"
" os2/makefile.os2, os2/os2.c\n"
" os2/dll/dll.def, os2/dll/unzipapi.c\n\n"
" rc = UZUnZipToStem('unzip.zip', 'stem.')\n"
" Returns: stem.0 = 7\n"
" stem.1 = unzip.c\n"
" stem.2 = unshrink.c\n"
" stem.3 = extract.c\n"
" stem.4 = os2/makefile.os2\n"
" stem.5 = os2/os2.c\n"
" stem.6 = os2/dll/dll.def\n"
" stem.7 = os2/dll/unzipapi.c\n"
" And the following contain the contents of the\n"
" various files:\n"
" stem.unzip.c\n"
" stem.unshrink.c\n"
" stem.extract.c\n"
" stem.os2/makefile.os2\n"
" stem.os2/os2.c\n"
" stem.os2/dll/dll.def\n"
" stem.os2/dll/unzipapi.c\n\n"
" rc = UZUnZipToStem('unzip.zip', 'stem.',,,'TREE')\n"
" Returns: stem.0 = 4\n"
" stem.1 = unzip.c\n"
" stem.2 = unshrink.c\n"
" stem.3 = extract.c\n"
" stem.4 = OS2/\n"
" stem.OS2.0 = 3\n"
" stem.OS2.1 = makefile.os2\n"
" stem.OS2.2 = os2.c\n"
" stem.OS2.3 = DLL/\n"
" stem.OS2.DLL.0 = 2\n"
" stem.OS2.DLL.1 = def\n"
" stem.OS2.DLL.2 = unzipapi.c\n"
"\n"
" And the following contain the contents of the\n"
" various programs:\n"
" stem.unzip.c\n"
" stem.unshrink.c\n"
" stem.extract.c\n"
" stem.OS2.makefile.os2\n"
" stem.OS2.os2.c\n"
" stem.OS2.DLL.dll.def\n"
" stem.OS2.DLL.unzipapi.c\n" },
{ "UZVER" , "UZVer" ,
"rc = UZVer([option])\n\n"
" rc String containing UnZip version info in the form 'x.xx'\n"
" If option is 'L' then info is in the form 'x.xx of <date>",
"Returns the version number of UnZip\n" },
{ "UZAPIVER" , "UZAPIVer" ,
"rc = UZAPIVer([option])\n\n"
" rc String containing API version info in the form 'x.xx'\n"
" If option is 'L' then info is in the form 'x.xx of <date>",
"Returns the version number of the API\n" },
{ 0 }
};
char *REXXBrief = "\
REXX functions:\n\
UZDropFuncs -- Makes all functions in this package unknown to REXX\n\
UZLoadFuncs -- Makes all functions in this package known to REXX\n\
UZFileTree -- Searches for files matching a given filespec\n\
UZUnZip -- UnZip command-line entry point\n\
UZUnZipToVar -- Unzip one file to a variable\n\
UZUnZipToStem -- Unzip files to a variable array\n\
UZVer -- Returns the UnZip version number\n\
UZAPIVer -- Returns the API version number\n";
#endif /* API_DOC && OS2DLL */

Binary file not shown.

View File

@@ -0,0 +1,2 @@
#include "wx/msw/wx.rc"

View File

@@ -0,0 +1,625 @@
/*---------------------------------------------------------------------------
ttyio.c
This file contains routines for doing console input/output, including code
for non-echoing input. It is used by the encryption/decryption code but
does not contain any restricted code itself. This file is shared between
Info-ZIP's Zip and UnZip.
Contains: echo() (VMS only)
Echon() (Unix only)
Echoff() (Unix only)
screenlines() (Unix only)
zgetch() (Unix and non-Unix versions)
getp() ("PC," Unix/Atari/Be, VMS/VMCMS/MVS)
---------------------------------------------------------------------------*/
#define __TTYIO_C /* identifies this source module */
#include "zip.h"
#include "crypt.h"
#if (CRYPT || (defined(UNZIP) && !defined(FUNZIP)))
/* Non-echo console/keyboard input is needed for (en/de)cryption's password
* entry, and for UnZip(SFX)'s MORE and Pause features.
* (The corresponding #endif is found at the end of this module.)
*/
#include "ttyio.h"
#ifndef PUTC
# define PUTC putc
#endif
#ifdef ZIP
# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
# undef GLOBAL
# endif
# define GLOBAL(g) g
#else
# define GLOBAL(g) G.g
#endif
#ifdef __BEOS__ /* why yes, we do */
# define HAVE_TERMIOS_H
#endif
#ifdef _POSIX_VERSION
# ifndef USE_POSIX_TERMIOS
# define USE_POSIX_TERMIOS /* use POSIX style termio (termios) */
# endif
# ifndef HAVE_TERMIOS_H
# define HAVE_TERMIOS_H /* POSIX termios.h */
# endif
#endif /* _POSIX_VERSION */
#ifdef UNZIP /* Zip handles this with the unix/configure script */
# ifndef _POSIX_VERSION
# if (defined(SYSV) || defined(CRAY)) && !defined(__MINT__)
# ifndef USE_SYSV_TERMIO
# define USE_SYSV_TERMIO
# endif
# ifdef COHERENT
# ifndef HAVE_TERMIO_H
# define HAVE_TERMIO_H
# endif
# ifdef HAVE_SYS_TERMIO_H
# undef HAVE_SYS_TERMIO_H
# endif
# else /* !COHERENT */
# ifdef HAVE_TERMIO_H
# undef HAVE_TERMIO_H
# endif
# ifndef HAVE_SYS_TERMIO_H
# define HAVE_SYS_TERMIO_H
# endif
# endif /* ?COHERENT */
# endif /* (SYSV || CRAY) && !__MINT__ */
# endif /* !_POSIX_VERSION */
# if !(defined(BSD4_4) || defined(SYSV) || defined(__convexc__))
# ifndef NO_FCNTL_H
# define NO_FCNTL_H
# endif
# endif /* !(BSD4_4 || SYSV || __convexc__) */
#endif /* UNZIP */
#ifdef HAVE_TERMIOS_H
# ifndef USE_POSIX_TERMIOS
# define USE_POSIX_TERMIOS
# endif
#endif
#if (defined(HAVE_TERMIO_H) || defined(HAVE_SYS_TERMIO_H))
# ifndef USE_SYSV_TERMIO
# define USE_SYSV_TERMIO
# endif
#endif
#if (defined(UNZIP) && !defined(FUNZIP) && defined(UNIX) && defined(MORE))
# include <sys/ioctl.h>
# define GOT_IOCTL_H
/* int ioctl OF((int, int, zvoid *)); GRR: may need for some systems */
#endif
#ifndef HAVE_WORKING_GETCH
/* include system support for switching of console echo */
# ifdef VMS
# include <descrip.h>
# include <iodef.h>
# include <ttdef.h>
# include <starlet.h>
# include <ssdef.h>
# else /* !VMS */
# ifdef HAVE_TERMIOS_H
# include <termios.h>
# define sgttyb termios
# define sg_flags c_lflag
# define GTTY(f, s) tcgetattr(f, (zvoid *) s)
# define STTY(f, s) tcsetattr(f, TCSAFLUSH, (zvoid *) s)
# else /* !HAVE_TERMIOS_H */
# ifdef USE_SYSV_TERMIO /* Amdahl, Cray, all SysV? */
# ifdef HAVE_TERMIO_H
# include <termio.h>
# endif
# ifdef HAVE_SYS_TERMIO_H
# include <sys/termio.h>
# endif
# ifdef NEED_PTEM
# include <sys/stream.h>
# include <sys/ptem.h>
# endif
# define sgttyb termio
# define sg_flags c_lflag
# define GTTY(f,s) ioctl(f,TCGETA,(zvoid *)s)
# define STTY(f,s) ioctl(f,TCSETAW,(zvoid *)s)
# else /* !USE_SYSV_TERMIO */
# ifndef CMS_MVS
# if (!defined(MINIX) && !defined(GOT_IOCTL_H))
# include <sys/ioctl.h>
# endif
# include <sgtty.h>
# define GTTY gtty
# define STTY stty
# ifdef UNZIP
/*
* XXX : Are these declarations needed at all ????
*/
/*
* GRR: let's find out... Hmmm, appears not...
int gtty OF((int, struct sgttyb *));
int stty OF((int, struct sgttyb *));
*/
# endif
# endif /* !CMS_MVS */
# endif /* ?USE_SYSV_TERMIO */
# endif /* ?HAVE_TERMIOS_H */
# ifndef NO_FCNTL_H
# ifndef UNZIP
# include <fcntl.h>
# endif
# else
char *ttyname OF((int));
# endif
# endif /* ?VMS */
#endif /* !HAVE_WORKING_GETCH */
#ifndef HAVE_WORKING_GETCH
#ifdef VMS
/*
* Turn keyboard echoing on or off (VMS). Loosely based on VMSmunch.c
* and hence on Joe Meadows' file.c code.
*/
int echo(opt)
int opt;
{
/*
* For VMS v5.x:
* IO$_SENSEMODE/SETMODE info: Programming, Vol. 7A, System Programming,
* I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
* sys$assign(), sys$qio() info: Programming, Vol. 4B, System Services,
* System Services Reference Manual, pp. sys-23, sys-379
* fixed-length descriptor info: Programming, Vol. 3, System Services,
* Intro to System Routines, sec. 2.9.2
* Greg Roelofs, 15 Aug 91
*/
/* SKM: make global? */
static struct dsc$descriptor_s DevDesc =
{11, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$COMMAND"};
/* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
static short DevChan, iosb[4];
static long status;
static unsigned long oldmode[2], newmode[2]; /* each = 8 bytes */
/* assign a channel to standard input */
status = sys$assign(&DevDesc, &DevChan, 0, 0);
if (!(status & 1))
return status;
/* use sys$qio and the IO$_SENSEMODE function to determine the current
* tty status (for password reading, could use IO$_READVBLK function
* instead, but echo on/off will be more general)
*/
status = sys$qiow(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
oldmode, 8, 0, 0, 0, 0);
if (!(status & 1))
return status;
status = iosb[0];
if (!(status & 1))
return status;
/* copy old mode into new-mode buffer, then modify to be either NOECHO or
* ECHO (depending on function argument opt)
*/
newmode[0] = oldmode[0];
newmode[1] = oldmode[1];
if (opt == 0) /* off */
newmode[1] |= TT$M_NOECHO; /* set NOECHO bit */
else
newmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */
/* use the IO$_SETMODE function to change the tty status */
status = sys$qiow(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
newmode, 8, 0, 0, 0, 0);
if (!(status & 1))
return status;
status = iosb[0];
if (!(status & 1))
return status;
/* deassign the sys$input channel by way of clean-up */
status = sys$dassgn(DevChan);
if (!(status & 1))
return status;
return SS$_NORMAL; /* we be happy */
} /* end function echo() */
#else /* !VMS: basically Unix */
/* For VM/CMS and MVS, non-echo terminal input is not (yet?) supported. */
#ifndef CMS_MVS
#ifdef ZIP /* moved to globals.h for UnZip */
static int echofd=(-1); /* file descriptor whose echo is off */
#endif
/*
* Turn echo off for file descriptor f. Assumes that f is a tty device.
*/
void Echoff(__G__ f)
__GDEF
int f; /* file descriptor for which to turn echo off */
{
struct sgttyb sg; /* tty device structure */
GLOBAL(echofd) = f;
GTTY(f, &sg); /* get settings */
sg.sg_flags &= ~ECHO; /* turn echo off */
STTY(f, &sg);
}
/*
* Turn echo back on for file descriptor echofd.
*/
void Echon(__G)
__GDEF
{
struct sgttyb sg; /* tty device structure */
if (GLOBAL(echofd) != -1) {
GTTY(GLOBAL(echofd), &sg); /* get settings */
sg.sg_flags |= ECHO; /* turn echo on */
STTY(GLOBAL(echofd), &sg);
GLOBAL(echofd) = -1;
}
}
#endif /* !CMS_MVS */
#endif /* ?VMS */
#if (defined(UNZIP) && !defined(FUNZIP))
#if (defined(UNIX) || defined(__BEOS__))
#ifdef MORE
/*
* Get the number of lines on the output terminal. SCO Unix apparently
* defines TIOCGWINSZ but doesn't support it (!M_UNIX).
*
* GRR: will need to know width of terminal someday, too, to account for
* line-wrapping.
*/
#if (defined(TIOCGWINSZ) && !defined(M_UNIX))
int screenlines()
{
struct winsize wsz;
#ifdef DEBUG_WINSZ
static int firsttime = TRUE;
#endif
/* see termio(4) under, e.g., SunOS */
if (ioctl(1, TIOCGWINSZ, &wsz) == 0) {
#ifdef DEBUG_WINSZ
if (firsttime) {
firsttime = FALSE;
fprintf(stderr, "ttyio.c screenlines(): ws_row = %d\n",
wsz.ws_row);
}
#endif
/* number of columns = ws_col */
return (wsz.ws_row > 0)? wsz.ws_row : 24; /* number of rows */
} else { /* this happens when piping to more(1), for example */
#ifdef DEBUG_WINSZ
if (firsttime) {
firsttime = FALSE;
fprintf(stderr,
"ttyio.c screenlines(): ioctl(TIOCGWINSZ) failed\n"));
}
#endif
return 24; /* VT-100 assumed to be minimal hardware */
}
}
#else /* !TIOCGWINSZ: service not available, fall back to semi-bogus method */
int screenlines()
{
char *envptr, *getenv();
int n;
/* GRR: this is overly simplistic, but don't have access to stty/gtty
* system anymore
*/
envptr = getenv("LINES");
if (envptr == (char *)NULL || (n = atoi(envptr)) < 5)
return 24; /* VT-100 assumed to be minimal hardware */
else
return n;
}
#endif /* ?(TIOCGWINSZ && !M_UNIX) */
#endif /* MORE */
/*
* Get a character from the given file descriptor without echo or newline.
*/
int zgetch(__G__ f)
__GDEF
int f; /* file descriptor from which to read */
{
#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
char oldmin, oldtim;
#endif
char c;
struct sgttyb sg; /* tty device structure */
GTTY(f, &sg); /* get settings */
#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
oldmin = sg.c_cc[VMIN]; /* save old values */
oldtim = sg.c_cc[VTIME];
sg.c_cc[VMIN] = 1; /* need only one char to return read() */
sg.c_cc[VTIME] = 0; /* no timeout */
sg.sg_flags &= ~ICANON; /* canonical mode off */
#else
sg.sg_flags |= CBREAK; /* cbreak mode on */
#endif
sg.sg_flags &= ~ECHO; /* turn echo off, too */
STTY(f, &sg); /* set cbreak mode */
GLOBAL(echofd) = f; /* in case ^C hit (not perfect: still CBREAK) */
read(f, &c, 1); /* read our character */
#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
sg.c_cc[VMIN] = oldmin; /* restore old values */
sg.c_cc[VTIME] = oldtim;
sg.sg_flags |= ICANON; /* canonical mode on */
#else
sg.sg_flags &= ~CBREAK; /* cbreak mode off */
#endif
sg.sg_flags |= ECHO; /* turn echo on */
STTY(f, &sg); /* restore canonical mode */
GLOBAL(echofd) = -1;
return (int)c;
}
#else /* !UNIX && !__BEOS__ */
int zgetch(__G__ f)
__GDEF
int f; /* file descriptor from which to read (must be open already) */
{
char c, c2;
/*---------------------------------------------------------------------------
Get a character from the given file descriptor without echo; can't fake
CBREAK mode (i.e., newline required), but can get rid of all chars up to
and including newline.
---------------------------------------------------------------------------*/
echoff(f);
read(f, &c, 1);
if (c != '\n')
do {
read(f, &c2, 1); /* throw away all other chars up thru newline */
} while (c2 != '\n');
echon();
return (int)c;
}
#endif /* ?(UNIX || __BEOS__) */
#endif /* UNZIP && !FUNZIP */
#endif /* !HAVE_WORKING_GETCH */
#if CRYPT /* getp() is only used with full encryption */
/*
* Simple compile-time check for source compatibility between
* zcrypt and ttyio:
*/
#if (!defined(CR_MAJORVER) || (CR_MAJORVER < 2) || (CR_MINORVER < 7))
error: This Info-ZIP tool requires zcrypt 2.7 or later.
#endif
/*
* Get a password of length n-1 or less into *p using the prompt *m.
* The entered password is not echoed.
*/
#ifdef HAVE_WORKING_GETCH
/*
* For the AMIGA, getch() is defined as Agetch(), which is in
* amiga/filedate.c; SAS/C 6.x provides a getch(), but since Agetch()
* uses the infrastructure that is already in place in filedate.c, it is
* smaller. With this function, echoff() and echon() are not needed.
*
* For the MAC, a non-echo macgetch() function is defined in the MacOS
* specific sources which uses the event handling mechanism of the
* desktop window manager to get a character from the keyboard.
*
* For the other systems in this section, a non-echo getch() function
* is either contained the C runtime library (conio package), or getch()
* is defined as an alias for a similar system specific RTL function.
*/
#ifndef WINDLL /* WINDLL does not support a console interface */
#ifndef QDOS /* QDOS supplies a variant of this function */
/* This is the getp() function for all systems (with TTY type user interface)
* that supply a working `non-echo' getch() function for "raw" console input.
*/
char *getp(__G__ m, p, n)
__GDEF
ZCONST char *m; /* prompt for password */
char *p; /* return value: line input */
int n; /* bytes available in p[] */
{
char c; /* one-byte buffer for read() to use */
int i; /* number of characters input */
char *w; /* warning on retry */
/* get password */
w = "";
do {
fputs(w, stderr); /* warning if back again */
fputs(m, stderr); /* display prompt and flush */
fflush(stderr);
i = 0;
do { /* read line, keeping first n characters */
if ((c = (char)getch()) == '\r')
c = '\n'; /* until user hits CR */
if (c == 8 || c == 127) {
if (i > 0) i--; /* the `backspace' and `del' keys works */
}
else if (i < n)
p[i++] = c; /* truncate past n */
} while (c != '\n');
PUTC('\n', stderr); fflush(stderr);
w = "(line too long--try again)\n";
} while (p[i-1] != '\n');
p[i-1] = 0; /* terminate at newline */
return p; /* return pointer to password */
} /* end function getp() */
#endif /* !QDOS */
#endif /* !WINDLL */
#else /* !HAVE_WORKING_GETCH */
#if (defined(UNIX) || defined(__MINT__) || defined(__BEOS__))
#ifndef _PATH_TTY
# ifdef __MINT__
# define _PATH_TTY ttyname(2)
# else
# define _PATH_TTY "/dev/tty"
# endif
#endif
char *getp(__G__ m, p, n)
__GDEF
ZCONST char *m; /* prompt for password */
char *p; /* return value: line input */
int n; /* bytes available in p[] */
{
char c; /* one-byte buffer for read() to use */
int i; /* number of characters input */
char *w; /* warning on retry */
int f; /* file descriptor for tty device */
#ifdef PASSWD_FROM_STDIN
/* Read from stdin. This is unsafe if the password is stored on disk. */
f = 0;
#else
/* turn off echo on tty */
if ((f = open(_PATH_TTY, 0)) == -1)
return NULL;
#endif
/* get password */
w = "";
do {
fputs(w, stderr); /* warning if back again */
fputs(m, stderr); /* prompt */
fflush(stderr);
i = 0;
echoff(f);
do { /* read line, keeping n */
read(f, &c, 1);
if (i < n)
p[i++] = c;
} while (c != '\n');
echon();
PUTC('\n', stderr); fflush(stderr);
w = "(line too long--try again)\n";
} while (p[i-1] != '\n');
p[i-1] = 0; /* terminate at newline */
#ifndef PASSWD_FROM_STDIN
close(f);
#endif
return p; /* return pointer to password */
} /* end function getp() */
#endif /* UNIX || __MINT__ || __BEOS__ */
#if (defined(VMS) || defined(CMS_MVS))
char *getp(__G__ m, p, n)
__GDEF
ZCONST char *m; /* prompt for password */
char *p; /* return value: line input */
int n; /* bytes available in p[] */
{
char c; /* one-byte buffer for read() to use */
int i; /* number of characters input */
char *w; /* warning on retry */
FILE *f; /* file structure for SYS$COMMAND device */
#ifdef PASSWD_FROM_STDIN
f = stdin;
#else
if ((f = fopen(ctermid(NULL), "r")) == NULL)
return NULL;
#endif
/* get password */
fflush(stdout);
w = "";
do {
if (*w) /* bug: VMS apparently adds \n to NULL fputs */
fputs(w, stderr); /* warning if back again */
fputs(m, stderr); /* prompt */
fflush(stderr);
i = 0;
echoff(f);
do { /* read line, keeping n */
if ((c = (char)getc(f)) == '\r')
c = '\n';
if (i < n)
p[i++] = c;
} while (c != '\n');
echon();
PUTC('\n', stderr); fflush(stderr);
w = "(line too long--try again)\n";
} while (p[i-1] != '\n');
p[i-1] = 0; /* terminate at newline */
#ifndef PASSWD_FROM_STDIN
fclose(f);
#endif
return p; /* return pointer to password */
} /* end function getp() */
#endif /* VMS || CMS_MVS */
#endif /* ?HAVE_WORKING_GETCH */
#endif /* CRYPT */
#endif /* CRYPT || (UNZIP && !FUNZIP) */

1424
utils/Install/sfxzip/unix.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,230 @@
/*---------------------------------------------------------------------------
unreduce.c
The Reducing algorithm is actually a combination of two distinct algorithms.
The first algorithm compresses repeated byte sequences, and the second al-
gorithm takes the compressed stream from the first algorithm and applies a
probabilistic compression method.
* Copyright 1989 Samuel H. Smith; All rights reserved
*
* Do not distribute modified versions without my permission.
* Do not remove or alter this notice or any other copyright notice.
* If you use this in your own program you must distribute source code.
* Do not use any of this in a commercial product.
See the accompanying file "COPYING" in UnZip source and binary distributions
for further information. This code is NOT used unless USE_SMITH_CODE is
explicitly defined (==> COPYRIGHT_CLEAN is not defined).
---------------------------------------------------------------------------*/
#define UNZIP_INTERNAL
#include "unzip.h" /* defines COPYRIGHT_CLEAN by default */
#ifndef COPYRIGHT_CLEAN
/**************************************/
/* UnReduce Defines, Typedefs, etc. */
/**************************************/
#define DLE 144
typedef uch f_array[64]; /* for followers[256][64] */
/******************************/
/* UnReduce Local Functions */
/******************************/
static void LoadFollowers OF((__GPRO__ f_array *followers, uch *Slen));
/*******************************/
/* UnReduce Global Constants */
/*******************************/
static ZCONST shrint L_table[] =
{0, 0x7f, 0x3f, 0x1f, 0x0f};
static ZCONST shrint D_shift[] =
{0, 0x07, 0x06, 0x05, 0x04};
static ZCONST shrint D_mask[] =
{0, 0x01, 0x03, 0x07, 0x0f};
static ZCONST shrint B_table[] =
{8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8};
/*************************/
/* Function unreduce() */
/*************************/
void unreduce(__G) /* expand probabilistically reduced data */
__GDEF
{
register int lchar = 0;
shrint nchar;
shrint ExState = 0;
shrint V = 0;
shrint Len = 0;
long s = G.ucsize; /* number of bytes left to decompress */
unsigned w = 0; /* position in output window slide[] */
unsigned u = 1; /* true if slide[] unflushed */
uch Slen[256];
f_array *followers = (f_array *)(slide + 0x4000);
int factor = G.lrec.compression_method - 1;
LoadFollowers(__G__ followers, Slen);
while (s > 0 /* && (!zipeof) */) {
if (Slen[lchar] == 0)
READBITS(8, nchar) /* ; */
else {
READBITS(1, nchar) /* ; */
if (nchar != 0)
READBITS(8, nchar) /* ; */
else {
shrint follower;
int bitsneeded = B_table[Slen[lchar]];
READBITS(bitsneeded, follower) /* ; */
nchar = followers[lchar][follower];
}
}
/* expand the resulting byte */
switch (ExState) {
case 0:
if (nchar != DLE) {
s--;
slide[w++] = (uch)nchar;
if (w == 0x4000) {
flush(__G__ slide, (ulg)w, 0);
w = u = 0;
}
}
else
ExState = 1;
break;
case 1:
if (nchar != 0) {
V = nchar;
Len = V & L_table[factor];
if (Len == L_table[factor])
ExState = 2;
else
ExState = 3;
} else {
s--;
slide[w++] = DLE;
if (w == 0x4000)
{
flush(__G__ slide, (ulg)w, 0);
w = u = 0;
}
ExState = 0;
}
break;
case 2:{
Len += nchar;
ExState = 3;
}
break;
case 3:{
register unsigned e;
register unsigned n = Len + 3;
register unsigned d = w - ((((V >> D_shift[factor]) &
D_mask[factor]) << 8) + nchar + 1);
s -= n;
do {
n -= (e = (e = 0x4000 - ((d &= 0x3fff) > w ? d : w)) > n ?
n : e);
if (u && w <= d)
{
memzero(slide + w, e);
w += e;
d += e;
}
else
if (w - d < e) /* (assume unsigned comparison) */
do { /* slow to avoid memcpy() overlap */
slide[w++] = slide[d++];
} while (--e);
else
{
memcpy(slide + w, slide + d, e);
w += e;
d += e;
}
if (w == 0x4000)
{
flush(__G__ slide, (ulg)w, 0);
w = u = 0;
}
} while (n);
ExState = 0;
}
break;
}
/* store character for next iteration */
lchar = nchar;
}
/* flush out slide */
flush(__G__ slide, (ulg)w, 0);
}
/******************************/
/* Function LoadFollowers() */
/******************************/
static void LoadFollowers(__G__ followers, Slen)
__GDEF
f_array *followers;
uch *Slen;
{
register int x;
register int i;
for (x = 255; x >= 0; x--) {
READBITS(6, Slen[x]) /* ; */
for (i = 0; (uch)i < Slen[x]; i++)
READBITS(8, followers[x][i]) /* ; */
}
}
#endif /* !COPYRIGHT_CLEAN */

View File

@@ -0,0 +1,301 @@
/*---------------------------------------------------------------------------
unshrink.c version 1.21 23 Nov 95
NOTE: This code may or may not infringe on the so-called "Welch
patent" owned by Unisys. (From reading the patent, it appears
that a pure LZW decompressor is *not* covered, but this claim has
not been tested in court, and Unisys is reported to believe other-
wise.) It is therefore the responsibility of the user to acquire
whatever license(s) may be required for legal use of this code.
THE INFO-ZIP GROUP DISCLAIMS ALL LIABILITY FOR USE OF THIS CODE
IN VIOLATION OF APPLICABLE PATENT LAW.
Shrinking is basically a dynamic LZW algorithm with allowed code sizes of
up to 13 bits; in addition, there is provision for partial clearing of
leaf nodes. PKWARE uses the special code 256 (decimal) to indicate a
change in code size or a partial clear of the code tree: 256,1 for the
former and 256,2 for the latter. [Note that partial clearing can "orphan"
nodes: the parent-to-be can be cleared before its new child is added,
but the child is added anyway (as an orphan, as though the parent still
existed). When the tree fills up to the point where the parent node is
reused, the orphan is effectively "adopted." Versions prior to 1.05 were
affected more due to greater use of pointers (to children and siblings
as well as parents).]
This replacement version of unshrink.c was written from scratch. It is
based only on the algorithms described in Mark Nelson's _The Data Compres-
sion Book_ and in Terry Welch's original paper in the June 1984 issue of
IEEE _Computer_; no existing source code, including any in Nelson's book,
was used.
Memory requirements have been reduced in this version and are now no more
than the original Sam Smith code. This is still larger than any of the
other algorithms: at a minimum, 8K+8K+16K (stack+values+parents) assuming
16-bit short ints, and this does not even include the output buffer (the
other algorithms leave the uncompressed data in the work area, typically
called slide[]). For machines with a 64KB data space this is a problem,
particularly when text conversion is required and line endings have more
than one character. UnZip's solution is to use two roughly equal halves
of outbuf for the ASCII conversion in such a case; the "unshrink" argument
to flush() signals that this is the case.
For large-memory machines, a second outbuf is allocated for translations,
but only if unshrinking and only if translations are required.
| binary mode | text mode
---------------------------------------------------
big mem | big outbuf | big outbuf + big outbuf2 <- malloc'd here
small mem | small outbuf | half + half small outbuf
Copyright 1994, 1995 Greg Roelofs. See the accompanying file "COPYING"
in UnZip 5.20 (or later) source or binary distributions.
---------------------------------------------------------------------------*/
#define UNZIP_INTERNAL
#include "unzip.h" /* defines LZW_CLEAN by default */
#ifndef LZW_CLEAN
static void partial_clear OF((__GPRO));
#ifdef DEBUG
# define OUTDBG(c) \
if ((c)<32 || (c)>=127) pipeit("\\x%02x",(c)); else { }
#else
# define OUTDBG(c)
#endif
/* HSIZE is defined as 2^13 (8192) in unzip.h */
#define BOGUSCODE 256
#define FLAG_BITS parent /* upper bits of parent[] used as flag bits */
#define CODE_MASK (HSIZE - 1) /* 0x1fff (lower bits are parent's index) */
#define FREE_CODE HSIZE /* 0x2000 (code is unused or was cleared) */
#define HAS_CHILD (HSIZE << 1) /* 0x4000 (code has a child--do not clear) */
#define parent G.area.shrink.Parent
#define Value G.area.shrink.value /* "value" conflicts with Pyramid ioctl.h */
#define stack G.area.shrink.Stack
/***********************/
/* Function unshrink() */
/***********************/
int unshrink(__G)
__GDEF
{
int offset = (HSIZE - 1);
uch *stacktop = stack + offset;
register uch *newstr;
int codesize=9, len, KwKwK, error;
shrint code, oldcode, freecode, curcode;
shrint lastfreecode;
unsigned int outbufsiz;
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
/* Normally realbuf and outbuf will be the same. However, if the data
* are redirected to a large memory buffer, realbuf will point to the
* new location while outbuf will remain pointing to the malloc'd
* memory buffer. */
uch *realbuf = G.outbuf;
#else
# define realbuf G.outbuf
#endif
/*---------------------------------------------------------------------------
Initialize various variables.
---------------------------------------------------------------------------*/
lastfreecode = BOGUSCODE;
#ifndef VMS /* VMS uses its own buffer scheme for textmode flush(). */
#ifndef SMALL_MEM
/* non-memory-limited machines: allocate second (large) buffer for
* textmode conversion in flush(), but only if needed */
if (G.pInfo->textmode && !G.outbuf2 &&
(G.outbuf2 = (uch *)malloc(TRANSBUFSIZ)) == (uch *)NULL)
return PK_MEM3;
#endif
#endif /* !VMS */
for (code = 0; code < BOGUSCODE; ++code) {
Value[code] = (uch)code;
parent[code] = BOGUSCODE;
}
for (code = BOGUSCODE+1; code < HSIZE; ++code)
parent[code] = FREE_CODE;
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide) { /* use normal outbuf unless we're a DLL routine */
realbuf = G.redirect_buffer;
outbufsiz = G.redirect_size;
} else
#endif
#ifdef DLL
if (G.pInfo->textmode && !G.redirect_data)
#else
if (G.pInfo->textmode)
#endif
outbufsiz = RAWBUFSIZ;
else
outbufsiz = OUTBUFSIZ;
G.outptr = realbuf;
G.outcnt = 0L;
/*---------------------------------------------------------------------------
Get and output first code, then loop over remaining ones.
---------------------------------------------------------------------------*/
READBITS(codesize, oldcode)
if (!G.zipeof) {
*G.outptr++ = (uch)oldcode;
OUTDBG((uch)oldcode)
++G.outcnt;
}
do {
READBITS(codesize, code)
if (G.zipeof)
break;
if (code == BOGUSCODE) { /* possible to have consecutive escapes? */
READBITS(codesize, code)
if (code == 1) {
++codesize;
Trace((stderr, " (codesize now %d bits)\n", codesize));
} else if (code == 2) {
Trace((stderr, " (partial clear code)\n"));
partial_clear(__G); /* clear leafs (nodes with no children) */
Trace((stderr, " (done with partial clear)\n"));
lastfreecode = BOGUSCODE; /* reset start of free-node search */
}
continue;
}
/*-----------------------------------------------------------------------
Translate code: traverse tree from leaf back to root.
-----------------------------------------------------------------------*/
newstr = stacktop;
curcode = code;
if (parent[curcode] == FREE_CODE) {
/* or (FLAG_BITS[curcode] & FREE_CODE)? */
KwKwK = TRUE;
Trace((stderr, " (found a KwKwK code %d; oldcode = %d)\n", code,
oldcode));
--newstr; /* last character will be same as first character */
curcode = oldcode;
} else
KwKwK = FALSE;
do {
*newstr-- = Value[curcode];
curcode = (shrint)(parent[curcode] & CODE_MASK);
} while (curcode != BOGUSCODE);
len = (int)(stacktop - newstr++);
if (KwKwK)
*stacktop = *newstr;
/*-----------------------------------------------------------------------
Write expanded string in reverse order to output buffer.
-----------------------------------------------------------------------*/
Trace((stderr, "code %4d; oldcode %4d; char %3d (%c); string [", code,
oldcode, (int)(*newstr), (*newstr<32 || *newstr>=127)? ' ':*newstr));
{
register uch *p;
for (p = newstr; p < newstr+len; ++p) {
*G.outptr++ = *p;
OUTDBG(*p)
if (++G.outcnt == outbufsiz) {
Trace((stderr, "doing flush(), outcnt = %lu\n", G.outcnt));
if ((error = flush(__G__ realbuf, G.outcnt, TRUE)) != 0)
pipeit("unshrink: flush() error (%d)\n",
error);
Trace((stderr, "done with flush()\n"));
G.outptr = realbuf;
G.outcnt = 0L;
}
}
}
/*-----------------------------------------------------------------------
Add new leaf (first character of newstr) to tree as child of oldcode.
-----------------------------------------------------------------------*/
/* search for freecode */
freecode = (shrint)(lastfreecode + 1);
/* add if-test before loop for speed? */
while (parent[freecode] != FREE_CODE)
++freecode;
lastfreecode = freecode;
Trace((stderr, "]; newcode %d\n", freecode));
Value[freecode] = *newstr;
parent[freecode] = oldcode;
oldcode = code;
} while (!G.zipeof);
/*---------------------------------------------------------------------------
Flush any remaining data and return to sender...
---------------------------------------------------------------------------*/
if (G.outcnt > 0L) {
Trace((stderr, "doing final flush(), outcnt = %lu\n", G.outcnt));
if ((error = flush(__G__ realbuf, G.outcnt, TRUE)) != 0)
pipeit("unshrink: flush() error (%d)\n", error);
Trace((stderr, "done with flush()\n"));
}
return PK_OK;
} /* end function unshrink() */
/****************************/
/* Function partial_clear() */ /* no longer recursive... */
/****************************/
static void partial_clear(__G)
__GDEF
{
register shrint code;
/* clear all nodes which have no children (i.e., leaf nodes only) */
/* first loop: mark each parent as such */
for (code = BOGUSCODE+1; code < HSIZE; ++code) {
register shrint cparent = (shrint)(parent[code] & CODE_MASK);
if (cparent > BOGUSCODE && cparent != FREE_CODE)
FLAG_BITS[cparent] |= HAS_CHILD; /* set parent's child-bit */
}
/* second loop: clear all nodes *not* marked as parents; reset flag bits */
for (code = BOGUSCODE+1; code < HSIZE; ++code) {
if (FLAG_BITS[code] & HAS_CHILD) /* just clear child-bit */
FLAG_BITS[code] &= ~HAS_CHILD;
else { /* leaf: lose it */
Trace((stderr, "%d\n", code));
parent[code] = FREE_CODE;
}
}
return;
}
#endif /* !LZW_CLEAN */

1744
utils/Install/sfxzip/unzip.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------
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 "version.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, 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, 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, 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);
}

2390
utils/Install/sfxzip/win32.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff