#define __EXTRACT_C
#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef WINDLL
# ifdef POCKET_UNZIP
# include "wince/intrface.h"
# else
# include "windll/windll.h"
# endif
#endif
#include "crypt.h"
#define GRRDUMP(buf,len) { \
int i, j; \
\
for (j = 0; j < (len)/16; ++j) { \
printf(" "); \
for (i = 0; i < 16; ++i) \
printf("%02x ", (uch)(buf)[i+(j<<4)]); \
printf("\n "); \
for (i = 0; i < 16; ++i) { \
char c = (char)(buf)[i+(j<<4)]; \
\
if (c == '\n') \
printf("\\n "); \
else if (c == '\r') \
printf("\\r "); \
else \
printf(" %c ", c); \
} \
printf("\n"); \
} \
if ((len) % 16) { \
printf(" "); \
for (i = j<<4; i < (len); ++i) \
printf("%02x ", (uch)(buf)[i]); \
printf("\n "); \
for (i = j<<4; i < (len); ++i) { \
char c = (char)(buf)[i]; \
\
if (c == '\n') \
printf("\\n "); \
else if (c == '\r') \
printf("\\r "); \
else \
printf(" %c ", c); \
} \
printf("\n"); \
} \
}
static int store_info OF((__GPRO));
#ifdef SET_DIR_ATTRIB
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,
unsigned *pnum_dirs, dirtime **pdirlist,
int error_in_archive));
#else
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,
int error_in_archive));
#endif
static int extract_or_test_member OF((__GPRO));
#ifndef SFX
static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
unsigned compr_offset,
int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
uch *eb_ucptr, ulg eb_ucsize)));
#endif
#if (defined(VMS) || defined(VMS_TEXT_CONV))
static void decompress_bits OF((uch *outptr, unsigned needlen,
ZCONST uch *bitptr));
#endif
#ifdef SET_DIR_ATTRIB
static int dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
#endif
static ZCONST char Far VersionMsg[] =
" skipping: %-22s need %s compat. v%u.%u (can do v%u.%u)\n";
static ZCONST char Far ComprMsgNum[] =
" skipping: %-22s unsupported compression method %u\n";
#ifndef SFX
static ZCONST char Far ComprMsgName[] =
" skipping: %-22s `%s' method not supported\n";
static ZCONST char Far CmprNone[] = "store";
static ZCONST char Far CmprShrink[] = "shrink";
static ZCONST char Far CmprReduce[] = "reduce";
static ZCONST char Far CmprImplode[] = "implode";
static ZCONST char Far CmprTokenize[] = "tokenize";
static ZCONST char Far CmprDeflate[] = "deflate";
static ZCONST char Far CmprDeflat64[] = "deflate64";
static ZCONST char Far CmprDCLImplode[] = "DCL implode";
static ZCONST char Far *ComprNames[NUM_METHODS] = {
CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode
};
#endif
static ZCONST char Far FilNamMsg[] =
"%s: bad filename length (%s)\n";
static ZCONST char Far ExtFieldMsg[] =
"%s: bad extra field length (%s)\n";
static ZCONST char Far OffsetMsg[] =
"file #%lu: bad zipfile offset (%s): %ld\n";
static ZCONST char Far ExtractMsg[] =
"%8sing: %-22s %s%s";
#ifndef SFX
static ZCONST char Far LengthMsg[] =
"%s %s: %ld bytes required to uncompress to %lu bytes;\n %s\
supposed to require %lu bytes%s%s%s\n";
#endif
static ZCONST char Far BadFileCommLength[] = "%s: bad file comment length\n";
static ZCONST char Far LocalHdrSig[] = "local header sig";
static ZCONST char Far BadLocalHdr[] = "file #%lu: bad local header\n";
static ZCONST char Far AttemptRecompensate[] =
" (attempting to re-compensate)\n";
#ifndef SFX
static ZCONST char Far BackslashPathSep[] =
"warning: %s appears to use backslashes as path separators\n";
#endif
static ZCONST char Far AbsolutePathWarning[] =
"warning: stripped absolute path spec from %s\n";
static ZCONST char Far SkipVolumeLabel[] =
" skipping: %-22s %svolume label\n";
#ifdef SET_DIR_ATTRIB
static ZCONST char Far DirlistEntryNoMem[] =
"warning: cannot alloc memory for dir times/permissions/UID/GID\n";
static ZCONST char Far DirlistSortNoMem[] =
"warning: cannot alloc memory to sort dir times/perms/etc.\n";
static ZCONST char Far DirlistSetAttrFailed[] =
"warning: set times/attribs failed for %s\n";
#endif
#ifndef WINDLL
static ZCONST char Far ReplaceQuery[] =
"replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
static ZCONST char Far AssumeNone[] = " NULL\n(assuming [N]one)\n";
static ZCONST char Far NewNameQuery[] = "new name: ";
static ZCONST char Far InvalidResponse[] = "error: invalid response [%c]\n";
#endif
static ZCONST char Far ErrorInArchive[] =
"At least one %serror was detected in %s.\n";
static ZCONST char Far ZeroFilesTested[] =
"Caution: zero files tested in %s.\n";
#ifndef VMS
static ZCONST char Far VMSFormatQuery[] =
"\n%s: stored in VMS format. Extract anyway? (y/n) ";
#endif
#if CRYPT
static ZCONST char Far SkipCannotGetPasswd[] =
" skipping: %-22s unable to get password\n";
static ZCONST char Far SkipIncorrectPasswd[] =
" skipping: %-22s incorrect password\n";
static ZCONST char Far FilesSkipBadPasswd[] =
"%lu file%s skipped because of incorrect password.\n";
static ZCONST char Far MaybeBadPasswd[] =
" (may instead be incorrect password)\n";
#else
static ZCONST char Far SkipEncrypted[] =
" skipping: %-22s encrypted (not supported)\n";
#endif
static ZCONST char Far NoErrInCompData[] =
"No errors detected in compressed data of %s.\n";
static ZCONST char Far NoErrInTestedFiles[] =
"No errors detected in %s for the %lu file%s tested.\n";
static ZCONST char Far FilesSkipped[] =
"%lu file%s skipped because of unsupported compression or encoding.\n";
static ZCONST char Far ErrUnzipFile[] = " error: %s%s %s\n";
static ZCONST char Far ErrUnzipNoFile[] = "\n error: %s%s\n";
static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
static ZCONST char Far Inflate[] = "inflate";
#ifndef SFX
static ZCONST char Far Explode[] = "explode";
#ifndef LZW_CLEAN
static ZCONST char Far Unshrink[] = "unshrink";
#endif
#endif
#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
static ZCONST char Far FileTruncated[] =
"warning: %s is probably truncated\n";
#endif
static ZCONST char Far FileUnknownCompMethod[] =
"%s: unknown compression method\n";
static ZCONST char Far BadCRC[] = " bad CRC %08lx (should be %08lx)\n";
char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
char ZCONST Far TruncNTSD[] =
" compressed WinNT security data missing (%d bytes)%s";
#ifndef SFX
static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
static ZCONST char Far InvalidComprDataEAs[] =
" invalid compressed data for EAs\n";
# if (defined(WIN32) && defined(NTSD_EAS))
static ZCONST char Far InvalidSecurityEAs[] =
" EAs fail security check\n";
# endif
static ZCONST char Far UnsuppNTSDVersEAs[] =
" unsupported NTSD EAs version %d\n";
static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
static ZCONST char Far UnknComprMethodEAs[] =
" unknown compression method for EAs (%u)\n";
static ZCONST char Far NotEnoughMemEAs[] =
" out of memory while inflating EAs\n";
static ZCONST char Far UnknErrorEAs[] =
" unknown error on extended attributes\n";
#endif
static ZCONST char Far UnsupportedExtraField[] =
"\nerror: unsupported extra-field compression type (%u)--skipping\n";
static ZCONST char Far BadExtraFieldCRC[] =
"error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
int extract_or_test_files(__G)
__GDEF
{
unsigned i, j;
long cd_bufstart;
uch *cd_inptr;
int cd_incnt;
ulg filnum=0L, blknum=0L;
int reached_end, no_endsig_found;
int error, error_in_archive=PK_COOL;
int *fn_matched=NULL, *xn_matched=NULL;
unsigned members_processed;
ulg num_skipped=0L, num_bad_pwd=0L;
LONGINT old_extra_bytes = 0L;
#ifdef SET_DIR_ATTRIB
unsigned num_dirs=0;
dirtime *dirlist=(dirtime *)NULL, **sorted_dirlist=(dirtime **)NULL;
#endif
G.pInfo = G.info;
#if CRYPT
G.newzip = TRUE;
#endif
#ifndef SFX
G.reported_backslash = FALSE;
#endif
if (G.filespecs > 0 &&
(fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
for (i = 0; i < G.filespecs; ++i)
fn_matched[i] = FALSE;
if (G.xfilespecs > 0 &&
(xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
for (i = 0; i < G.xfilespecs; ++i)
xn_matched[i] = FALSE;
members_processed = 0;
no_endsig_found = FALSE;
reached_end = FALSE;
while (!reached_end) {
j = 0;
#ifdef AMIGA
memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
#endif
while ((j < DIR_BLKSIZ)) {
G.pInfo = &G.info[j];
if (readbuf(__G__ G.sig, 4) == 0) {
error_in_archive = PK_EOF;
reached_end = TRUE;
break;
}
if (strncmp(G.sig, central_hdr_sig, 4)) {
if ((members_processed & (unsigned)0xFFFF) ==
(unsigned)G.ecrec.total_entries_central_dir) {
no_endsig_found =
(strncmp(G.sig, end_central_sig, 4) != 0);
} else {
Info(slide, 0x401, ((char *)slide,
LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
Info(slide, 0x401, ((char *)slide,
LoadFarString(ReportMsg)));
error_in_archive = PK_BADERR;
}
reached_end = TRUE;
break;
}
if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
error_in_archive = error;
reached_end = TRUE;
break;
}
if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
PK_COOL)
{
if (error > error_in_archive)
error_in_archive = error;
if (error > PK_WARN) {
Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
FnFilter1(G.filename), "central"));
reached_end = TRUE;
break;
}
}
if ((error = do_string(__G__ G.crec.extra_field_length,
EXTRA_FIELD)) != 0)
{
if (error > error_in_archive)
error_in_archive = error;
if (error > PK_WARN) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(ExtFieldMsg),
FnFilter1(G.filename), "central"));
reached_end = TRUE;
break;
}
}
#ifdef AMIGA
G.filenote_slot = j;
if ((error = do_string(__G__ G.crec.file_comment_length,
uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
#else
if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
!= PK_COOL)
#endif
{
if (error > error_in_archive)
error_in_archive = error;
if (error > PK_WARN) {
Info(slide, 0x421, ((char *)slide,
LoadFarString(BadFileCommLength),
FnFilter1(G.filename)));
reached_end = TRUE;
break;
}
}
if (G.process_all_files) {
if (store_info(__G))
++j;
else
++num_skipped;
} else {
int do_this_file;
if (G.filespecs == 0)
do_this_file = TRUE;
else {
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;
if (fn_matched)
fn_matched[i] = TRUE;
break;
}
}
if (do_this_file) {
for (i = 0; i < G.xfilespecs; i++)
if (match(G.filename, G.pxnames[i], uO.C_flag)) {
do_this_file = FALSE;
if (xn_matched)
xn_matched[i] = TRUE;
break;
}
}
if (do_this_file) {
if (store_info(__G))
++j;
else
++num_skipped;
}
}
members_processed++;
}
cd_bufstart = G.cur_zipfile_bufstart;
cd_inptr = G.inptr;
cd_incnt = G.incnt;
error = extract_or_test_entrylist(__G__ j,
&filnum, &num_bad_pwd, &old_extra_bytes,
#ifdef SET_DIR_ATTRIB
&num_dirs, &dirlist,
#endif
error_in_archive);
if (error != PK_COOL) {
if (error > error_in_archive)
error_in_archive = error;
if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
if (fn_matched)
free((zvoid *)fn_matched);
if (xn_matched)
free((zvoid *)xn_matched);
return error_in_archive;
}
}
#ifdef USE_STRM_INPUT
fseek((FILE *)G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);
G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
#else
G.cur_zipfile_bufstart =
lseek(G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);
#endif
read(G.zipfd, (char *)G.inbuf, INBUFSIZ);
G.inptr = cd_inptr;
G.incnt = cd_incnt;
++blknum;
#ifdef TEST
printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
cur_zipfile_bufstart);
printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
printf("incnt = %d\n\n", G.incnt);
#endif
}
#ifdef SET_DIR_ATTRIB
if (num_dirs > 0) {
sorted_dirlist = (dirtime **)malloc(num_dirs*sizeof(dirtime *));
if (sorted_dirlist == (dirtime **)NULL) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(DirlistSortNoMem)));
while (dirlist != (dirtime *)NULL) {
dirtime *d = dirlist;
dirlist = dirlist->next;
free(d);
}
} else {
if (num_dirs == 1)
sorted_dirlist[0] = dirlist;
else {
for (i = 0; i < num_dirs; ++i) {
sorted_dirlist[i] = dirlist;
dirlist = dirlist->next;
}
qsort((char *)sorted_dirlist, num_dirs, sizeof(dirtime *),
dircomp);
}
Trace((stderr, "setting directory times/perms/attributes\n"));
for (i = 0; i < num_dirs; ++i) {
dirtime *d = sorted_dirlist[i];
Trace((stderr, "dir = %s\n", d->fn));
if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
Info(slide, 0x201, ((char *)slide,
LoadFarString(DirlistSetAttrFailed), d->fn));
if (!error_in_archive)
error_in_archive = error;
}
free(d->fn);
free(d);
}
free(sorted_dirlist);
}
}
#endif
#if (defined(WIN32) && defined(NTSD_EAS))
process_defer_NT(__G);
#endif
if (fn_matched) {
for (i = 0; i < G.filespecs; ++i)
if (!fn_matched[i]) {
#ifdef DLL
if (!G.redirect_data && !G.redirect_text)
Info(slide, 0x401, ((char *)slide,
LoadFarString(FilenameNotMatched), G.pfnames[i]));
else
setFileNotFound(__G);
#else
Info(slide, 1, ((char *)slide,
LoadFarString(FilenameNotMatched), G.pfnames[i]));
#endif
if (error_in_archive <= PK_WARN)
error_in_archive = PK_FIND;
}
free((zvoid *)fn_matched);
}
if (xn_matched) {
for (i = 0; i < G.xfilespecs; ++i)
if (!xn_matched[i])
Info(slide, 0x401, ((char *)slide,
LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
free((zvoid *)xn_matched);
}
#ifndef SFX
if (no_endsig_found) {
Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
if (!error_in_archive)
error_in_archive = PK_WARN;
}
#endif
if (uO.tflag) {
ulg num = filnum - num_bad_pwd;
if (uO.qflag < 2) {
if (error_in_archive)
Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
(error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
else if (num == 0L)
Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
G.zipfn));
else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
G.zipfn));
else
Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
, G.zipfn, num, (num==1L)? "":"s"));
if (num_skipped > 0L)
Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
num_skipped, (num_skipped==1L)? "":"s"));
#if CRYPT
if (num_bad_pwd > 0L)
Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
, num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
#endif
} else if ((uO.qflag == 0) && !error_in_archive && (num == 0))
Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
G.zipfn));
}
if ((filnum == 0) && error_in_archive <= PK_WARN) {
if (num_skipped > 0L)
error_in_archive = IZ_UNSUP;
else
error_in_archive = PK_FIND;
}
#if CRYPT
else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
error_in_archive = IZ_BADPWD;
#endif
else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
error_in_archive = IZ_UNSUP;
#if CRYPT
else if ((num_bad_pwd > 0L) && !error_in_archive)
error_in_archive = PK_WARN;
#endif
return error_in_archive;
}
static int store_info(__G)
__GDEF
{
#ifdef SFX
# ifdef USE_DEFLATE64
# define UNKN_COMPR \
(G.crec.compression_method!=STORED && G.crec.compression_method<DEFLATED \
&& G.crec.compression_method>ENHDEFLATED)
# else
# define UNKN_COMPR \
(G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED)
# endif
#else
# ifdef COPYRIGHT_CLEAN
# define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
G.crec.compression_method <= REDUCED4)
# else
# define UNKN_RED FALSE
# endif
# ifdef LZW_CLEAN
# define UNKN_SHR (G.crec.compression_method == SHRUNK)
# else
# define UNKN_SHR FALSE
# endif
# ifdef USE_DEFLATE64
# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
G.crec.compression_method==TOKENIZED || \
G.crec.compression_method>ENHDEFLATED)
# else
# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
G.crec.compression_method==TOKENIZED || \
G.crec.compression_method>DEFLATED)
# endif
#endif
G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1;
G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8;
G.pInfo->textfile = G.crec.internal_file_attributes & 1;
G.pInfo->crc = G.crec.crc32;
G.pInfo->compr_size = G.crec.csize;
G.pInfo->uncompr_size = G.crec.ucsize;
switch (uO.aflag) {
case 0:
G.pInfo->textmode = FALSE;
break;
case 1:
G.pInfo->textmode = G.pInfo->textfile;
break;
default:
G.pInfo->textmode = TRUE;
break;
}
if (G.crec.version_needed_to_extract[1] == VMS_) {
if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
FnFilter1(G.filename), "VMS",
G.crec.version_needed_to_extract[0] / 10,
G.crec.version_needed_to_extract[0] % 10,
VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
return 0;
}
#ifndef VMS
else if (!uO.tflag && !IS_OVERWRT_ALL) {
Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
FnFilter1(G.filename)));
fgets(G.answerbuf, 9, stdin);
if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
return 0;
}
#endif
} else if (G.crec.version_needed_to_extract[0] > UNZIP_VERSION) {
if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
FnFilter1(G.filename), "PK",
G.crec.version_needed_to_extract[0] / 10,
G.crec.version_needed_to_extract[0] % 10,
UNZIP_VERSION / 10, UNZIP_VERSION % 10));
return 0;
}
if UNKN_COMPR {
if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
#ifndef SFX
if (G.crec.compression_method < NUM_METHODS)
Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
FnFilter1(G.filename),
LoadFarStringSmall(ComprNames[G.crec.compression_method])));
else
#endif
Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
FnFilter1(G.filename),
G.crec.compression_method));
}
return 0;
}
#if (!CRYPT)
if (G.pInfo->encrypted) {
if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
FnFilter1(G.filename)));
return 0;
}
#endif
mapattr(__G);
G.pInfo->diskstart = G.crec.disk_number_start;
G.pInfo->offset = (long)G.crec.relative_offset_local_header;
return 1;
}
static int extract_or_test_entrylist(__G__ numchunk,
pfilnum, pnum_bad_pwd, pold_extra_bytes,
#ifdef SET_DIR_ATTRIB
pnum_dirs, pdirlist,
#endif
error_in_archive)
__GDEF
unsigned numchunk;
ulg *pfilnum;
ulg *pnum_bad_pwd;
LONGINT *pold_extra_bytes;
#ifdef SET_DIR_ATTRIB
unsigned *pnum_dirs;
dirtime **pdirlist;
#endif
int error_in_archive;
{
unsigned i;
int renamed, query;
int skip_entry;
long bufstart, inbuf_offset, request;
int error, errcode;
#define SKIP_NO 0
#define SKIP_Y_EXISTING 1
#define SKIP_Y_NONEXIST 2
for (i = 0; i < numchunk; ++i) {
(*pfilnum)++;
G.pInfo = &G.info[i];
#ifdef NOVELL_BUG_FAILSAFE
G.dne = FALSE;
#endif
request = G.pInfo->offset + G.extra_bytes;
inbuf_offset = request % INBUFSIZ;
bufstart = request - inbuf_offset;
Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
request, inbuf_offset));
Trace((stderr,
"debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
bufstart, G.cur_zipfile_bufstart));
if (request < 0) {
Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
G.zipfn, LoadFarString(ReportMsg)));
error_in_archive = PK_ERR;
if (*pfilnum == 1 && G.extra_bytes != 0L) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(AttemptRecompensate)));
*pold_extra_bytes = G.extra_bytes;
G.extra_bytes = 0L;
request = G.pInfo->offset;
inbuf_offset = request % INBUFSIZ;
bufstart = request - inbuf_offset;
Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
request, inbuf_offset));
Trace((stderr,
"debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
bufstart, G.cur_zipfile_bufstart));
if (request < 0) {
Trace((stderr,
"debug: recompensated request still < 0\n"));
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(SeekMsg),
G.zipfn, LoadFarString(ReportMsg)));
error_in_archive = PK_BADERR;
continue;
}
} else {
error_in_archive = PK_BADERR;
continue;
}
}
if (bufstart != G.cur_zipfile_bufstart) {
Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
#ifdef USE_STRM_INPUT
fseek((FILE *)G.zipfd, (LONGINT)bufstart, SEEK_SET);
G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
#else
G.cur_zipfile_bufstart =
lseek(G.zipfd, (LONGINT)bufstart, SEEK_SET);
#endif
if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ)) <= 0)
{
Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
*pfilnum, "lseek", bufstart));
error_in_archive = PK_BADERR;
continue;
}
G.inptr = G.inbuf + (int)inbuf_offset;
G.incnt -= (int)inbuf_offset;
} else {
G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
G.inptr = G.inbuf + (int)inbuf_offset;
}
if (readbuf(__G__ G.sig, 4) == 0) {
Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
*pfilnum, "EOF", request));
error_in_archive = PK_BADERR;
continue;
}
if (strncmp(G.sig, local_hdr_sig, 4)) {
Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
*pfilnum, LoadFarStringSmall(LocalHdrSig), request));
error_in_archive = PK_ERR;
if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
(G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(AttemptRecompensate)));
if (G.extra_bytes) {
*pold_extra_bytes = G.extra_bytes;
G.extra_bytes = 0L;
} else
G.extra_bytes = *pold_extra_bytes;
if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
(readbuf(__G__ G.sig, 4) == 0)) {
if (error != PK_BADERR)
Info(slide, 0x401, ((char *)slide,
LoadFarString(OffsetMsg), *pfilnum, "EOF", request));
error_in_archive = PK_BADERR;
continue;
}
if (strncmp(G.sig, local_hdr_sig, 4)) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(OffsetMsg), *pfilnum,
LoadFarStringSmall(LocalHdrSig), request));
error_in_archive = PK_BADERR;
continue;
}
} else
continue;
}
if ((error = process_local_file_hdr(__G)) != PK_COOL) {
Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
*pfilnum));
error_in_archive = error;
continue;
}
if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
PK_COOL)
{
if (error > error_in_archive)
error_in_archive = error;
if (error > PK_WARN) {
Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
FnFilter1(G.filename), "local"));
continue;
}
}
if (G.extra_field != (uch *)NULL) {
free(G.extra_field);
G.extra_field = (uch *)NULL;
}
if ((error =
do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
{
if (error > error_in_archive)
error_in_archive = error;
if (error > PK_WARN) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(ExtFieldMsg),
FnFilter1(G.filename), "local"));
continue;
}
}
#if CRYPT
if (G.pInfo->encrypted &&
(error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
if (error == PK_WARN) {
if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
Info(slide, 0x401, ((char *)slide,
LoadFarString(SkipIncorrectPasswd),
FnFilter1(G.filename)));
++(*pnum_bad_pwd);
} else {
if (error > error_in_archive)
error_in_archive = error;
Info(slide, 0x401, ((char *)slide,
LoadFarString(SkipCannotGetPasswd),
FnFilter1(G.filename)));
}
continue;
}
#endif
#ifdef DLL
if (!uO.tflag && !uO.cflag && !G.redirect_data)
#else
if (!uO.tflag && !uO.cflag)
#endif
{
renamed = FALSE;
startover:
query = FALSE;
skip_entry = SKIP_NO;
#ifndef SFX
if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
char *p=G.filename;
if (*p) do {
if (*p == '\\') {
if (!G.reported_backslash) {
Info(slide, 0x21, ((char *)slide,
LoadFarString(BackslashPathSep), G.zipfn));
G.reported_backslash = TRUE;
if (!error_in_archive)
error_in_archive = PK_WARN;
}
*p = '/';
}
} while (*PREINCSTR(p));
}
#endif
if (!renamed) {
if (G.filename[0] == '/') {
Info(slide, 0x401, ((char *)slide,
LoadFarString(AbsolutePathWarning),
FnFilter1(G.filename)));
if (!error_in_archive)
error_in_archive = PK_WARN;
do {
char *p = G.filename + 1;
do {
*(p-1) = *p;
} while (*p++ != '\0');
} while (G.filename[0] == '/');
}
}
error = mapname(__G__ renamed);
if ((errcode = error & ~MPN_MASK) != PK_OK &&
error_in_archive < errcode)
error_in_archive = errcode;
if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
if (errcode == MPN_CREATED_DIR) {
#ifdef SET_DIR_ATTRIB
dirtime *d_entry;
d_entry = (dirtime *)malloc(sizeof(dirtime));
if (d_entry == (dirtime *)NULL) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(DirlistEntryNoMem)));
} else {
unsigned eb_izux_flg;
d_entry->next = (*pdirlist);
(*pdirlist) = d_entry;
(*pdirlist)->fn =
(char *)malloc(strlen(G.filename) + 1);
if ((*pdirlist)->fn == (char *)NULL) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(DirlistEntryNoMem)));
(*pdirlist) = d_entry->next;
free(d_entry);
if (!error_in_archive)
error_in_archive = PK_WARN;
continue;
}
strcpy((*pdirlist)->fn, G.filename);
(*pdirlist)->perms = G.pInfo->file_attr;
#ifdef USE_EF_UT_TIME
eb_izux_flg = G.extra_field? ef_scan_for_izux(
G.extra_field, G.lrec.extra_field_length, 0,
G.lrec.last_mod_dos_datetime,
#ifdef IZ_CHECK_TZ
(G.tz_is_valid ? &((*pdirlist)->u.t3) : NULL),
#else
&((*pdirlist)->u.t3),
#endif
(*pdirlist)->uidgid)
: 0;
#else
eb_izux_flg = 0;
#endif
if (eb_izux_flg & EB_UT_FL_MTIME) {
TTrace((stderr,
"\nextract: Unix dir e.f. modtime = %ld\n",
(*pdirlist)->u.t3.mtime));
} else {
(*pdirlist)->u.t3.mtime = dos_to_unix_time(
G.lrec.last_mod_dos_datetime);
}
if (eb_izux_flg & EB_UT_FL_ATIME) {
TTrace((stderr,
"\nextract: Unix dir e.f. actime = %ld\n",
(*pdirlist)->u.t3.atime));
} else {
(*pdirlist)->u.t3.atime =
(*pdirlist)->u.t3.mtime;
}
(*pdirlist)->have_uidgid =
#ifdef RESTORE_UIDGID
(uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
#else
0;
#endif
++(*pnum_dirs);
}
#endif
} else if (errcode == MPN_VOL_LABEL) {
#ifdef DOS_OS2_W32
Info(slide, 0x401, ((char *)slide,
LoadFarString(SkipVolumeLabel),
FnFilter1(G.filename),
uO.volflag? "hard disk " : ""));
#else
Info(slide, 1, ((char *)slide,
LoadFarString(SkipVolumeLabel),
FnFilter1(G.filename), ""));
#endif
} else if (errcode > MPN_INF_SKIP &&
error_in_archive < PK_ERR)
error_in_archive = PK_ERR;
Trace((stderr, "mapname(%s) returns error code = %d\n",
FnFilter1(G.filename), error));
continue;
}
#ifdef QDOS
QFilename(__G__ G.filename);
#endif
switch (check_for_newer(__G__ G.filename)) {
case DOES_NOT_EXIST:
#ifdef NOVELL_BUG_FAILSAFE
G.dne = TRUE;
#endif
if (uO.fflag && !renamed)
skip_entry = SKIP_Y_NONEXIST;
break;
case EXISTS_AND_OLDER:
#ifdef UNIXBACKUP
if (!uO.B_flag)
#endif
{
if (IS_OVERWRT_NONE)
skip_entry = SKIP_Y_EXISTING;
else if (!IS_OVERWRT_ALL)
query = TRUE;
}
break;
case EXISTS_AND_NEWER:
#ifdef UNIXBACKUP
if ((!uO.B_flag && IS_OVERWRT_NONE) ||
#else
if (IS_OVERWRT_NONE ||
#endif
(uO.uflag && !renamed)) {
skip_entry = SKIP_Y_EXISTING;
} else {
#ifdef UNIXBACKUP
if (!IS_OVERWRT_ALL && !uO.B_flag)
#else
if (!IS_OVERWRT_ALL)
#endif
query = TRUE;
}
break;
}
if (query) {
#ifdef WINDLL
switch (G.lpUserFunctions->replace != NULL ?
(*G.lpUserFunctions->replace)(G.filename) :
IDM_REPLACE_NONE) {
case IDM_REPLACE_RENAME:
_ISO_INTERN(G.filename);
renamed = TRUE;
goto startover;
case IDM_REPLACE_ALL:
G.overwrite_mode = OVERWRT_ALWAYS;
case IDM_REPLACE_YES:
break;
case IDM_REPLACE_NONE:
G.overwrite_mode = OVERWRT_NEVER;
case IDM_REPLACE_NO:
skip_entry = SKIP_Y_EXISTING;
break;
}
#else
extent fnlen;
reprompt:
Info(slide, 0x81, ((char *)slide,
LoadFarString(ReplaceQuery),
FnFilter1(G.filename)));
if (fgets(G.answerbuf, 9, stdin) == (char *)NULL) {
Info(slide, 1, ((char *)slide,
LoadFarString(AssumeNone)));
*G.answerbuf = 'N';
if (!error_in_archive)
error_in_archive = 1;
}
switch (*G.answerbuf) {
case 'r':
case 'R':
do {
Info(slide, 0x81, ((char *)slide,
LoadFarString(NewNameQuery)));
fgets(G.filename, FILNAMSIZ, stdin);
fnlen = strlen(G.filename);
if (lastchar(G.filename, fnlen) == '\n')
G.filename[--fnlen] = '\0';
} while (fnlen == 0);
#ifdef WIN32
_OEM_INTERN(G.filename);
#endif
renamed = TRUE;
goto startover;
case 'A':
G.overwrite_mode = OVERWRT_ALWAYS;
case 'y':
case 'Y':
break;
case 'N':
G.overwrite_mode = OVERWRT_NEVER;
case 'n':
skip_entry = SKIP_Y_EXISTING;
break;
default:
Info(slide, 1, ((char *)slide,
LoadFarString(InvalidResponse), *G.answerbuf));
goto reprompt;
}
#endif
}
if (skip_entry != SKIP_NO) {
#ifdef WINDLL
if (skip_entry == SKIP_Y_EXISTING) {
Info(slide, 0, ((char *)slide,
((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
"Target file exists.\nSkipping %s\n" :
"Target file newer.\nSkipping %s\n"),
FnFilter1(G.filename)));
}
#endif
continue;
}
}
#ifdef DLL
if ((G.statreportcb != NULL) &&
(*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
G.filename, NULL)) {
return IZ_CTRLC;
}
#endif
#ifdef MACOS
UserStop();
#endif
#ifdef AMIGA
G.filenote_slot = i;
#endif
G.disk_full = 0;
if ((error = extract_or_test_member(__G)) != PK_COOL) {
if (error > error_in_archive)
error_in_archive = error;
#ifdef DLL
if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
#else
if (G.disk_full > 1) {
#endif
return error_in_archive;
}
}
#ifdef DLL
if ((G.statreportcb != NULL) &&
(*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
G.filename, (zvoid *)&G.lrec.ucsize)) {
return IZ_CTRLC;
}
#endif
#ifdef MACOS
UserStop();
#endif
}
return error_in_archive;
}
static int extract_or_test_member(__G)
__GDEF
{
char *nul="[empty] ", *txt="[text] ", *bin="[binary]";
#ifdef CMS_MVS
char *ebc="[ebcdic]";
#endif
register int b;
int r, error=PK_COOL;
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
ulg wsize;
#else
# define wsize WSIZE
#endif
G.bits_left = 0;
G.bitbuf = 0L;
G.zipeof = 0;
G.newfile = TRUE;
G.crc32val = CRCVAL_INITIAL;
#ifdef SYMLINKS
if (S_ISLNK(G.pInfo->file_attr) &&
(G.pInfo->hostnum == UNIX_ || G.pInfo->hostnum == ATARI_ ||
G.pInfo->hostnum == BEOS_) &&
!uO.tflag && !uO.cflag && (G.lrec.ucsize > 0))
G.symlnk = TRUE;
else
G.symlnk = FALSE;
#endif
if (uO.tflag) {
if (!uO.qflag)
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
FnFilter1(G.filename), "", ""));
} else {
#ifdef DLL
if (uO.cflag && !G.redirect_data)
#else
if (uO.cflag)
#endif
{
#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
G.outfile = freopen("", "wb", stdout);
#else
G.outfile = stdout;
#endif
#ifdef DOS_FLX_NLM_OS2_W32
#if (defined(__HIGHC__) && !defined(FLEXOS))
setmode(G.outfile, _BINARY);
#else
setmode(fileno(G.outfile), O_BINARY);
#endif
# define NEWLINE "\r\n"
#else
# define NEWLINE "\n"
#endif
#ifdef VMS
if (open_outfile(__G))
return PK_DISK;
#endif
} else if (open_outfile(__G))
return PK_DISK;
}
defer_leftover_input(__G);
switch (G.lrec.compression_method) {
case STORED:
if (!uO.tflag && QCOND2) {
#ifdef SYMLINKS
if (G.symlnk)
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
"link", FnFilter1(G.filename), "", ""));
else
#endif
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
"extract", FnFilter1(G.filename),
(uO.aflag != 1 )?
"" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
bin)), uO.cflag? NEWLINE : ""));
}
#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
G.outptr = redirSlide;
G.outcnt = 0L;
while ((b = NEXTBYTE) != EOF) {
*G.outptr++ = (uch)b;
if (++G.outcnt == wsize) {
error = flush(__G__ redirSlide, G.outcnt, 0);
G.outptr = redirSlide;
G.outcnt = 0L;
if (error != PK_COOL || G.disk_full) break;
}
}
if (G.outcnt)
flush(__G__ redirSlide, G.outcnt, 0);
break;
#ifndef SFX
#ifndef LZW_CLEAN
case SHRUNK:
if (!uO.tflag && QCOND2) {
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
(uO.aflag != 1 )?
"" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
}
if ((r = unshrink(__G)) != PK_COOL) {
if (r < PK_DISK) {
if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipFile),
LoadFarString(NotEnoughMem),
LoadFarStringSmall2(Unshrink),
FnFilter1(G.filename)));
else
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipNoFile),
LoadFarString(NotEnoughMem),
LoadFarStringSmall2(Unshrink)));
}
error = r;
}
break;
#endif
#ifndef COPYRIGHT_CLEAN
case REDUCED1:
case REDUCED2:
case REDUCED3:
case REDUCED4:
if (!uO.tflag && QCOND2) {
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
"unreduc", FnFilter1(G.filename),
(uO.aflag != 1 )?
"" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
}
if ((r = unreduce(__G)) != PK_COOL) {
error = r;
}
break;
#endif
case IMPLODED:
if (!uO.tflag && QCOND2) {
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
"explod", FnFilter1(G.filename),
(uO.aflag != 1 )?
"" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
}
if (((r = explode(__G)) != 0) && (r != 5)) {
if (r < PK_DISK) {
if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipFile), r == 3?
LoadFarString(NotEnoughMem) :
LoadFarString(InvalidComprData),
LoadFarStringSmall2(Explode),
FnFilter1(G.filename)));
else
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipNoFile), r == 3?
LoadFarString(NotEnoughMem) :
LoadFarString(InvalidComprData),
LoadFarStringSmall2(Explode)));
error = (r == 3)? PK_MEM3 : PK_ERR;
} else {
error = r;
}
}
if (r == 5) {
int warning = ((ulg)G.used_csize <= G.lrec.csize);
if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
"", warning? "warning" : "error", G.used_csize,
G.lrec.ucsize, warning? " " : "", G.lrec.csize,
" [", FnFilter1(G.filename), "]"));
else
Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
"\n", warning? "warning" : "error", G.used_csize,
G.lrec.ucsize, warning? " ":"", G.lrec.csize,
"", "", "."));
error = warning? PK_WARN : PK_ERR;
}
break;
#endif
case DEFLATED:
#ifdef USE_DEFLATE64
case ENHDEFLATED:
#endif
if (!uO.tflag && QCOND2) {
Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
"inflat", FnFilter1(G.filename),
(uO.aflag != 1 )?
"" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
}
#ifndef USE_ZLIB
# define UZinflate inflate
#endif
if ((r = UZinflate(__G__
(G.lrec.compression_method == ENHDEFLATED)))
!= 0) {
if (r < PK_DISK) {
if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipFile), r == 3?
LoadFarString(NotEnoughMem) :
LoadFarString(InvalidComprData),
LoadFarStringSmall2(Inflate),
FnFilter1(G.filename)));
else
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipNoFile), r == 3?
LoadFarString(NotEnoughMem) :
LoadFarString(InvalidComprData),
LoadFarStringSmall2(Inflate)));
error = (r == 3)? PK_MEM3 : PK_ERR;
} else {
error = r;
}
}
break;
default:
Info(slide, 0x401, ((char *)slide,
LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
undefer_input(__G);
return PK_WARN;
}
#ifdef VMS
if (!uO.tflag)
close_outfile(__G);
#else
#ifdef DLL
if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
if (G.redirect_data)
FINISH_REDIRECT();
else
close_outfile(__G);
}
#else
if (!uO.tflag && !uO.cflag)
close_outfile(__G);
#endif
#endif
if (G.disk_full) {
if (G.disk_full > 1) {
#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
if (unlink(G.filename) != 0)
Trace((stderr, "extract.c: could not delete %s\n",
FnFilter1(G.filename)));
#else
Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
FnFilter1(G.filename)));
#endif
error = PK_DISK;
} else {
error = PK_WARN;
}
}
if (error > PK_WARN) {
undefer_input(__G);
return error;
}
if (G.crc32val != G.lrec.crc32) {
if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
Info(slide, 0x401, ((char *)slide, "%-22s ",
FnFilter1(G.filename)));
Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
G.lrec.crc32));
#if CRYPT
if (G.pInfo->encrypted)
Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
#endif
error = PK_ERR;
} else if (uO.tflag) {
#ifndef SFX
if (G.extra_field) {
if ((r = TestExtraField(__G__ G.extra_field,
G.lrec.extra_field_length)) > error)
error = r;
} else
#endif
if (!uO.qflag)
Info(slide, 0, ((char *)slide, " OK\n"));
} else {
if (QCOND2 && !error)
Info(slide, 0, ((char *)slide, "\n"));
}
undefer_input(__G);
return error;
}
#ifndef SFX
static int TestExtraField(__G__ ef, ef_len)
__GDEF
uch *ef;
unsigned ef_len;
{
ush ebID;
unsigned ebLen;
unsigned eb_cmpr_offs = 0;
int r;
while (ef_len >= EB_HEADSIZE) {
ebID = makeword(ef);
ebLen = (unsigned)makeword(ef+EB_LEN);
if (ebLen > (ef_len - EB_HEADSIZE)) {
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
FnFilter1(G.filename)));
Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
ebLen, (ef_len - EB_HEADSIZE)));
return PK_ERR;
}
switch (ebID) {
case EF_OS2:
case EF_ACL:
case EF_MAC3:
case EF_BEOS:
switch (ebID) {
case EF_OS2:
case EF_ACL:
eb_cmpr_offs = EB_OS2_HLEN;
break;
case EF_MAC3:
if (ebLen >= EB_MAC3_HLEN &&
(makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
& EB_M3_FL_UNCMPR) &&
(makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
eb_cmpr_offs = 0;
else
eb_cmpr_offs = EB_MAC3_HLEN;
break;
case EF_BEOS:
if (ebLen >= EB_BEOS_HLEN &&
(*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
(makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
eb_cmpr_offs = 0;
else
eb_cmpr_offs = EB_BEOS_HLEN;
break;
}
if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
!= PK_OK) {
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
FnFilter1(G.filename)));
switch (r) {
case IZ_EF_TRUNC:
Info(slide, 1, ((char *)slide,
LoadFarString(TruncEAs),
ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
break;
case PK_ERR:
Info(slide, 1, ((char *)slide,
LoadFarString(InvalidComprDataEAs)));
break;
case PK_MEM3:
case PK_MEM4:
Info(slide, 1, ((char *)slide,
LoadFarString(NotEnoughMemEAs)));
break;
default:
if ((r & 0xff) != PK_ERR)
Info(slide, 1, ((char *)slide,
LoadFarString(UnknErrorEAs)));
else {
ush m = (ush)(r >> 8);
if (m == DEFLATED)
Info(slide, 1, ((char *)slide,
LoadFarString(BadCRC_EAs)));
else
Info(slide, 1, ((char *)slide,
LoadFarString(UnknComprMethodEAs), m));
}
break;
}
return r;
}
break;
case EF_NTSD:
Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
(PK_WARN | 0x4000) :
test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
if (r != PK_OK) {
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
FnFilter1(G.filename)));
switch (r) {
case IZ_EF_TRUNC:
Info(slide, 1, ((char *)slide,
LoadFarString(TruncNTSD),
ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
break;
#if (defined(WIN32) && defined(NTSD_EAS))
case PK_WARN:
Info(slide, 1, ((char *)slide,
LoadFarString(InvalidSecurityEAs)));
break;
#endif
case PK_ERR:
Info(slide, 1, ((char *)slide,
LoadFarString(InvalidComprDataEAs)));
break;
case PK_MEM3:
case PK_MEM4:
Info(slide, 1, ((char *)slide,
LoadFarString(NotEnoughMemEAs)));
break;
case (PK_WARN | 0x4000):
Info(slide, 1, ((char *)slide,
LoadFarString(UnsuppNTSDVersEAs),
(int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
r = PK_WARN;
break;
default:
if ((r & 0xff) != PK_ERR)
Info(slide, 1, ((char *)slide,
LoadFarString(UnknErrorEAs)));
else {
ush m = (ush)(r >> 8);
if (m == DEFLATED)
Info(slide, 1, ((char *)slide,
LoadFarString(BadCRC_EAs)));
else
Info(slide, 1, ((char *)slide,
LoadFarString(UnknComprMethodEAs), m));
}
break;
}
return r;
}
break;
case EF_PKVMS:
if (makelong(ef+EB_HEADSIZE) !=
crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
(extent)(ebLen-4)))
Info(slide, 1, ((char *)slide,
LoadFarString(BadCRC_EAs)));
break;
case EF_PKW32:
case EF_PKUNIX:
case EF_ASIUNIX:
case EF_IZVMS:
case EF_IZUNIX:
case EF_VMCMS:
case EF_MVS:
case EF_SPARK:
case EF_TANDEM:
case EF_THEOS:
case EF_AV:
default:
break;
}
ef_len -= (ebLen + EB_HEADSIZE);
ef += (ebLen + EB_HEADSIZE);
}
if (!uO.qflag)
Info(slide, 0, ((char *)slide, " OK\n"));
return PK_COOL;
}
#ifdef PROTO
static int test_compr_eb(
__GPRO__
uch *eb,
unsigned eb_size,
unsigned compr_offset,
int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
uch *eb_ucptr, ulg eb_ucsize))
#else
static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
__GDEF
uch *eb;
unsigned eb_size;
unsigned compr_offset;
int (*test_uc_ebdata)();
#endif
{
ulg eb_ucsize;
uch *eb_ucptr;
int r;
if (compr_offset < 4)
return PK_OK;
if ((eb_size < (EB_UCSIZE_P + 4)) ||
((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
eb_size <= (compr_offset + EB_CMPRHEADLEN)))
return IZ_EF_TRUNC;
if ((eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
return PK_MEM4;
r = memextract(__G__ eb_ucptr, eb_ucsize,
eb + (EB_HEADSIZE + compr_offset),
(ulg)(eb_size - compr_offset));
if (r == PK_OK && test_uc_ebdata != NULL)
r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
free(eb_ucptr);
return r;
}
#endif
int memextract(__G__ tgt, tgtsize, src, srcsize)
__GDEF
uch *tgt;
ulg tgtsize;
ZCONST uch *src;
ulg srcsize;
{
long old_csize=G.csize;
uch *old_inptr=G.inptr;
int old_incnt=G.incnt;
int r, error=PK_OK;
ush method;
ulg extra_field_crc;
method = makeword(src);
extra_field_crc = makelong(src+2);
G.inptr = (uch *)src + (2 + 4);
G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
G.mem_mode = TRUE;
G.outbufptr = tgt;
G.outsize = tgtsize;
switch (method) {
case STORED:
memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
G.outcnt = G.csize;
break;
case DEFLATED:
#ifdef USE_DEFLATE64
case ENHDEFLATED:
#endif
G.outcnt = 0L;
if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
if (!uO.tflag)
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(ErrUnzipNoFile), r == 3?
LoadFarString(NotEnoughMem) :
LoadFarString(InvalidComprData),
LoadFarStringSmall2(Inflate)));
error = (r == 3)? PK_MEM3 : PK_ERR;
}
if (G.outcnt == 0L)
break;
break;
default:
if (uO.tflag)
error = PK_ERR | ((int)method << 8);
else {
Info(slide, 0x401, ((char *)slide,
LoadFarString(UnsupportedExtraField), method));
error = PK_ERR;
}
break;
}
G.inptr = old_inptr;
G.incnt = old_incnt;
G.csize = old_csize;
G.mem_mode = FALSE;
if (!error) {
register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
if (crcval != extra_field_crc) {
if (uO.tflag)
error = PK_ERR | (DEFLATED << 8);
else {
Info(slide, 0x401, ((char *)slide,
LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
extra_field_crc));
error = PK_ERR;
}
}
}
return error;
}
int memflush(__G__ rawbuf, size)
__GDEF
ZCONST uch *rawbuf;
ulg size;
{
if (size > G.outsize)
return PK_DISK;
memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
G.outbufptr += (unsigned int)size;
G.outsize -= size;
G.outcnt += size;
return 0;
}
#if (defined(VMS) || defined(VMS_TEXT_CONV))
uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
__GDEF
ZCONST uch *ebdata;
unsigned size;
unsigned *retlen;
ZCONST uch *init;
unsigned needlen;
{
uch *ucdata;
int cmptype;
unsigned usiz, csiz;
cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
csiz = size - EB_IZVMS_HLEN;
usiz = (cmptype == EB_IZVMS_BCSTOR ?
csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
if (retlen)
*retlen = usiz;
if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
return NULL;
if (init && (usiz < needlen))
memcpy((char *)ucdata, (ZCONST char *)init, needlen);
switch (cmptype)
{
case EB_IZVMS_BCSTOR:
memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
break;
case EB_IZVMS_BC00:
decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
break;
case EB_IZVMS_BCDEFL:
memextract(__G__ ucdata, (ulg)usiz,
ebdata+EB_IZVMS_HLEN, (ulg)csiz);
break;
default:
free(ucdata);
ucdata = NULL;
}
return ucdata;
}
static void decompress_bits(outptr, needlen, bitptr)
uch *outptr;
unsigned needlen;
ZCONST uch *bitptr;
{
ulg bitbuf = 0;
int bitcnt = 0;
#define _FILL { bitbuf |= (*bitptr++) << bitcnt;\
bitcnt += 8; \
}
while (needlen--)
{
if (bitcnt <= 0)
_FILL;
if (bitbuf & 1)
{
bitbuf >>= 1;
if ((bitcnt -= 1) < 8)
_FILL;
*outptr++ = (uch)bitbuf;
bitcnt -= 8;
bitbuf >>= 8;
}
else
{
*outptr++ = '\0';
bitcnt -= 1;
bitbuf >>= 1;
}
}
}
#endif
char *fnfilter(raw, space)
ZCONST char *raw;
uch *space;
{
#ifndef NATIVE
ZCONST uch *r=(ZCONST uch *)raw;
uch *s=space;
while (*r) {
#ifdef QDOS
if (qlflag & 2) {
if (*r == '/' || *r == '.') {
++r;
*s++ = '_';
continue;
}
} else
#endif
if (*r < 32) {
*s++ = '^', *s++ = (uch)(64 + *r++);
} else {
#ifdef _MBCS
unsigned i;
for (i = CLEN(r); i > 0; i--)
*s++ = *r++;
#else
*s++ = *r++;
#endif
}
}
*s = '\0';
#ifdef WINDLL
INTERN_TO_ISO((char *)space, (char *)space);
#else
#ifdef WIN32
INTERN_TO_OEM((char *)space, (char *)space);
#endif
#endif
return (char *)space;
#else
return (char *)raw;
#endif
}
#ifdef SET_DIR_ATTRIB
static int dircomp(a, b)
ZCONST zvoid *a, *b;
{
return strcmp((*(dirtime **)b)->fn, (*(dirtime **)a)->fn);
}
#if 0
static int namecmp(s1, s2)
ZCONST char *s1, *s2;
{
int d;
for (;;) {
d = (int)(uch)case_map(*s1)
- (int)(uch)case_map(*s2);
if (d || *s1 == 0 || *s2 == 0)
return d;
s1++;
s2++;
}
}
#endif
#endif