13ae76c23SDarkWyrm/*
23ae76c23SDarkWyrm  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
33ae76c23SDarkWyrm
43ae76c23SDarkWyrm  See the accompanying file LICENSE, version 2000-Apr-09 or later
53ae76c23SDarkWyrm  (the contents of which are also included in unzip.h) for terms of use.
63ae76c23SDarkWyrm  If, for some reason, all these files are missing, the Info-ZIP license
73ae76c23SDarkWyrm  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
83ae76c23SDarkWyrm*/
93ae76c23SDarkWyrm/*---------------------------------------------------------------------------
103ae76c23SDarkWyrm
113ae76c23SDarkWyrm  extract.c
123ae76c23SDarkWyrm
133ae76c23SDarkWyrm  This file contains the high-level routines ("driver routines") for extrac-
143ae76c23SDarkWyrm  ting and testing zipfile members.  It calls the low-level routines in files
153ae76c23SDarkWyrm  explode.c, inflate.c, unreduce.c and unshrink.c.
163ae76c23SDarkWyrm
173ae76c23SDarkWyrm  Contains:  extract_or_test_files()
183ae76c23SDarkWyrm             store_info()
193ae76c23SDarkWyrm             extract_or_test_entrylist()
203ae76c23SDarkWyrm             extract_or_test_member()
213ae76c23SDarkWyrm             TestExtraField()
223ae76c23SDarkWyrm             test_compr_eb()
233ae76c23SDarkWyrm             memextract()
243ae76c23SDarkWyrm             memflush()
253ae76c23SDarkWyrm             extract_izvms_block()    (VMS or VMS_TEXT_CONV)
263ae76c23SDarkWyrm             fnfilter()
273ae76c23SDarkWyrm
283ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
293ae76c23SDarkWyrm
303ae76c23SDarkWyrm
313ae76c23SDarkWyrm#define __EXTRACT_C     /* identifies this source module */
323ae76c23SDarkWyrm#define UNZIP_INTERNAL
333ae76c23SDarkWyrm#include "unzip.h"
343ae76c23SDarkWyrm#ifdef WINDLL
353ae76c23SDarkWyrm#  ifdef POCKET_UNZIP
363ae76c23SDarkWyrm#    include "wince/intrface.h"
373ae76c23SDarkWyrm#  else
383ae76c23SDarkWyrm#    include "windll/windll.h"
393ae76c23SDarkWyrm#  endif
403ae76c23SDarkWyrm#endif
413ae76c23SDarkWyrm#include "crypt.h"
423ae76c23SDarkWyrm
433ae76c23SDarkWyrm#define GRRDUMP(buf,len) { \
443ae76c23SDarkWyrm    int i, j; \
453ae76c23SDarkWyrm \
463ae76c23SDarkWyrm    for (j = 0;  j < (len)/16;  ++j) { \
473ae76c23SDarkWyrm        printf("        "); \
483ae76c23SDarkWyrm        for (i = 0;  i < 16;  ++i) \
493ae76c23SDarkWyrm            printf("%02x ", (uch)(buf)[i+(j<<4)]); \
503ae76c23SDarkWyrm        printf("\n        "); \
513ae76c23SDarkWyrm        for (i = 0;  i < 16;  ++i) { \
523ae76c23SDarkWyrm            char c = (char)(buf)[i+(j<<4)]; \
533ae76c23SDarkWyrm \
543ae76c23SDarkWyrm            if (c == '\n') \
553ae76c23SDarkWyrm                printf("\\n "); \
563ae76c23SDarkWyrm            else if (c == '\r') \
573ae76c23SDarkWyrm                printf("\\r "); \
583ae76c23SDarkWyrm            else \
593ae76c23SDarkWyrm                printf(" %c ", c); \
603ae76c23SDarkWyrm        } \
613ae76c23SDarkWyrm        printf("\n"); \
623ae76c23SDarkWyrm    } \
633ae76c23SDarkWyrm    if ((len) % 16) { \
643ae76c23SDarkWyrm        printf("        "); \
653ae76c23SDarkWyrm        for (i = j<<4;  i < (len);  ++i) \
663ae76c23SDarkWyrm            printf("%02x ", (uch)(buf)[i]); \
673ae76c23SDarkWyrm        printf("\n        "); \
683ae76c23SDarkWyrm        for (i = j<<4;  i < (len);  ++i) { \
693ae76c23SDarkWyrm            char c = (char)(buf)[i]; \
703ae76c23SDarkWyrm \
713ae76c23SDarkWyrm            if (c == '\n') \
723ae76c23SDarkWyrm                printf("\\n "); \
733ae76c23SDarkWyrm            else if (c == '\r') \
743ae76c23SDarkWyrm                printf("\\r "); \
753ae76c23SDarkWyrm            else \
763ae76c23SDarkWyrm                printf(" %c ", c); \
773ae76c23SDarkWyrm        } \
783ae76c23SDarkWyrm        printf("\n"); \
793ae76c23SDarkWyrm    } \
803ae76c23SDarkWyrm}
813ae76c23SDarkWyrm
823ae76c23SDarkWyrmstatic int store_info OF((__GPRO));
833ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
843ae76c23SDarkWyrmstatic int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
853ae76c23SDarkWyrm                ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,
863ae76c23SDarkWyrm                unsigned *pnum_dirs, dirtime **pdirlist,
873ae76c23SDarkWyrm                int error_in_archive));
883ae76c23SDarkWyrm#else
893ae76c23SDarkWyrmstatic int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
903ae76c23SDarkWyrm                ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,
913ae76c23SDarkWyrm                int error_in_archive));
923ae76c23SDarkWyrm#endif
933ae76c23SDarkWyrmstatic int extract_or_test_member OF((__GPRO));
943ae76c23SDarkWyrm#ifndef SFX
953ae76c23SDarkWyrm   static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
963ae76c23SDarkWyrm   static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
973ae76c23SDarkWyrm        unsigned compr_offset,
983ae76c23SDarkWyrm        int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
993ae76c23SDarkWyrm                              uch *eb_ucptr, ulg eb_ucsize)));
1003ae76c23SDarkWyrm#endif
1013ae76c23SDarkWyrm#if (defined(VMS) || defined(VMS_TEXT_CONV))
1023ae76c23SDarkWyrm   static void decompress_bits OF((uch *outptr, unsigned needlen,
1033ae76c23SDarkWyrm                                   ZCONST uch *bitptr));
1043ae76c23SDarkWyrm#endif
1053ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
1063ae76c23SDarkWyrm   static int dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
1073ae76c23SDarkWyrm#endif
1083ae76c23SDarkWyrm
1093ae76c23SDarkWyrm
1103ae76c23SDarkWyrm
1113ae76c23SDarkWyrm/*******************************/
1123ae76c23SDarkWyrm/*  Strings used in extract.c  */
1133ae76c23SDarkWyrm/*******************************/
1143ae76c23SDarkWyrm
1153ae76c23SDarkWyrmstatic ZCONST char Far VersionMsg[] =
1163ae76c23SDarkWyrm  "   skipping: %-22s  need %s compat. v%u.%u (can do v%u.%u)\n";
1173ae76c23SDarkWyrmstatic ZCONST char Far ComprMsgNum[] =
1183ae76c23SDarkWyrm  "   skipping: %-22s  unsupported compression method %u\n";
1193ae76c23SDarkWyrm#ifndef SFX
1203ae76c23SDarkWyrm   static ZCONST char Far ComprMsgName[] =
1213ae76c23SDarkWyrm     "   skipping: %-22s  `%s' method not supported\n";
1223ae76c23SDarkWyrm   static ZCONST char Far CmprNone[]       = "store";
1233ae76c23SDarkWyrm   static ZCONST char Far CmprShrink[]     = "shrink";
1243ae76c23SDarkWyrm   static ZCONST char Far CmprReduce[]     = "reduce";
1253ae76c23SDarkWyrm   static ZCONST char Far CmprImplode[]    = "implode";
1263ae76c23SDarkWyrm   static ZCONST char Far CmprTokenize[]   = "tokenize";
1273ae76c23SDarkWyrm   static ZCONST char Far CmprDeflate[]    = "deflate";
1283ae76c23SDarkWyrm   static ZCONST char Far CmprDeflat64[]   = "deflate64";
1293ae76c23SDarkWyrm   static ZCONST char Far CmprDCLImplode[] = "DCL implode";
1303ae76c23SDarkWyrm   static ZCONST char Far *ComprNames[NUM_METHODS] = {
1313ae76c23SDarkWyrm     CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
1323ae76c23SDarkWyrm     CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode
1333ae76c23SDarkWyrm   };
1343ae76c23SDarkWyrm#endif /* !SFX */
1353ae76c23SDarkWyrmstatic ZCONST char Far FilNamMsg[] =
1363ae76c23SDarkWyrm  "%s:  bad filename length (%s)\n";
1373ae76c23SDarkWyrmstatic ZCONST char Far ExtFieldMsg[] =
1383ae76c23SDarkWyrm  "%s:  bad extra field length (%s)\n";
1393ae76c23SDarkWyrmstatic ZCONST char Far OffsetMsg[] =
1403ae76c23SDarkWyrm  "file #%lu:  bad zipfile offset (%s):  %ld\n";
1413ae76c23SDarkWyrmstatic ZCONST char Far ExtractMsg[] =
1423ae76c23SDarkWyrm  "%8sing: %-22s  %s%s";
1433ae76c23SDarkWyrm#ifndef SFX
1443ae76c23SDarkWyrm   static ZCONST char Far LengthMsg[] =
1453ae76c23SDarkWyrm     "%s  %s:  %ld bytes required to uncompress to %lu bytes;\n    %s\
1463ae76c23SDarkWyrm      supposed to require %lu bytes%s%s%s\n";
1473ae76c23SDarkWyrm#endif
1483ae76c23SDarkWyrm
1493ae76c23SDarkWyrmstatic ZCONST char Far BadFileCommLength[] = "%s:  bad file comment length\n";
1503ae76c23SDarkWyrmstatic ZCONST char Far LocalHdrSig[] = "local header sig";
1513ae76c23SDarkWyrmstatic ZCONST char Far BadLocalHdr[] = "file #%lu:  bad local header\n";
1523ae76c23SDarkWyrmstatic ZCONST char Far AttemptRecompensate[] =
1533ae76c23SDarkWyrm  "  (attempting to re-compensate)\n";
1543ae76c23SDarkWyrm#ifndef SFX
1553ae76c23SDarkWyrm   static ZCONST char Far BackslashPathSep[] =
1563ae76c23SDarkWyrm     "warning:  %s appears to use backslashes as path separators\n";
1573ae76c23SDarkWyrm#endif
1583ae76c23SDarkWyrmstatic ZCONST char Far AbsolutePathWarning[] =
1593ae76c23SDarkWyrm  "warning:  stripped absolute path spec from %s\n";
1603ae76c23SDarkWyrmstatic ZCONST char Far SkipVolumeLabel[] =
1613ae76c23SDarkWyrm  "   skipping: %-22s  %svolume label\n";
1623ae76c23SDarkWyrm
1633ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB  /* messages of code for setting directory attributes */
1643ae76c23SDarkWyrm   static ZCONST char Far DirlistEntryNoMem[] =
1653ae76c23SDarkWyrm     "warning:  cannot alloc memory for dir times/permissions/UID/GID\n";
1663ae76c23SDarkWyrm   static ZCONST char Far DirlistSortNoMem[] =
1673ae76c23SDarkWyrm     "warning:  cannot alloc memory to sort dir times/perms/etc.\n";
1683ae76c23SDarkWyrm   static ZCONST char Far DirlistSetAttrFailed[] =
1693ae76c23SDarkWyrm     "warning:  set times/attribs failed for %s\n";
1703ae76c23SDarkWyrm#endif
1713ae76c23SDarkWyrm
1723ae76c23SDarkWyrm#ifndef WINDLL
1733ae76c23SDarkWyrm   static ZCONST char Far ReplaceQuery[] =
1743ae76c23SDarkWyrm     "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
1753ae76c23SDarkWyrm   static ZCONST char Far AssumeNone[] = " NULL\n(assuming [N]one)\n";
1763ae76c23SDarkWyrm   static ZCONST char Far NewNameQuery[] = "new name: ";
1773ae76c23SDarkWyrm   static ZCONST char Far InvalidResponse[] = "error:  invalid response [%c]\n";
1783ae76c23SDarkWyrm#endif /* !WINDLL */
1793ae76c23SDarkWyrm
1803ae76c23SDarkWyrmstatic ZCONST char Far ErrorInArchive[] =
1813ae76c23SDarkWyrm  "At least one %serror was detected in %s.\n";
1823ae76c23SDarkWyrmstatic ZCONST char Far ZeroFilesTested[] =
1833ae76c23SDarkWyrm  "Caution:  zero files tested in %s.\n";
1843ae76c23SDarkWyrm
1853ae76c23SDarkWyrm#ifndef VMS
1863ae76c23SDarkWyrm   static ZCONST char Far VMSFormatQuery[] =
1873ae76c23SDarkWyrm     "\n%s:  stored in VMS format.  Extract anyway? (y/n) ";
1883ae76c23SDarkWyrm#endif
1893ae76c23SDarkWyrm
1903ae76c23SDarkWyrm#if CRYPT
1913ae76c23SDarkWyrm   static ZCONST char Far SkipCannotGetPasswd[] =
1923ae76c23SDarkWyrm     "   skipping: %-22s  unable to get password\n";
1933ae76c23SDarkWyrm   static ZCONST char Far SkipIncorrectPasswd[] =
1943ae76c23SDarkWyrm     "   skipping: %-22s  incorrect password\n";
1953ae76c23SDarkWyrm   static ZCONST char Far FilesSkipBadPasswd[] =
1963ae76c23SDarkWyrm     "%lu file%s skipped because of incorrect password.\n";
1973ae76c23SDarkWyrm   static ZCONST char Far MaybeBadPasswd[] =
1983ae76c23SDarkWyrm     "    (may instead be incorrect password)\n";
1993ae76c23SDarkWyrm#else
2003ae76c23SDarkWyrm   static ZCONST char Far SkipEncrypted[] =
2013ae76c23SDarkWyrm     "   skipping: %-22s  encrypted (not supported)\n";
2023ae76c23SDarkWyrm#endif
2033ae76c23SDarkWyrm
2043ae76c23SDarkWyrmstatic ZCONST char Far NoErrInCompData[] =
2053ae76c23SDarkWyrm  "No errors detected in compressed data of %s.\n";
2063ae76c23SDarkWyrmstatic ZCONST char Far NoErrInTestedFiles[] =
2073ae76c23SDarkWyrm  "No errors detected in %s for the %lu file%s tested.\n";
2083ae76c23SDarkWyrmstatic ZCONST char Far FilesSkipped[] =
2093ae76c23SDarkWyrm  "%lu file%s skipped because of unsupported compression or encoding.\n";
2103ae76c23SDarkWyrm
2113ae76c23SDarkWyrmstatic ZCONST char Far ErrUnzipFile[] = "  error:  %s%s %s\n";
2123ae76c23SDarkWyrmstatic ZCONST char Far ErrUnzipNoFile[] = "\n  error:  %s%s\n";
2133ae76c23SDarkWyrmstatic ZCONST char Far NotEnoughMem[] = "not enough memory to ";
2143ae76c23SDarkWyrmstatic ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
2153ae76c23SDarkWyrmstatic ZCONST char Far Inflate[] = "inflate";
2163ae76c23SDarkWyrm
2173ae76c23SDarkWyrm#ifndef SFX
2183ae76c23SDarkWyrm   static ZCONST char Far Explode[] = "explode";
2193ae76c23SDarkWyrm#ifndef LZW_CLEAN
2203ae76c23SDarkWyrm   static ZCONST char Far Unshrink[] = "unshrink";
2213ae76c23SDarkWyrm#endif
2223ae76c23SDarkWyrm#endif
2233ae76c23SDarkWyrm
2243ae76c23SDarkWyrm#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
2253ae76c23SDarkWyrm   static ZCONST char Far FileTruncated[] =
2263ae76c23SDarkWyrm     "warning:  %s is probably truncated\n";
2273ae76c23SDarkWyrm#endif
2283ae76c23SDarkWyrm
2293ae76c23SDarkWyrmstatic ZCONST char Far FileUnknownCompMethod[] =
2303ae76c23SDarkWyrm  "%s:  unknown compression method\n";
2313ae76c23SDarkWyrmstatic ZCONST char Far BadCRC[] = " bad CRC %08lx  (should be %08lx)\n";
2323ae76c23SDarkWyrm
2333ae76c23SDarkWyrm      /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
2343ae76c23SDarkWyrmchar ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
2353ae76c23SDarkWyrmchar ZCONST Far TruncNTSD[] =
2363ae76c23SDarkWyrm  " compressed WinNT security data missing (%d bytes)%s";
2373ae76c23SDarkWyrm
2383ae76c23SDarkWyrm#ifndef SFX
2393ae76c23SDarkWyrm   static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
2403ae76c23SDarkWyrm     EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
2413ae76c23SDarkWyrm   static ZCONST char Far InvalidComprDataEAs[] =
2423ae76c23SDarkWyrm     " invalid compressed data for EAs\n";
2433ae76c23SDarkWyrm#  if (defined(WIN32) && defined(NTSD_EAS))
2443ae76c23SDarkWyrm     static ZCONST char Far InvalidSecurityEAs[] =
2453ae76c23SDarkWyrm       " EAs fail security check\n";
2463ae76c23SDarkWyrm#  endif
2473ae76c23SDarkWyrm   static ZCONST char Far UnsuppNTSDVersEAs[] =
2483ae76c23SDarkWyrm     " unsupported NTSD EAs version %d\n";
2493ae76c23SDarkWyrm   static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
2503ae76c23SDarkWyrm   static ZCONST char Far UnknComprMethodEAs[] =
2513ae76c23SDarkWyrm     " unknown compression method for EAs (%u)\n";
2523ae76c23SDarkWyrm   static ZCONST char Far NotEnoughMemEAs[] =
2533ae76c23SDarkWyrm     " out of memory while inflating EAs\n";
2543ae76c23SDarkWyrm   static ZCONST char Far UnknErrorEAs[] =
2553ae76c23SDarkWyrm     " unknown error on extended attributes\n";
2563ae76c23SDarkWyrm#endif /* !SFX */
2573ae76c23SDarkWyrm
2583ae76c23SDarkWyrmstatic ZCONST char Far UnsupportedExtraField[] =
2593ae76c23SDarkWyrm  "\nerror:  unsupported extra-field compression type (%u)--skipping\n";
2603ae76c23SDarkWyrmstatic ZCONST char Far BadExtraFieldCRC[] =
2613ae76c23SDarkWyrm  "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";
2623ae76c23SDarkWyrm
2633ae76c23SDarkWyrm
2643ae76c23SDarkWyrm
2653ae76c23SDarkWyrm
2663ae76c23SDarkWyrm
2673ae76c23SDarkWyrm/**************************************/
2683ae76c23SDarkWyrm/*  Function extract_or_test_files()  */
2693ae76c23SDarkWyrm/**************************************/
2703ae76c23SDarkWyrm
2713ae76c23SDarkWyrmint extract_or_test_files(__G)    /* return PK-type error code */
2723ae76c23SDarkWyrm     __GDEF
2733ae76c23SDarkWyrm{
2743ae76c23SDarkWyrm    unsigned i, j;
2753ae76c23SDarkWyrm    long cd_bufstart;
2763ae76c23SDarkWyrm    uch *cd_inptr;
2773ae76c23SDarkWyrm    int cd_incnt;
2783ae76c23SDarkWyrm    ulg filnum=0L, blknum=0L;
2793ae76c23SDarkWyrm    int reached_end, no_endsig_found;
2803ae76c23SDarkWyrm    int error, error_in_archive=PK_COOL;
2813ae76c23SDarkWyrm    int *fn_matched=NULL, *xn_matched=NULL;
2823ae76c23SDarkWyrm    unsigned members_processed;
2833ae76c23SDarkWyrm    ulg num_skipped=0L, num_bad_pwd=0L;
2843ae76c23SDarkWyrm    LONGINT old_extra_bytes = 0L;
2853ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
2863ae76c23SDarkWyrm    unsigned num_dirs=0;
2873ae76c23SDarkWyrm    dirtime *dirlist=(dirtime *)NULL, **sorted_dirlist=(dirtime **)NULL;
2883ae76c23SDarkWyrm#endif
2893ae76c23SDarkWyrm
2903ae76c23SDarkWyrm/*---------------------------------------------------------------------------
2913ae76c23SDarkWyrm    The basic idea of this function is as follows.  Since the central di-
2923ae76c23SDarkWyrm    rectory lies at the end of the zipfile and the member files lie at the
2933ae76c23SDarkWyrm    beginning or middle or wherever, it is not very desirable to simply
2943ae76c23SDarkWyrm    read a central directory entry, jump to the member and extract it, and
2953ae76c23SDarkWyrm    then jump back to the central directory.  In the case of a large zipfile
2963ae76c23SDarkWyrm    this would lead to a whole lot of disk-grinding, especially if each mem-
2973ae76c23SDarkWyrm    ber file is small.  Instead, we read from the central directory the per-
2983ae76c23SDarkWyrm    tinent information for a block of files, then go extract/test the whole
2993ae76c23SDarkWyrm    block.  Thus this routine contains two small(er) loops within a very
3003ae76c23SDarkWyrm    large outer loop:  the first of the small ones reads a block of files
3013ae76c23SDarkWyrm    from the central directory; the second extracts or tests each file; and
3023ae76c23SDarkWyrm    the outer one loops over blocks.  There's some file-pointer positioning
3033ae76c23SDarkWyrm    stuff in between, but that's about it.  Btw, it's because of this jump-
3043ae76c23SDarkWyrm    ing around that we can afford to be lenient if an error occurs in one of
3053ae76c23SDarkWyrm    the member files:  we should still be able to go find the other members,
3063ae76c23SDarkWyrm    since we know the offset of each from the beginning of the zipfile.
3073ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
3083ae76c23SDarkWyrm
3093ae76c23SDarkWyrm    G.pInfo = G.info;
3103ae76c23SDarkWyrm
3113ae76c23SDarkWyrm#if CRYPT
3123ae76c23SDarkWyrm    G.newzip = TRUE;
3133ae76c23SDarkWyrm#endif
3143ae76c23SDarkWyrm#ifndef SFX
3153ae76c23SDarkWyrm    G.reported_backslash = FALSE;
3163ae76c23SDarkWyrm#endif
3173ae76c23SDarkWyrm
3183ae76c23SDarkWyrm    /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
3193ae76c23SDarkWyrm    if (G.filespecs > 0  &&
3203ae76c23SDarkWyrm        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
3213ae76c23SDarkWyrm        for (i = 0;  i < G.filespecs;  ++i)
3223ae76c23SDarkWyrm            fn_matched[i] = FALSE;
3233ae76c23SDarkWyrm    if (G.xfilespecs > 0  &&
3243ae76c23SDarkWyrm        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
3253ae76c23SDarkWyrm        for (i = 0;  i < G.xfilespecs;  ++i)
3263ae76c23SDarkWyrm            xn_matched[i] = FALSE;
3273ae76c23SDarkWyrm
3283ae76c23SDarkWyrm/*---------------------------------------------------------------------------
3293ae76c23SDarkWyrm    Begin main loop over blocks of member files.  We know the entire central
3303ae76c23SDarkWyrm    directory is on this disk:  we would not have any of this information un-
3313ae76c23SDarkWyrm    less the end-of-central-directory record was on this disk, and we would
3323ae76c23SDarkWyrm    not have gotten to this routine unless this is also the disk on which
3333ae76c23SDarkWyrm    the central directory starts.  In practice, this had better be the ONLY
3343ae76c23SDarkWyrm    disk in the archive, but we'll add multi-disk support soon.
3353ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
3363ae76c23SDarkWyrm
3373ae76c23SDarkWyrm    members_processed = 0;
3383ae76c23SDarkWyrm    no_endsig_found = FALSE;
3393ae76c23SDarkWyrm    reached_end = FALSE;
3403ae76c23SDarkWyrm    while (!reached_end) {
3413ae76c23SDarkWyrm        j = 0;
3423ae76c23SDarkWyrm#ifdef AMIGA
3433ae76c23SDarkWyrm        memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
3443ae76c23SDarkWyrm#endif
3453ae76c23SDarkWyrm
3463ae76c23SDarkWyrm        /*
3473ae76c23SDarkWyrm         * Loop through files in central directory, storing offsets, file
3483ae76c23SDarkWyrm         * attributes, case-conversion and text-conversion flags until block
3493ae76c23SDarkWyrm         * size is reached.
3503ae76c23SDarkWyrm         */
3513ae76c23SDarkWyrm
3523ae76c23SDarkWyrm        while ((j < DIR_BLKSIZ)) {
3533ae76c23SDarkWyrm            G.pInfo = &G.info[j];
3543ae76c23SDarkWyrm
3553ae76c23SDarkWyrm            if (readbuf(__G__ G.sig, 4) == 0) {
3563ae76c23SDarkWyrm                error_in_archive = PK_EOF;
3573ae76c23SDarkWyrm                reached_end = TRUE;     /* ...so no more left to do */
3583ae76c23SDarkWyrm                break;
3593ae76c23SDarkWyrm            }
3603ae76c23SDarkWyrm            if (strncmp(G.sig, central_hdr_sig, 4)) {  /* is it a new entry? */
3613ae76c23SDarkWyrm                /* no new central directory entry
3623ae76c23SDarkWyrm                 * -> is the number of processed entries compatible with the
3633ae76c23SDarkWyrm                 *    number of entries as stored in the end_central record?
3643ae76c23SDarkWyrm                 */
3653ae76c23SDarkWyrm                if ((members_processed & (unsigned)0xFFFF) ==
3663ae76c23SDarkWyrm                    (unsigned)G.ecrec.total_entries_central_dir) {
3673ae76c23SDarkWyrm                    /* yes, so look if we ARE back at the end_central record
3683ae76c23SDarkWyrm                     */
3693ae76c23SDarkWyrm                    no_endsig_found =
3703ae76c23SDarkWyrm                      (strncmp(G.sig, end_central_sig, 4) != 0);
3713ae76c23SDarkWyrm                } else {
3723ae76c23SDarkWyrm                    /* no; we have found an error in the central directory
3733ae76c23SDarkWyrm                     * -> report it and stop searching for more Zip entries
3743ae76c23SDarkWyrm                     */
3753ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
3763ae76c23SDarkWyrm                      LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
3773ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
3783ae76c23SDarkWyrm                      LoadFarString(ReportMsg)));
3793ae76c23SDarkWyrm                    error_in_archive = PK_BADERR;
3803ae76c23SDarkWyrm                }
3813ae76c23SDarkWyrm                reached_end = TRUE;     /* ...so no more left to do */
3823ae76c23SDarkWyrm                break;
3833ae76c23SDarkWyrm            }
3843ae76c23SDarkWyrm            /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
3853ae76c23SDarkWyrm            if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
3863ae76c23SDarkWyrm                error_in_archive = error;   /* only PK_EOF defined */
3873ae76c23SDarkWyrm                reached_end = TRUE;     /* ...so no more left to do */
3883ae76c23SDarkWyrm                break;
3893ae76c23SDarkWyrm            }
3903ae76c23SDarkWyrm            if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
3913ae76c23SDarkWyrm                 PK_COOL)
3923ae76c23SDarkWyrm            {
3933ae76c23SDarkWyrm                if (error > error_in_archive)
3943ae76c23SDarkWyrm                    error_in_archive = error;
3953ae76c23SDarkWyrm                if (error > PK_WARN) {  /* fatal:  no more left to do */
3963ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
3973ae76c23SDarkWyrm                      FnFilter1(G.filename), "central"));
3983ae76c23SDarkWyrm                    reached_end = TRUE;
3993ae76c23SDarkWyrm                    break;
4003ae76c23SDarkWyrm                }
4013ae76c23SDarkWyrm            }
4023ae76c23SDarkWyrm            if ((error = do_string(__G__ G.crec.extra_field_length,
4033ae76c23SDarkWyrm                EXTRA_FIELD)) != 0)
4043ae76c23SDarkWyrm            {
4053ae76c23SDarkWyrm                if (error > error_in_archive)
4063ae76c23SDarkWyrm                    error_in_archive = error;
4073ae76c23SDarkWyrm                if (error > PK_WARN) {  /* fatal */
4083ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
4093ae76c23SDarkWyrm                      LoadFarString(ExtFieldMsg),
4103ae76c23SDarkWyrm                      FnFilter1(G.filename), "central"));
4113ae76c23SDarkWyrm                    reached_end = TRUE;
4123ae76c23SDarkWyrm                    break;
4133ae76c23SDarkWyrm                }
4143ae76c23SDarkWyrm            }
4153ae76c23SDarkWyrm#ifdef AMIGA
4163ae76c23SDarkWyrm            G.filenote_slot = j;
4173ae76c23SDarkWyrm            if ((error = do_string(__G__ G.crec.file_comment_length,
4183ae76c23SDarkWyrm                                   uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
4193ae76c23SDarkWyrm#else
4203ae76c23SDarkWyrm            if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
4213ae76c23SDarkWyrm                != PK_COOL)
4223ae76c23SDarkWyrm#endif
4233ae76c23SDarkWyrm            {
4243ae76c23SDarkWyrm                if (error > error_in_archive)
4253ae76c23SDarkWyrm                    error_in_archive = error;
4263ae76c23SDarkWyrm                if (error > PK_WARN) {  /* fatal */
4273ae76c23SDarkWyrm                    Info(slide, 0x421, ((char *)slide,
4283ae76c23SDarkWyrm                      LoadFarString(BadFileCommLength),
4293ae76c23SDarkWyrm                      FnFilter1(G.filename)));
4303ae76c23SDarkWyrm                    reached_end = TRUE;
4313ae76c23SDarkWyrm                    break;
4323ae76c23SDarkWyrm                }
4333ae76c23SDarkWyrm            }
4343ae76c23SDarkWyrm            if (G.process_all_files) {
4353ae76c23SDarkWyrm                if (store_info(__G))
4363ae76c23SDarkWyrm                    ++j;  /* file is OK; info[] stored; continue with next */
4373ae76c23SDarkWyrm                else
4383ae76c23SDarkWyrm                    ++num_skipped;
4393ae76c23SDarkWyrm            } else {
4403ae76c23SDarkWyrm                int   do_this_file;
4413ae76c23SDarkWyrm
4423ae76c23SDarkWyrm                if (G.filespecs == 0)
4433ae76c23SDarkWyrm                    do_this_file = TRUE;
4443ae76c23SDarkWyrm                else {  /* check if this entry matches an `include' argument */
4453ae76c23SDarkWyrm                    do_this_file = FALSE;
4463ae76c23SDarkWyrm                    for (i = 0; i < G.filespecs; i++)
4473ae76c23SDarkWyrm                        if (match(G.filename, G.pfnames[i], uO.C_flag)) {
4483ae76c23SDarkWyrm                            do_this_file = TRUE;  /* ^-- ignore case or not? */
4493ae76c23SDarkWyrm                            if (fn_matched)
4503ae76c23SDarkWyrm                                fn_matched[i] = TRUE;
4513ae76c23SDarkWyrm                            break;       /* found match, so stop looping */
4523ae76c23SDarkWyrm                        }
4533ae76c23SDarkWyrm                }
4543ae76c23SDarkWyrm                if (do_this_file) {  /* check if this is an excluded file */
4553ae76c23SDarkWyrm                    for (i = 0; i < G.xfilespecs; i++)
4563ae76c23SDarkWyrm                        if (match(G.filename, G.pxnames[i], uO.C_flag)) {
4573ae76c23SDarkWyrm                            do_this_file = FALSE; /* ^-- ignore case or not? */
4583ae76c23SDarkWyrm                            if (xn_matched)
4593ae76c23SDarkWyrm                                xn_matched[i] = TRUE;
4603ae76c23SDarkWyrm                            break;
4613ae76c23SDarkWyrm                        }
4623ae76c23SDarkWyrm                }
4633ae76c23SDarkWyrm                if (do_this_file) {
4643ae76c23SDarkWyrm                    if (store_info(__G))
4653ae76c23SDarkWyrm                        ++j;            /* file is OK */
4663ae76c23SDarkWyrm                    else
4673ae76c23SDarkWyrm                        ++num_skipped;  /* unsupp. compression or encryption */
4683ae76c23SDarkWyrm                }
4693ae76c23SDarkWyrm            } /* end if (process_all_files) */
4703ae76c23SDarkWyrm
4713ae76c23SDarkWyrm            members_processed++;
4723ae76c23SDarkWyrm
4733ae76c23SDarkWyrm        } /* end while-loop (adding files to current block) */
4743ae76c23SDarkWyrm
4753ae76c23SDarkWyrm        /* save position in central directory so can come back later */
4763ae76c23SDarkWyrm        cd_bufstart = G.cur_zipfile_bufstart;
4773ae76c23SDarkWyrm        cd_inptr = G.inptr;
4783ae76c23SDarkWyrm        cd_incnt = G.incnt;
4793ae76c23SDarkWyrm
4803ae76c23SDarkWyrm    /*-----------------------------------------------------------------------
4813ae76c23SDarkWyrm        Second loop:  process files in current block, extracting or testing
4823ae76c23SDarkWyrm        each one.
4833ae76c23SDarkWyrm      -----------------------------------------------------------------------*/
4843ae76c23SDarkWyrm
4853ae76c23SDarkWyrm        error = extract_or_test_entrylist(__G__ j,
4863ae76c23SDarkWyrm                        &filnum, &num_bad_pwd, &old_extra_bytes,
4873ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
4883ae76c23SDarkWyrm                        &num_dirs, &dirlist,
4893ae76c23SDarkWyrm#endif
4903ae76c23SDarkWyrm                        error_in_archive);
4913ae76c23SDarkWyrm        if (error != PK_COOL) {
4923ae76c23SDarkWyrm            if (error > error_in_archive)
4933ae76c23SDarkWyrm                error_in_archive = error;       /* ...and keep going */
4943ae76c23SDarkWyrm            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
4953ae76c23SDarkWyrm                if (fn_matched)
4963ae76c23SDarkWyrm                    free((zvoid *)fn_matched);
4973ae76c23SDarkWyrm                if (xn_matched)
4983ae76c23SDarkWyrm                    free((zvoid *)xn_matched);
4993ae76c23SDarkWyrm                return error_in_archive;        /* (unless disk full) */
5003ae76c23SDarkWyrm            }
5013ae76c23SDarkWyrm        }
5023ae76c23SDarkWyrm
5033ae76c23SDarkWyrm
5043ae76c23SDarkWyrm        /*
5053ae76c23SDarkWyrm         * Jump back to where we were in the central directory, then go and do
5063ae76c23SDarkWyrm         * the next batch of files.
5073ae76c23SDarkWyrm         */
5083ae76c23SDarkWyrm
5093ae76c23SDarkWyrm#ifdef USE_STRM_INPUT
5103ae76c23SDarkWyrm        fseek((FILE *)G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);
5113ae76c23SDarkWyrm        G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
5123ae76c23SDarkWyrm#else /* !USE_STRM_INPUT */
5133ae76c23SDarkWyrm        G.cur_zipfile_bufstart =
5143ae76c23SDarkWyrm          lseek(G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);
5153ae76c23SDarkWyrm#endif /* ?USE_STRM_INPUT */
5163ae76c23SDarkWyrm        read(G.zipfd, (char *)G.inbuf, INBUFSIZ);  /* been here before... */
5173ae76c23SDarkWyrm        G.inptr = cd_inptr;
5183ae76c23SDarkWyrm        G.incnt = cd_incnt;
5193ae76c23SDarkWyrm        ++blknum;
5203ae76c23SDarkWyrm
5213ae76c23SDarkWyrm#ifdef TEST
5223ae76c23SDarkWyrm        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
5233ae76c23SDarkWyrm        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
5243ae76c23SDarkWyrm          cur_zipfile_bufstart);
5253ae76c23SDarkWyrm        printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
5263ae76c23SDarkWyrm        printf("incnt = %d\n\n", G.incnt);
5273ae76c23SDarkWyrm#endif
5283ae76c23SDarkWyrm
5293ae76c23SDarkWyrm    } /* end while-loop (blocks of files in central directory) */
5303ae76c23SDarkWyrm
5313ae76c23SDarkWyrm/*---------------------------------------------------------------------------
5323ae76c23SDarkWyrm    Go back through saved list of directories, sort and set times/perms/UIDs
5333ae76c23SDarkWyrm    and GIDs from the deepest level on up.
5343ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
5353ae76c23SDarkWyrm
5363ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
5373ae76c23SDarkWyrm    if (num_dirs > 0) {
5383ae76c23SDarkWyrm        sorted_dirlist = (dirtime **)malloc(num_dirs*sizeof(dirtime *));
5393ae76c23SDarkWyrm        if (sorted_dirlist == (dirtime **)NULL) {
5403ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide,
5413ae76c23SDarkWyrm              LoadFarString(DirlistSortNoMem)));
5423ae76c23SDarkWyrm            while (dirlist != (dirtime *)NULL) {
5433ae76c23SDarkWyrm                dirtime *d = dirlist;
5443ae76c23SDarkWyrm
5453ae76c23SDarkWyrm                dirlist = dirlist->next;
5463ae76c23SDarkWyrm                free(d);
5473ae76c23SDarkWyrm            }
5483ae76c23SDarkWyrm        } else {
5493ae76c23SDarkWyrm            if (num_dirs == 1)
5503ae76c23SDarkWyrm                sorted_dirlist[0] = dirlist;
5513ae76c23SDarkWyrm            else {
5523ae76c23SDarkWyrm                for (i = 0;  i < num_dirs;  ++i) {
5533ae76c23SDarkWyrm                    sorted_dirlist[i] = dirlist;
5543ae76c23SDarkWyrm                    dirlist = dirlist->next;
5553ae76c23SDarkWyrm                }
5563ae76c23SDarkWyrm                qsort((char *)sorted_dirlist, num_dirs, sizeof(dirtime *),
5573ae76c23SDarkWyrm                  dircomp);
5583ae76c23SDarkWyrm            }
5593ae76c23SDarkWyrm
5603ae76c23SDarkWyrm            Trace((stderr, "setting directory times/perms/attributes\n"));
5613ae76c23SDarkWyrm            for (i = 0;  i < num_dirs;  ++i) {
5623ae76c23SDarkWyrm                dirtime *d = sorted_dirlist[i];
5633ae76c23SDarkWyrm
5643ae76c23SDarkWyrm                Trace((stderr, "dir = %s\n", d->fn));
5653ae76c23SDarkWyrm                if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
5663ae76c23SDarkWyrm                    Info(slide, 0x201, ((char *)slide,
5673ae76c23SDarkWyrm                      LoadFarString(DirlistSetAttrFailed), d->fn));
5683ae76c23SDarkWyrm                    if (!error_in_archive)
5693ae76c23SDarkWyrm                        error_in_archive = error;
5703ae76c23SDarkWyrm                }
5713ae76c23SDarkWyrm                free(d->fn);
5723ae76c23SDarkWyrm                free(d);
5733ae76c23SDarkWyrm            }
5743ae76c23SDarkWyrm            free(sorted_dirlist);
5753ae76c23SDarkWyrm        }
5763ae76c23SDarkWyrm    }
5773ae76c23SDarkWyrm#endif /* SET_DIR_ATTRIB */
5783ae76c23SDarkWyrm
5793ae76c23SDarkWyrm#if (defined(WIN32) && defined(NTSD_EAS))
5803ae76c23SDarkWyrm    process_defer_NT(__G);  /* process any deferred items for this .zip file */
5813ae76c23SDarkWyrm#endif
5823ae76c23SDarkWyrm
5833ae76c23SDarkWyrm/*---------------------------------------------------------------------------
5843ae76c23SDarkWyrm    Check for unmatched filespecs on command line and print warning if any
5853ae76c23SDarkWyrm    found.  Free allocated memory.
5863ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
5873ae76c23SDarkWyrm
5883ae76c23SDarkWyrm    if (fn_matched) {
5893ae76c23SDarkWyrm        for (i = 0;  i < G.filespecs;  ++i)
5903ae76c23SDarkWyrm            if (!fn_matched[i]) {
5913ae76c23SDarkWyrm#ifdef DLL
5923ae76c23SDarkWyrm                if (!G.redirect_data && !G.redirect_text)
5933ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
5943ae76c23SDarkWyrm                      LoadFarString(FilenameNotMatched), G.pfnames[i]));
5953ae76c23SDarkWyrm                else
5963ae76c23SDarkWyrm                    setFileNotFound(__G);
5973ae76c23SDarkWyrm#else
5983ae76c23SDarkWyrm                Info(slide, 1, ((char *)slide,
5993ae76c23SDarkWyrm                  LoadFarString(FilenameNotMatched), G.pfnames[i]));
6003ae76c23SDarkWyrm#endif
6013ae76c23SDarkWyrm                if (error_in_archive <= PK_WARN)
6023ae76c23SDarkWyrm                    error_in_archive = PK_FIND;   /* some files not found */
6033ae76c23SDarkWyrm            }
6043ae76c23SDarkWyrm        free((zvoid *)fn_matched);
6053ae76c23SDarkWyrm    }
6063ae76c23SDarkWyrm    if (xn_matched) {
6073ae76c23SDarkWyrm        for (i = 0;  i < G.xfilespecs;  ++i)
6083ae76c23SDarkWyrm            if (!xn_matched[i])
6093ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
6103ae76c23SDarkWyrm                  LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
6113ae76c23SDarkWyrm        free((zvoid *)xn_matched);
6123ae76c23SDarkWyrm    }
6133ae76c23SDarkWyrm
6143ae76c23SDarkWyrm/*---------------------------------------------------------------------------
6153ae76c23SDarkWyrm    Double-check that we're back at the end-of-central-directory record, and
6163ae76c23SDarkWyrm    print quick summary of results, if we were just testing the archive.  We
6173ae76c23SDarkWyrm    send the summary to stdout so that people doing the testing in the back-
6183ae76c23SDarkWyrm    ground and redirecting to a file can just do a "tail" on the output file.
6193ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
6203ae76c23SDarkWyrm
6213ae76c23SDarkWyrm#ifndef SFX
6223ae76c23SDarkWyrm    if (no_endsig_found) {                      /* just to make sure */
6233ae76c23SDarkWyrm        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
6243ae76c23SDarkWyrm        Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
6253ae76c23SDarkWyrm        if (!error_in_archive)       /* don't overwrite stronger error */
6263ae76c23SDarkWyrm            error_in_archive = PK_WARN;
6273ae76c23SDarkWyrm    }
6283ae76c23SDarkWyrm#endif /* !SFX */
6293ae76c23SDarkWyrm    if (uO.tflag) {
6303ae76c23SDarkWyrm        ulg num = filnum - num_bad_pwd;
6313ae76c23SDarkWyrm
6323ae76c23SDarkWyrm        if (uO.qflag < 2) {        /* GRR 930710:  was (uO.qflag == 1) */
6333ae76c23SDarkWyrm            if (error_in_archive)
6343ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
6353ae76c23SDarkWyrm                  (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
6363ae76c23SDarkWyrm            else if (num == 0L)
6373ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
6383ae76c23SDarkWyrm                  G.zipfn));
6393ae76c23SDarkWyrm            else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
6403ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
6413ae76c23SDarkWyrm                  G.zipfn));
6423ae76c23SDarkWyrm            else
6433ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
6443ae76c23SDarkWyrm                  , G.zipfn, num, (num==1L)? "":"s"));
6453ae76c23SDarkWyrm            if (num_skipped > 0L)
6463ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
6473ae76c23SDarkWyrm                  num_skipped, (num_skipped==1L)? "":"s"));
6483ae76c23SDarkWyrm#if CRYPT
6493ae76c23SDarkWyrm            if (num_bad_pwd > 0L)
6503ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
6513ae76c23SDarkWyrm                  , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
6523ae76c23SDarkWyrm#endif /* CRYPT */
6533ae76c23SDarkWyrm        } else if ((uO.qflag == 0) && !error_in_archive && (num == 0))
6543ae76c23SDarkWyrm            Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
6553ae76c23SDarkWyrm              G.zipfn));
6563ae76c23SDarkWyrm    }
6573ae76c23SDarkWyrm
6583ae76c23SDarkWyrm    /* give warning if files not tested or extracted (first condition can still
6593ae76c23SDarkWyrm     * happen if zipfile is empty and no files specified on command line) */
6603ae76c23SDarkWyrm
6613ae76c23SDarkWyrm    if ((filnum == 0) && error_in_archive <= PK_WARN) {
6623ae76c23SDarkWyrm        if (num_skipped > 0L)
6633ae76c23SDarkWyrm            error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
6643ae76c23SDarkWyrm        else
6653ae76c23SDarkWyrm            error_in_archive = PK_FIND;  /* no files found at all */
6663ae76c23SDarkWyrm    }
6673ae76c23SDarkWyrm#if CRYPT
6683ae76c23SDarkWyrm    else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
6693ae76c23SDarkWyrm        error_in_archive = IZ_BADPWD;    /* bad passwd => all files skipped */
6703ae76c23SDarkWyrm#endif
6713ae76c23SDarkWyrm    else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
6723ae76c23SDarkWyrm        error_in_archive = IZ_UNSUP;     /* was PK_WARN; Jean-loup complained */
6733ae76c23SDarkWyrm#if CRYPT
6743ae76c23SDarkWyrm    else if ((num_bad_pwd > 0L) && !error_in_archive)
6753ae76c23SDarkWyrm        error_in_archive = PK_WARN;
6763ae76c23SDarkWyrm#endif
6773ae76c23SDarkWyrm
6783ae76c23SDarkWyrm    return error_in_archive;
6793ae76c23SDarkWyrm
6803ae76c23SDarkWyrm} /* end function extract_or_test_files() */
6813ae76c23SDarkWyrm
6823ae76c23SDarkWyrm
6833ae76c23SDarkWyrm
6843ae76c23SDarkWyrm
6853ae76c23SDarkWyrm
6863ae76c23SDarkWyrm/***************************/
6873ae76c23SDarkWyrm/*  Function store_info()  */
6883ae76c23SDarkWyrm/***************************/
6893ae76c23SDarkWyrm
6903ae76c23SDarkWyrmstatic int store_info(__G)   /* return 0 if skipping, 1 if OK */
6913ae76c23SDarkWyrm    __GDEF
6923ae76c23SDarkWyrm{
6933ae76c23SDarkWyrm#ifdef SFX
6943ae76c23SDarkWyrm#  ifdef USE_DEFLATE64
6953ae76c23SDarkWyrm#    define UNKN_COMPR \
6963ae76c23SDarkWyrm     (G.crec.compression_method!=STORED && G.crec.compression_method<DEFLATED \
6973ae76c23SDarkWyrm      && G.crec.compression_method>ENHDEFLATED)
6983ae76c23SDarkWyrm#  else
6993ae76c23SDarkWyrm#    define UNKN_COMPR \
7003ae76c23SDarkWyrm     (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED)
7013ae76c23SDarkWyrm#  endif
7023ae76c23SDarkWyrm#else
7033ae76c23SDarkWyrm#  ifdef COPYRIGHT_CLEAN  /* no reduced files */
7043ae76c23SDarkWyrm#    define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
7053ae76c23SDarkWyrm                      G.crec.compression_method <= REDUCED4)
7063ae76c23SDarkWyrm#  else
7073ae76c23SDarkWyrm#    define UNKN_RED  FALSE  /* reducing not unknown */
7083ae76c23SDarkWyrm#  endif
7093ae76c23SDarkWyrm#  ifdef LZW_CLEAN  /* no shrunk files */
7103ae76c23SDarkWyrm#    define UNKN_SHR (G.crec.compression_method == SHRUNK)
7113ae76c23SDarkWyrm#  else
7123ae76c23SDarkWyrm#    define UNKN_SHR  FALSE  /* unshrinking not unknown */
7133ae76c23SDarkWyrm#  endif
7143ae76c23SDarkWyrm#  ifdef USE_DEFLATE64
7153ae76c23SDarkWyrm#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
7163ae76c23SDarkWyrm     G.crec.compression_method==TOKENIZED || \
7173ae76c23SDarkWyrm     G.crec.compression_method>ENHDEFLATED)
7183ae76c23SDarkWyrm#  else
7193ae76c23SDarkWyrm#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
7203ae76c23SDarkWyrm     G.crec.compression_method==TOKENIZED || \
7213ae76c23SDarkWyrm     G.crec.compression_method>DEFLATED)
7223ae76c23SDarkWyrm#  endif
7233ae76c23SDarkWyrm#endif
7243ae76c23SDarkWyrm
7253ae76c23SDarkWyrm/*---------------------------------------------------------------------------
7263ae76c23SDarkWyrm    Check central directory info for version/compatibility requirements.
7273ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
7283ae76c23SDarkWyrm
7293ae76c23SDarkWyrm    G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1;   /* bit field */
7303ae76c23SDarkWyrm    G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8;  /* bit */
7313ae76c23SDarkWyrm    G.pInfo->textfile = G.crec.internal_file_attributes & 1;    /* bit field */
7323ae76c23SDarkWyrm    G.pInfo->crc = G.crec.crc32;
7333ae76c23SDarkWyrm    G.pInfo->compr_size = G.crec.csize;
7343ae76c23SDarkWyrm    G.pInfo->uncompr_size = G.crec.ucsize;
7353ae76c23SDarkWyrm
7363ae76c23SDarkWyrm    switch (uO.aflag) {
7373ae76c23SDarkWyrm        case 0:
7383ae76c23SDarkWyrm            G.pInfo->textmode = FALSE;   /* bit field */
7393ae76c23SDarkWyrm            break;
7403ae76c23SDarkWyrm        case 1:
7413ae76c23SDarkWyrm            G.pInfo->textmode = G.pInfo->textfile;   /* auto-convert mode */
7423ae76c23SDarkWyrm            break;
7433ae76c23SDarkWyrm        default:  /* case 2: */
7443ae76c23SDarkWyrm            G.pInfo->textmode = TRUE;
7453ae76c23SDarkWyrm            break;
7463ae76c23SDarkWyrm    }
7473ae76c23SDarkWyrm
7483ae76c23SDarkWyrm    if (G.crec.version_needed_to_extract[1] == VMS_) {
7493ae76c23SDarkWyrm        if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
7503ae76c23SDarkWyrm            if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
7513ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
7523ae76c23SDarkWyrm                  FnFilter1(G.filename), "VMS",
7533ae76c23SDarkWyrm                  G.crec.version_needed_to_extract[0] / 10,
7543ae76c23SDarkWyrm                  G.crec.version_needed_to_extract[0] % 10,
7553ae76c23SDarkWyrm                  VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
7563ae76c23SDarkWyrm            return 0;
7573ae76c23SDarkWyrm        }
7583ae76c23SDarkWyrm#ifndef VMS   /* won't be able to use extra field, but still have data */
7593ae76c23SDarkWyrm        else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
7603ae76c23SDarkWyrm            Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
7613ae76c23SDarkWyrm              FnFilter1(G.filename)));
7623ae76c23SDarkWyrm            fgets(G.answerbuf, 9, stdin);
7633ae76c23SDarkWyrm            if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
7643ae76c23SDarkWyrm                return 0;
7653ae76c23SDarkWyrm        }
7663ae76c23SDarkWyrm#endif /* !VMS */
7673ae76c23SDarkWyrm    /* usual file type:  don't need VMS to extract */
7683ae76c23SDarkWyrm    } else if (G.crec.version_needed_to_extract[0] > UNZIP_VERSION) {
7693ae76c23SDarkWyrm        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
7703ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
7713ae76c23SDarkWyrm              FnFilter1(G.filename), "PK",
7723ae76c23SDarkWyrm              G.crec.version_needed_to_extract[0] / 10,
7733ae76c23SDarkWyrm              G.crec.version_needed_to_extract[0] % 10,
7743ae76c23SDarkWyrm              UNZIP_VERSION / 10, UNZIP_VERSION % 10));
7753ae76c23SDarkWyrm        return 0;
7763ae76c23SDarkWyrm    }
7773ae76c23SDarkWyrm
7783ae76c23SDarkWyrm    if UNKN_COMPR {
7793ae76c23SDarkWyrm        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
7803ae76c23SDarkWyrm#ifndef SFX
7813ae76c23SDarkWyrm            if (G.crec.compression_method < NUM_METHODS)
7823ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
7833ae76c23SDarkWyrm                  FnFilter1(G.filename),
7843ae76c23SDarkWyrm                  LoadFarStringSmall(ComprNames[G.crec.compression_method])));
7853ae76c23SDarkWyrm            else
7863ae76c23SDarkWyrm#endif
7873ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
7883ae76c23SDarkWyrm                  FnFilter1(G.filename),
7893ae76c23SDarkWyrm                  G.crec.compression_method));
7903ae76c23SDarkWyrm        }
7913ae76c23SDarkWyrm        return 0;
7923ae76c23SDarkWyrm    }
7933ae76c23SDarkWyrm#if (!CRYPT)
7943ae76c23SDarkWyrm    if (G.pInfo->encrypted) {
7953ae76c23SDarkWyrm        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
7963ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
7973ae76c23SDarkWyrm              FnFilter1(G.filename)));
7983ae76c23SDarkWyrm        return 0;
7993ae76c23SDarkWyrm    }
8003ae76c23SDarkWyrm#endif /* !CRYPT */
8013ae76c23SDarkWyrm
8023ae76c23SDarkWyrm    /* map whatever file attributes we have into the local format */
8033ae76c23SDarkWyrm    mapattr(__G);   /* GRR:  worry about return value later */
8043ae76c23SDarkWyrm
8053ae76c23SDarkWyrm    G.pInfo->diskstart = G.crec.disk_number_start;
8063ae76c23SDarkWyrm    G.pInfo->offset = (long)G.crec.relative_offset_local_header;
8073ae76c23SDarkWyrm    return 1;
8083ae76c23SDarkWyrm
8093ae76c23SDarkWyrm} /* end function store_info() */
8103ae76c23SDarkWyrm
8113ae76c23SDarkWyrm
8123ae76c23SDarkWyrm
8133ae76c23SDarkWyrm
8143ae76c23SDarkWyrm
8153ae76c23SDarkWyrm/******************************************/
8163ae76c23SDarkWyrm/*  Function extract_or_test_entrylist()  */
8173ae76c23SDarkWyrm/******************************************/
8183ae76c23SDarkWyrm
8193ae76c23SDarkWyrmstatic int extract_or_test_entrylist(__G__ numchunk,
8203ae76c23SDarkWyrm                pfilnum, pnum_bad_pwd, pold_extra_bytes,
8213ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
8223ae76c23SDarkWyrm                pnum_dirs, pdirlist,
8233ae76c23SDarkWyrm#endif
8243ae76c23SDarkWyrm                error_in_archive)    /* return PK-type error code */
8253ae76c23SDarkWyrm    __GDEF
8263ae76c23SDarkWyrm    unsigned numchunk;
8273ae76c23SDarkWyrm    ulg *pfilnum;
8283ae76c23SDarkWyrm    ulg *pnum_bad_pwd;
8293ae76c23SDarkWyrm    LONGINT *pold_extra_bytes;
8303ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
8313ae76c23SDarkWyrm    unsigned *pnum_dirs;
8323ae76c23SDarkWyrm    dirtime **pdirlist;
8333ae76c23SDarkWyrm#endif
8343ae76c23SDarkWyrm    int error_in_archive;
8353ae76c23SDarkWyrm{
8363ae76c23SDarkWyrm    unsigned i;
8373ae76c23SDarkWyrm    int renamed, query;
8383ae76c23SDarkWyrm    int skip_entry;
8393ae76c23SDarkWyrm    long bufstart, inbuf_offset, request;
8403ae76c23SDarkWyrm    int error, errcode;
8413ae76c23SDarkWyrm
8423ae76c23SDarkWyrm/* possible values for local skip_entry flag: */
8433ae76c23SDarkWyrm#define SKIP_NO         0       /* do not skip this entry */
8443ae76c23SDarkWyrm#define SKIP_Y_EXISTING 1       /* skip this entry, do not overwrite file */
8453ae76c23SDarkWyrm#define SKIP_Y_NONEXIST 2       /* skip this entry, do not create new file */
8463ae76c23SDarkWyrm
8473ae76c23SDarkWyrm    /*-----------------------------------------------------------------------
8483ae76c23SDarkWyrm        Second loop:  process files in current block, extracting or testing
8493ae76c23SDarkWyrm        each one.
8503ae76c23SDarkWyrm      -----------------------------------------------------------------------*/
8513ae76c23SDarkWyrm
8523ae76c23SDarkWyrm    for (i = 0; i < numchunk; ++i) {
8533ae76c23SDarkWyrm        (*pfilnum)++;   /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
8543ae76c23SDarkWyrm        G.pInfo = &G.info[i];
8553ae76c23SDarkWyrm#ifdef NOVELL_BUG_FAILSAFE
8563ae76c23SDarkWyrm        G.dne = FALSE;  /* assume file exists until stat() says otherwise */
8573ae76c23SDarkWyrm#endif
8583ae76c23SDarkWyrm
8593ae76c23SDarkWyrm        /* if the target position is not within the current input buffer
8603ae76c23SDarkWyrm         * (either haven't yet read far enough, or (maybe) skipping back-
8613ae76c23SDarkWyrm         * ward), skip to the target position and reset readbuf(). */
8623ae76c23SDarkWyrm
8633ae76c23SDarkWyrm        /* seek_zipf(__G__ pInfo->offset);  */
8643ae76c23SDarkWyrm        request = G.pInfo->offset + G.extra_bytes;
8653ae76c23SDarkWyrm        inbuf_offset = request % INBUFSIZ;
8663ae76c23SDarkWyrm        bufstart = request - inbuf_offset;
8673ae76c23SDarkWyrm
8683ae76c23SDarkWyrm        Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
8693ae76c23SDarkWyrm          request, inbuf_offset));
8703ae76c23SDarkWyrm        Trace((stderr,
8713ae76c23SDarkWyrm          "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
8723ae76c23SDarkWyrm          bufstart, G.cur_zipfile_bufstart));
8733ae76c23SDarkWyrm        if (request < 0) {
8743ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
8753ae76c23SDarkWyrm              G.zipfn, LoadFarString(ReportMsg)));
8763ae76c23SDarkWyrm            error_in_archive = PK_ERR;
8773ae76c23SDarkWyrm            if (*pfilnum == 1 && G.extra_bytes != 0L) {
8783ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
8793ae76c23SDarkWyrm                  LoadFarString(AttemptRecompensate)));
8803ae76c23SDarkWyrm                *pold_extra_bytes = G.extra_bytes;
8813ae76c23SDarkWyrm                G.extra_bytes = 0L;
8823ae76c23SDarkWyrm                request = G.pInfo->offset;  /* could also check if != 0 */
8833ae76c23SDarkWyrm                inbuf_offset = request % INBUFSIZ;
8843ae76c23SDarkWyrm                bufstart = request - inbuf_offset;
8853ae76c23SDarkWyrm                Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
8863ae76c23SDarkWyrm                  request, inbuf_offset));
8873ae76c23SDarkWyrm                Trace((stderr,
8883ae76c23SDarkWyrm                  "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
8893ae76c23SDarkWyrm                  bufstart, G.cur_zipfile_bufstart));
8903ae76c23SDarkWyrm                /* try again */
8913ae76c23SDarkWyrm                if (request < 0) {
8923ae76c23SDarkWyrm                    Trace((stderr,
8933ae76c23SDarkWyrm                      "debug: recompensated request still < 0\n"));
8943ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
8953ae76c23SDarkWyrm                      LoadFarStringSmall(SeekMsg),
8963ae76c23SDarkWyrm                      G.zipfn, LoadFarString(ReportMsg)));
8973ae76c23SDarkWyrm                    error_in_archive = PK_BADERR;
8983ae76c23SDarkWyrm                    continue;
8993ae76c23SDarkWyrm                }
9003ae76c23SDarkWyrm            } else {
9013ae76c23SDarkWyrm                error_in_archive = PK_BADERR;
9023ae76c23SDarkWyrm                continue;  /* this one hosed; try next */
9033ae76c23SDarkWyrm            }
9043ae76c23SDarkWyrm        }
9053ae76c23SDarkWyrm
9063ae76c23SDarkWyrm        if (bufstart != G.cur_zipfile_bufstart) {
9073ae76c23SDarkWyrm            Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
9083ae76c23SDarkWyrm#ifdef USE_STRM_INPUT
9093ae76c23SDarkWyrm            fseek((FILE *)G.zipfd, (LONGINT)bufstart, SEEK_SET);
9103ae76c23SDarkWyrm            G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
9113ae76c23SDarkWyrm#else /* !USE_STRM_INPUT */
9123ae76c23SDarkWyrm            G.cur_zipfile_bufstart =
9133ae76c23SDarkWyrm              lseek(G.zipfd, (LONGINT)bufstart, SEEK_SET);
9143ae76c23SDarkWyrm#endif /* ?USE_STRM_INPUT */
9153ae76c23SDarkWyrm            if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ)) <= 0)
9163ae76c23SDarkWyrm            {
9173ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
9183ae76c23SDarkWyrm                  *pfilnum, "lseek", bufstart));
9193ae76c23SDarkWyrm                error_in_archive = PK_BADERR;
9203ae76c23SDarkWyrm                continue;   /* can still do next file */
9213ae76c23SDarkWyrm            }
9223ae76c23SDarkWyrm            G.inptr = G.inbuf + (int)inbuf_offset;
9233ae76c23SDarkWyrm            G.incnt -= (int)inbuf_offset;
9243ae76c23SDarkWyrm        } else {
9253ae76c23SDarkWyrm            G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
9263ae76c23SDarkWyrm            G.inptr = G.inbuf + (int)inbuf_offset;
9273ae76c23SDarkWyrm        }
9283ae76c23SDarkWyrm
9293ae76c23SDarkWyrm        /* should be in proper position now, so check for sig */
9303ae76c23SDarkWyrm        if (readbuf(__G__ G.sig, 4) == 0) {  /* bad offset */
9313ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
9323ae76c23SDarkWyrm              *pfilnum, "EOF", request));
9333ae76c23SDarkWyrm            error_in_archive = PK_BADERR;
9343ae76c23SDarkWyrm            continue;   /* but can still try next one */
9353ae76c23SDarkWyrm        }
9363ae76c23SDarkWyrm        if (strncmp(G.sig, local_hdr_sig, 4)) {
9373ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
9383ae76c23SDarkWyrm              *pfilnum, LoadFarStringSmall(LocalHdrSig), request));
9393ae76c23SDarkWyrm            /*
9403ae76c23SDarkWyrm                GRRDUMP(G.sig, 4)
9413ae76c23SDarkWyrm                GRRDUMP(local_hdr_sig, 4)
9423ae76c23SDarkWyrm             */
9433ae76c23SDarkWyrm            error_in_archive = PK_ERR;
9443ae76c23SDarkWyrm            if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
9453ae76c23SDarkWyrm                (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
9463ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
9473ae76c23SDarkWyrm                  LoadFarString(AttemptRecompensate)));
9483ae76c23SDarkWyrm                if (G.extra_bytes) {
9493ae76c23SDarkWyrm                    *pold_extra_bytes = G.extra_bytes;
9503ae76c23SDarkWyrm                    G.extra_bytes = 0L;
9513ae76c23SDarkWyrm                } else
9523ae76c23SDarkWyrm                    G.extra_bytes = *pold_extra_bytes; /* third attempt */
9533ae76c23SDarkWyrm                if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
9543ae76c23SDarkWyrm                    (readbuf(__G__ G.sig, 4) == 0)) {  /* bad offset */
9553ae76c23SDarkWyrm                    if (error != PK_BADERR)
9563ae76c23SDarkWyrm                      Info(slide, 0x401, ((char *)slide,
9573ae76c23SDarkWyrm                        LoadFarString(OffsetMsg), *pfilnum, "EOF", request));
9583ae76c23SDarkWyrm                    error_in_archive = PK_BADERR;
9593ae76c23SDarkWyrm                    continue;   /* but can still try next one */
9603ae76c23SDarkWyrm                }
9613ae76c23SDarkWyrm                if (strncmp(G.sig, local_hdr_sig, 4)) {
9623ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
9633ae76c23SDarkWyrm                      LoadFarString(OffsetMsg), *pfilnum,
9643ae76c23SDarkWyrm                      LoadFarStringSmall(LocalHdrSig), request));
9653ae76c23SDarkWyrm                    error_in_archive = PK_BADERR;
9663ae76c23SDarkWyrm                    continue;
9673ae76c23SDarkWyrm                }
9683ae76c23SDarkWyrm            } else
9693ae76c23SDarkWyrm                continue;  /* this one hosed; try next */
9703ae76c23SDarkWyrm        }
9713ae76c23SDarkWyrm        if ((error = process_local_file_hdr(__G)) != PK_COOL) {
9723ae76c23SDarkWyrm            Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
9733ae76c23SDarkWyrm              *pfilnum));
9743ae76c23SDarkWyrm            error_in_archive = error;   /* only PK_EOF defined */
9753ae76c23SDarkWyrm            continue;   /* can still try next one */
9763ae76c23SDarkWyrm        }
9773ae76c23SDarkWyrm        if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
9783ae76c23SDarkWyrm             PK_COOL)
9793ae76c23SDarkWyrm        {
9803ae76c23SDarkWyrm            if (error > error_in_archive)
9813ae76c23SDarkWyrm                error_in_archive = error;
9823ae76c23SDarkWyrm            if (error > PK_WARN) {
9833ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
9843ae76c23SDarkWyrm                  FnFilter1(G.filename), "local"));
9853ae76c23SDarkWyrm                continue;   /* go on to next one */
9863ae76c23SDarkWyrm            }
9873ae76c23SDarkWyrm        }
9883ae76c23SDarkWyrm        if (G.extra_field != (uch *)NULL) {
9893ae76c23SDarkWyrm            free(G.extra_field);
9903ae76c23SDarkWyrm            G.extra_field = (uch *)NULL;
9913ae76c23SDarkWyrm        }
9923ae76c23SDarkWyrm        if ((error =
9933ae76c23SDarkWyrm             do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
9943ae76c23SDarkWyrm        {
9953ae76c23SDarkWyrm            if (error > error_in_archive)
9963ae76c23SDarkWyrm                error_in_archive = error;
9973ae76c23SDarkWyrm            if (error > PK_WARN) {
9983ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
9993ae76c23SDarkWyrm                  LoadFarString(ExtFieldMsg),
10003ae76c23SDarkWyrm                  FnFilter1(G.filename), "local"));
10013ae76c23SDarkWyrm                continue;   /* go on */
10023ae76c23SDarkWyrm            }
10033ae76c23SDarkWyrm        }
10043ae76c23SDarkWyrm
10053ae76c23SDarkWyrm#if CRYPT
10063ae76c23SDarkWyrm        if (G.pInfo->encrypted &&
10073ae76c23SDarkWyrm            (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
10083ae76c23SDarkWyrm            if (error == PK_WARN) {
10093ae76c23SDarkWyrm                if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
10103ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
10113ae76c23SDarkWyrm                      LoadFarString(SkipIncorrectPasswd),
10123ae76c23SDarkWyrm                      FnFilter1(G.filename)));
10133ae76c23SDarkWyrm                ++(*pnum_bad_pwd);
10143ae76c23SDarkWyrm            } else {  /* (error > PK_WARN) */
10153ae76c23SDarkWyrm                if (error > error_in_archive)
10163ae76c23SDarkWyrm                    error_in_archive = error;
10173ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
10183ae76c23SDarkWyrm                  LoadFarString(SkipCannotGetPasswd),
10193ae76c23SDarkWyrm                  FnFilter1(G.filename)));
10203ae76c23SDarkWyrm            }
10213ae76c23SDarkWyrm            continue;   /* go on to next file */
10223ae76c23SDarkWyrm        }
10233ae76c23SDarkWyrm#endif /* CRYPT */
10243ae76c23SDarkWyrm
10253ae76c23SDarkWyrm        /*
10263ae76c23SDarkWyrm         * just about to extract file:  if extracting to disk, check if
10273ae76c23SDarkWyrm         * already exists, and if so, take appropriate action according to
10283ae76c23SDarkWyrm         * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
10293ae76c23SDarkWyrm         * loop because we don't store the possibly renamed filename[] in
10303ae76c23SDarkWyrm         * info[])
10313ae76c23SDarkWyrm         */
10323ae76c23SDarkWyrm#ifdef DLL
10333ae76c23SDarkWyrm        if (!uO.tflag && !uO.cflag && !G.redirect_data)
10343ae76c23SDarkWyrm#else
10353ae76c23SDarkWyrm        if (!uO.tflag && !uO.cflag)
10363ae76c23SDarkWyrm#endif
10373ae76c23SDarkWyrm        {
10383ae76c23SDarkWyrm            renamed = FALSE;   /* user hasn't renamed output file yet */
10393ae76c23SDarkWyrm
10403ae76c23SDarkWyrmstartover:
10413ae76c23SDarkWyrm            query = FALSE;
10423ae76c23SDarkWyrm            skip_entry = SKIP_NO;
10433ae76c23SDarkWyrm            /* for files from DOS FAT, check for use of backslash instead
10443ae76c23SDarkWyrm             *  of slash as directory separator (bug in some zipper(s); so
10453ae76c23SDarkWyrm             *  far, not a problem in HPFS, NTFS or VFAT systems)
10463ae76c23SDarkWyrm             */
10473ae76c23SDarkWyrm#ifndef SFX
10483ae76c23SDarkWyrm            if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
10493ae76c23SDarkWyrm                char *p=G.filename;
10503ae76c23SDarkWyrm
10513ae76c23SDarkWyrm                if (*p) do {
10523ae76c23SDarkWyrm                    if (*p == '\\') {
10533ae76c23SDarkWyrm                        if (!G.reported_backslash) {
10543ae76c23SDarkWyrm                            Info(slide, 0x21, ((char *)slide,
10553ae76c23SDarkWyrm                              LoadFarString(BackslashPathSep), G.zipfn));
10563ae76c23SDarkWyrm                            G.reported_backslash = TRUE;
10573ae76c23SDarkWyrm                            if (!error_in_archive)
10583ae76c23SDarkWyrm                                error_in_archive = PK_WARN;
10593ae76c23SDarkWyrm                        }
10603ae76c23SDarkWyrm                        *p = '/';
10613ae76c23SDarkWyrm                    }
10623ae76c23SDarkWyrm                } while (*PREINCSTR(p));
10633ae76c23SDarkWyrm            }
10643ae76c23SDarkWyrm#endif /* !SFX */
10653ae76c23SDarkWyrm
10663ae76c23SDarkWyrm            if (!renamed) {
10673ae76c23SDarkWyrm               /* remove absolute path specs */
10683ae76c23SDarkWyrm               if (G.filename[0] == '/') {
10693ae76c23SDarkWyrm                   Info(slide, 0x401, ((char *)slide,
10703ae76c23SDarkWyrm                        LoadFarString(AbsolutePathWarning),
10713ae76c23SDarkWyrm                        FnFilter1(G.filename)));
10723ae76c23SDarkWyrm                   if (!error_in_archive)
10733ae76c23SDarkWyrm                       error_in_archive = PK_WARN;
10743ae76c23SDarkWyrm                   do {
10753ae76c23SDarkWyrm                       char *p = G.filename + 1;
10763ae76c23SDarkWyrm                       do {
10773ae76c23SDarkWyrm                           *(p-1) = *p;
10783ae76c23SDarkWyrm                       } while (*p++ != '\0');
10793ae76c23SDarkWyrm                   } while (G.filename[0] == '/');
10803ae76c23SDarkWyrm               }
10813ae76c23SDarkWyrm            }
10823ae76c23SDarkWyrm
10833ae76c23SDarkWyrm            /* mapname can create dirs if not freshening or if renamed */
10843ae76c23SDarkWyrm            error = mapname(__G__ renamed);
10853ae76c23SDarkWyrm            if ((errcode = error & ~MPN_MASK) != PK_OK &&
10863ae76c23SDarkWyrm                error_in_archive < errcode)
10873ae76c23SDarkWyrm                error_in_archive = errcode;
10883ae76c23SDarkWyrm            if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
10893ae76c23SDarkWyrm                if (errcode == MPN_CREATED_DIR) {
10903ae76c23SDarkWyrm#ifdef SET_DIR_ATTRIB
10913ae76c23SDarkWyrm                    dirtime *d_entry;
10923ae76c23SDarkWyrm
10933ae76c23SDarkWyrm                    d_entry = (dirtime *)malloc(sizeof(dirtime));
10943ae76c23SDarkWyrm                    if (d_entry == (dirtime *)NULL) {
10953ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
10963ae76c23SDarkWyrm                             LoadFarString(DirlistEntryNoMem)));
10973ae76c23SDarkWyrm                    } else {
10983ae76c23SDarkWyrm                        unsigned eb_izux_flg;
10993ae76c23SDarkWyrm
11003ae76c23SDarkWyrm                        d_entry->next = (*pdirlist);
11013ae76c23SDarkWyrm                        (*pdirlist) = d_entry;
11023ae76c23SDarkWyrm                        (*pdirlist)->fn =
11033ae76c23SDarkWyrm                          (char *)malloc(strlen(G.filename) + 1);
11043ae76c23SDarkWyrm                        if ((*pdirlist)->fn == (char *)NULL) {
11053ae76c23SDarkWyrm                            Info(slide, 0x401, ((char *)slide,
11063ae76c23SDarkWyrm                              LoadFarString(DirlistEntryNoMem)));
11073ae76c23SDarkWyrm                            (*pdirlist) = d_entry->next;
11083ae76c23SDarkWyrm                            free(d_entry);
11093ae76c23SDarkWyrm                            if (!error_in_archive)
11103ae76c23SDarkWyrm                                error_in_archive = PK_WARN;
11113ae76c23SDarkWyrm                            continue;
11123ae76c23SDarkWyrm                        }
11133ae76c23SDarkWyrm                        strcpy((*pdirlist)->fn, G.filename);
11143ae76c23SDarkWyrm                        (*pdirlist)->perms = G.pInfo->file_attr;
11153ae76c23SDarkWyrm#ifdef USE_EF_UT_TIME
11163ae76c23SDarkWyrm                        eb_izux_flg = G.extra_field? ef_scan_for_izux(
11173ae76c23SDarkWyrm                          G.extra_field, G.lrec.extra_field_length, 0,
11183ae76c23SDarkWyrm                          G.lrec.last_mod_dos_datetime,
11193ae76c23SDarkWyrm#ifdef IZ_CHECK_TZ
11203ae76c23SDarkWyrm                          (G.tz_is_valid ? &((*pdirlist)->u.t3) : NULL),
11213ae76c23SDarkWyrm#else
11223ae76c23SDarkWyrm                          &((*pdirlist)->u.t3),
11233ae76c23SDarkWyrm#endif
11243ae76c23SDarkWyrm                          (*pdirlist)->uidgid)
11253ae76c23SDarkWyrm                          : 0;
11263ae76c23SDarkWyrm#else /* !USE_EF_UT_TIME */
11273ae76c23SDarkWyrm                        eb_izux_flg = 0;
11283ae76c23SDarkWyrm#endif /* ?USE_EF_UT_TIME */
11293ae76c23SDarkWyrm                        if (eb_izux_flg & EB_UT_FL_MTIME) {
11303ae76c23SDarkWyrm                            TTrace((stderr,
11313ae76c23SDarkWyrm                              "\nextract:  Unix dir e.f. modtime = %ld\n",
11323ae76c23SDarkWyrm                              (*pdirlist)->u.t3.mtime));
11333ae76c23SDarkWyrm                        } else {
11343ae76c23SDarkWyrm                            (*pdirlist)->u.t3.mtime = dos_to_unix_time(
11353ae76c23SDarkWyrm                              G.lrec.last_mod_dos_datetime);
11363ae76c23SDarkWyrm                        }
11373ae76c23SDarkWyrm                        if (eb_izux_flg & EB_UT_FL_ATIME) {
11383ae76c23SDarkWyrm                            TTrace((stderr,
11393ae76c23SDarkWyrm                              "\nextract:  Unix dir e.f. actime = %ld\n",
11403ae76c23SDarkWyrm                              (*pdirlist)->u.t3.atime));
11413ae76c23SDarkWyrm                        } else {
11423ae76c23SDarkWyrm                            (*pdirlist)->u.t3.atime =
11433ae76c23SDarkWyrm                              (*pdirlist)->u.t3.mtime;
11443ae76c23SDarkWyrm                        }
11453ae76c23SDarkWyrm                        (*pdirlist)->have_uidgid =
11463ae76c23SDarkWyrm#ifdef RESTORE_UIDGID
11473ae76c23SDarkWyrm                            (uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
11483ae76c23SDarkWyrm#else
11493ae76c23SDarkWyrm                            0;
11503ae76c23SDarkWyrm#endif
11513ae76c23SDarkWyrm                        ++(*pnum_dirs);
11523ae76c23SDarkWyrm                    }
11533ae76c23SDarkWyrm#endif /* SET_DIR_ATTRIB */
11543ae76c23SDarkWyrm                } else if (errcode == MPN_VOL_LABEL) {
11553ae76c23SDarkWyrm#ifdef DOS_OS2_W32
11563ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
11573ae76c23SDarkWyrm                      LoadFarString(SkipVolumeLabel),
11583ae76c23SDarkWyrm                      FnFilter1(G.filename),
11593ae76c23SDarkWyrm                      uO.volflag? "hard disk " : ""));
11603ae76c23SDarkWyrm#else
11613ae76c23SDarkWyrm                    Info(slide, 1, ((char *)slide,
11623ae76c23SDarkWyrm                      LoadFarString(SkipVolumeLabel),
11633ae76c23SDarkWyrm                      FnFilter1(G.filename), ""));
11643ae76c23SDarkWyrm#endif
11653ae76c23SDarkWyrm                } else if (errcode > MPN_INF_SKIP &&
11663ae76c23SDarkWyrm                           error_in_archive < PK_ERR)
11673ae76c23SDarkWyrm                    error_in_archive = PK_ERR;
11683ae76c23SDarkWyrm                Trace((stderr, "mapname(%s) returns error code = %d\n",
11693ae76c23SDarkWyrm                  FnFilter1(G.filename), error));
11703ae76c23SDarkWyrm                continue;   /* go on to next file */
11713ae76c23SDarkWyrm            }
11723ae76c23SDarkWyrm
11733ae76c23SDarkWyrm#ifdef QDOS
11743ae76c23SDarkWyrm            QFilename(__G__ G.filename);
11753ae76c23SDarkWyrm#endif
11763ae76c23SDarkWyrm            switch (check_for_newer(__G__ G.filename)) {
11773ae76c23SDarkWyrm                case DOES_NOT_EXIST:
11783ae76c23SDarkWyrm#ifdef NOVELL_BUG_FAILSAFE
11793ae76c23SDarkWyrm                    G.dne = TRUE;   /* stat() says file DOES NOT EXIST */
11803ae76c23SDarkWyrm#endif
11813ae76c23SDarkWyrm                    /* freshen (no new files): skip unless just renamed */
11823ae76c23SDarkWyrm                    if (uO.fflag && !renamed)
11833ae76c23SDarkWyrm                        skip_entry = SKIP_Y_NONEXIST;
11843ae76c23SDarkWyrm                    break;
11853ae76c23SDarkWyrm                case EXISTS_AND_OLDER:
11863ae76c23SDarkWyrm#ifdef UNIXBACKUP
11873ae76c23SDarkWyrm                    if (!uO.B_flag)
11883ae76c23SDarkWyrm#endif
11893ae76c23SDarkWyrm                    {
11903ae76c23SDarkWyrm                        if (IS_OVERWRT_NONE)
11913ae76c23SDarkWyrm                            /* never overwrite:  skip file */
11923ae76c23SDarkWyrm                            skip_entry = SKIP_Y_EXISTING;
11933ae76c23SDarkWyrm                        else if (!IS_OVERWRT_ALL)
11943ae76c23SDarkWyrm                            query = TRUE;
11953ae76c23SDarkWyrm                    }
11963ae76c23SDarkWyrm                    break;
11973ae76c23SDarkWyrm                case EXISTS_AND_NEWER:             /* (or equal) */
11983ae76c23SDarkWyrm#ifdef UNIXBACKUP
11993ae76c23SDarkWyrm                    if ((!uO.B_flag && IS_OVERWRT_NONE) ||
12003ae76c23SDarkWyrm#else
12013ae76c23SDarkWyrm                    if (IS_OVERWRT_NONE ||
12023ae76c23SDarkWyrm#endif
12033ae76c23SDarkWyrm                        (uO.uflag && !renamed)) {
12043ae76c23SDarkWyrm                        /* skip if update/freshen & orig name */
12053ae76c23SDarkWyrm                        skip_entry = SKIP_Y_EXISTING;
12063ae76c23SDarkWyrm                    } else {
12073ae76c23SDarkWyrm#ifdef UNIXBACKUP
12083ae76c23SDarkWyrm                        if (!IS_OVERWRT_ALL && !uO.B_flag)
12093ae76c23SDarkWyrm#else
12103ae76c23SDarkWyrm                        if (!IS_OVERWRT_ALL)
12113ae76c23SDarkWyrm#endif
12123ae76c23SDarkWyrm                            query = TRUE;
12133ae76c23SDarkWyrm                    }
12143ae76c23SDarkWyrm                    break;
12153ae76c23SDarkWyrm                }
12163ae76c23SDarkWyrm            if (query) {
12173ae76c23SDarkWyrm#ifdef WINDLL
12183ae76c23SDarkWyrm                switch (G.lpUserFunctions->replace != NULL ?
12193ae76c23SDarkWyrm                        (*G.lpUserFunctions->replace)(G.filename) :
12203ae76c23SDarkWyrm                        IDM_REPLACE_NONE) {
12213ae76c23SDarkWyrm                    case IDM_REPLACE_RENAME:
12223ae76c23SDarkWyrm                        _ISO_INTERN(G.filename);
12233ae76c23SDarkWyrm                        renamed = TRUE;
12243ae76c23SDarkWyrm                        goto startover;
12253ae76c23SDarkWyrm                    case IDM_REPLACE_ALL:
12263ae76c23SDarkWyrm                        G.overwrite_mode = OVERWRT_ALWAYS;
12273ae76c23SDarkWyrm                        /* FALL THROUGH, extract */
12283ae76c23SDarkWyrm                    case IDM_REPLACE_YES:
12293ae76c23SDarkWyrm                        break;
12303ae76c23SDarkWyrm                    case IDM_REPLACE_NONE:
12313ae76c23SDarkWyrm                        G.overwrite_mode = OVERWRT_NEVER;
12323ae76c23SDarkWyrm                        /* FALL THROUGH, skip */
12333ae76c23SDarkWyrm                    case IDM_REPLACE_NO:
12343ae76c23SDarkWyrm                        skip_entry = SKIP_Y_EXISTING;
12353ae76c23SDarkWyrm                        break;
12363ae76c23SDarkWyrm                }
12373ae76c23SDarkWyrm#else /* !WINDLL */
12383ae76c23SDarkWyrm                extent fnlen;
12393ae76c23SDarkWyrmreprompt:
12403ae76c23SDarkWyrm                Info(slide, 0x81, ((char *)slide,
12413ae76c23SDarkWyrm                  LoadFarString(ReplaceQuery),
12423ae76c23SDarkWyrm                  FnFilter1(G.filename)));
12433ae76c23SDarkWyrm                if (fgets(G.answerbuf, 9, stdin) == (char *)NULL) {
12443ae76c23SDarkWyrm                    Info(slide, 1, ((char *)slide,
12453ae76c23SDarkWyrm                      LoadFarString(AssumeNone)));
12463ae76c23SDarkWyrm                    *G.answerbuf = 'N';
12473ae76c23SDarkWyrm                    if (!error_in_archive)
12483ae76c23SDarkWyrm                        error_in_archive = 1;  /* not extracted:  warning */
12493ae76c23SDarkWyrm                }
12503ae76c23SDarkWyrm                switch (*G.answerbuf) {
12513ae76c23SDarkWyrm                    case 'r':
12523ae76c23SDarkWyrm                    case 'R':
12533ae76c23SDarkWyrm                        do {
12543ae76c23SDarkWyrm                            Info(slide, 0x81, ((char *)slide,
12553ae76c23SDarkWyrm                              LoadFarString(NewNameQuery)));
12563ae76c23SDarkWyrm                            fgets(G.filename, FILNAMSIZ, stdin);
12573ae76c23SDarkWyrm                            /* usually get \n here:  better check for it */
12583ae76c23SDarkWyrm                            fnlen = strlen(G.filename);
12593ae76c23SDarkWyrm                            if (lastchar(G.filename, fnlen) == '\n')
12603ae76c23SDarkWyrm                                G.filename[--fnlen] = '\0';
12613ae76c23SDarkWyrm                        } while (fnlen == 0);
12623ae76c23SDarkWyrm#ifdef WIN32  /* WIN32 fgets( ... , stdin) returns OEM coded strings */
12633ae76c23SDarkWyrm                        _OEM_INTERN(G.filename);
12643ae76c23SDarkWyrm#endif
12653ae76c23SDarkWyrm                        renamed = TRUE;
12663ae76c23SDarkWyrm                        goto startover;   /* sorry for a goto */
12673ae76c23SDarkWyrm                    case 'A':   /* dangerous option:  force caps */
12683ae76c23SDarkWyrm                        G.overwrite_mode = OVERWRT_ALWAYS;
12693ae76c23SDarkWyrm                        /* FALL THROUGH, extract */
12703ae76c23SDarkWyrm                    case 'y':
12713ae76c23SDarkWyrm                    case 'Y':
12723ae76c23SDarkWyrm                        break;
12733ae76c23SDarkWyrm                    case 'N':
12743ae76c23SDarkWyrm                        G.overwrite_mode = OVERWRT_NEVER;
12753ae76c23SDarkWyrm                        /* FALL THROUGH, skip */
12763ae76c23SDarkWyrm                    case 'n':
12773ae76c23SDarkWyrm                        /* skip file */
12783ae76c23SDarkWyrm                        skip_entry = SKIP_Y_EXISTING;
12793ae76c23SDarkWyrm                        break;
12803ae76c23SDarkWyrm                    default:
12813ae76c23SDarkWyrm                        Info(slide, 1, ((char *)slide,
12823ae76c23SDarkWyrm                          LoadFarString(InvalidResponse), *G.answerbuf));
12833ae76c23SDarkWyrm                        goto reprompt;   /* yet another goto? */
12843ae76c23SDarkWyrm                } /* end switch (*answerbuf) */
12853ae76c23SDarkWyrm#endif /* ?WINDLL */
12863ae76c23SDarkWyrm            } /* end if (query) */
12873ae76c23SDarkWyrm            if (skip_entry != SKIP_NO) {
12883ae76c23SDarkWyrm#ifdef WINDLL
12893ae76c23SDarkWyrm                if (skip_entry == SKIP_Y_EXISTING) {
12903ae76c23SDarkWyrm                    /* report skipping of an existing entry */
12913ae76c23SDarkWyrm                    Info(slide, 0, ((char *)slide,
12923ae76c23SDarkWyrm                      ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
12933ae76c23SDarkWyrm                       "Target file exists.\nSkipping %s\n" :
12943ae76c23SDarkWyrm                       "Target file newer.\nSkipping %s\n"),
12953ae76c23SDarkWyrm                      FnFilter1(G.filename)));
12963ae76c23SDarkWyrm                }
12973ae76c23SDarkWyrm#endif /* WINDLL */
12983ae76c23SDarkWyrm                continue;
12993ae76c23SDarkWyrm            }
13003ae76c23SDarkWyrm        } /* end if (extracting to disk) */
13013ae76c23SDarkWyrm
13023ae76c23SDarkWyrm#ifdef DLL
13033ae76c23SDarkWyrm        if ((G.statreportcb != NULL) &&
13043ae76c23SDarkWyrm            (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
13053ae76c23SDarkWyrm                              G.filename, NULL)) {
13063ae76c23SDarkWyrm            return IZ_CTRLC;        /* cancel operation by user request */
13073ae76c23SDarkWyrm        }
13083ae76c23SDarkWyrm#endif
13093ae76c23SDarkWyrm#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
13103ae76c23SDarkWyrm        UserStop();
13113ae76c23SDarkWyrm#endif
13123ae76c23SDarkWyrm#ifdef AMIGA
13133ae76c23SDarkWyrm        G.filenote_slot = i;
13143ae76c23SDarkWyrm#endif
13153ae76c23SDarkWyrm        G.disk_full = 0;
13163ae76c23SDarkWyrm        if ((error = extract_or_test_member(__G)) != PK_COOL) {
13173ae76c23SDarkWyrm            if (error > error_in_archive)
13183ae76c23SDarkWyrm                error_in_archive = error;       /* ...and keep going */
13193ae76c23SDarkWyrm#ifdef DLL
13203ae76c23SDarkWyrm            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
13213ae76c23SDarkWyrm#else
13223ae76c23SDarkWyrm            if (G.disk_full > 1) {
13233ae76c23SDarkWyrm#endif
13243ae76c23SDarkWyrm                return error_in_archive;        /* (unless disk full) */
13253ae76c23SDarkWyrm            }
13263ae76c23SDarkWyrm        }
13273ae76c23SDarkWyrm#ifdef DLL
13283ae76c23SDarkWyrm        if ((G.statreportcb != NULL) &&
13293ae76c23SDarkWyrm            (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
13303ae76c23SDarkWyrm                              G.filename, (zvoid *)&G.lrec.ucsize)) {
13313ae76c23SDarkWyrm            return IZ_CTRLC;        /* cancel operation by user request */
13323ae76c23SDarkWyrm        }
13333ae76c23SDarkWyrm#endif
13343ae76c23SDarkWyrm#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
13353ae76c23SDarkWyrm        UserStop();
13363ae76c23SDarkWyrm#endif
13373ae76c23SDarkWyrm    } /* end for-loop (i:  files in current block) */
13383ae76c23SDarkWyrm
13393ae76c23SDarkWyrm    return error_in_archive;
13403ae76c23SDarkWyrm
13413ae76c23SDarkWyrm} /* end function extract_or_test_entrylist() */
13423ae76c23SDarkWyrm
13433ae76c23SDarkWyrm
13443ae76c23SDarkWyrm
13453ae76c23SDarkWyrm
13463ae76c23SDarkWyrm
13473ae76c23SDarkWyrm/***************************************/
13483ae76c23SDarkWyrm/*  Function extract_or_test_member()  */
13493ae76c23SDarkWyrm/***************************************/
13503ae76c23SDarkWyrm
13513ae76c23SDarkWyrmstatic int extract_or_test_member(__G)    /* return PK-type error code */
13523ae76c23SDarkWyrm     __GDEF
13533ae76c23SDarkWyrm{
13543ae76c23SDarkWyrm    char *nul="[empty] ", *txt="[text]  ", *bin="[binary]";
13553ae76c23SDarkWyrm#ifdef CMS_MVS
13563ae76c23SDarkWyrm    char *ebc="[ebcdic]";
13573ae76c23SDarkWyrm#endif
13583ae76c23SDarkWyrm    register int b;
13593ae76c23SDarkWyrm    int r, error=PK_COOL;
13603ae76c23SDarkWyrm#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
13613ae76c23SDarkWyrm    ulg wsize;
13623ae76c23SDarkWyrm#else
13633ae76c23SDarkWyrm#   define wsize WSIZE
13643ae76c23SDarkWyrm#endif
13653ae76c23SDarkWyrm
13663ae76c23SDarkWyrm
13673ae76c23SDarkWyrm/*---------------------------------------------------------------------------
13683ae76c23SDarkWyrm    Initialize variables, buffers, etc.
13693ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
13703ae76c23SDarkWyrm
13713ae76c23SDarkWyrm    G.bits_left = 0;
13723ae76c23SDarkWyrm    G.bitbuf = 0L;       /* unreduce and unshrink only */
13733ae76c23SDarkWyrm    G.zipeof = 0;
13743ae76c23SDarkWyrm    G.newfile = TRUE;
13753ae76c23SDarkWyrm    G.crc32val = CRCVAL_INITIAL;
13763ae76c23SDarkWyrm
13773ae76c23SDarkWyrm#ifdef SYMLINKS
13783ae76c23SDarkWyrm    /* if file came from Unix and is a symbolic link and we are extracting
13793ae76c23SDarkWyrm     * to disk, prepare to restore the link */
13803ae76c23SDarkWyrm    if (S_ISLNK(G.pInfo->file_attr) &&
13813ae76c23SDarkWyrm        (G.pInfo->hostnum == UNIX_ || G.pInfo->hostnum == ATARI_ ||
13823ae76c23SDarkWyrm         G.pInfo->hostnum == BEOS_) &&
13833ae76c23SDarkWyrm        !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0))
13843ae76c23SDarkWyrm        G.symlnk = TRUE;
13853ae76c23SDarkWyrm    else
13863ae76c23SDarkWyrm        G.symlnk = FALSE;
13873ae76c23SDarkWyrm#endif /* SYMLINKS */
13883ae76c23SDarkWyrm
13893ae76c23SDarkWyrm    if (uO.tflag) {
13903ae76c23SDarkWyrm        if (!uO.qflag)
13913ae76c23SDarkWyrm            Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
13923ae76c23SDarkWyrm              FnFilter1(G.filename), "", ""));
13933ae76c23SDarkWyrm    } else {
13943ae76c23SDarkWyrm#ifdef DLL
13953ae76c23SDarkWyrm        if (uO.cflag && !G.redirect_data)
13963ae76c23SDarkWyrm#else
13973ae76c23SDarkWyrm        if (uO.cflag)
13983ae76c23SDarkWyrm#endif
13993ae76c23SDarkWyrm        {
14003ae76c23SDarkWyrm#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
14013ae76c23SDarkWyrm            G.outfile = freopen("", "wb", stdout);   /* VAC++ ignores setmode */
14023ae76c23SDarkWyrm#else
14033ae76c23SDarkWyrm            G.outfile = stdout;
14043ae76c23SDarkWyrm#endif
14053ae76c23SDarkWyrm#ifdef DOS_FLX_NLM_OS2_W32
14063ae76c23SDarkWyrm#if (defined(__HIGHC__) && !defined(FLEXOS))
14073ae76c23SDarkWyrm            setmode(G.outfile, _BINARY);
14083ae76c23SDarkWyrm#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
14093ae76c23SDarkWyrm            setmode(fileno(G.outfile), O_BINARY);
14103ae76c23SDarkWyrm#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
14113ae76c23SDarkWyrm#           define NEWLINE "\r\n"
14123ae76c23SDarkWyrm#else /* !DOS_FLX_NLM_OS2_W32 */
14133ae76c23SDarkWyrm#           define NEWLINE "\n"
14143ae76c23SDarkWyrm#endif /* ?DOS_FLX_NLM_OS2_W32 */
14153ae76c23SDarkWyrm#ifdef VMS
14163ae76c23SDarkWyrm            if (open_outfile(__G))   /* VMS:  required even for stdout! */
14173ae76c23SDarkWyrm                return PK_DISK;
14183ae76c23SDarkWyrm#endif
14193ae76c23SDarkWyrm        } else if (open_outfile(__G))
14203ae76c23SDarkWyrm            return PK_DISK;
14213ae76c23SDarkWyrm    }
14223ae76c23SDarkWyrm
14233ae76c23SDarkWyrm/*---------------------------------------------------------------------------
14243ae76c23SDarkWyrm    Unpack the file.
14253ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
14263ae76c23SDarkWyrm
14273ae76c23SDarkWyrm    defer_leftover_input(__G);    /* so NEXTBYTE bounds check will work */
14283ae76c23SDarkWyrm    switch (G.lrec.compression_method) {
14293ae76c23SDarkWyrm        case STORED:
14303ae76c23SDarkWyrm            if (!uO.tflag && QCOND2) {
14313ae76c23SDarkWyrm#ifdef SYMLINKS
14323ae76c23SDarkWyrm                if (G.symlnk)   /* can also be deflated, but rarer... */
14333ae76c23SDarkWyrm                    Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
14343ae76c23SDarkWyrm                      "link", FnFilter1(G.filename), "", ""));
14353ae76c23SDarkWyrm                else
14363ae76c23SDarkWyrm#endif /* SYMLINKS */
14373ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
14383ae76c23SDarkWyrm                  "extract", FnFilter1(G.filename),
14393ae76c23SDarkWyrm                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
14403ae76c23SDarkWyrm                  "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
14413ae76c23SDarkWyrm                  bin)), uO.cflag? NEWLINE : ""));
14423ae76c23SDarkWyrm            }
14433ae76c23SDarkWyrm#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
14443ae76c23SDarkWyrm            if (G.redirect_slide) {
14453ae76c23SDarkWyrm                wsize = G.redirect_size; redirSlide = G.redirect_buffer;
14463ae76c23SDarkWyrm            } else {
14473ae76c23SDarkWyrm                wsize = WSIZE; redirSlide = slide;
14483ae76c23SDarkWyrm            }
14493ae76c23SDarkWyrm#endif
14503ae76c23SDarkWyrm            G.outptr = redirSlide;
14513ae76c23SDarkWyrm            G.outcnt = 0L;
14523ae76c23SDarkWyrm            while ((b = NEXTBYTE) != EOF) {
14533ae76c23SDarkWyrm                *G.outptr++ = (uch)b;
14543ae76c23SDarkWyrm                if (++G.outcnt == wsize) {
14553ae76c23SDarkWyrm                    error = flush(__G__ redirSlide, G.outcnt, 0);
14563ae76c23SDarkWyrm                    G.outptr = redirSlide;
14573ae76c23SDarkWyrm                    G.outcnt = 0L;
14583ae76c23SDarkWyrm                    if (error != PK_COOL || G.disk_full) break;
14593ae76c23SDarkWyrm                }
14603ae76c23SDarkWyrm            }
14613ae76c23SDarkWyrm            if (G.outcnt)          /* flush final (partial) buffer */
14623ae76c23SDarkWyrm                flush(__G__ redirSlide, G.outcnt, 0);
14633ae76c23SDarkWyrm            break;
14643ae76c23SDarkWyrm
14653ae76c23SDarkWyrm#ifndef SFX
14663ae76c23SDarkWyrm#ifndef LZW_CLEAN
14673ae76c23SDarkWyrm        case SHRUNK:
14683ae76c23SDarkWyrm            if (!uO.tflag && QCOND2) {
14693ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
14703ae76c23SDarkWyrm                  LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
14713ae76c23SDarkWyrm                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
14723ae76c23SDarkWyrm                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
14733ae76c23SDarkWyrm            }
14743ae76c23SDarkWyrm            if ((r = unshrink(__G)) != PK_COOL) {
14753ae76c23SDarkWyrm                if (r < PK_DISK) {
14763ae76c23SDarkWyrm                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
14773ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
14783ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipFile),
14793ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem),
14803ae76c23SDarkWyrm                          LoadFarStringSmall2(Unshrink),
14813ae76c23SDarkWyrm                          FnFilter1(G.filename)));
14823ae76c23SDarkWyrm                    else
14833ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
14843ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipNoFile),
14853ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem),
14863ae76c23SDarkWyrm                          LoadFarStringSmall2(Unshrink)));
14873ae76c23SDarkWyrm                }
14883ae76c23SDarkWyrm                error = r;
14893ae76c23SDarkWyrm            }
14903ae76c23SDarkWyrm            break;
14913ae76c23SDarkWyrm#endif /* !LZW_CLEAN */
14923ae76c23SDarkWyrm
14933ae76c23SDarkWyrm#ifndef COPYRIGHT_CLEAN
14943ae76c23SDarkWyrm        case REDUCED1:
14953ae76c23SDarkWyrm        case REDUCED2:
14963ae76c23SDarkWyrm        case REDUCED3:
14973ae76c23SDarkWyrm        case REDUCED4:
14983ae76c23SDarkWyrm            if (!uO.tflag && QCOND2) {
14993ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
15003ae76c23SDarkWyrm                  "unreduc", FnFilter1(G.filename),
15013ae76c23SDarkWyrm                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
15023ae76c23SDarkWyrm                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
15033ae76c23SDarkWyrm            }
15043ae76c23SDarkWyrm            if ((r = unreduce(__G)) != PK_COOL) {
15053ae76c23SDarkWyrm                /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
15063ae76c23SDarkWyrm                error = r;
15073ae76c23SDarkWyrm            }
15083ae76c23SDarkWyrm            break;
15093ae76c23SDarkWyrm#endif /* !COPYRIGHT_CLEAN */
15103ae76c23SDarkWyrm
15113ae76c23SDarkWyrm        case IMPLODED:
15123ae76c23SDarkWyrm            if (!uO.tflag && QCOND2) {
15133ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
15143ae76c23SDarkWyrm                  "explod", FnFilter1(G.filename),
15153ae76c23SDarkWyrm                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
15163ae76c23SDarkWyrm                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
15173ae76c23SDarkWyrm            }
15183ae76c23SDarkWyrm            if (((r = explode(__G)) != 0) && (r != 5)) { /* treat 5 specially */
15193ae76c23SDarkWyrm                if (r < PK_DISK) {
15203ae76c23SDarkWyrm                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
15213ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
15223ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipFile), r == 3?
15233ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem) :
15243ae76c23SDarkWyrm                          LoadFarString(InvalidComprData),
15253ae76c23SDarkWyrm                          LoadFarStringSmall2(Explode),
15263ae76c23SDarkWyrm                          FnFilter1(G.filename)));
15273ae76c23SDarkWyrm                    else
15283ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
15293ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
15303ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem) :
15313ae76c23SDarkWyrm                          LoadFarString(InvalidComprData),
15323ae76c23SDarkWyrm                          LoadFarStringSmall2(Explode)));
15333ae76c23SDarkWyrm                    error = (r == 3)? PK_MEM3 : PK_ERR;
15343ae76c23SDarkWyrm                } else {
15353ae76c23SDarkWyrm                    error = r;
15363ae76c23SDarkWyrm                }
15373ae76c23SDarkWyrm            }
15383ae76c23SDarkWyrm            if (r == 5) {
15393ae76c23SDarkWyrm                int warning = ((ulg)G.used_csize <= G.lrec.csize);
15403ae76c23SDarkWyrm
15413ae76c23SDarkWyrm                if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
15423ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
15433ae76c23SDarkWyrm                      "", warning?  "warning" : "error", G.used_csize,
15443ae76c23SDarkWyrm                      G.lrec.ucsize, warning?  "  " : "", G.lrec.csize,
15453ae76c23SDarkWyrm                      " [", FnFilter1(G.filename), "]"));
15463ae76c23SDarkWyrm                else
15473ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
15483ae76c23SDarkWyrm                      "\n", warning? "warning" : "error", G.used_csize,
15493ae76c23SDarkWyrm                      G.lrec.ucsize, warning? "  ":"", G.lrec.csize,
15503ae76c23SDarkWyrm                      "", "", "."));
15513ae76c23SDarkWyrm                error = warning? PK_WARN : PK_ERR;
15523ae76c23SDarkWyrm            }
15533ae76c23SDarkWyrm            break;
15543ae76c23SDarkWyrm#endif /* !SFX */
15553ae76c23SDarkWyrm
15563ae76c23SDarkWyrm        case DEFLATED:
15573ae76c23SDarkWyrm#ifdef USE_DEFLATE64
15583ae76c23SDarkWyrm        case ENHDEFLATED:
15593ae76c23SDarkWyrm#endif
15603ae76c23SDarkWyrm            if (!uO.tflag && QCOND2) {
15613ae76c23SDarkWyrm                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
15623ae76c23SDarkWyrm                  "inflat", FnFilter1(G.filename),
15633ae76c23SDarkWyrm                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
15643ae76c23SDarkWyrm                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
15653ae76c23SDarkWyrm            }
15663ae76c23SDarkWyrm#ifndef USE_ZLIB  /* zlib's function is called inflate(), too */
15673ae76c23SDarkWyrm#  define UZinflate inflate
15683ae76c23SDarkWyrm#endif
15693ae76c23SDarkWyrm            if ((r = UZinflate(__G__
15703ae76c23SDarkWyrm                               (G.lrec.compression_method == ENHDEFLATED)))
15713ae76c23SDarkWyrm                != 0) {
15723ae76c23SDarkWyrm                if (r < PK_DISK) {
15733ae76c23SDarkWyrm                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
15743ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
15753ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipFile), r == 3?
15763ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem) :
15773ae76c23SDarkWyrm                          LoadFarString(InvalidComprData),
15783ae76c23SDarkWyrm                          LoadFarStringSmall2(Inflate),
15793ae76c23SDarkWyrm                          FnFilter1(G.filename)));
15803ae76c23SDarkWyrm                    else
15813ae76c23SDarkWyrm                        Info(slide, 0x401, ((char *)slide,
15823ae76c23SDarkWyrm                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
15833ae76c23SDarkWyrm                          LoadFarString(NotEnoughMem) :
15843ae76c23SDarkWyrm                          LoadFarString(InvalidComprData),
15853ae76c23SDarkWyrm                          LoadFarStringSmall2(Inflate)));
15863ae76c23SDarkWyrm                    error = (r == 3)? PK_MEM3 : PK_ERR;
15873ae76c23SDarkWyrm                } else {
15883ae76c23SDarkWyrm                    error = r;
15893ae76c23SDarkWyrm                }
15903ae76c23SDarkWyrm            }
15913ae76c23SDarkWyrm            break;
15923ae76c23SDarkWyrm
15933ae76c23SDarkWyrm        default:   /* should never get to this point */
15943ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide,
15953ae76c23SDarkWyrm              LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
15963ae76c23SDarkWyrm            /* close and delete file before return? */
15973ae76c23SDarkWyrm            undefer_input(__G);
15983ae76c23SDarkWyrm            return PK_WARN;
15993ae76c23SDarkWyrm
16003ae76c23SDarkWyrm    } /* end switch (compression method) */
16013ae76c23SDarkWyrm
16023ae76c23SDarkWyrm/*---------------------------------------------------------------------------
16033ae76c23SDarkWyrm    Close the file and set its date and time (not necessarily in that order),
16043ae76c23SDarkWyrm    and make sure the CRC checked out OK.  Logical-AND the CRC for 64-bit
16053ae76c23SDarkWyrm    machines (redundant on 32-bit machines).
16063ae76c23SDarkWyrm  ---------------------------------------------------------------------------*/
16073ae76c23SDarkWyrm
16083ae76c23SDarkWyrm#ifdef VMS                  /* VMS:  required even for stdout! (final flush) */
16093ae76c23SDarkWyrm    if (!uO.tflag)           /* don't close NULL file */
16103ae76c23SDarkWyrm        close_outfile(__G);
16113ae76c23SDarkWyrm#else
16123ae76c23SDarkWyrm#ifdef DLL
16133ae76c23SDarkWyrm    if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
16143ae76c23SDarkWyrm        if (G.redirect_data)
16153ae76c23SDarkWyrm            FINISH_REDIRECT();
16163ae76c23SDarkWyrm        else
16173ae76c23SDarkWyrm            close_outfile(__G);
16183ae76c23SDarkWyrm    }
16193ae76c23SDarkWyrm#else
16203ae76c23SDarkWyrm    if (!uO.tflag && !uO.cflag)   /* don't close NULL file or stdout */
16213ae76c23SDarkWyrm        close_outfile(__G);
16223ae76c23SDarkWyrm#endif
16233ae76c23SDarkWyrm#endif /* VMS */
16243ae76c23SDarkWyrm
16253ae76c23SDarkWyrm            /* GRR: CONVERT close_outfile() TO NON-VOID:  CHECK FOR ERRORS! */
16263ae76c23SDarkWyrm
16273ae76c23SDarkWyrm
16283ae76c23SDarkWyrm    if (G.disk_full) {            /* set by flush() */
16293ae76c23SDarkWyrm        if (G.disk_full > 1) {
16303ae76c23SDarkWyrm#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
16313ae76c23SDarkWyrm            /* delete the incomplete file if we can */
16323ae76c23SDarkWyrm            if (unlink(G.filename) != 0)
16333ae76c23SDarkWyrm                Trace((stderr, "extract.c:  could not delete %s\n",
16343ae76c23SDarkWyrm                  FnFilter1(G.filename)));
16353ae76c23SDarkWyrm#else
16363ae76c23SDarkWyrm            /* warn user about the incomplete file */
16373ae76c23SDarkWyrm            Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
16383ae76c23SDarkWyrm              FnFilter1(G.filename)));
16393ae76c23SDarkWyrm#endif
16403ae76c23SDarkWyrm            error = PK_DISK;
16413ae76c23SDarkWyrm        } else {
16423ae76c23SDarkWyrm            error = PK_WARN;
16433ae76c23SDarkWyrm        }
16443ae76c23SDarkWyrm    }
16453ae76c23SDarkWyrm
16463ae76c23SDarkWyrm    if (error > PK_WARN) {/* don't print redundant CRC error if error already */
16473ae76c23SDarkWyrm        undefer_input(__G);
16483ae76c23SDarkWyrm        return error;
16493ae76c23SDarkWyrm    }
16503ae76c23SDarkWyrm    if (G.crc32val != G.lrec.crc32) {
16513ae76c23SDarkWyrm        /* if quiet enough, we haven't output the filename yet:  do it */
16523ae76c23SDarkWyrm        if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
16533ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, "%-22s ",
16543ae76c23SDarkWyrm              FnFilter1(G.filename)));
16553ae76c23SDarkWyrm        Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
16563ae76c23SDarkWyrm          G.lrec.crc32));
16573ae76c23SDarkWyrm#if CRYPT
16583ae76c23SDarkWyrm        if (G.pInfo->encrypted)
16593ae76c23SDarkWyrm            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
16603ae76c23SDarkWyrm#endif
16613ae76c23SDarkWyrm        error = PK_ERR;
16623ae76c23SDarkWyrm    } else if (uO.tflag) {
16633ae76c23SDarkWyrm#ifndef SFX
16643ae76c23SDarkWyrm        if (G.extra_field) {
16653ae76c23SDarkWyrm            if ((r = TestExtraField(__G__ G.extra_field,
16663ae76c23SDarkWyrm                                    G.lrec.extra_field_length)) > error)
16673ae76c23SDarkWyrm                error = r;
16683ae76c23SDarkWyrm        } else
16693ae76c23SDarkWyrm#endif /* !SFX */
16703ae76c23SDarkWyrm        if (!uO.qflag)
16713ae76c23SDarkWyrm            Info(slide, 0, ((char *)slide, " OK\n"));
16723ae76c23SDarkWyrm    } else {
16733ae76c23SDarkWyrm        if (QCOND2 && !error)   /* GRR:  is stdout reset to text mode yet? */
16743ae76c23SDarkWyrm            Info(slide, 0, ((char *)slide, "\n"));
16753ae76c23SDarkWyrm    }
16763ae76c23SDarkWyrm
16773ae76c23SDarkWyrm    undefer_input(__G);
16783ae76c23SDarkWyrm    return error;
16793ae76c23SDarkWyrm
16803ae76c23SDarkWyrm} /* end function extract_or_test_member() */
16813ae76c23SDarkWyrm
16823ae76c23SDarkWyrm
16833ae76c23SDarkWyrm
16843ae76c23SDarkWyrm
16853ae76c23SDarkWyrm
16863ae76c23SDarkWyrm#ifndef SFX
16873ae76c23SDarkWyrm
16883ae76c23SDarkWyrm/*******************************/
16893ae76c23SDarkWyrm/*  Function TestExtraField()  */
16903ae76c23SDarkWyrm/*******************************/
16913ae76c23SDarkWyrm
16923ae76c23SDarkWyrmstatic int TestExtraField(__G__ ef, ef_len)
16933ae76c23SDarkWyrm    __GDEF
16943ae76c23SDarkWyrm    uch *ef;
16953ae76c23SDarkWyrm    unsigned ef_len;
16963ae76c23SDarkWyrm{
16973ae76c23SDarkWyrm    ush ebID;
16983ae76c23SDarkWyrm    unsigned ebLen;
16993ae76c23SDarkWyrm    unsigned eb_cmpr_offs = 0;
17003ae76c23SDarkWyrm    int r;
17013ae76c23SDarkWyrm
17023ae76c23SDarkWyrm    /* we know the regular compressed file data tested out OK, or else we
17033ae76c23SDarkWyrm     * wouldn't be here ==> print filename if any extra-field errors found
17043ae76c23SDarkWyrm     */
17053ae76c23SDarkWyrm    while (ef_len >= EB_HEADSIZE) {
17063ae76c23SDarkWyrm        ebID = makeword(ef);
17073ae76c23SDarkWyrm        ebLen = (unsigned)makeword(ef+EB_LEN);
17083ae76c23SDarkWyrm
17093ae76c23SDarkWyrm        if (ebLen > (ef_len - EB_HEADSIZE)) {
17103ae76c23SDarkWyrm           /* Discovered some extra field inconsistency! */
17113ae76c23SDarkWyrm            if (uO.qflag)
17123ae76c23SDarkWyrm                Info(slide, 1, ((char *)slide, "%-22s ",
17133ae76c23SDarkWyrm                  FnFilter1(G.filename)));
17143ae76c23SDarkWyrm            Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
17153ae76c23SDarkWyrm              ebLen, (ef_len - EB_HEADSIZE)));
17163ae76c23SDarkWyrm            return PK_ERR;
17173ae76c23SDarkWyrm        }
17183ae76c23SDarkWyrm
17193ae76c23SDarkWyrm        switch (ebID) {
17203ae76c23SDarkWyrm            case EF_OS2:
17213ae76c23SDarkWyrm            case EF_ACL:
17223ae76c23SDarkWyrm            case EF_MAC3:
17233ae76c23SDarkWyrm            case EF_BEOS:
17243ae76c23SDarkWyrm                switch (ebID) {
17253ae76c23SDarkWyrm                  case EF_OS2:
17263ae76c23SDarkWyrm                  case EF_ACL:
17273ae76c23SDarkWyrm                    eb_cmpr_offs = EB_OS2_HLEN;
17283ae76c23SDarkWyrm                    break;
17293ae76c23SDarkWyrm                  case EF_MAC3:
17303ae76c23SDarkWyrm                    if (ebLen >= EB_MAC3_HLEN &&
17313ae76c23SDarkWyrm                        (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
17323ae76c23SDarkWyrm                         & EB_M3_FL_UNCMPR) &&
17333ae76c23SDarkWyrm                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
17343ae76c23SDarkWyrm                        eb_cmpr_offs = 0;
17353ae76c23SDarkWyrm                    else
17363ae76c23SDarkWyrm                        eb_cmpr_offs = EB_MAC3_HLEN;
17373ae76c23SDarkWyrm                    break;
17383ae76c23SDarkWyrm                  case EF_BEOS:
17393ae76c23SDarkWyrm                    if (ebLen >= EB_BEOS_HLEN &&
17403ae76c23SDarkWyrm                        (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
17413ae76c23SDarkWyrm                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
17423ae76c23SDarkWyrm                        eb_cmpr_offs = 0;
17433ae76c23SDarkWyrm                    else
17443ae76c23SDarkWyrm                        eb_cmpr_offs = EB_BEOS_HLEN;
17453ae76c23SDarkWyrm                    break;
17463ae76c23SDarkWyrm                }
17473ae76c23SDarkWyrm                if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
17483ae76c23SDarkWyrm                    != PK_OK) {
17493ae76c23SDarkWyrm                    if (uO.qflag)
17503ae76c23SDarkWyrm                        Info(slide, 1, ((char *)slide, "%-22s ",
17513ae76c23SDarkWyrm                          FnFilter1(G.filename)));
17523ae76c23SDarkWyrm                    switch (r) {
17533ae76c23SDarkWyrm                        case IZ_EF_TRUNC:
17543ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
17553ae76c23SDarkWyrm                              LoadFarString(TruncEAs),
17563ae76c23SDarkWyrm                              ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
17573ae76c23SDarkWyrm                            break;
17583ae76c23SDarkWyrm                        case PK_ERR:
17593ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
17603ae76c23SDarkWyrm                              LoadFarString(InvalidComprDataEAs)));
17613ae76c23SDarkWyrm                            break;
17623ae76c23SDarkWyrm                        case PK_MEM3:
17633ae76c23SDarkWyrm                        case PK_MEM4:
17643ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
17653ae76c23SDarkWyrm                              LoadFarString(NotEnoughMemEAs)));
17663ae76c23SDarkWyrm                            break;
17673ae76c23SDarkWyrm                        default:
17683ae76c23SDarkWyrm                            if ((r & 0xff) != PK_ERR)
17693ae76c23SDarkWyrm                                Info(slide, 1, ((char *)slide,
17703ae76c23SDarkWyrm                                  LoadFarString(UnknErrorEAs)));
17713ae76c23SDarkWyrm                            else {
17723ae76c23SDarkWyrm                                ush m = (ush)(r >> 8);
17733ae76c23SDarkWyrm                                if (m == DEFLATED)            /* GRR KLUDGE! */
17743ae76c23SDarkWyrm                                    Info(slide, 1, ((char *)slide,
17753ae76c23SDarkWyrm                                      LoadFarString(BadCRC_EAs)));
17763ae76c23SDarkWyrm                                else
17773ae76c23SDarkWyrm                                    Info(slide, 1, ((char *)slide,
17783ae76c23SDarkWyrm                                      LoadFarString(UnknComprMethodEAs), m));
17793ae76c23SDarkWyrm                            }
17803ae76c23SDarkWyrm                            break;
17813ae76c23SDarkWyrm                    }
17823ae76c23SDarkWyrm                    return r;
17833ae76c23SDarkWyrm                }
17843ae76c23SDarkWyrm                break;
17853ae76c23SDarkWyrm
17863ae76c23SDarkWyrm            case EF_NTSD:
17873ae76c23SDarkWyrm                Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
17883ae76c23SDarkWyrm                r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
17893ae76c23SDarkWyrm                    ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
17903ae76c23SDarkWyrm                     (PK_WARN | 0x4000) :
17913ae76c23SDarkWyrm                     test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
17923ae76c23SDarkWyrm                if (r != PK_OK) {
17933ae76c23SDarkWyrm                    if (uO.qflag)
17943ae76c23SDarkWyrm                        Info(slide, 1, ((char *)slide, "%-22s ",
17953ae76c23SDarkWyrm                          FnFilter1(G.filename)));
17963ae76c23SDarkWyrm                    switch (r) {
17973ae76c23SDarkWyrm                        case IZ_EF_TRUNC:
17983ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
17993ae76c23SDarkWyrm                              LoadFarString(TruncNTSD),
18003ae76c23SDarkWyrm                              ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
18013ae76c23SDarkWyrm                            break;
18023ae76c23SDarkWyrm#if (defined(WIN32) && defined(NTSD_EAS))
18033ae76c23SDarkWyrm                        case PK_WARN:
18043ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
18053ae76c23SDarkWyrm                              LoadFarString(InvalidSecurityEAs)));
18063ae76c23SDarkWyrm                            break;
18073ae76c23SDarkWyrm#endif
18083ae76c23SDarkWyrm                        case PK_ERR:
18093ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
18103ae76c23SDarkWyrm                              LoadFarString(InvalidComprDataEAs)));
18113ae76c23SDarkWyrm                            break;
18123ae76c23SDarkWyrm                        case PK_MEM3:
18133ae76c23SDarkWyrm                        case PK_MEM4:
18143ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
18153ae76c23SDarkWyrm                              LoadFarString(NotEnoughMemEAs)));
18163ae76c23SDarkWyrm                            break;
18173ae76c23SDarkWyrm                        case (PK_WARN | 0x4000):
18183ae76c23SDarkWyrm                            Info(slide, 1, ((char *)slide,
18193ae76c23SDarkWyrm                              LoadFarString(UnsuppNTSDVersEAs),
18203ae76c23SDarkWyrm                              (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
18213ae76c23SDarkWyrm                            r = PK_WARN;
18223ae76c23SDarkWyrm                            break;
18233ae76c23SDarkWyrm                        default:
18243ae76c23SDarkWyrm                            if ((r & 0xff) != PK_ERR)
18253ae76c23SDarkWyrm                                Info(slide, 1, ((char *)slide,
18263ae76c23SDarkWyrm                                  LoadFarString(UnknErrorEAs)));
18273ae76c23SDarkWyrm                            else {
18283ae76c23SDarkWyrm                                ush m = (ush)(r >> 8);
18293ae76c23SDarkWyrm                                if (m == DEFLATED)            /* GRR KLUDGE! */
18303ae76c23SDarkWyrm                                    Info(slide, 1, ((char *)slide,
18313ae76c23SDarkWyrm                                      LoadFarString(BadCRC_EAs)));
18323ae76c23SDarkWyrm                                else
18333ae76c23SDarkWyrm                                    Info(slide, 1, ((char *)slide,
18343ae76c23SDarkWyrm                                      LoadFarString(UnknComprMethodEAs), m));
18353ae76c23SDarkWyrm                            }
18363ae76c23SDarkWyrm                            break;
18373ae76c23SDarkWyrm                    }
18383ae76c23SDarkWyrm                    return r;
18393ae76c23SDarkWyrm                }
18403ae76c23SDarkWyrm                break;
18413ae76c23SDarkWyrm            case EF_PKVMS:
18423ae76c23SDarkWyrm                if (makelong(ef+EB_HEADSIZE) !=
18433ae76c23SDarkWyrm                    crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
18443ae76c23SDarkWyrm                          (extent)(ebLen-4)))
18453ae76c23SDarkWyrm                    Info(slide, 1, ((char *)slide,
18463ae76c23SDarkWyrm                      LoadFarString(BadCRC_EAs)));
18473ae76c23SDarkWyrm                break;
18483ae76c23SDarkWyrm            case EF_PKW32:
18493ae76c23SDarkWyrm            case EF_PKUNIX:
18503ae76c23SDarkWyrm            case EF_ASIUNIX:
18513ae76c23SDarkWyrm            case EF_IZVMS:
18523ae76c23SDarkWyrm            case EF_IZUNIX:
18533ae76c23SDarkWyrm            case EF_VMCMS:
18543ae76c23SDarkWyrm            case EF_MVS:
18553ae76c23SDarkWyrm            case EF_SPARK:
18563ae76c23SDarkWyrm            case EF_TANDEM:
18573ae76c23SDarkWyrm            case EF_THEOS:
18583ae76c23SDarkWyrm            case EF_AV:
18593ae76c23SDarkWyrm            default:
18603ae76c23SDarkWyrm                break;
18613ae76c23SDarkWyrm        }
18623ae76c23SDarkWyrm        ef_len -= (ebLen + EB_HEADSIZE);
18633ae76c23SDarkWyrm        ef += (ebLen + EB_HEADSIZE);
18643ae76c23SDarkWyrm    }
18653ae76c23SDarkWyrm
18663ae76c23SDarkWyrm    if (!uO.qflag)
18673ae76c23SDarkWyrm        Info(slide, 0, ((char *)slide, " OK\n"));
18683ae76c23SDarkWyrm
18693ae76c23SDarkWyrm    return PK_COOL;
18703ae76c23SDarkWyrm
18713ae76c23SDarkWyrm} /* end function TestExtraField() */
18723ae76c23SDarkWyrm
18733ae76c23SDarkWyrm
18743ae76c23SDarkWyrm
18753ae76c23SDarkWyrm
18763ae76c23SDarkWyrm
18773ae76c23SDarkWyrm/******************************/
18783ae76c23SDarkWyrm/*  Function test_compr_eb()  */
18793ae76c23SDarkWyrm/******************************/
18803ae76c23SDarkWyrm
18813ae76c23SDarkWyrm#ifdef PROTO
18823ae76c23SDarkWyrmstatic int test_compr_eb(
18833ae76c23SDarkWyrm    __GPRO__
18843ae76c23SDarkWyrm    uch *eb,
18853ae76c23SDarkWyrm    unsigned eb_size,
18863ae76c23SDarkWyrm    unsigned compr_offset,
18873ae76c23SDarkWyrm    int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
18883ae76c23SDarkWyrm                          uch *eb_ucptr, ulg eb_ucsize))
18893ae76c23SDarkWyrm#else /* !PROTO */
18903ae76c23SDarkWyrmstatic int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
18913ae76c23SDarkWyrm    __GDEF
18923ae76c23SDarkWyrm    uch *eb;
18933ae76c23SDarkWyrm    unsigned eb_size;
18943ae76c23SDarkWyrm    unsigned compr_offset;
18953ae76c23SDarkWyrm    int (*test_uc_ebdata)();
18963ae76c23SDarkWyrm#endif /* ?PROTO */
18973ae76c23SDarkWyrm{
18983ae76c23SDarkWyrm    ulg eb_ucsize;
18993ae76c23SDarkWyrm    uch *eb_ucptr;
19003ae76c23SDarkWyrm    int r;
19013ae76c23SDarkWyrm
19023ae76c23SDarkWyrm    if (compr_offset < 4)                /* field is not compressed: */
19033ae76c23SDarkWyrm        return PK_OK;                    /* do nothing and signal OK */
19043ae76c23SDarkWyrm
19053ae76c23SDarkWyrm    if ((eb_size < (EB_UCSIZE_P + 4)) ||
19063ae76c23SDarkWyrm        ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
19073ae76c23SDarkWyrm         eb_size <= (compr_offset + EB_CMPRHEADLEN)))
19083ae76c23SDarkWyrm        return IZ_EF_TRUNC;               /* no compressed data! */
19093ae76c23SDarkWyrm
19103ae76c23SDarkWyrm    if ((eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
19113ae76c23SDarkWyrm        return PK_MEM4;
19123ae76c23SDarkWyrm
19133ae76c23SDarkWyrm    r = memextract(__G__ eb_ucptr, eb_ucsize,
19143ae76c23SDarkWyrm                   eb + (EB_HEADSIZE + compr_offset),
19153ae76c23SDarkWyrm                   (ulg)(eb_size - compr_offset));
19163ae76c23SDarkWyrm
19173ae76c23SDarkWyrm    if (r == PK_OK && test_uc_ebdata != NULL)
19183ae76c23SDarkWyrm        r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
19193ae76c23SDarkWyrm
19203ae76c23SDarkWyrm    free(eb_ucptr);
19213ae76c23SDarkWyrm    return r;
19223ae76c23SDarkWyrm
19233ae76c23SDarkWyrm} /* end function test_compr_eb() */
19243ae76c23SDarkWyrm
19253ae76c23SDarkWyrm#endif /* !SFX */
19263ae76c23SDarkWyrm
19273ae76c23SDarkWyrm
19283ae76c23SDarkWyrm
19293ae76c23SDarkWyrm
19303ae76c23SDarkWyrm
19313ae76c23SDarkWyrm/***************************/
19323ae76c23SDarkWyrm/*  Function memextract()  */
19333ae76c23SDarkWyrm/***************************/
19343ae76c23SDarkWyrm
19353ae76c23SDarkWyrmint memextract(__G__ tgt, tgtsize, src, srcsize)  /* extract compressed */
19363ae76c23SDarkWyrm    __GDEF                                        /*  extra field block; */
19373ae76c23SDarkWyrm    uch *tgt;                                     /*  return PK-type error */
19383ae76c23SDarkWyrm    ulg tgtsize;                                  /*  level */
19393ae76c23SDarkWyrm    ZCONST uch *src;
19403ae76c23SDarkWyrm    ulg srcsize;
19413ae76c23SDarkWyrm{
19423ae76c23SDarkWyrm    long old_csize=G.csize;
19433ae76c23SDarkWyrm    uch *old_inptr=G.inptr;
19443ae76c23SDarkWyrm    int  old_incnt=G.incnt;
19453ae76c23SDarkWyrm    int  r, error=PK_OK;
19463ae76c23SDarkWyrm    ush  method;
19473ae76c23SDarkWyrm    ulg  extra_field_crc;
19483ae76c23SDarkWyrm
19493ae76c23SDarkWyrm
19503ae76c23SDarkWyrm    method = makeword(src);
19513ae76c23SDarkWyrm    extra_field_crc = makelong(src+2);
19523ae76c23SDarkWyrm
19533ae76c23SDarkWyrm    /* compressed extra field exists completely in memory at this location: */
19543ae76c23SDarkWyrm    G.inptr = (uch *)src + (2 + 4);     /* method and extra_field_crc */
19553ae76c23SDarkWyrm    G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
19563ae76c23SDarkWyrm    G.mem_mode = TRUE;
19573ae76c23SDarkWyrm    G.outbufptr = tgt;
19583ae76c23SDarkWyrm    G.outsize = tgtsize;
19593ae76c23SDarkWyrm
19603ae76c23SDarkWyrm    switch (method) {
19613ae76c23SDarkWyrm        case STORED:
19623ae76c23SDarkWyrm            memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
19633ae76c23SDarkWyrm            G.outcnt = G.csize;   /* for CRC calculation */
19643ae76c23SDarkWyrm            break;
19653ae76c23SDarkWyrm        case DEFLATED:
19663ae76c23SDarkWyrm#ifdef USE_DEFLATE64
19673ae76c23SDarkWyrm        case ENHDEFLATED:
19683ae76c23SDarkWyrm#endif
19693ae76c23SDarkWyrm            G.outcnt = 0L;
19703ae76c23SDarkWyrm            if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
19713ae76c23SDarkWyrm                if (!uO.tflag)
19723ae76c23SDarkWyrm                    Info(slide, 0x401, ((char *)slide,
19733ae76c23SDarkWyrm                      LoadFarStringSmall(ErrUnzipNoFile), r == 3?
19743ae76c23SDarkWyrm                      LoadFarString(NotEnoughMem) :
19753ae76c23SDarkWyrm                      LoadFarString(InvalidComprData),
19763ae76c23SDarkWyrm                      LoadFarStringSmall2(Inflate)));
19773ae76c23SDarkWyrm                error = (r == 3)? PK_MEM3 : PK_ERR;
19783ae76c23SDarkWyrm            }
19793ae76c23SDarkWyrm            if (G.outcnt == 0L)   /* inflate's final FLUSH sets outcnt */
19803ae76c23SDarkWyrm                break;
19813ae76c23SDarkWyrm            break;
19823ae76c23SDarkWyrm        default:
19833ae76c23SDarkWyrm            if (uO.tflag)
19843ae76c23SDarkWyrm                error = PK_ERR | ((int)method << 8);
19853ae76c23SDarkWyrm            else {
19863ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
19873ae76c23SDarkWyrm                  LoadFarString(UnsupportedExtraField), method));
19883ae76c23SDarkWyrm                error = PK_ERR;  /* GRR:  should be passed on up via SetEAs() */
19893ae76c23SDarkWyrm            }
19903ae76c23SDarkWyrm            break;
19913ae76c23SDarkWyrm    }
19923ae76c23SDarkWyrm
19933ae76c23SDarkWyrm    G.inptr = old_inptr;
19943ae76c23SDarkWyrm    G.incnt = old_incnt;
19953ae76c23SDarkWyrm    G.csize = old_csize;
19963ae76c23SDarkWyrm    G.mem_mode = FALSE;
19973ae76c23SDarkWyrm
19983ae76c23SDarkWyrm    if (!error) {
19993ae76c23SDarkWyrm        register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
20003ae76c23SDarkWyrm
20013ae76c23SDarkWyrm        if (crcval != extra_field_crc) {
20023ae76c23SDarkWyrm            if (uO.tflag)
20033ae76c23SDarkWyrm                error = PK_ERR | (DEFLATED << 8);  /* kludge for now */
20043ae76c23SDarkWyrm            else {
20053ae76c23SDarkWyrm                Info(slide, 0x401, ((char *)slide,
20063ae76c23SDarkWyrm                  LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
20073ae76c23SDarkWyrm                  extra_field_crc));
20083ae76c23SDarkWyrm                error = PK_ERR;
20093ae76c23SDarkWyrm            }
20103ae76c23SDarkWyrm        }
20113ae76c23SDarkWyrm    }
20123ae76c23SDarkWyrm    return error;
20133ae76c23SDarkWyrm
20143ae76c23SDarkWyrm} /* end function memextract() */
20153ae76c23SDarkWyrm
20163ae76c23SDarkWyrm
20173ae76c23SDarkWyrm
20183ae76c23SDarkWyrm
20193ae76c23SDarkWyrm
20203ae76c23SDarkWyrm/*************************/
20213ae76c23SDarkWyrm/*  Function memflush()  */
20223ae76c23SDarkWyrm/*************************/
20233ae76c23SDarkWyrm
20243ae76c23SDarkWyrmint memflush(__G__ rawbuf, size)
20253ae76c23SDarkWyrm    __GDEF
20263ae76c23SDarkWyrm    ZCONST uch *rawbuf;
20273ae76c23SDarkWyrm    ulg size;
20283ae76c23SDarkWyrm{
20293ae76c23SDarkWyrm    if (size > G.outsize)
20303ae76c23SDarkWyrm        /* Here, PK_DISK is a bit off-topic, but in the sense of marking
20313ae76c23SDarkWyrm           "overflow of output space", its use may be tolerated. */
20323ae76c23SDarkWyrm        return PK_DISK;   /* more data than output buffer can hold */
20333ae76c23SDarkWyrm
20343ae76c23SDarkWyrm
20353ae76c23SDarkWyrm
20363ae76c23SDarkWyrm    memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
20373ae76c23SDarkWyrm    G.outbufptr += (unsigned int)size;
20383ae76c23SDarkWyrm    G.outsize -= size;
20393ae76c23SDarkWyrm    G.outcnt += size;
20403ae76c23SDarkWyrm
20413ae76c23SDarkWyrm    return 0;
20423ae76c23SDarkWyrm
20433ae76c23SDarkWyrm} /* end function memflush() */
20443ae76c23SDarkWyrm
20453ae76c23SDarkWyrm
20463ae76c23SDarkWyrm
20473ae76c23SDarkWyrm
20483ae76c23SDarkWyrm
20493ae76c23SDarkWyrm#if (defined(VMS) || defined(VMS_TEXT_CONV))
20503ae76c23SDarkWyrm
20513ae76c23SDarkWyrm/************************************/
20523ae76c23SDarkWyrm/*  Function extract_izvms_block()  */
20533ae76c23SDarkWyrm/************************************/
20543ae76c23SDarkWyrm
20553ae76c23SDarkWyrm/*
20563ae76c23SDarkWyrm * Extracts block from p. If resulting length is less then needed, fill
20573ae76c23SDarkWyrm * extra space with corresponding bytes from 'init'.
20583ae76c23SDarkWyrm * Currently understands 3 formats of block compression:
20593ae76c23SDarkWyrm * - Simple storing
20603ae76c23SDarkWyrm * - Compression of zero bytes to zero bits
20613ae76c23SDarkWyrm * - Deflation (see memextract())
20623ae76c23SDarkWyrm * The IZVMS block data is returned in malloc'd space.
20633ae76c23SDarkWyrm */
20643ae76c23SDarkWyrmuch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
20653ae76c23SDarkWyrm    __GDEF
20663ae76c23SDarkWyrm    ZCONST uch *ebdata;
20673ae76c23SDarkWyrm    unsigned size;
20683ae76c23SDarkWyrm    unsigned *retlen;
20693ae76c23SDarkWyrm    ZCONST uch *init;
20703ae76c23SDarkWyrm    unsigned needlen;
20713ae76c23SDarkWyrm{
20723ae76c23SDarkWyrm    uch *ucdata;       /* Pointer to block allocated */
20733ae76c23SDarkWyrm    int cmptype;
20743ae76c23SDarkWyrm    unsigned usiz, csiz;
20753ae76c23SDarkWyrm
20763ae76c23SDarkWyrm    cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
20773ae76c23SDarkWyrm    csiz = size - EB_IZVMS_HLEN;
20783ae76c23SDarkWyrm    usiz = (cmptype == EB_IZVMS_BCSTOR ?
20793ae76c23SDarkWyrm            csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
20803ae76c23SDarkWyrm
20813ae76c23SDarkWyrm    if (retlen)
20823ae76c23SDarkWyrm        *retlen = usiz;
20833ae76c23SDarkWyrm
20843ae76c23SDarkWyrm    if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
20853ae76c23SDarkWyrm        return NULL;
20863ae76c23SDarkWyrm
20873ae76c23SDarkWyrm    if (init && (usiz < needlen))
20883ae76c23SDarkWyrm        memcpy((char *)ucdata, (ZCONST char *)init, needlen);
20893ae76c23SDarkWyrm
20903ae76c23SDarkWyrm    switch (cmptype)
20913ae76c23SDarkWyrm    {
20923ae76c23SDarkWyrm        case EB_IZVMS_BCSTOR: /* The simplest case */
20933ae76c23SDarkWyrm            memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
20943ae76c23SDarkWyrm            break;
20953ae76c23SDarkWyrm        case EB_IZVMS_BC00:
20963ae76c23SDarkWyrm            decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
20973ae76c23SDarkWyrm            break;
20983ae76c23SDarkWyrm        case EB_IZVMS_BCDEFL:
20993ae76c23SDarkWyrm            memextract(__G__ ucdata, (ulg)usiz,
21003ae76c23SDarkWyrm                       ebdata+EB_IZVMS_HLEN, (ulg)csiz);
21013ae76c23SDarkWyrm            break;
21023ae76c23SDarkWyrm        default:
21033ae76c23SDarkWyrm            free(ucdata);
21043ae76c23SDarkWyrm            ucdata = NULL;
21053ae76c23SDarkWyrm    }
21063ae76c23SDarkWyrm    return ucdata;
21073ae76c23SDarkWyrm
21083ae76c23SDarkWyrm} /* end of extract_izvms_block */
21093ae76c23SDarkWyrm
21103ae76c23SDarkWyrm
21113ae76c23SDarkWyrm
21123ae76c23SDarkWyrm
21133ae76c23SDarkWyrm
21143ae76c23SDarkWyrm/********************************/
21153ae76c23SDarkWyrm/*  Function decompress_bits()  */
21163ae76c23SDarkWyrm/********************************/
21173ae76c23SDarkWyrm/*
21183ae76c23SDarkWyrm *  Simple uncompression routine. The compression uses bit stream.
21193ae76c23SDarkWyrm *  Compression scheme:
21203ae76c23SDarkWyrm *
21213ae76c23SDarkWyrm *  if (byte!=0)
21223ae76c23SDarkWyrm *      putbit(1),putbyte(byte)
21233ae76c23SDarkWyrm *  else
21243ae76c23SDarkWyrm *      putbit(0)
21253ae76c23SDarkWyrm */
21263ae76c23SDarkWyrmstatic void decompress_bits(outptr, needlen, bitptr)
21273ae76c23SDarkWyrm    uch *outptr;        /* Pointer into output block */
21283ae76c23SDarkWyrm    unsigned needlen;   /* Size of uncompressed block */
21293ae76c23SDarkWyrm    ZCONST uch *bitptr; /* Pointer into compressed data */
21303ae76c23SDarkWyrm{
21313ae76c23SDarkWyrm    ulg bitbuf = 0;
21323ae76c23SDarkWyrm    int bitcnt = 0;
21333ae76c23SDarkWyrm
21343ae76c23SDarkWyrm#define _FILL   {       bitbuf |= (*bitptr++) << bitcnt;\
21353ae76c23SDarkWyrm                        bitcnt += 8;                    \
21363ae76c23SDarkWyrm                }
21373ae76c23SDarkWyrm
21383ae76c23SDarkWyrm    while (needlen--)
21393ae76c23SDarkWyrm    {
21403ae76c23SDarkWyrm        if (bitcnt <= 0)
21413ae76c23SDarkWyrm            _FILL;
21423ae76c23SDarkWyrm
21433ae76c23SDarkWyrm        if (bitbuf & 1)
21443ae76c23SDarkWyrm        {
21453ae76c23SDarkWyrm            bitbuf >>= 1;
21463ae76c23SDarkWyrm            if ((bitcnt -= 1) < 8)
21473ae76c23SDarkWyrm                _FILL;
21483ae76c23SDarkWyrm            *outptr++ = (uch)bitbuf;
21493ae76c23SDarkWyrm            bitcnt -= 8;
21503ae76c23SDarkWyrm            bitbuf >>= 8;
21513ae76c23SDarkWyrm        }
21523ae76c23SDarkWyrm        else
21533ae76c23SDarkWyrm        {
21543ae76c23SDarkWyrm            *outptr++ = '\0';
21553ae76c23SDarkWyrm