Subversion Repositories Kolibri OS

Rev

Rev 6725 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6725 Rev 6775
1
/*
1
/*
2
  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
2
  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
3
 
3
 
4
  See the accompanying file LICENSE, version 2009-Jan-02 or later
4
  See the accompanying file LICENSE, version 2009-Jan-02 or later
5
  (the contents of which are also included in unzip.h) for terms of use.
5
  (the contents of which are also included in unzip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
8
*/
9
/*---------------------------------------------------------------------------
9
/*---------------------------------------------------------------------------
10
 
10
 
11
  extract.c
11
  extract.c
12
 
12
 
13
  This file contains the high-level routines ("driver routines") for extrac-
13
  This file contains the high-level routines ("driver routines") for extrac-
14
  ting and testing zipfile members.  It calls the low-level routines in files
14
  ting and testing zipfile members.  It calls the low-level routines in files
15
  explode.c, inflate.c, unreduce.c and unshrink.c.
15
  explode.c, inflate.c, unreduce.c and unshrink.c.
16
 
16
 
17
  Contains:  extract_or_test_files()
17
  Contains:  extract_or_test_files()
18
             store_info()
18
             store_info()
19
             find_compr_idx()
19
             find_compr_idx()
20
             extract_or_test_entrylist()
20
             extract_or_test_entrylist()
21
             extract_or_test_member()
21
             extract_or_test_member()
22
             TestExtraField()
22
             TestExtraField()
23
             test_compr_eb()
23
             test_compr_eb()
24
             memextract()
24
             memextract()
25
             memflush()
25
             memflush()
26
             extract_izvms_block()    (VMS or VMS_TEXT_CONV)
26
             extract_izvms_block()    (VMS or VMS_TEXT_CONV)
27
             set_deferred_symlink()   (SYMLINKS only)
27
             set_deferred_symlink()   (SYMLINKS only)
28
             fnfilter()
28
             fnfilter()
29
             dircomp()                (SET_DIR_ATTRIB only)
29
             dircomp()                (SET_DIR_ATTRIB only)
30
             UZbunzip2()              (USE_BZIP2 only)
30
             UZbunzip2()              (USE_BZIP2 only)
31
 
31
 
32
  ---------------------------------------------------------------------------*/
32
  ---------------------------------------------------------------------------*/
33
 
33
 
34
 
34
 
35
#define __EXTRACT_C     /* identifies this source module */
35
#define __EXTRACT_C     /* identifies this source module */
36
#define UNZIP_INTERNAL
36
#define UNZIP_INTERNAL
37
#include "unzip.h"
37
#include "unzip.h"
38
#ifdef WINDLL
38
#ifdef WINDLL
39
#  ifdef POCKET_UNZIP
39
#  ifdef POCKET_UNZIP
40
#    include "wince/intrface.h"
40
#    include "wince/intrface.h"
41
#  else
41
#  else
42
#    include "windll/windll.h"
42
#    include "windll/windll.h"
43
#  endif
43
#  endif
44
#endif
44
#endif
45
#include "crc32.h"
45
#include "crc32.h"
46
#include "crypt.h"
46
#include "crypt.h"
47
 
47
 
48
#define GRRDUMP(buf,len) { \
48
#define GRRDUMP(buf,len) { \
49
    int i, j; \
49
    int i, j; \
50
 \
50
 \
51
    for (j = 0;  j < (len)/16;  ++j) { \
51
    for (j = 0;  j < (len)/16;  ++j) { \
52
        printf("        "); \
52
        printf("        "); \
53
        for (i = 0;  i < 16;  ++i) \
53
        for (i = 0;  i < 16;  ++i) \
54
            printf("%02x ", (uch)(buf)[i+(j<<4)]); \
54
            printf("%02x ", (uch)(buf)[i+(j<<4)]); \
55
        printf("\n        "); \
55
        printf("\n        "); \
56
        for (i = 0;  i < 16;  ++i) { \
56
        for (i = 0;  i < 16;  ++i) { \
57
            char c = (char)(buf)[i+(j<<4)]; \
57
            char c = (char)(buf)[i+(j<<4)]; \
58
 \
58
 \
59
            if (c == '\n') \
59
            if (c == '\n') \
60
                printf("\\n "); \
60
                printf("\\n "); \
61
            else if (c == '\r') \
61
            else if (c == '\r') \
62
                printf("\\r "); \
62
                printf("\\r "); \
63
            else \
63
            else \
64
                printf(" %c ", c); \
64
                printf(" %c ", c); \
65
        } \
65
        } \
66
        printf("\n"); \
66
        printf("\n"); \
67
    } \
67
    } \
68
    if ((len) % 16) { \
68
    if ((len) % 16) { \
69
        printf("        "); \
69
        printf("        "); \
70
        for (i = j<<4;  i < (len);  ++i) \
70
        for (i = j<<4;  i < (len);  ++i) \
71
            printf("%02x ", (uch)(buf)[i]); \
71
            printf("%02x ", (uch)(buf)[i]); \
72
        printf("\n        "); \
72
        printf("\n        "); \
73
        for (i = j<<4;  i < (len);  ++i) { \
73
        for (i = j<<4;  i < (len);  ++i) { \
74
            char c = (char)(buf)[i]; \
74
            char c = (char)(buf)[i]; \
75
 \
75
 \
76
            if (c == '\n') \
76
            if (c == '\n') \
77
                printf("\\n "); \
77
                printf("\\n "); \
78
            else if (c == '\r') \
78
            else if (c == '\r') \
79
                printf("\\r "); \
79
                printf("\\r "); \
80
            else \
80
            else \
81
                printf(" %c ", c); \
81
                printf(" %c ", c); \
82
        } \
82
        } \
83
        printf("\n"); \
83
        printf("\n"); \
84
    } \
84
    } \
85
}
85
}
86
 
86
 
87
static int store_info OF((__GPRO));
87
static int store_info OF((__GPRO));
88
#ifdef SET_DIR_ATTRIB
88
#ifdef SET_DIR_ATTRIB
89
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
89
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
90
                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
90
                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
91
                unsigned *pnum_dirs, direntry **pdirlist,
91
                unsigned *pnum_dirs, direntry **pdirlist,
92
                int error_in_archive));
92
                int error_in_archive));
93
#else
93
#else
94
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
94
static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
95
                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
95
                ulg *pfilnum, ulg *pnum_bad_pwd, zoff_t *pold_extra_bytes,
96
                int error_in_archive));
96
                int error_in_archive));
97
#endif
97
#endif
98
static int extract_or_test_member OF((__GPRO));
98
static int extract_or_test_member OF((__GPRO));
99
#ifndef SFX
99
#ifndef SFX
100
   static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
100
   static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
101
   static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
101
   static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
102
        unsigned compr_offset,
102
        unsigned compr_offset,
103
        int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
103
        int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
104
                              uch *eb_ucptr, ulg eb_ucsize)));
104
                              uch *eb_ucptr, ulg eb_ucsize)));
105
#endif
105
#endif
106
#if (defined(VMS) || defined(VMS_TEXT_CONV))
106
#if (defined(VMS) || defined(VMS_TEXT_CONV))
107
   static void decompress_bits OF((uch *outptr, unsigned needlen,
107
   static void decompress_bits OF((uch *outptr, unsigned needlen,
108
                                   ZCONST uch *bitptr));
108
                                   ZCONST uch *bitptr));
109
#endif
109
#endif
110
#ifdef SYMLINKS
110
#ifdef SYMLINKS
111
   static void set_deferred_symlink OF((__GPRO__ slinkentry *slnk_entry));
111
   static void set_deferred_symlink OF((__GPRO__ slinkentry *slnk_entry));
112
#endif
112
#endif
113
#ifdef SET_DIR_ATTRIB
113
#ifdef SET_DIR_ATTRIB
114
   static int Cdecl dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
114
   static int Cdecl dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
115
#endif
115
#endif
116
 
116
 
117
 
117
 
118
 
118
 
119
/*******************************/
119
/*******************************/
120
/*  Strings used in extract.c  */
120
/*  Strings used in extract.c  */
121
/*******************************/
121
/*******************************/
122
 
122
 
123
static ZCONST char Far VersionMsg[] =
123
static ZCONST char Far VersionMsg[] =
124
  "   skipping: %-22s  need %s compat. v%u.%u (can do v%u.%u)\n";
124
  "   skipping: %-22s  need %s compat. v%u.%u (can do v%u.%u)\n";
125
static ZCONST char Far ComprMsgNum[] =
125
static ZCONST char Far ComprMsgNum[] =
126
  "   skipping: %-22s  unsupported compression method %u\n";
126
  "   skipping: %-22s  unsupported compression method %u\n";
127
#ifndef SFX
127
#ifndef SFX
128
   static ZCONST char Far ComprMsgName[] =
128
   static ZCONST char Far ComprMsgName[] =
129
     "   skipping: %-22s  `%s' method not supported\n";
129
     "   skipping: %-22s  `%s' method not supported\n";
130
   static ZCONST char Far CmprNone[]       = "store";
130
   static ZCONST char Far CmprNone[]       = "store";
131
   static ZCONST char Far CmprShrink[]     = "shrink";
131
   static ZCONST char Far CmprShrink[]     = "shrink";
132
   static ZCONST char Far CmprReduce[]     = "reduce";
132
   static ZCONST char Far CmprReduce[]     = "reduce";
133
   static ZCONST char Far CmprImplode[]    = "implode";
133
   static ZCONST char Far CmprImplode[]    = "implode";
134
   static ZCONST char Far CmprTokenize[]   = "tokenize";
134
   static ZCONST char Far CmprTokenize[]   = "tokenize";
135
   static ZCONST char Far CmprDeflate[]    = "deflate";
135
   static ZCONST char Far CmprDeflate[]    = "deflate";
136
   static ZCONST char Far CmprDeflat64[]   = "deflate64";
136
   static ZCONST char Far CmprDeflat64[]   = "deflate64";
137
   static ZCONST char Far CmprDCLImplode[] = "DCL implode";
137
   static ZCONST char Far CmprDCLImplode[] = "DCL implode";
138
   static ZCONST char Far CmprBzip[]       = "bzip2";
138
   static ZCONST char Far CmprBzip[]       = "bzip2";
139
   static ZCONST char Far CmprLZMA[]       = "LZMA";
139
   static ZCONST char Far CmprLZMA[]       = "LZMA";
140
   static ZCONST char Far CmprIBMTerse[]   = "IBM/Terse";
140
   static ZCONST char Far CmprIBMTerse[]   = "IBM/Terse";
141
   static ZCONST char Far CmprIBMLZ77[]    = "IBM LZ77";
141
   static ZCONST char Far CmprIBMLZ77[]    = "IBM LZ77";
142
   static ZCONST char Far CmprWavPack[]    = "WavPack";
142
   static ZCONST char Far CmprWavPack[]    = "WavPack";
143
   static ZCONST char Far CmprPPMd[]       = "PPMd";
143
   static ZCONST char Far CmprPPMd[]       = "PPMd";
144
   static ZCONST char Far *ComprNames[NUM_METHODS] = {
144
   static ZCONST char Far *ComprNames[NUM_METHODS] = {
145
     CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
145
     CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
146
     CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode,
146
     CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode,
147
     CmprBzip, CmprLZMA, CmprIBMTerse, CmprIBMLZ77, CmprWavPack, CmprPPMd
147
     CmprBzip, CmprLZMA, CmprIBMTerse, CmprIBMLZ77, CmprWavPack, CmprPPMd
148
   };
148
   };
149
   static ZCONST unsigned ComprIDs[NUM_METHODS] = {
149
   static ZCONST unsigned ComprIDs[NUM_METHODS] = {
150
     STORED, SHRUNK, REDUCED1, REDUCED2, REDUCED3, REDUCED4,
150
     STORED, SHRUNK, REDUCED1, REDUCED2, REDUCED3, REDUCED4,
151
     IMPLODED, TOKENIZED, DEFLATED, ENHDEFLATED, DCLIMPLODED,
151
     IMPLODED, TOKENIZED, DEFLATED, ENHDEFLATED, DCLIMPLODED,
152
     BZIPPED, LZMAED, IBMTERSED, IBMLZ77ED, WAVPACKED, PPMDED
152
     BZIPPED, LZMAED, IBMTERSED, IBMLZ77ED, WAVPACKED, PPMDED
153
   };
153
   };
154
#endif /* !SFX */
154
#endif /* !SFX */
155
static ZCONST char Far FilNamMsg[] =
155
static ZCONST char Far FilNamMsg[] =
156
  "%s:  bad filename length (%s)\n";
156
  "%s:  bad filename length (%s)\n";
157
#ifndef SFX
157
#ifndef SFX
158
   static ZCONST char Far WarnNoMemCFName[] =
158
   static ZCONST char Far WarnNoMemCFName[] =
159
     "%s:  warning, no memory for comparison with local header\n";
159
     "%s:  warning, no memory for comparison with local header\n";
160
   static ZCONST char Far LvsCFNamMsg[] =
160
   static ZCONST char Far LvsCFNamMsg[] =
161
     "%s:  mismatching \"local\" filename (%s),\n\
161
     "%s:  mismatching \"local\" filename (%s),\n\
162
         continuing with \"central\" filename version\n";
162
         continuing with \"central\" filename version\n";
163
#endif /* !SFX */
163
#endif /* !SFX */
164
#if (!defined(SFX) && defined(UNICODE_SUPPORT))
164
#if (!defined(SFX) && defined(UNICODE_SUPPORT))
165
   static ZCONST char Far GP11FlagsDiffer[] =
165
   static ZCONST char Far GP11FlagsDiffer[] =
166
     "file #%lu (%s):\n\
166
     "file #%lu (%s):\n\
167
         mismatch between local and central GPF bit 11 (\"UTF-8\"),\n\
167
         mismatch between local and central GPF bit 11 (\"UTF-8\"),\n\
168
         continuing with central flag (IsUTF8 = %d)\n";
168
         continuing with central flag (IsUTF8 = %d)\n";
169
#endif /* !SFX && UNICODE_SUPPORT */
169
#endif /* !SFX && UNICODE_SUPPORT */
170
static ZCONST char Far WrnStorUCSizCSizDiff[] =
170
static ZCONST char Far WrnStorUCSizCSizDiff[] =
171
  "%s:  ucsize %s <> csize %s for STORED entry\n\
171
  "%s:  ucsize %s <> csize %s for STORED entry\n\
172
         continuing with \"compressed\" size value\n";
172
         continuing with \"compressed\" size value\n";
173
static ZCONST char Far ExtFieldMsg[] =
173
static ZCONST char Far ExtFieldMsg[] =
174
  "%s:  bad extra field length (%s)\n";
174
  "%s:  bad extra field length (%s)\n";
175
static ZCONST char Far OffsetMsg[] =
175
static ZCONST char Far OffsetMsg[] =
176
  "file #%lu:  bad zipfile offset (%s):  %ld\n";
176
  "file #%lu:  bad zipfile offset (%s):  %ld\n";
177
static ZCONST char Far ExtractMsg[] =
177
static ZCONST char Far ExtractMsg[] =
178
  "%8sing: %-22s  %s%s";
178
  "%8sing: %-22s  %s%s";
179
#ifndef SFX
179
#ifndef SFX
180
   static ZCONST char Far LengthMsg[] =
180
   static ZCONST char Far LengthMsg[] =
181
     "%s  %s:  %s bytes required to uncompress to %s bytes;\n    %s\
181
     "%s  %s:  %s bytes required to uncompress to %s bytes;\n    %s\
182
      supposed to require %s bytes%s%s%s\n";
182
      supposed to require %s bytes%s%s%s\n";
183
#endif
183
#endif
184
 
184
 
185
static ZCONST char Far BadFileCommLength[] = "%s:  bad file comment length\n";
185
static ZCONST char Far BadFileCommLength[] = "%s:  bad file comment length\n";
186
static ZCONST char Far LocalHdrSig[] = "local header sig";
186
static ZCONST char Far LocalHdrSig[] = "local header sig";
187
static ZCONST char Far BadLocalHdr[] = "file #%lu:  bad local header\n";
187
static ZCONST char Far BadLocalHdr[] = "file #%lu:  bad local header\n";
188
static ZCONST char Far AttemptRecompensate[] =
188
static ZCONST char Far AttemptRecompensate[] =
189
  "  (attempting to re-compensate)\n";
189
  "  (attempting to re-compensate)\n";
190
#ifndef SFX
190
#ifndef SFX
191
   static ZCONST char Far BackslashPathSep[] =
191
   static ZCONST char Far BackslashPathSep[] =
192
     "warning:  %s appears to use backslashes as path separators\n";
192
     "warning:  %s appears to use backslashes as path separators\n";
193
#endif
193
#endif
194
static ZCONST char Far AbsolutePathWarning[] =
194
static ZCONST char Far AbsolutePathWarning[] =
195
  "warning:  stripped absolute path spec from %s\n";
195
  "warning:  stripped absolute path spec from %s\n";
196
static ZCONST char Far SkipVolumeLabel[] =
196
static ZCONST char Far SkipVolumeLabel[] =
197
  "   skipping: %-22s  %svolume label\n";
197
  "   skipping: %-22s  %svolume label\n";
198
 
198
 
199
#ifdef SET_DIR_ATTRIB   /* messages of code for setting directory attributes */
199
#ifdef SET_DIR_ATTRIB   /* messages of code for setting directory attributes */
200
   static ZCONST char Far DirlistEntryNoMem[] =
200
   static ZCONST char Far DirlistEntryNoMem[] =
201
     "warning:  cannot alloc memory for dir times/permissions/UID/GID\n";
201
     "warning:  cannot alloc memory for dir times/permissions/UID/GID\n";
202
   static ZCONST char Far DirlistSortNoMem[] =
202
   static ZCONST char Far DirlistSortNoMem[] =
203
     "warning:  cannot alloc memory to sort dir times/perms/etc.\n";
203
     "warning:  cannot alloc memory to sort dir times/perms/etc.\n";
204
   static ZCONST char Far DirlistSetAttrFailed[] =
204
   static ZCONST char Far DirlistSetAttrFailed[] =
205
     "warning:  set times/attribs failed for %s\n";
205
     "warning:  set times/attribs failed for %s\n";
206
   static ZCONST char Far DirlistFailAttrSum[] =
206
   static ZCONST char Far DirlistFailAttrSum[] =
207
     "     failed setting times/attribs for %lu dir entries";
207
     "     failed setting times/attribs for %lu dir entries";
208
#endif
208
#endif
209
 
209
 
210
#ifdef SYMLINKS         /* messages of the deferred symlinks handler */
210
#ifdef SYMLINKS         /* messages of the deferred symlinks handler */
211
   static ZCONST char Far SymLnkWarnNoMem[] =
211
   static ZCONST char Far SymLnkWarnNoMem[] =
212
     "warning:  deferred symlink (%s) failed:\n\
212
     "warning:  deferred symlink (%s) failed:\n\
213
          out of memory\n";
213
          out of memory\n";
214
   static ZCONST char Far SymLnkWarnInvalid[] =
214
   static ZCONST char Far SymLnkWarnInvalid[] =
215
     "warning:  deferred symlink (%s) failed:\n\
215
     "warning:  deferred symlink (%s) failed:\n\
216
          invalid placeholder file\n";
216
          invalid placeholder file\n";
217
   static ZCONST char Far SymLnkDeferred[] =
217
   static ZCONST char Far SymLnkDeferred[] =
218
     "finishing deferred symbolic links:\n";
218
     "finishing deferred symbolic links:\n";
219
   static ZCONST char Far SymLnkFinish[] =
219
   static ZCONST char Far SymLnkFinish[] =
220
     "  %-22s -> %s\n";
220
     "  %-22s -> %s\n";
221
#endif
221
#endif
222
 
222
 
223
#ifndef WINDLL
223
#ifndef WINDLL
224
   static ZCONST char Far ReplaceQuery[] =
224
   static ZCONST char Far ReplaceQuery[] =
225
# ifdef VMS
225
# ifdef VMS
226
     "new version of %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
226
     "new version of %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
227
# else
227
# else
228
     "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
228
     "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
229
# endif
229
# endif
230
   static ZCONST char Far AssumeNone[] =
230
   static ZCONST char Far AssumeNone[] =
231
     " NULL\n(EOF or read error, treating as \"[N]one\" ...)\n";
231
     " NULL\n(EOF or read error, treating as \"[N]one\" ...)\n";
232
   static ZCONST char Far NewNameQuery[] = "new name: ";
232
   static ZCONST char Far NewNameQuery[] = "new name: ";
233
   static ZCONST char Far InvalidResponse[] =
233
   static ZCONST char Far InvalidResponse[] =
234
     "error:  invalid response [%s]\n";
234
     "error:  invalid response [%s]\n";
235
#endif /* !WINDLL */
235
#endif /* !WINDLL */
236
 
236
 
237
static ZCONST char Far ErrorInArchive[] =
237
static ZCONST char Far ErrorInArchive[] =
238
  "At least one %serror was detected in %s.\n";
238
  "At least one %serror was detected in %s.\n";
239
static ZCONST char Far ZeroFilesTested[] =
239
static ZCONST char Far ZeroFilesTested[] =
240
  "Caution:  zero files tested in %s.\n";
240
  "Caution:  zero files tested in %s.\n";
241
 
241
 
242
#ifndef VMS
242
#ifndef VMS
243
   static ZCONST char Far VMSFormatQuery[] =
243
   static ZCONST char Far VMSFormatQuery[] =
244
     "\n%s:  stored in VMS format.  Extract anyway? (y/n) ";
244
     "\n%s:  stored in VMS format.  Extract anyway? (y/n) ";
245
#endif
245
#endif
246
 
246
 
247
#if CRYPT
247
#if CRYPT
248
   static ZCONST char Far SkipCannotGetPasswd[] =
248
   static ZCONST char Far SkipCannotGetPasswd[] =
249
     "   skipping: %-22s  unable to get password\n";
249
     "   skipping: %-22s  unable to get password\n";
250
   static ZCONST char Far SkipIncorrectPasswd[] =
250
   static ZCONST char Far SkipIncorrectPasswd[] =
251
     "   skipping: %-22s  incorrect password\n";
251
     "   skipping: %-22s  incorrect password\n";
252
   static ZCONST char Far FilesSkipBadPasswd[] =
252
   static ZCONST char Far FilesSkipBadPasswd[] =
253
     "%lu file%s skipped because of incorrect password.\n";
253
     "%lu file%s skipped because of incorrect password.\n";
254
   static ZCONST char Far MaybeBadPasswd[] =
254
   static ZCONST char Far MaybeBadPasswd[] =
255
     "    (may instead be incorrect password)\n";
255
     "    (may instead be incorrect password)\n";
256
#else
256
#else
257
   static ZCONST char Far SkipEncrypted[] =
257
   static ZCONST char Far SkipEncrypted[] =
258
     "   skipping: %-22s  encrypted (not supported)\n";
258
     "   skipping: %-22s  encrypted (not supported)\n";
259
#endif
259
#endif
260
 
260
 
261
static ZCONST char Far NoErrInCompData[] =
261
static ZCONST char Far NoErrInCompData[] =
262
  "No errors detected in compressed data of %s.\n";
262
  "No errors detected in compressed data of %s.\n";
263
static ZCONST char Far NoErrInTestedFiles[] =
263
static ZCONST char Far NoErrInTestedFiles[] =
264
  "No errors detected in %s for the %lu file%s tested.\n";
264
  "No errors detected in %s for the %lu file%s tested.\n";
265
static ZCONST char Far FilesSkipped[] =
265
static ZCONST char Far FilesSkipped[] =
266
  "%lu file%s skipped because of unsupported compression or encoding.\n";
266
  "%lu file%s skipped because of unsupported compression or encoding.\n";
267
 
267
 
268
static ZCONST char Far ErrUnzipFile[] = "  error:  %s%s %s\n";
268
static ZCONST char Far ErrUnzipFile[] = "  error:  %s%s %s\n";
269
static ZCONST char Far ErrUnzipNoFile[] = "\n  error:  %s%s\n";
269
static ZCONST char Far ErrUnzipNoFile[] = "\n  error:  %s%s\n";
270
static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
270
static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
271
static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
271
static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
272
static ZCONST char Far Inflate[] = "inflate";
272
static ZCONST char Far Inflate[] = "inflate";
273
#ifdef USE_BZIP2
273
#ifdef USE_BZIP2
274
  static ZCONST char Far BUnzip[] = "bunzip";
274
  static ZCONST char Far BUnzip[] = "bunzip";
275
#endif
275
#endif
276
 
276
 
277
#ifndef SFX
277
#ifndef SFX
278
   static ZCONST char Far Explode[] = "explode";
278
   static ZCONST char Far Explode[] = "explode";
279
#ifndef LZW_CLEAN
279
#ifndef LZW_CLEAN
280
   static ZCONST char Far Unshrink[] = "unshrink";
280
   static ZCONST char Far Unshrink[] = "unshrink";
281
#endif
281
#endif
282
#endif
282
#endif
283
 
283
 
284
#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
284
#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
285
   static ZCONST char Far FileTruncated[] =
285
   static ZCONST char Far FileTruncated[] =
286
     "warning:  %s is probably truncated\n";
286
     "warning:  %s is probably truncated\n";
287
#endif
287
#endif
288
 
288
 
289
static ZCONST char Far FileUnknownCompMethod[] =
289
static ZCONST char Far FileUnknownCompMethod[] =
290
  "%s:  unknown compression method\n";
290
  "%s:  unknown compression method\n";
291
static ZCONST char Far BadCRC[] = " bad CRC %08lx  (should be %08lx)\n";
291
static ZCONST char Far BadCRC[] = " bad CRC %08lx  (should be %08lx)\n";
292
 
292
 
293
      /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
293
      /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
294
char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
294
char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
295
char ZCONST Far TruncNTSD[] =
295
char ZCONST Far TruncNTSD[] =
296
  " compressed WinNT security data missing (%d bytes)%s";
296
  " compressed WinNT security data missing (%d bytes)%s";
297
 
297
 
298
#ifndef SFX
298
#ifndef SFX
299
   static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
299
   static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
300
     EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
300
     EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
301
   static ZCONST char Far InvalidComprDataEAs[] =
301
   static ZCONST char Far InvalidComprDataEAs[] =
302
     " invalid compressed data for EAs\n";
302
     " invalid compressed data for EAs\n";
303
#  if (defined(WIN32) && defined(NTSD_EAS))
303
#  if (defined(WIN32) && defined(NTSD_EAS))
304
     static ZCONST char Far InvalidSecurityEAs[] =
304
     static ZCONST char Far InvalidSecurityEAs[] =
305
       " EAs fail security check\n";
305
       " EAs fail security check\n";
306
#  endif
306
#  endif
307
   static ZCONST char Far UnsuppNTSDVersEAs[] =
307
   static ZCONST char Far UnsuppNTSDVersEAs[] =
308
     " unsupported NTSD EAs version %d\n";
308
     " unsupported NTSD EAs version %d\n";
309
   static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
309
   static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
310
   static ZCONST char Far UnknComprMethodEAs[] =
310
   static ZCONST char Far UnknComprMethodEAs[] =
311
     " unknown compression method for EAs (%u)\n";
311
     " unknown compression method for EAs (%u)\n";
312
   static ZCONST char Far NotEnoughMemEAs[] =
312
   static ZCONST char Far NotEnoughMemEAs[] =
313
     " out of memory while inflating EAs\n";
313
     " out of memory while inflating EAs\n";
314
   static ZCONST char Far UnknErrorEAs[] =
314
   static ZCONST char Far UnknErrorEAs[] =
315
     " unknown error on extended attributes\n";
315
     " unknown error on extended attributes\n";
316
#endif /* !SFX */
316
#endif /* !SFX */
317
 
317
 
318
static ZCONST char Far UnsupportedExtraField[] =
318
static ZCONST char Far UnsupportedExtraField[] =
319
  "\nerror:  unsupported extra-field compression type (%u)--skipping\n";
319
  "\nerror:  unsupported extra-field compression type (%u)--skipping\n";
320
static ZCONST char Far BadExtraFieldCRC[] =
320
static ZCONST char Far BadExtraFieldCRC[] =
321
  "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";
321
  "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";
322
 
322
 
323
 
323
 
324
 
324
 
325
 
325
 
326
 
326
 
327
/**************************************/
327
/**************************************/
328
/*  Function extract_or_test_files()  */
328
/*  Function extract_or_test_files()  */
329
/**************************************/
329
/**************************************/
330
 
330
 
331
int extract_or_test_files(__G)    /* return PK-type error code */
331
int extract_or_test_files(__G)    /* return PK-type error code */
332
     __GDEF
332
     __GDEF
333
{
333
{
334
    unsigned i, j;
334
    unsigned i, j;
335
    zoff_t cd_bufstart;
335
    zoff_t cd_bufstart;
336
    uch *cd_inptr;
336
    uch *cd_inptr;
337
    int cd_incnt;
337
    int cd_incnt;
338
    ulg filnum=0L, blknum=0L;
338
    ulg filnum=0L, blknum=0L;
339
    int reached_end;
339
    int reached_end;
340
#ifndef SFX
340
#ifndef SFX
341
    int no_endsig_found;
341
    int no_endsig_found;
342
#endif
342
#endif
343
    int error, error_in_archive=PK_COOL;
343
    int error, error_in_archive=PK_COOL;
344
    int *fn_matched=NULL, *xn_matched=NULL;
344
    int *fn_matched=NULL, *xn_matched=NULL;
345
    zucn_t members_processed;
345
    zucn_t members_processed;
346
    ulg num_skipped=0L, num_bad_pwd=0L;
346
    ulg num_skipped=0L, num_bad_pwd=0L;
347
    zoff_t old_extra_bytes = 0L;
347
    zoff_t old_extra_bytes = 0L;
348
#ifdef SET_DIR_ATTRIB
348
#ifdef SET_DIR_ATTRIB
349
    unsigned num_dirs=0;
349
    unsigned num_dirs=0;
350
    direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
350
    direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
351
#endif
351
#endif
352
 
352
 
353
    /*
353
    /*
354
     * First, two general initializations are applied. These have been moved
354
     * First, two general initializations are applied. These have been moved
355
     * here from process_zipfiles() because they are only needed for accessing
355
     * here from process_zipfiles() because they are only needed for accessing
356
     * and/or extracting the data content of the zip archive.
356
     * and/or extracting the data content of the zip archive.
357
     */
357
     */
358
 
358
 
359
    /* a) initialize the CRC table pointer (once) */
359
    /* a) initialize the CRC table pointer (once) */
360
    if (CRC_32_TAB == NULL) {
360
    if (CRC_32_TAB == NULL) {
361
        if ((CRC_32_TAB = get_crc_table()) == NULL) {
361
        if ((CRC_32_TAB = get_crc_table()) == NULL) {
362
            return PK_MEM;
362
            return PK_MEM;
363
        }
363
        }
364
    }
364
    }
365
 
365
 
366
#if (!defined(SFX) || defined(SFX_EXDIR))
366
#if (!defined(SFX) || defined(SFX_EXDIR))
367
    /* b) check out if specified extraction root directory exists */
367
    /* b) check out if specified extraction root directory exists */
368
    if (uO.exdir != (char *)NULL && G.extract_flag) {
368
    if (uO.exdir != (char *)NULL && G.extract_flag) {
369
        G.create_dirs = !uO.fflag;
369
        G.create_dirs = !uO.fflag;
370
        if ((error = checkdir(__G__ uO.exdir, ROOT)) > MPN_INF_SKIP) {
370
        if ((error = checkdir(__G__ uO.exdir, ROOT)) > MPN_INF_SKIP) {
371
            /* out of memory, or file in way */
371
            /* out of memory, or file in way */
372
            return (error == MPN_NOMEM ? PK_MEM : PK_ERR);
372
            return (error == MPN_NOMEM ? PK_MEM : PK_ERR);
373
        }
373
        }
374
    }
374
    }
375
#endif /* !SFX || SFX_EXDIR */
375
#endif /* !SFX || SFX_EXDIR */
376
 
376
 
377
/*---------------------------------------------------------------------------
377
/*---------------------------------------------------------------------------
378
    The basic idea of this function is as follows.  Since the central di-
378
    The basic idea of this function is as follows.  Since the central di-
379
    rectory lies at the end of the zipfile and the member files lie at the
379
    rectory lies at the end of the zipfile and the member files lie at the
380
    beginning or middle or wherever, it is not very desirable to simply
380
    beginning or middle or wherever, it is not very desirable to simply
381
    read a central directory entry, jump to the member and extract it, and
381
    read a central directory entry, jump to the member and extract it, and
382
    then jump back to the central directory.  In the case of a large zipfile
382
    then jump back to the central directory.  In the case of a large zipfile
383
    this would lead to a whole lot of disk-grinding, especially if each mem-
383
    this would lead to a whole lot of disk-grinding, especially if each mem-
384
    ber file is small.  Instead, we read from the central directory the per-
384
    ber file is small.  Instead, we read from the central directory the per-
385
    tinent information for a block of files, then go extract/test the whole
385
    tinent information for a block of files, then go extract/test the whole
386
    block.  Thus this routine contains two small(er) loops within a very
386
    block.  Thus this routine contains two small(er) loops within a very
387
    large outer loop:  the first of the small ones reads a block of files
387
    large outer loop:  the first of the small ones reads a block of files
388
    from the central directory; the second extracts or tests each file; and
388
    from the central directory; the second extracts or tests each file; and
389
    the outer one loops over blocks.  There's some file-pointer positioning
389
    the outer one loops over blocks.  There's some file-pointer positioning
390
    stuff in between, but that's about it.  Btw, it's because of this jump-
390
    stuff in between, but that's about it.  Btw, it's because of this jump-
391
    ing around that we can afford to be lenient if an error occurs in one of
391
    ing around that we can afford to be lenient if an error occurs in one of
392
    the member files:  we should still be able to go find the other members,
392
    the member files:  we should still be able to go find the other members,
393
    since we know the offset of each from the beginning of the zipfile.
393
    since we know the offset of each from the beginning of the zipfile.
394
  ---------------------------------------------------------------------------*/
394
  ---------------------------------------------------------------------------*/
395
 
395
 
396
    G.pInfo = G.info;
396
    G.pInfo = G.info;
397
 
397
 
398
#if CRYPT
398
#if CRYPT
399
    G.newzip = TRUE;
399
    G.newzip = TRUE;
400
#endif
400
#endif
401
#ifndef SFX
401
#ifndef SFX
402
    G.reported_backslash = FALSE;
402
    G.reported_backslash = FALSE;
403
#endif
403
#endif
404
 
404
 
405
    /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
405
    /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
406
    if (G.filespecs > 0  &&
406
    if (G.filespecs > 0  &&
407
        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
407
        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
408
        for (i = 0;  i < G.filespecs;  ++i)
408
        for (i = 0;  i < G.filespecs;  ++i)
409
            fn_matched[i] = FALSE;
409
            fn_matched[i] = FALSE;
410
    if (G.xfilespecs > 0  &&
410
    if (G.xfilespecs > 0  &&
411
        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
411
        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
412
        for (i = 0;  i < G.xfilespecs;  ++i)
412
        for (i = 0;  i < G.xfilespecs;  ++i)
413
            xn_matched[i] = FALSE;
413
            xn_matched[i] = FALSE;
414
 
414
 
415
/*---------------------------------------------------------------------------
415
/*---------------------------------------------------------------------------
416
    Begin main loop over blocks of member files.  We know the entire central
416
    Begin main loop over blocks of member files.  We know the entire central
417
    directory is on this disk:  we would not have any of this information un-
417
    directory is on this disk:  we would not have any of this information un-
418
    less the end-of-central-directory record was on this disk, and we would
418
    less the end-of-central-directory record was on this disk, and we would
419
    not have gotten to this routine unless this is also the disk on which
419
    not have gotten to this routine unless this is also the disk on which
420
    the central directory starts.  In practice, this had better be the ONLY
420
    the central directory starts.  In practice, this had better be the ONLY
421
    disk in the archive, but we'll add multi-disk support soon.
421
    disk in the archive, but we'll add multi-disk support soon.
422
  ---------------------------------------------------------------------------*/
422
  ---------------------------------------------------------------------------*/
423
 
423
 
424
    members_processed = 0;
424
    members_processed = 0;
425
#ifndef SFX
425
#ifndef SFX
426
    no_endsig_found = FALSE;
426
    no_endsig_found = FALSE;
427
#endif
427
#endif
428
    reached_end = FALSE;
428
    reached_end = FALSE;
429
    while (!reached_end) {
429
    while (!reached_end) {
430
        j = 0;
430
        j = 0;
431
#ifdef AMIGA
431
#ifdef AMIGA
432
        memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
432
        memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
433
#endif
433
#endif
434
 
434
 
435
        /*
435
        /*
436
         * Loop through files in central directory, storing offsets, file
436
         * Loop through files in central directory, storing offsets, file
437
         * attributes, case-conversion and text-conversion flags until block
437
         * attributes, case-conversion and text-conversion flags until block
438
         * size is reached.
438
         * size is reached.
439
         */
439
         */
440
 
440
 
441
        while ((j < DIR_BLKSIZ)) {
441
        while ((j < DIR_BLKSIZ)) {
442
            G.pInfo = &G.info[j];
442
            G.pInfo = &G.info[j];
443
 
443
 
444
            if (readbuf(__G__ G.sig, 4) == 0) {
444
            if (readbuf(__G__ G.sig, 4) == 0) {
445
                error_in_archive = PK_EOF;
445
                error_in_archive = PK_EOF;
446
                reached_end = TRUE;     /* ...so no more left to do */
446
                reached_end = TRUE;     /* ...so no more left to do */
447
                break;
447
                break;
448
            }
448
            }
449
            if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a new entry? */
449
            if (memcmp(G.sig, central_hdr_sig, 4)) {  /* is it a new entry? */
450
                /* no new central directory entry
450
                /* no new central directory entry
451
                 * -> is the number of processed entries compatible with the
451
                 * -> is the number of processed entries compatible with the
452
                 *    number of entries as stored in the end_central record?
452
                 *    number of entries as stored in the end_central record?
453
                 */
453
                 */
454
                if ((members_processed
454
                if ((members_processed
455
                     & (G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
455
                     & (G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
456
                    == G.ecrec.total_entries_central_dir) {
456
                    == G.ecrec.total_entries_central_dir) {
457
#ifndef SFX
457
#ifndef SFX
458
                    /* yes, so look if we ARE back at the end_central record
458
                    /* yes, so look if we ARE back at the end_central record
459
                     */
459
                     */
460
                    no_endsig_found =
460
                    no_endsig_found =
461
                      ( (memcmp(G.sig,
461
                      ( (memcmp(G.sig,
462
                                (G.ecrec.have_ecr64 ?
462
                                (G.ecrec.have_ecr64 ?
463
                                 end_central64_sig : end_central_sig),
463
                                 end_central64_sig : end_central_sig),
464
                                4) != 0)
464
                                4) != 0)
465
                       && (!G.ecrec.is_zip64_archive)
465
                       && (!G.ecrec.is_zip64_archive)
466
                       && (memcmp(G.sig, end_central_sig, 4) != 0)
466
                       && (memcmp(G.sig, end_central_sig, 4) != 0)
467
                      );
467
                      );
468
#endif /* !SFX */
468
#endif /* !SFX */
469
                } else {
469
                } else {
470
                    /* no; we have found an error in the central directory
470
                    /* no; we have found an error in the central directory
471
                     * -> report it and stop searching for more Zip entries
471
                     * -> report it and stop searching for more Zip entries
472
                     */
472
                     */
473
                    Info(slide, 0x401, ((char *)slide,
473
                    Info(slide, 0x401, ((char *)slide,
474
                      LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
474
                      LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
475
                    Info(slide, 0x401, ((char *)slide,
475
                    Info(slide, 0x401, ((char *)slide,
476
                      LoadFarString(ReportMsg)));
476
                      LoadFarString(ReportMsg)));
477
                    error_in_archive = PK_BADERR;
477
                    error_in_archive = PK_BADERR;
478
                }
478
                }
479
                reached_end = TRUE;     /* ...so no more left to do */
479
                reached_end = TRUE;     /* ...so no more left to do */
480
                break;
480
                break;
481
            }
481
            }
482
            /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
482
            /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
483
            if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
483
            if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
484
                error_in_archive = error;   /* only PK_EOF defined */
484
                error_in_archive = error;   /* only PK_EOF defined */
485
                reached_end = TRUE;     /* ...so no more left to do */
485
                reached_end = TRUE;     /* ...so no more left to do */
486
                break;
486
                break;
487
            }
487
            }
488
            if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
488
            if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
489
                 PK_COOL)
489
                 PK_COOL)
490
            {
490
            {
491
                if (error > error_in_archive)
491
                if (error > error_in_archive)
492
                    error_in_archive = error;
492
                    error_in_archive = error;
493
                if (error > PK_WARN) {  /* fatal:  no more left to do */
493
                if (error > PK_WARN) {  /* fatal:  no more left to do */
494
                    Info(slide, 0x401, ((char *)slide,
494
                    Info(slide, 0x401, ((char *)slide,
495
                      LoadFarString(FilNamMsg),
495
                      LoadFarString(FilNamMsg),
496
                      FnFilter1(G.filename), "central"));
496
                      FnFilter1(G.filename), "central"));
497
                    reached_end = TRUE;
497
                    reached_end = TRUE;
498
                    break;
498
                    break;
499
                }
499
                }
500
            }
500
            }
501
            if ((error = do_string(__G__ G.crec.extra_field_length,
501
            if ((error = do_string(__G__ G.crec.extra_field_length,
502
                EXTRA_FIELD)) != 0)
502
                EXTRA_FIELD)) != 0)
503
            {
503
            {
504
                if (error > error_in_archive)
504
                if (error > error_in_archive)
505
                    error_in_archive = error;
505
                    error_in_archive = error;
506
                if (error > PK_WARN) {  /* fatal */
506
                if (error > PK_WARN) {  /* fatal */
507
                    Info(slide, 0x401, ((char *)slide,
507
                    Info(slide, 0x401, ((char *)slide,
508
                      LoadFarString(ExtFieldMsg),
508
                      LoadFarString(ExtFieldMsg),
509
                      FnFilter1(G.filename), "central"));
509
                      FnFilter1(G.filename), "central"));
510
                    reached_end = TRUE;
510
                    reached_end = TRUE;
511
                    break;
511
                    break;
512
                }
512
                }
513
            }
513
            }
514
#ifdef AMIGA
514
#ifdef AMIGA
515
            G.filenote_slot = j;
515
            G.filenote_slot = j;
516
            if ((error = do_string(__G__ G.crec.file_comment_length,
516
            if ((error = do_string(__G__ G.crec.file_comment_length,
517
                                   uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
517
                                   uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
518
#else
518
#else
519
            if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
519
            if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
520
                != PK_COOL)
520
                != PK_COOL)
521
#endif
521
#endif
522
            {
522
            {
523
                if (error > error_in_archive)
523
                if (error > error_in_archive)
524
                    error_in_archive = error;
524
                    error_in_archive = error;
525
                if (error > PK_WARN) {  /* fatal */
525
                if (error > PK_WARN) {  /* fatal */
526
                    Info(slide, 0x421, ((char *)slide,
526
                    Info(slide, 0x421, ((char *)slide,
527
                      LoadFarString(BadFileCommLength),
527
                      LoadFarString(BadFileCommLength),
528
                      FnFilter1(G.filename)));
528
                      FnFilter1(G.filename)));
529
                    reached_end = TRUE;
529
                    reached_end = TRUE;
530
                    break;
530
                    break;
531
                }
531
                }
532
            }
532
            }
533
            if (G.process_all_files) {
533
            if (G.process_all_files) {
534
                if (store_info(__G))
534
                if (store_info(__G))
535
                    ++j;  /* file is OK; info[] stored; continue with next */
535
                    ++j;  /* file is OK; info[] stored; continue with next */
536
                else
536
                else
537
                    ++num_skipped;
537
                    ++num_skipped;
538
            } else {
538
            } else {
539
                int   do_this_file;
539
                int   do_this_file;
540
 
540
 
541
                if (G.filespecs == 0)
541
                if (G.filespecs == 0)
542
                    do_this_file = TRUE;
542
                    do_this_file = TRUE;
543
                else {  /* check if this entry matches an `include' argument */
543
                else {  /* check if this entry matches an `include' argument */
544
                    do_this_file = FALSE;
544
                    do_this_file = FALSE;
545
                    for (i = 0; i < G.filespecs; i++)
545
                    for (i = 0; i < G.filespecs; i++)
546
                        if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
546
                        if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
547
                            do_this_file = TRUE;  /* ^-- ignore case or not? */
547
                            do_this_file = TRUE;  /* ^-- ignore case or not? */
548
                            if (fn_matched)
548
                            if (fn_matched)
549
                                fn_matched[i] = TRUE;
549
                                fn_matched[i] = TRUE;
550
                            break;       /* found match, so stop looping */
550
                            break;       /* found match, so stop looping */
551
                        }
551
                        }
552
                }
552
                }
553
                if (do_this_file) {  /* check if this is an excluded file */
553
                if (do_this_file) {  /* check if this is an excluded file */
554
                    for (i = 0; i < G.xfilespecs; i++)
554
                    for (i = 0; i < G.xfilespecs; i++)
555
                        if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
555
                        if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
556
                            do_this_file = FALSE; /* ^-- ignore case or not? */
556
                            do_this_file = FALSE; /* ^-- ignore case or not? */
557
                            if (xn_matched)
557
                            if (xn_matched)
558
                                xn_matched[i] = TRUE;
558
                                xn_matched[i] = TRUE;
559
                            break;
559
                            break;
560
                        }
560
                        }
561
                }
561
                }
562
                if (do_this_file) {
562
                if (do_this_file) {
563
                    if (store_info(__G))
563
                    if (store_info(__G))
564
                        ++j;            /* file is OK */
564
                        ++j;            /* file is OK */
565
                    else
565
                    else
566
                        ++num_skipped;  /* unsupp. compression or encryption */
566
                        ++num_skipped;  /* unsupp. compression or encryption */
567
                }
567
                }
568
            } /* end if (process_all_files) */
568
            } /* end if (process_all_files) */
569
 
569
 
570
            members_processed++;
570
            members_processed++;
571
 
571
 
572
        } /* end while-loop (adding files to current block) */
572
        } /* end while-loop (adding files to current block) */
573
 
573
 
574
        /* save position in central directory so can come back later */
574
        /* save position in central directory so can come back later */
575
        cd_bufstart = G.cur_zipfile_bufstart;
575
        cd_bufstart = G.cur_zipfile_bufstart;
576
        cd_inptr = G.inptr;
576
        cd_inptr = G.inptr;
577
        cd_incnt = G.incnt;
577
        cd_incnt = G.incnt;
578
 
578
 
579
    /*-----------------------------------------------------------------------
579
    /*-----------------------------------------------------------------------
580
        Second loop:  process files in current block, extracting or testing
580
        Second loop:  process files in current block, extracting or testing
581
        each one.
581
        each one.
582
      -----------------------------------------------------------------------*/
582
      -----------------------------------------------------------------------*/
583
 
583
 
584
        error = extract_or_test_entrylist(__G__ j,
584
        error = extract_or_test_entrylist(__G__ j,
585
                        &filnum, &num_bad_pwd, &old_extra_bytes,
585
                        &filnum, &num_bad_pwd, &old_extra_bytes,
586
#ifdef SET_DIR_ATTRIB
586
#ifdef SET_DIR_ATTRIB
587
                        &num_dirs, &dirlist,
587
                        &num_dirs, &dirlist,
588
#endif
588
#endif
589
                        error_in_archive);
589
                        error_in_archive);
590
        if (error != PK_COOL) {
590
        if (error != PK_COOL) {
591
            if (error > error_in_archive)
591
            if (error > error_in_archive)
592
                error_in_archive = error;
592
                error_in_archive = error;
593
            /* ...and keep going (unless disk full or user break) */
593
            /* ...and keep going (unless disk full or user break) */
594
            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
594
            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
595
                /* clear reached_end to signal premature stop ... */
595
                /* clear reached_end to signal premature stop ... */
596
                reached_end = FALSE;
596
                reached_end = FALSE;
597
                /* ... and cancel scanning the central directory */
597
                /* ... and cancel scanning the central directory */
598
                break;
598
                break;
599
            }
599
            }
600
        }
600
        }
601
 
601
 
602
 
602
 
603
        /*
603
        /*
604
         * Jump back to where we were in the central directory, then go and do
604
         * Jump back to where we were in the central directory, then go and do
605
         * the next batch of files.
605
         * the next batch of files.
606
         */
606
         */
607
 
607
 
608
#ifdef USE_STRM_INPUT
608
#ifdef USE_STRM_INPUT
609
        zfseeko(G.zipfd, cd_bufstart, SEEK_SET);
609
        zfseeko(G.zipfd, cd_bufstart, SEEK_SET);
610
        G.cur_zipfile_bufstart = zftello(G.zipfd);
610
        G.cur_zipfile_bufstart = zftello(G.zipfd);
611
#else /* !USE_STRM_INPUT */
611
#else /* !USE_STRM_INPUT */
612
        G.cur_zipfile_bufstart =
612
        G.cur_zipfile_bufstart =
613
          zlseek(G.zipfd, cd_bufstart, SEEK_SET);
613
          zlseek(G.zipfd, cd_bufstart, SEEK_SET);
614
#endif /* ?USE_STRM_INPUT */
614
#endif /* ?USE_STRM_INPUT */
615
        read(G.zipfd, (char *)G.inbuf, INBUFSIZ);  /* been here before... */
615
        read(G.zipfd, (char *)G.inbuf, INBUFSIZ);  /* been here before... */
616
        G.inptr = cd_inptr;
616
        G.inptr = cd_inptr;
617
        G.incnt = cd_incnt;
617
        G.incnt = cd_incnt;
618
        ++blknum;
618
        ++blknum;
619
 
619
 
620
#ifdef TEST
620
#ifdef TEST
621
        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
621
        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
622
        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
622
        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
623
          cur_zipfile_bufstart);
623
          cur_zipfile_bufstart);
624
        printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
624
        printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
625
        printf("incnt = %d\n\n", G.incnt);
625
        printf("incnt = %d\n\n", G.incnt);
626
#endif
626
#endif
627
 
627
 
628
    } /* end while-loop (blocks of files in central directory) */
628
    } /* end while-loop (blocks of files in central directory) */
629
 
629
 
630
/*---------------------------------------------------------------------------
630
/*---------------------------------------------------------------------------
631
    Process the list of deferred symlink extractions and finish up
631
    Process the list of deferred symlink extractions and finish up
632
    the symbolic links.
632
    the symbolic links.
633
  ---------------------------------------------------------------------------*/
633
  ---------------------------------------------------------------------------*/
634
 
634
 
635
#ifdef SYMLINKS
635
#ifdef SYMLINKS
636
    if (G.slink_last != NULL) {
636
    if (G.slink_last != NULL) {
637
        if (QCOND2)
637
        if (QCOND2)
638
            Info(slide, 0, ((char *)slide, LoadFarString(SymLnkDeferred)));
638
            Info(slide, 0, ((char *)slide, LoadFarString(SymLnkDeferred)));
639
        while (G.slink_head != NULL) {
639
        while (G.slink_head != NULL) {
640
           set_deferred_symlink(__G__ G.slink_head);
640
           set_deferred_symlink(__G__ G.slink_head);
641
           /* remove the processed entry from the chain and free its memory */
641
           /* remove the processed entry from the chain and free its memory */
642
           G.slink_last = G.slink_head;
642
           G.slink_last = G.slink_head;
643
           G.slink_head = G.slink_last->next;
643
           G.slink_head = G.slink_last->next;
644
           free(G.slink_last);
644
           free(G.slink_last);
645
       }
645
       }
646
       G.slink_last = NULL;
646
       G.slink_last = NULL;
647
    }
647
    }
648
#endif /* SYMLINKS */
648
#endif /* SYMLINKS */
649
 
649
 
650
/*---------------------------------------------------------------------------
650
/*---------------------------------------------------------------------------
651
    Go back through saved list of directories, sort and set times/perms/UIDs
651
    Go back through saved list of directories, sort and set times/perms/UIDs
652
    and GIDs from the deepest level on up.
652
    and GIDs from the deepest level on up.
653
  ---------------------------------------------------------------------------*/
653
  ---------------------------------------------------------------------------*/
654
 
654
 
655
#ifdef SET_DIR_ATTRIB
655
#ifdef SET_DIR_ATTRIB
-
 
656
//Trace((stderr, "SET_DIR_ATTRIB[%d] \n", num_dirs));  hmm, too big number
-
 
657
 
656
    if (num_dirs > 0) {
658
    if (num_dirs > 0) {
657
        sorted_dirlist = (direntry **)malloc(num_dirs*sizeof(direntry *));
659
        sorted_dirlist = (direntry **)malloc(num_dirs*sizeof(direntry *));
658
        if (sorted_dirlist == (direntry **)NULL) {
660
        if (sorted_dirlist == (direntry **)NULL) {
659
            Info(slide, 0x401, ((char *)slide,
661
            Info(slide, 0x401, ((char *)slide,
660
              LoadFarString(DirlistSortNoMem)));
662
              LoadFarString(DirlistSortNoMem)));
661
            while (dirlist != (direntry *)NULL) {
663
            while (dirlist != (direntry *)NULL) {
662
                direntry *d = dirlist;
664
                direntry *d = dirlist;
663
 
665
 
664
                dirlist = dirlist->next;
666
                dirlist = dirlist->next;
665
                free(d);
667
                free(d);
666
            }
668
            }
667
        } else {
669
        } else {
668
            ulg ndirs_fail = 0;
670
            ulg ndirs_fail = 0;
669
 
671
 
670
            if (num_dirs == 1)
672
            if (num_dirs == 1)
671
                sorted_dirlist[0] = dirlist;
673
                sorted_dirlist[0] = dirlist;
672
            else {
674
            else {
673
                for (i = 0;  i < num_dirs;  ++i) {
675
                for (i = 0;  i < num_dirs;  ++i) {
674
                    sorted_dirlist[i] = dirlist;
676
                    sorted_dirlist[i] = dirlist;
675
                    dirlist = dirlist->next;
677
                    dirlist = dirlist->next;
676
                }
678
                }
677
                qsort((char *)sorted_dirlist, num_dirs, sizeof(direntry *),
679
                qsort((char *)sorted_dirlist, num_dirs, sizeof(direntry *),
678
                  dircomp);
680
                  dircomp);
679
            }
681
            }
680
 
682
 
681
            Trace((stderr, "setting directory times/perms/attributes\n"));
683
            Trace((stderr, "setting directory times/perms/attributes\n"));
682
            for (i = 0;  i < num_dirs;  ++i) {
684
            for (i = 0;  i < num_dirs;  ++i) {
683
                direntry *d = sorted_dirlist[i];
685
                direntry *d = sorted_dirlist[i];
684
 
686
 
685
                Trace((stderr, "dir = %s\n", d->fn));
687
                Trace((stderr, "dir = %s\n", d->fn));
686
                if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
688
                if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
687
                    ndirs_fail++;
689
                    ndirs_fail++;
688
                    Info(slide, 0x201, ((char *)slide,
690
                    Info(slide, 0x201, ((char *)slide,
689
                      LoadFarString(DirlistSetAttrFailed), d->fn));
691
                      LoadFarString(DirlistSetAttrFailed), d->fn));
690
                    if (!error_in_archive)
692
                    if (!error_in_archive)
691
                        error_in_archive = error;
693
                        error_in_archive = error;
692
                }
694
                }
693
                free(d);
695
                free(d);
694
            }
696
            }
695
            free(sorted_dirlist);
697
            free(sorted_dirlist);
696
            if (!uO.tflag && QCOND2) {
698
            if (!uO.tflag && QCOND2) {
697
                if (ndirs_fail > 0)
699
                if (ndirs_fail > 0)
698
                    Info(slide, 0, ((char *)slide,
700
                    Info(slide, 0, ((char *)slide,
699
                      LoadFarString(DirlistFailAttrSum), ndirs_fail));
701
                      LoadFarString(DirlistFailAttrSum), ndirs_fail));
700
            }
702
            }
701
        }
703
        }
702
    }
704
    }
703
#endif /* SET_DIR_ATTRIB */
705
#endif /* SET_DIR_ATTRIB */
704
 
706
 
705
/*---------------------------------------------------------------------------
707
/*---------------------------------------------------------------------------
706
    Check for unmatched filespecs on command line and print warning if any
708
    Check for unmatched filespecs on command line and print warning if any
707
    found.  Free allocated memory.  (But suppress check when central dir
709
    found.  Free allocated memory.  (But suppress check when central dir
708
    scan was interrupted prematurely.)
710
    scan was interrupted prematurely.)
709
  ---------------------------------------------------------------------------*/
711
  ---------------------------------------------------------------------------*/
710
 
712
 
711
    if (fn_matched) {
713
    if (fn_matched) {
712
        if (reached_end) for (i = 0;  i < G.filespecs;  ++i)
714
        if (reached_end) for (i = 0;  i < G.filespecs;  ++i)
713
            if (!fn_matched[i]) {
715
            if (!fn_matched[i]) {
714
#ifdef DLL
716
#ifdef DLL
715
                if (!G.redirect_data && !G.redirect_text)
717
                if (!G.redirect_data && !G.redirect_text)
716
                    Info(slide, 0x401, ((char *)slide,
718
                    Info(slide, 0x401, ((char *)slide,
717
                      LoadFarString(FilenameNotMatched), G.pfnames[i]));
719
                      LoadFarString(FilenameNotMatched), G.pfnames[i]));
718
                else
720
                else
719
                    setFileNotFound(__G);
721
                    setFileNotFound(__G);
720
#else
722
#else
721
                Info(slide, 1, ((char *)slide,
723
                Info(slide, 1, ((char *)slide,
722
                  LoadFarString(FilenameNotMatched), G.pfnames[i]));
724
                  LoadFarString(FilenameNotMatched), G.pfnames[i]));
723
#endif
725
#endif
724
                if (error_in_archive <= PK_WARN)
726
                if (error_in_archive <= PK_WARN)
725
                    error_in_archive = PK_FIND;   /* some files not found */
727
                    error_in_archive = PK_FIND;   /* some files not found */
726
            }
728
            }
727
        free((zvoid *)fn_matched);
729
        free((zvoid *)fn_matched);
728
    }
730
    }
729
    if (xn_matched) {
731
    if (xn_matched) {
730
        if (reached_end) for (i = 0;  i < G.xfilespecs;  ++i)
732
        if (reached_end) for (i = 0;  i < G.xfilespecs;  ++i)
731
            if (!xn_matched[i])
733
            if (!xn_matched[i])
732
                Info(slide, 0x401, ((char *)slide,
734
                Info(slide, 0x401, ((char *)slide,
733
                  LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
735
                  LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
734
        free((zvoid *)xn_matched);
736
        free((zvoid *)xn_matched);
735
    }
737
    }
736
 
738
 
737
/*---------------------------------------------------------------------------
739
/*---------------------------------------------------------------------------
738
    Now, all locally allocated memory has been released.  When the central
740
    Now, all locally allocated memory has been released.  When the central
739
    directory processing has been interrupted prematurely, it is safe to
741
    directory processing has been interrupted prematurely, it is safe to
740
    return immediately.  All completeness checks and summary messages are
742
    return immediately.  All completeness checks and summary messages are
741
    skipped in this case.
743
    skipped in this case.
742
  ---------------------------------------------------------------------------*/
744
  ---------------------------------------------------------------------------*/
743
    if (!reached_end)
745
    if (!reached_end)
744
        return error_in_archive;
746
        return error_in_archive;
745
 
747
 
746
/*---------------------------------------------------------------------------
748
/*---------------------------------------------------------------------------
747
    Double-check that we're back at the end-of-central-directory record, and
749
    Double-check that we're back at the end-of-central-directory record, and
748
    print quick summary of results, if we were just testing the archive.  We
750
    print quick summary of results, if we were just testing the archive.  We
749
    send the summary to stdout so that people doing the testing in the back-
751
    send the summary to stdout so that people doing the testing in the back-
750
    ground and redirecting to a file can just do a "tail" on the output file.
752
    ground and redirecting to a file can just do a "tail" on the output file.
751
  ---------------------------------------------------------------------------*/
753
  ---------------------------------------------------------------------------*/
752
 
754
 
753
#ifndef SFX
755
#ifndef SFX
754
    if (no_endsig_found) {                      /* just to make sure */
756
    if (no_endsig_found) {                      /* just to make sure */
755
        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
757
        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
756
        Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
758
        Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
757
        if (!error_in_archive)       /* don't overwrite stronger error */
759
        if (!error_in_archive)       /* don't overwrite stronger error */
758
            error_in_archive = PK_WARN;
760
            error_in_archive = PK_WARN;
759
    }
761
    }
760
#endif /* !SFX */
762
#endif /* !SFX */
761
    if (uO.tflag) {
763
    if (uO.tflag) {
762
        ulg num = filnum - num_bad_pwd;
764
        ulg num = filnum - num_bad_pwd;
763
 
765
 
764
        if (uO.qflag < 2) {        /* GRR 930710:  was (uO.qflag == 1) */
766
        if (uO.qflag < 2) {        /* GRR 930710:  was (uO.qflag == 1) */
765
            if (error_in_archive)
767
            if (error_in_archive)
766
                Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
768
                Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
767
                  (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
769
                  (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
768
            else if (num == 0L)
770
            else if (num == 0L)
769
                Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
771
                Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
770
                  G.zipfn));
772
                  G.zipfn));
771
            else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
773
            else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
772
                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
774
                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
773
                  G.zipfn));
775
                  G.zipfn));
774
            else
776
            else
775
                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
777
                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
776
                  , G.zipfn, num, (num==1L)? "":"s"));
778
                  , G.zipfn, num, (num==1L)? "":"s"));
777
            if (num_skipped > 0L)
779
            if (num_skipped > 0L)
778
                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
780
                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
779
                  num_skipped, (num_skipped==1L)? "":"s"));
781
                  num_skipped, (num_skipped==1L)? "":"s"));
780
#if CRYPT
782
#if CRYPT
781
            if (num_bad_pwd > 0L)
783
            if (num_bad_pwd > 0L)
782
                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
784
                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
783
                  , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
785
                  , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
784
#endif /* CRYPT */
786
#endif /* CRYPT */
785
        }
787
        }
786
    }
788
    }
787
 
789
 
788
    /* give warning if files not tested or extracted (first condition can still
790
    /* give warning if files not tested or extracted (first condition can still
789
     * happen if zipfile is empty and no files specified on command line) */
791
     * happen if zipfile is empty and no files specified on command line) */
790
 
792
 
791
    if ((filnum == 0) && error_in_archive <= PK_WARN) {
793
    if ((filnum == 0) && error_in_archive <= PK_WARN) {
792
        if (num_skipped > 0L)
794
        if (num_skipped > 0L)
793
            error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
795
            error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
794
        else
796
        else
795
            error_in_archive = PK_FIND;  /* no files found at all */
797
            error_in_archive = PK_FIND;  /* no files found at all */
796
    }
798
    }
797
#if CRYPT
799
#if CRYPT
798
    else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
800
    else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
799
        error_in_archive = IZ_BADPWD;    /* bad passwd => all files skipped */
801
        error_in_archive = IZ_BADPWD;    /* bad passwd => all files skipped */
800
#endif
802
#endif
801
    else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
803
    else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
802
        error_in_archive = IZ_UNSUP;     /* was PK_WARN; Jean-loup complained */
804
        error_in_archive = IZ_UNSUP;     /* was PK_WARN; Jean-loup complained */
803
#if CRYPT
805
#if CRYPT
804
    else if ((num_bad_pwd > 0L) && !error_in_archive)
806
    else if ((num_bad_pwd > 0L) && !error_in_archive)
805
        error_in_archive = PK_WARN;
807
        error_in_archive = PK_WARN;
806
#endif
808
#endif
807
 
809
 
808
    return error_in_archive;
810
    return error_in_archive;
809
 
811
 
810
} /* end function extract_or_test_files() */
812
} /* end function extract_or_test_files() */
811
 
813
 
812
 
814
 
813
 
815
 
814
 
816
 
815
 
817
 
816
/***************************/
818
/***************************/
817
/*  Function store_info()  */
819
/*  Function store_info()  */
818
/***************************/
820
/***************************/
819
 
821
 
820
static int store_info(__G)   /* return 0 if skipping, 1 if OK */
822
static int store_info(__G)   /* return 0 if skipping, 1 if OK */
821
    __GDEF
823
    __GDEF
822
{
824
{
823
#ifdef USE_BZIP2
825
#ifdef USE_BZIP2
824
#  define UNKN_BZ2 (G.crec.compression_method!=BZIPPED)
826
#  define UNKN_BZ2 (G.crec.compression_method!=BZIPPED)
825
#else
827
#else
826
#  define UNKN_BZ2 TRUE       /* bzip2 unknown */
828
#  define UNKN_BZ2 TRUE       /* bzip2 unknown */
827
#endif
829
#endif
828
 
830
 
829
#ifdef USE_LZMA
831
#ifdef USE_LZMA
830
#  define UNKN_LZMA (G.crec.compression_method!=LZMAED)
832
#  define UNKN_LZMA (G.crec.compression_method!=LZMAED)
831
#else
833
#else
832
#  define UNKN_LZMA TRUE      /* LZMA unknown */
834
#  define UNKN_LZMA TRUE      /* LZMA unknown */
833
#endif
835
#endif
834
 
836
 
835
#ifdef USE_WAVP
837
#ifdef USE_WAVP
836
#  define UNKN_WAVP (G.crec.compression_method!=WAVPACKED)
838
#  define UNKN_WAVP (G.crec.compression_method!=WAVPACKED)
837
#else
839
#else
838
#  define UNKN_WAVP TRUE      /* WavPack unknown */
840
#  define UNKN_WAVP TRUE      /* WavPack unknown */
839
#endif
841
#endif
840
 
842
 
841
#ifdef USE_PPMD
843
#ifdef USE_PPMD
842
#  define UNKN_PPMD (G.crec.compression_method!=PPMDED)
844
#  define UNKN_PPMD (G.crec.compression_method!=PPMDED)
843
#else
845
#else
844
#  define UNKN_PPMD TRUE      /* PPMd unknown */
846
#  define UNKN_PPMD TRUE      /* PPMd unknown */
845
#endif
847
#endif
846
 
848
 
847
#ifdef SFX
849
#ifdef SFX
848
#  ifdef USE_DEFLATE64
850
#  ifdef USE_DEFLATE64
849
#    define UNKN_COMPR \
851
#    define UNKN_COMPR \
850
     (G.crec.compression_method!=STORED && G.crec.compression_method
852
     (G.crec.compression_method!=STORED && G.crec.compression_method
851
      && G.crec.compression_method>ENHDEFLATED \
853
      && G.crec.compression_method>ENHDEFLATED \
852
      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
854
      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
853
#  else
855
#  else
854
#    define UNKN_COMPR \
856
#    define UNKN_COMPR \
855
     (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED\
857
     (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED\
856
      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
858
      && UNKN_BZ2 && UNKN_LZMA && UNKN_WAVP && UNKN_PPMD)
857
#  endif
859
#  endif
858
#else
860
#else
859
#  ifdef COPYRIGHT_CLEAN  /* no reduced files */
861
#  ifdef COPYRIGHT_CLEAN  /* no reduced files */
860
#    define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
862
#    define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
861
                      G.crec.compression_method <= REDUCED4)
863
                      G.crec.compression_method <= REDUCED4)
862
#  else
864
#  else
863
#    define UNKN_RED  FALSE  /* reducing not unknown */
865
#    define UNKN_RED  FALSE  /* reducing not unknown */
864
#  endif
866
#  endif
865
#  ifdef LZW_CLEAN  /* no shrunk files */
867
#  ifdef LZW_CLEAN  /* no shrunk files */
866
#    define UNKN_SHR (G.crec.compression_method == SHRUNK)
868
#    define UNKN_SHR (G.crec.compression_method == SHRUNK)
867
#  else
869
#  else
868
#    define UNKN_SHR  FALSE  /* unshrinking not unknown */
870
#    define UNKN_SHR  FALSE  /* unshrinking not unknown */
869
#  endif
871
#  endif
870
#  ifdef USE_DEFLATE64
872
#  ifdef USE_DEFLATE64
871
#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
873
#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
872
     G.crec.compression_method==TOKENIZED || \
874
     G.crec.compression_method==TOKENIZED || \
873
     (G.crec.compression_method>ENHDEFLATED && UNKN_BZ2 && UNKN_LZMA \
875
     (G.crec.compression_method>ENHDEFLATED && UNKN_BZ2 && UNKN_LZMA \
874
      && UNKN_WAVP && UNKN_PPMD))
876
      && UNKN_WAVP && UNKN_PPMD))
875
#  else
877
#  else
876
#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
878
#    define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
877
     G.crec.compression_method==TOKENIZED || \
879
     G.crec.compression_method==TOKENIZED || \
878
     (G.crec.compression_method>DEFLATED && UNKN_BZ2 && UNKN_LZMA \
880
     (G.crec.compression_method>DEFLATED && UNKN_BZ2 && UNKN_LZMA \
879
      && UNKN_WAVP && UNKN_PPMD))
881
      && UNKN_WAVP && UNKN_PPMD))
880
#  endif
882
#  endif
881
#endif
883
#endif
882
 
884
 
883
#if (defined(USE_BZIP2) && (UNZIP_VERSION < UNZIP_BZ2VERS))
885
#if (defined(USE_BZIP2) && (UNZIP_VERSION < UNZIP_BZ2VERS))
884
    int unzvers_support = (UNKN_BZ2 ? UNZIP_VERSION : UNZIP_BZ2VERS);
886
    int unzvers_support = (UNKN_BZ2 ? UNZIP_VERSION : UNZIP_BZ2VERS);
885
#   define UNZVERS_SUPPORT  unzvers_support
887
#   define UNZVERS_SUPPORT  unzvers_support
886
#else
888
#else
887
#   define UNZVERS_SUPPORT  UNZIP_VERSION
889
#   define UNZVERS_SUPPORT  UNZIP_VERSION
888
#endif
890
#endif
889
 
891
 
890
/*---------------------------------------------------------------------------
892
/*---------------------------------------------------------------------------
891
    Check central directory info for version/compatibility requirements.
893
    Check central directory info for version/compatibility requirements.
892
  ---------------------------------------------------------------------------*/
894
  ---------------------------------------------------------------------------*/
893
 
895
 
894
    G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1;   /* bit field */
896
    G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1;   /* bit field */
895
    G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8;  /* bit */
897
    G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8;  /* bit */
896
    G.pInfo->textfile = G.crec.internal_file_attributes & 1;    /* bit field */
898
    G.pInfo->textfile = G.crec.internal_file_attributes & 1;    /* bit field */
897
    G.pInfo->crc = G.crec.crc32;
899
    G.pInfo->crc = G.crec.crc32;
898
    G.pInfo->compr_size = G.crec.csize;
900
    G.pInfo->compr_size = G.crec.csize;
899
    G.pInfo->uncompr_size = G.crec.ucsize;
901
    G.pInfo->uncompr_size = G.crec.ucsize;
900
 
902
 
901
    switch (uO.aflag) {
903
    switch (uO.aflag) {
902
        case 0:
904
        case 0:
903
            G.pInfo->textmode = FALSE;   /* bit field */
905
            G.pInfo->textmode = FALSE;   /* bit field */
904
            break;
906
            break;
905
        case 1:
907
        case 1:
906
            G.pInfo->textmode = G.pInfo->textfile;   /* auto-convert mode */
908
            G.pInfo->textmode = G.pInfo->textfile;   /* auto-convert mode */
907
            break;
909
            break;
908
        default:  /* case 2: */
910
        default:  /* case 2: */
909
            G.pInfo->textmode = TRUE;
911
            G.pInfo->textmode = TRUE;
910
            break;
912
            break;
911
    }
913
    }
912
 
914
 
913
    if (G.crec.version_needed_to_extract[1] == VMS_) {
915
    if (G.crec.version_needed_to_extract[1] == VMS_) {
914
        if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
916
        if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
915
            if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
917
            if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
916
                Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
918
                Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
917
                  FnFilter1(G.filename), "VMS",
919
                  FnFilter1(G.filename), "VMS",
918
                  G.crec.version_needed_to_extract[0] / 10,
920
                  G.crec.version_needed_to_extract[0] / 10,
919
                  G.crec.version_needed_to_extract[0] % 10,
921
                  G.crec.version_needed_to_extract[0] % 10,
920
                  VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
922
                  VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
921
            return 0;
923
            return 0;
922
        }
924
        }
923
#ifndef VMS   /* won't be able to use extra field, but still have data */
925
#ifndef VMS   /* won't be able to use extra field, but still have data */
924
        else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
926
        else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
925
            Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
927
            Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
926
              FnFilter1(G.filename)));
928
              FnFilter1(G.filename)));
927
            fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
929
            fgets(G.answerbuf, sizeof(G.answerbuf), stdin);
928
            if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
930
            if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
929
                return 0;
931
                return 0;
930
        }
932
        }
931
#endif /* !VMS */
933
#endif /* !VMS */
932
    /* usual file type:  don't need VMS to extract */
934
    /* usual file type:  don't need VMS to extract */
933
    } else if (G.crec.version_needed_to_extract[0] > UNZVERS_SUPPORT) {
935
    } else if (G.crec.version_needed_to_extract[0] > UNZVERS_SUPPORT) {
934
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
936
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
935
            Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
937
            Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
936
              FnFilter1(G.filename), "PK",
938
              FnFilter1(G.filename), "PK",
937
              G.crec.version_needed_to_extract[0] / 10,
939
              G.crec.version_needed_to_extract[0] / 10,
938
              G.crec.version_needed_to_extract[0] % 10,
940
              G.crec.version_needed_to_extract[0] % 10,
939
              UNZVERS_SUPPORT / 10, UNZVERS_SUPPORT % 10));
941
              UNZVERS_SUPPORT / 10, UNZVERS_SUPPORT % 10));
940
        return 0;
942
        return 0;
941
    }
943
    }
942
 
944
 
943
    if (UNKN_COMPR) {
945
    if (UNKN_COMPR) {
944
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
946
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
945
#ifndef SFX
947
#ifndef SFX
946
            unsigned cmpridx;
948
            unsigned cmpridx;
947
 
949
 
948
            if ((cmpridx = find_compr_idx(G.crec.compression_method))
950
            if ((cmpridx = find_compr_idx(G.crec.compression_method))
949
                < NUM_METHODS)
951
                < NUM_METHODS)
950
                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
952
                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
951
                  FnFilter1(G.filename),
953
                  FnFilter1(G.filename),
952
                  LoadFarStringSmall(ComprNames[cmpridx])));
954
                  LoadFarStringSmall(ComprNames[cmpridx])));
953
            else
955
            else
954
#endif
956
#endif
955
                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
957
                Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
956
                  FnFilter1(G.filename),
958
                  FnFilter1(G.filename),
957
                  G.crec.compression_method));
959
                  G.crec.compression_method));
958
        }
960
        }
959
        return 0;
961
        return 0;
960
    }
962
    }
961
#if (!CRYPT)
963
#if (!CRYPT)
962
    if (G.pInfo->encrypted) {
964
    if (G.pInfo->encrypted) {
963
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
965
        if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
964
            Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
966
            Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
965
              FnFilter1(G.filename)));
967
              FnFilter1(G.filename)));
966
        return 0;
968
        return 0;
967
    }
969
    }
968
#endif /* !CRYPT */
970
#endif /* !CRYPT */
969
 
971
 
970
#ifndef SFX
972
#ifndef SFX
971
    /* store a copy of the central header filename for later comparison */
973
    /* store a copy of the central header filename for later comparison */
972
    if ((G.pInfo->cfilname = zfmalloc(strlen(G.filename) + 1)) == NULL) {
974
    if ((G.pInfo->cfilname = zfmalloc(strlen(G.filename) + 1)) == NULL) {
973
        Info(slide, 0x401, ((char *)slide, LoadFarString(WarnNoMemCFName),
975
        Info(slide, 0x401, ((char *)slide, LoadFarString(WarnNoMemCFName),
974
          FnFilter1(G.filename)));
976
          FnFilter1(G.filename)));
975
    } else
977
    } else
976
        zfstrcpy(G.pInfo->cfilname, G.filename);
978
        zfstrcpy(G.pInfo->cfilname, G.filename);
977
#endif /* !SFX */
979
#endif /* !SFX */
978
 
980
 
979
    /* map whatever file attributes we have into the local format */
981
    /* map whatever file attributes we have into the local format */
980
    mapattr(__G);   /* GRR:  worry about return value later */
982
    mapattr(__G);   /* GRR:  worry about return value later */
981
 
983
 
982
    G.pInfo->diskstart = G.crec.disk_number_start;
984
    G.pInfo->diskstart = G.crec.disk_number_start;
983
    G.pInfo->offset = (zoff_t)G.crec.relative_offset_local_header;
985
    G.pInfo->offset = (zoff_t)G.crec.relative_offset_local_header;
984
    return 1;
986
    return 1;
985
 
987
 
986
} /* end function store_info() */
988
} /* end function store_info() */
987
 
989
 
988
 
990
 
989
 
991
 
990
 
992
 
991
 
993
 
992
#ifndef SFX
994
#ifndef SFX
993
/*******************************/
995
/*******************************/
994
/*  Function find_compr_idx()  */
996
/*  Function find_compr_idx()  */
995
/*******************************/
997
/*******************************/
996
 
998
 
997
unsigned find_compr_idx(compr_methodnum)
999
unsigned find_compr_idx(compr_methodnum)
998
    unsigned compr_methodnum;
1000
    unsigned compr_methodnum;
999
{
1001
{
1000
    unsigned i;
1002
    unsigned i;
1001
 
1003
 
1002
    for (i = 0; i < NUM_METHODS; i++) {
1004
    for (i = 0; i < NUM_METHODS; i++) {
1003
        if (ComprIDs[i] == compr_methodnum) break;
1005
        if (ComprIDs[i] == compr_methodnum) break;
1004
    }
1006
    }
1005
    return i;
1007
    return i;
1006
}
1008
}
1007
#endif /* !SFX */
1009
#endif /* !SFX */
1008
 
1010
 
1009
 
1011
 
1010
 
1012
 
1011
 
1013
 
1012
 
1014
 
1013
/******************************************/
1015
/******************************************/
1014
/*  Function extract_or_test_entrylist()  */
1016
/*  Function extract_or_test_entrylist()  */
1015
/******************************************/
1017
/******************************************/
1016
 
1018
 
1017
static int extract_or_test_entrylist(__G__ numchunk,
1019
static int extract_or_test_entrylist(__G__ numchunk,
1018
                pfilnum, pnum_bad_pwd, pold_extra_bytes,
1020
                pfilnum, pnum_bad_pwd, pold_extra_bytes,
1019
#ifdef SET_DIR_ATTRIB
1021
#ifdef SET_DIR_ATTRIB
1020
                pnum_dirs, pdirlist,
1022
                pnum_dirs, pdirlist,
1021
#endif
1023
#endif
1022
                error_in_archive)    /* return PK-type error code */
1024
                error_in_archive)    /* return PK-type error code */
1023
    __GDEF
1025
    __GDEF
1024
    unsigned numchunk;
1026
    unsigned numchunk;
1025
    ulg *pfilnum;
1027
    ulg *pfilnum;
1026
    ulg *pnum_bad_pwd;
1028
    ulg *pnum_bad_pwd;
1027
    zoff_t *pold_extra_bytes;
1029
    zoff_t *pold_extra_bytes;
1028
#ifdef SET_DIR_ATTRIB
1030
#ifdef SET_DIR_ATTRIB
1029
    unsigned *pnum_dirs;
1031
    unsigned *pnum_dirs;
1030
    direntry **pdirlist;
1032
    direntry **pdirlist;
1031
#endif
1033
#endif
1032
    int error_in_archive;
1034
    int error_in_archive;
1033
{
1035
{
1034
    unsigned i;
1036
    unsigned i;
1035
    int renamed, query;
1037
    int renamed, query;
1036
    int skip_entry;
1038
    int skip_entry;
1037
    zoff_t bufstart, inbuf_offset, request;
1039
    zoff_t bufstart, inbuf_offset, request;
1038
    int error, errcode;
1040
    int error, errcode;
1039
 
1041
 
1040
/* possible values for local skip_entry flag: */
1042
/* possible values for local skip_entry flag: */
1041
#define SKIP_NO         0       /* do not skip this entry */
1043
#define SKIP_NO         0       /* do not skip this entry */
1042
#define SKIP_Y_EXISTING 1       /* skip this entry, do not overwrite file */
1044
#define SKIP_Y_EXISTING 1       /* skip this entry, do not overwrite file */
1043
#define SKIP_Y_NONEXIST 2       /* skip this entry, do not create new file */
1045
#define SKIP_Y_NONEXIST 2       /* skip this entry, do not create new file */
1044
 
1046
 
1045
    /*-----------------------------------------------------------------------
1047
    /*-----------------------------------------------------------------------
1046
        Second loop:  process files in current block, extracting or testing
1048
        Second loop:  process files in current block, extracting or testing
1047
        each one.
1049
        each one.
1048
      -----------------------------------------------------------------------*/
1050
      -----------------------------------------------------------------------*/
1049
 
1051
 
1050
    for (i = 0; i < numchunk; ++i) {
1052
    for (i = 0; i < numchunk; ++i) {
1051
        (*pfilnum)++;   /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
1053
        (*pfilnum)++;   /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
1052
        G.pInfo = &G.info[i];
1054
        G.pInfo = &G.info[i];
1053
#ifdef NOVELL_BUG_FAILSAFE
1055
#ifdef NOVELL_BUG_FAILSAFE
1054
        G.dne = FALSE;  /* assume file exists until stat() says otherwise */
1056
        G.dne = FALSE;  /* assume file exists until stat() says otherwise */
1055
#endif
1057
#endif
1056
 
1058
 
1057
        /* if the target position is not within the current input buffer
1059
        /* if the target position is not within the current input buffer
1058
         * (either haven't yet read far enough, or (maybe) skipping back-
1060
         * (either haven't yet read far enough, or (maybe) skipping back-
1059
         * ward), skip to the target position and reset readbuf(). */
1061
         * ward), skip to the target position and reset readbuf(). */
1060
 
1062
 
1061
        /* seek_zipf(__G__ pInfo->offset);  */
1063
        /* seek_zipf(__G__ pInfo->offset);  */
1062
        request = G.pInfo->offset + G.extra_bytes;
1064
        request = G.pInfo->offset + G.extra_bytes;
1063
        inbuf_offset = request % INBUFSIZ;
1065
        inbuf_offset = request % INBUFSIZ;
1064
        bufstart = request - inbuf_offset;
1066
        bufstart = request - inbuf_offset;
1065
 
1067
 
1066
        Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
1068
        Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
1067
          (long)request, (long)inbuf_offset));
1069
          (long)request, (long)inbuf_offset));
1068
        Trace((stderr,
1070
        Trace((stderr,
1069
          "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
1071
          "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
1070
          (long)bufstart, (long)G.cur_zipfile_bufstart));
1072
          (long)bufstart, (long)G.cur_zipfile_bufstart));
1071
        if (request < 0) {
1073
        if (request < 0) {
1072
            Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
1074
            Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
1073
              G.zipfn, LoadFarString(ReportMsg)));
1075
              G.zipfn, LoadFarString(ReportMsg)));
1074
            error_in_archive = PK_ERR;
1076
            error_in_archive = PK_ERR;
1075
            if (*pfilnum == 1 && G.extra_bytes != 0L) {
1077
            if (*pfilnum == 1 && G.extra_bytes != 0L) {
1076
                Info(slide, 0x401, ((char *)slide,
1078
                Info(slide, 0x401, ((char *)slide,
1077
                  LoadFarString(AttemptRecompensate)));
1079
                  LoadFarString(AttemptRecompensate)));
1078
                *pold_extra_bytes = G.extra_bytes;
1080
                *pold_extra_bytes = G.extra_bytes;
1079
                G.extra_bytes = 0L;
1081
                G.extra_bytes = 0L;
1080
                request = G.pInfo->offset;  /* could also check if != 0 */
1082
                request = G.pInfo->offset;  /* could also check if != 0 */
1081
                inbuf_offset = request % INBUFSIZ;
1083
                inbuf_offset = request % INBUFSIZ;
1082
                bufstart = request - inbuf_offset;
1084
                bufstart = request - inbuf_offset;
1083
                Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
1085
                Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
1084
                  (long)request, (long)inbuf_offset));
1086
                  (long)request, (long)inbuf_offset));
1085
                Trace((stderr,
1087
                Trace((stderr,
1086
                  "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
1088
                  "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
1087
                  (long)bufstart, (long)G.cur_zipfile_bufstart));
1089
                  (long)bufstart, (long)G.cur_zipfile_bufstart));
1088
                /* try again */
1090
                /* try again */
1089
                if (request < 0) {
1091
                if (request < 0) {
1090
                    Trace((stderr,
1092
                    Trace((stderr,
1091
                      "debug: recompensated request still < 0\n"));
1093
                      "debug: recompensated request still < 0\n"));
1092
                    Info(slide, 0x401, ((char *)slide,
1094
                    Info(slide, 0x401, ((char *)slide,
1093
                      LoadFarStringSmall(SeekMsg),
1095
                      LoadFarStringSmall(SeekMsg),
1094
                      G.zipfn, LoadFarString(ReportMsg)));
1096
                      G.zipfn, LoadFarString(ReportMsg)));
1095
                    error_in_archive = PK_BADERR;
1097
                    error_in_archive = PK_BADERR;
1096
                    continue;
1098
                    continue;
1097
                }
1099
                }
1098
            } else {
1100
            } else {
1099
                error_in_archive = PK_BADERR;
1101
                error_in_archive = PK_BADERR;
1100
                continue;  /* this one hosed; try next */
1102
                continue;  /* this one hosed; try next */
1101
            }
1103
            }
1102
        }
1104
        }
1103
 
1105
 
1104
        if (bufstart != G.cur_zipfile_bufstart) {
1106
        if (bufstart != G.cur_zipfile_bufstart) {
1105
            Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
1107
            Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
1106
#ifdef USE_STRM_INPUT
1108
#ifdef USE_STRM_INPUT
1107
            zfseeko(G.zipfd, bufstart, SEEK_SET);
1109
            zfseeko(G.zipfd, bufstart, SEEK_SET);
1108
            G.cur_zipfile_bufstart = zftello(G.zipfd);
1110
            G.cur_zipfile_bufstart = zftello(G.zipfd);
1109
#else /* !USE_STRM_INPUT */
1111
#else /* !USE_STRM_INPUT */
1110
            G.cur_zipfile_bufstart =
1112
            G.cur_zipfile_bufstart =
1111
              zlseek(G.zipfd, bufstart, SEEK_SET);
1113
              zlseek(G.zipfd, bufstart, SEEK_SET);
1112
#endif /* ?USE_STRM_INPUT */
1114
#endif /* ?USE_STRM_INPUT */
1113
            if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
1115
            if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
1114
            {
1116
            {
1115
                Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1117
                Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1116
                  *pfilnum, "lseek", (long)bufstart));
1118
                  *pfilnum, "lseek", (long)bufstart));
1117
                error_in_archive = PK_BADERR;
1119
                error_in_archive = PK_BADERR;
1118
                continue;   /* can still do next file */
1120
                continue;   /* can still do next file */
1119
            }
1121
            }
1120
            G.inptr = G.inbuf + (int)inbuf_offset;
1122
            G.inptr = G.inbuf + (int)inbuf_offset;
1121
            G.incnt -= (int)inbuf_offset;
1123
            G.incnt -= (int)inbuf_offset;
1122
        } else {
1124
        } else {
1123
            G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
1125
            G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
1124
            G.inptr = G.inbuf + (int)inbuf_offset;
1126
            G.inptr = G.inbuf + (int)inbuf_offset;
1125
        }
1127
        }
1126
 
1128
 
1127
        /* should be in proper position now, so check for sig */
1129
        /* should be in proper position now, so check for sig */
1128
        if (readbuf(__G__ G.sig, 4) == 0) {  /* bad offset */
1130
        if (readbuf(__G__ G.sig, 4) == 0) {  /* bad offset */
1129
            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1131
            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1130
              *pfilnum, "EOF", (long)request));
1132
              *pfilnum, "EOF", (long)request));
1131
            error_in_archive = PK_BADERR;
1133
            error_in_archive = PK_BADERR;
1132
            continue;   /* but can still try next one */
1134
            continue;   /* but can still try next one */
1133
        }
1135
        }
1134
        if (memcmp(G.sig, local_hdr_sig, 4)) {
1136
        if (memcmp(G.sig, local_hdr_sig, 4)) {
1135
            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1137
            Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
1136
              *pfilnum, LoadFarStringSmall(LocalHdrSig), (long)request));
1138
              *pfilnum, LoadFarStringSmall(LocalHdrSig), (long)request));
1137
            /*
1139
            /*
1138
                GRRDUMP(G.sig, 4)
1140
                GRRDUMP(G.sig, 4)
1139
                GRRDUMP(local_hdr_sig, 4)
1141
                GRRDUMP(local_hdr_sig, 4)
1140
             */
1142
             */
1141
            error_in_archive = PK_ERR;
1143
            error_in_archive = PK_ERR;
1142
            if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
1144
            if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
1143
                (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
1145
                (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
1144
                Info(slide, 0x401, ((char *)slide,
1146
                Info(slide, 0x401, ((char *)slide,
1145
                  LoadFarString(AttemptRecompensate)));
1147
                  LoadFarString(AttemptRecompensate)));
1146
                if (G.extra_bytes) {
1148
                if (G.extra_bytes) {
1147
                    *pold_extra_bytes = G.extra_bytes;
1149
                    *pold_extra_bytes = G.extra_bytes;
1148
                    G.extra_bytes = 0L;
1150
                    G.extra_bytes = 0L;
1149
                } else
1151
                } else
1150
                    G.extra_bytes = *pold_extra_bytes; /* third attempt */
1152
                    G.extra_bytes = *pold_extra_bytes; /* third attempt */
1151
                if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
1153
                if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
1152
                    (readbuf(__G__ G.sig, 4) == 0)) {  /* bad offset */
1154
                    (readbuf(__G__ G.sig, 4) == 0)) {  /* bad offset */
1153
                    if (error != PK_BADERR)
1155
                    if (error != PK_BADERR)
1154
                      Info(slide, 0x401, ((char *)slide,
1156
                      Info(slide, 0x401, ((char *)slide,
1155
                        LoadFarString(OffsetMsg), *pfilnum, "EOF",
1157
                        LoadFarString(OffsetMsg), *pfilnum, "EOF",
1156
                        (long)request));
1158
                        (long)request));
1157
                    error_in_archive = PK_BADERR;
1159
                    error_in_archive = PK_BADERR;
1158
                    continue;   /* but can still try next one */
1160
                    continue;   /* but can still try next one */
1159
                }
1161
                }
1160
                if (memcmp(G.sig, local_hdr_sig, 4)) {
1162
                if (memcmp(G.sig, local_hdr_sig, 4)) {
1161
                    Info(slide, 0x401, ((char *)slide,
1163
                    Info(slide, 0x401, ((char *)slide,
1162
                      LoadFarString(OffsetMsg), *pfilnum,
1164
                      LoadFarString(OffsetMsg), *pfilnum,
1163
                      LoadFarStringSmall(LocalHdrSig), (long)request));
1165
                      LoadFarStringSmall(LocalHdrSig), (long)request));
1164
                    error_in_archive = PK_BADERR;
1166
                    error_in_archive = PK_BADERR;
1165
                    continue;
1167
                    continue;
1166
                }
1168
                }
1167
            } else
1169
            } else
1168
                continue;  /* this one hosed; try next */
1170
                continue;  /* this one hosed; try next */
1169
        }
1171
        }
1170
        if ((error = process_local_file_hdr(__G)) != PK_COOL) {
1172
        if ((error = process_local_file_hdr(__G)) != PK_COOL) {
1171
            Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
1173
            Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
1172
              *pfilnum));
1174
              *pfilnum));
1173
            error_in_archive = error;   /* only PK_EOF defined */
1175
            error_in_archive = error;   /* only PK_EOF defined */
1174
            continue;   /* can still try next one */
1176
            continue;   /* can still try next one */
1175
        }
1177
        }
1176
#if (!defined(SFX) && defined(UNICODE_SUPPORT))
1178
#if (!defined(SFX) && defined(UNICODE_SUPPORT))
1177
        if (((G.lrec.general_purpose_bit_flag & (1 << 11)) == (1 << 11))
1179
        if (((G.lrec.general_purpose_bit_flag & (1 << 11)) == (1 << 11))
1178
            != (G.pInfo->GPFIsUTF8 != 0)) {
1180
            != (G.pInfo->GPFIsUTF8 != 0)) {
1179
            if (QCOND2) {
1181
            if (QCOND2) {
1180
#  ifdef SMALL_MEM
1182
#  ifdef SMALL_MEM
1181
                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
1183
                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
1182
 
1184
 
1183
                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
1185
                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
1184
#    define  cFile_PrintBuf  temp_cfilnam
1186
#    define  cFile_PrintBuf  temp_cfilnam
1185
#  else
1187
#  else
1186
#    define  cFile_PrintBuf  G.pInfo->cfilname
1188
#    define  cFile_PrintBuf  G.pInfo->cfilname
1187
#  endif
1189
#  endif
1188
                Info(slide, 0x421, ((char *)slide,
1190
                Info(slide, 0x421, ((char *)slide,
1189
                  LoadFarStringSmall2(GP11FlagsDiffer),
1191
                  LoadFarStringSmall2(GP11FlagsDiffer),
1190
                  *pfilnum, FnFilter1(cFile_PrintBuf), G.pInfo->GPFIsUTF8));
1192
                  *pfilnum, FnFilter1(cFile_PrintBuf), G.pInfo->GPFIsUTF8));
1191
#  undef    cFile_PrintBuf
1193
#  undef    cFile_PrintBuf
1192
            }
1194
            }
1193
            if (error_in_archive < PK_WARN)
1195
            if (error_in_archive < PK_WARN)
1194
                error_in_archive = PK_WARN;
1196
                error_in_archive = PK_WARN;
1195
        }
1197
        }
1196
#endif /* !SFX && UNICODE_SUPPORT */
1198
#endif /* !SFX && UNICODE_SUPPORT */
1197
        if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
1199
        if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
1198
             PK_COOL)
1200
             PK_COOL)
1199
        {
1201
        {
1200
            if (error > error_in_archive)
1202
            if (error > error_in_archive)
1201
                error_in_archive = error;
1203
                error_in_archive = error;
1202
            if (error > PK_WARN) {
1204
            if (error > PK_WARN) {
1203
                Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
1205
                Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
1204
                  FnFilter1(G.filename), "local"));
1206
                  FnFilter1(G.filename), "local"));
1205
                continue;   /* go on to next one */
1207
                continue;   /* go on to next one */
1206
            }
1208
            }
1207
        }
1209
        }
1208
        if (G.extra_field != (uch *)NULL) {
1210
        if (G.extra_field != (uch *)NULL) {
1209
            free(G.extra_field);
1211
            free(G.extra_field);
1210
            G.extra_field = (uch *)NULL;
1212
            G.extra_field = (uch *)NULL;
1211
        }
1213
        }
1212
        if ((error =
1214
        if ((error =
1213
             do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
1215
             do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
1214
        {
1216
        {
1215
            if (error > error_in_archive)
1217
            if (error > error_in_archive)
1216
                error_in_archive = error;
1218
                error_in_archive = error;
1217
            if (error > PK_WARN) {
1219
            if (error > PK_WARN) {
1218
                Info(slide, 0x401, ((char *)slide,
1220
                Info(slide, 0x401, ((char *)slide,
1219
                  LoadFarString(ExtFieldMsg),
1221
                  LoadFarString(ExtFieldMsg),
1220
                  FnFilter1(G.filename), "local"));
1222
                  FnFilter1(G.filename), "local"));
1221
                continue;   /* go on */
1223
                continue;   /* go on */
1222
            }
1224
            }
1223
        }
1225
        }
1224
#ifndef SFX
1226
#ifndef SFX
1225
        /* Filename consistency checks must come after reading in the local
1227
        /* Filename consistency checks must come after reading in the local
1226
         * extra field, so that a UTF-8 entry name e.f. block has already
1228
         * extra field, so that a UTF-8 entry name e.f. block has already
1227
         * been processed.
1229
         * been processed.
1228
         */
1230
         */
1229
        if (G.pInfo->cfilname != (char Far *)NULL) {
1231
        if (G.pInfo->cfilname != (char Far *)NULL) {
1230
            if (zfstrcmp(G.pInfo->cfilname, G.filename) != 0) {
1232
            if (zfstrcmp(G.pInfo->cfilname, G.filename) != 0) {
1231
#  ifdef SMALL_MEM
1233
#  ifdef SMALL_MEM
1232
                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
1234
                char *temp_cfilnam = slide + (7 * (WSIZE>>3));
1233
 
1235
 
1234
                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
1236
                zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
1235
#    define  cFile_PrintBuf  temp_cfilnam
1237
#    define  cFile_PrintBuf  temp_cfilnam
1236
#  else
1238
#  else
1237
#    define  cFile_PrintBuf  G.pInfo->cfilname
1239
#    define  cFile_PrintBuf  G.pInfo->cfilname
1238
#  endif
1240
#  endif
1239
                Info(slide, 0x401, ((char *)slide,
1241
                Info(slide, 0x401, ((char *)slide,
1240
                  LoadFarStringSmall2(LvsCFNamMsg),
1242
                  LoadFarStringSmall2(LvsCFNamMsg),
1241
                  FnFilter2(cFile_PrintBuf), FnFilter1(G.filename)));
1243
                  FnFilter2(cFile_PrintBuf), FnFilter1(G.filename)));
1242
#  undef    cFile_PrintBuf
1244
#  undef    cFile_PrintBuf
1243
                zfstrcpy(G.filename, G.pInfo->cfilname);
1245
                zfstrcpy(G.filename, G.pInfo->cfilname);
1244
                if (error_in_archive < PK_WARN)
1246
                if (error_in_archive < PK_WARN)
1245
                    error_in_archive = PK_WARN;
1247
                    error_in_archive = PK_WARN;
1246
            }
1248
            }
1247
            zffree(G.pInfo->cfilname);
1249
            zffree(G.pInfo->cfilname);
1248
            G.pInfo->cfilname = (char Far *)NULL;
1250
            G.pInfo->cfilname = (char Far *)NULL;
1249
        }
1251
        }
1250
#endif /* !SFX */
1252
#endif /* !SFX */
1251
        /* Size consistency checks must come after reading in the local extra
1253
        /* Size consistency checks must come after reading in the local extra
1252
         * field, so that any Zip64 extension local e.f. block has already
1254
         * field, so that any Zip64 extension local e.f. block has already
1253
         * been processed.
1255
         * been processed.
1254
         */
1256
         */
1255
        if (G.lrec.compression_method == STORED) {
1257
        if (G.lrec.compression_method == STORED) {
1256
            zusz_t csiz_decrypted = G.lrec.csize;
1258
            zusz_t csiz_decrypted = G.lrec.csize;
1257
 
1259
 
1258
            if (G.pInfo->encrypted)
1260
            if (G.pInfo->encrypted)
1259
                csiz_decrypted -= 12;
1261
                csiz_decrypted -= 12;
1260
            if (G.lrec.ucsize != csiz_decrypted) {
1262
            if (G.lrec.ucsize != csiz_decrypted) {
1261
                Info(slide, 0x401, ((char *)slide,
1263
                Info(slide, 0x401, ((char *)slide,
1262
                  LoadFarStringSmall2(WrnStorUCSizCSizDiff),
1264
                  LoadFarStringSmall2(WrnStorUCSizCSizDiff),
1263
                  FnFilter1(G.filename),
1265
                  FnFilter1(G.filename),
1264
                  FmZofft(G.lrec.ucsize, NULL, "u"),
1266
                  FmZofft(G.lrec.ucsize, NULL, "u"),
1265
                  FmZofft(csiz_decrypted, NULL, "u")));
1267
                  FmZofft(csiz_decrypted, NULL, "u")));
1266
                G.lrec.ucsize = csiz_decrypted;
1268
                G.lrec.ucsize = csiz_decrypted;
1267
                if (error_in_archive < PK_WARN)
1269
                if (error_in_archive < PK_WARN)
1268
                    error_in_archive = PK_WARN;
1270
                    error_in_archive = PK_WARN;
1269
            }
1271
            }
1270
        }
1272
        }
1271
 
1273
 
1272
#if CRYPT
1274
#if CRYPT
1273
        if (G.pInfo->encrypted &&
1275
        if (G.pInfo->encrypted &&
1274
            (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
1276
            (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
1275
            if (error == PK_WARN) {
1277
            if (error == PK_WARN) {
1276
                if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
1278
                if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
1277
                    Info(slide, 0x401, ((char *)slide,
1279
                    Info(slide, 0x401, ((char *)slide,
1278
                      LoadFarString(SkipIncorrectPasswd),
1280
                      LoadFarString(SkipIncorrectPasswd),
1279
                      FnFilter1(G.filename)));
1281
                      FnFilter1(G.filename)));
1280
                ++(*pnum_bad_pwd);
1282
                ++(*pnum_bad_pwd);
1281
            } else {  /* (error > PK_WARN) */
1283
            } else {  /* (error > PK_WARN) */
1282
                if (error > error_in_archive)
1284
                if (error > error_in_archive)
1283
                    error_in_archive = error;
1285
                    error_in_archive = error;
1284
                Info(slide, 0x401, ((char *)slide,
1286
                Info(slide, 0x401, ((char *)slide,
1285
                  LoadFarString(SkipCannotGetPasswd),
1287
                  LoadFarString(SkipCannotGetPasswd),
1286
                  FnFilter1(G.filename)));
1288
                  FnFilter1(G.filename)));
1287
            }
1289
            }
1288
            continue;   /* go on to next file */
1290
            continue;   /* go on to next file */
1289
        }
1291
        }
1290
#endif /* CRYPT */
1292
#endif /* CRYPT */
1291
 
1293
 
1292
        /*
1294
        /*
1293
         * just about to extract file:  if extracting to disk, check if
1295
         * just about to extract file:  if extracting to disk, check if
1294
         * already exists, and if so, take appropriate action according to
1296
         * already exists, and if so, take appropriate action according to
1295
         * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
1297
         * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
1296
         * loop because we don't store the possibly renamed filename[] in
1298
         * loop because we don't store the possibly renamed filename[] in
1297
         * info[])
1299
         * info[])
1298
         */
1300
         */
1299
#ifdef DLL
1301
#ifdef DLL
1300
        if (!uO.tflag && !uO.cflag && !G.redirect_data)
1302
        if (!uO.tflag && !uO.cflag && !G.redirect_data)
1301
#else
1303
#else
1302
        if (!uO.tflag && !uO.cflag)
1304
        if (!uO.tflag && !uO.cflag)
1303
#endif
1305
#endif
1304
        {
1306
        {
1305
            renamed = FALSE;   /* user hasn't renamed output file yet */
1307
            renamed = FALSE;   /* user hasn't renamed output file yet */
1306
 
1308
 
1307
startover:
1309
startover:
1308
            query = FALSE;
1310
            query = FALSE;
1309
            skip_entry = SKIP_NO;
1311
            skip_entry = SKIP_NO;
1310
            /* for files from DOS FAT, check for use of backslash instead
1312
            /* for files from DOS FAT, check for use of backslash instead
1311
             *  of slash as directory separator (bug in some zipper(s); so
1313
             *  of slash as directory separator (bug in some zipper(s); so
1312
             *  far, not a problem in HPFS, NTFS or VFAT systems)
1314
             *  far, not a problem in HPFS, NTFS or VFAT systems)
1313
             */
1315
             */
1314
#ifndef SFX
1316
#ifndef SFX
1315
            if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
1317
            if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
1316
                char *p=G.filename;
1318
                char *p=G.filename;
1317
 
1319
 
1318
                if (*p) do {
1320
                if (*p) do {
1319
                    if (*p == '\\') {
1321
                    if (*p == '\\') {
1320
                        if (!G.reported_backslash) {
1322
                        if (!G.reported_backslash) {
1321
                            Info(slide, 0x21, ((char *)slide,
1323
                            Info(slide, 0x21, ((char *)slide,
1322
                              LoadFarString(BackslashPathSep), G.zipfn));
1324
                              LoadFarString(BackslashPathSep), G.zipfn));
1323
                            G.reported_backslash = TRUE;
1325
                            G.reported_backslash = TRUE;
1324
                            if (!error_in_archive)
1326
                            if (!error_in_archive)
1325
                                error_in_archive = PK_WARN;
1327
                                error_in_archive = PK_WARN;
1326
                        }
1328
                        }
1327
                        *p = '/';
1329
                        *p = '/';
1328
                    }
1330
                    }
1329
                } while (*PREINCSTR(p));
1331
                } while (*PREINCSTR(p));
1330
            }
1332
            }
1331
#endif /* !SFX */
1333
#endif /* !SFX */
1332
 
1334
 
1333
            if (!renamed) {
1335
            if (!renamed) {
1334
               /* remove absolute path specs */
1336
               /* remove absolute path specs */
1335
               if (G.filename[0] == '/') {
1337
               if (G.filename[0] == '/') {
1336
                   Info(slide, 0x401, ((char *)slide,
1338
                   Info(slide, 0x401, ((char *)slide,
1337
                        LoadFarString(AbsolutePathWarning),
1339
                        LoadFarString(AbsolutePathWarning),
1338
                        FnFilter1(G.filename)));
1340
                        FnFilter1(G.filename)));
1339
                   if (!error_in_archive)
1341
                   if (!error_in_archive)
1340
                       error_in_archive = PK_WARN;
1342
                       error_in_archive = PK_WARN;
1341
                   do {
1343
                   do {
1342
                       char *p = G.filename + 1;
1344
                       char *p = G.filename + 1;
1343
                       do {
1345
                       do {
1344
                           *(p-1) = *p;
1346
                           *(p-1) = *p;
1345
                       } while (*p++ != '\0');
1347
                       } while (*p++ != '\0');
1346
                   } while (G.filename[0] == '/');
1348
                   } while (G.filename[0] == '/');
1347
               }
1349
               }
1348
            }
1350
            }
1349
 
1351
 
1350
            /* mapname can create dirs if not freshening or if renamed */
1352
            /* mapname can create dirs if not freshening or if renamed */
1351
            error = mapname(__G__ renamed);
1353
            error = mapname(__G__ renamed);
1352
            if ((errcode = error & ~MPN_MASK) != PK_OK &&
1354
            if ((errcode = error & ~MPN_MASK) != PK_OK &&
1353
                error_in_archive < errcode)
1355
                error_in_archive < errcode)
1354
                error_in_archive = errcode;
1356
                error_in_archive = errcode;
1355
            if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
1357
            if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
1356
                if (errcode == MPN_CREATED_DIR) {
1358
                if (errcode == MPN_CREATED_DIR) {
1357
#ifdef SET_DIR_ATTRIB
1359
#ifdef SET_DIR_ATTRIB
1358
                    direntry *d_entry;
1360
                    direntry *d_entry;
1359
 
1361
 
1360
                    error = defer_dir_attribs(__G__ &d_entry);
1362
                    error = defer_dir_attribs(__G__ &d_entry);
1361
                    if (d_entry == (direntry *)NULL) {
1363
                    if (d_entry == (direntry *)NULL) {
1362
                        /* There may be no dir_attribs info available, or
1364
                        /* There may be no dir_attribs info available, or
1363
                         * we have encountered a mem allocation error.
1365
                         * we have encountered a mem allocation error.
1364
                         * In case of an error, report it and set program
1366
                         * In case of an error, report it and set program
1365
                         * error state to warning level.
1367
                         * error state to warning level.
1366
                         */
1368
                         */
1367
                        if (error) {
1369
                        if (error) {
1368
                            Info(slide, 0x401, ((char *)slide,
1370
                            Info(slide, 0x401, ((char *)slide,
1369
                                 LoadFarString(DirlistEntryNoMem)));
1371
                                 LoadFarString(DirlistEntryNoMem)));
1370
                            if (!error_in_archive)
1372
                            if (!error_in_archive)
1371
                                error_in_archive = PK_WARN;
1373
                                error_in_archive = PK_WARN;
1372
                        }
1374
                        }
1373
                    } else {
1375
                    } else {
1374
                        d_entry->next = (*pdirlist);
1376
                        d_entry->next = (*pdirlist);
1375
                        (*pdirlist) = d_entry;
1377
                        (*pdirlist) = d_entry;
1376
                        ++(*pnum_dirs);
1378
                        ++(*pnum_dirs);
1377
                    }
1379
                    }
1378
#endif /* SET_DIR_ATTRIB */
1380
#endif /* SET_DIR_ATTRIB */
1379
                } else if (errcode == MPN_VOL_LABEL) {
1381
                } else if (errcode == MPN_VOL_LABEL) {
1380
#ifdef DOS_OS2_W32
1382
#ifdef DOS_OS2_W32
1381
                    Info(slide, 0x401, ((char *)slide,
1383
                    Info(slide, 0x401, ((char *)slide,
1382
                      LoadFarString(SkipVolumeLabel),
1384
                      LoadFarString(SkipVolumeLabel),
1383
                      FnFilter1(G.filename),
1385
                      FnFilter1(G.filename),
1384
                      uO.volflag? "hard disk " : ""));
1386
                      uO.volflag? "hard disk " : ""));
1385
#else
1387
#else
1386
                    Info(slide, 1, ((char *)slide,
1388
                    Info(slide, 1, ((char *)slide,
1387
                      LoadFarString(SkipVolumeLabel),
1389
                      LoadFarString(SkipVolumeLabel),
1388
                      FnFilter1(G.filename), ""));
1390
                      FnFilter1(G.filename), ""));
1389
#endif
1391
#endif
1390
                } else if (errcode > MPN_INF_SKIP &&
1392
                } else if (errcode > MPN_INF_SKIP &&
1391
                           error_in_archive < PK_ERR)
1393
                           error_in_archive < PK_ERR)
1392
                    error_in_archive = PK_ERR;
1394
                    error_in_archive = PK_ERR;
1393
                Trace((stderr, "mapname(%s) returns error code = %d\n",
1395
                Trace((stderr, "mapname(%s) returns error code = %d\n",
1394
                  FnFilter1(G.filename), error));
1396
                  FnFilter1(G.filename), error));
1395
                continue;   /* go on to next file */
1397
                continue;   /* go on to next file */
1396
            }
1398
            }
1397
 
1399
 
1398
#ifdef QDOS
1400
#ifdef QDOS
1399
            QFilename(__G__ G.filename);
1401
            QFilename(__G__ G.filename);
1400
#endif
1402
#endif
1401
            switch (check_for_newer(__G__ G.filename)) {
1403
            switch (check_for_newer(__G__ G.filename)) {
1402
                case DOES_NOT_EXIST:
1404
                case DOES_NOT_EXIST:
1403
#ifdef NOVELL_BUG_FAILSAFE
1405
#ifdef NOVELL_BUG_FAILSAFE
1404
                    G.dne = TRUE;   /* stat() says file DOES NOT EXIST */
1406
                    G.dne = TRUE;   /* stat() says file DOES NOT EXIST */
1405
#endif
1407
#endif
1406
                    /* freshen (no new files): skip unless just renamed */
1408
                    /* freshen (no new files): skip unless just renamed */
1407
                    if (uO.fflag && !renamed)
1409
                    if (uO.fflag && !renamed)
1408
                        skip_entry = SKIP_Y_NONEXIST;
1410
                        skip_entry = SKIP_Y_NONEXIST;
1409
                    break;
1411
                    break;
1410
                case EXISTS_AND_OLDER:
1412
                case EXISTS_AND_OLDER:
1411
#ifdef UNIXBACKUP
1413
#ifdef UNIXBACKUP
1412
                    if (!uO.B_flag)
1414
                    if (!uO.B_flag)
1413
#endif
1415
#endif
1414
                    {
1416
                    {
1415
                        if (IS_OVERWRT_NONE)
1417
                        if (IS_OVERWRT_NONE)
1416
                            /* never overwrite:  skip file */
1418
                            /* never overwrite:  skip file */
1417
                            skip_entry = SKIP_Y_EXISTING;
1419
                            skip_entry = SKIP_Y_EXISTING;
1418
                        else if (!IS_OVERWRT_ALL)
1420
                        else if (!IS_OVERWRT_ALL)
1419
                            query = TRUE;
1421
                            query = TRUE;
1420
                    }
1422
                    }
1421
                    break;
1423
                    break;
1422
                case EXISTS_AND_NEWER:             /* (or equal) */
1424
                case EXISTS_AND_NEWER:             /* (or equal) */
1423
#ifdef UNIXBACKUP
1425
#ifdef UNIXBACKUP
1424
                    if ((!uO.B_flag && IS_OVERWRT_NONE) ||
1426
                    if ((!uO.B_flag && IS_OVERWRT_NONE) ||
1425
#else
1427
#else
1426
                    if (IS_OVERWRT_NONE ||
1428
                    if (IS_OVERWRT_NONE ||
1427
#endif
1429
#endif
1428
                        (uO.uflag && !renamed)) {
1430
                        (uO.uflag && !renamed)) {
1429
                        /* skip if update/freshen & orig name */
1431
                        /* skip if update/freshen & orig name */
1430
                        skip_entry = SKIP_Y_EXISTING;
1432
                        skip_entry = SKIP_Y_EXISTING;
1431
                    } else {
1433
                    } else {
1432
#ifdef UNIXBACKUP
1434
#ifdef UNIXBACKUP
1433
                        if (!IS_OVERWRT_ALL && !uO.B_flag)
1435
                        if (!IS_OVERWRT_ALL && !uO.B_flag)
1434
#else
1436
#else
1435
                        if (!IS_OVERWRT_ALL)
1437
                        if (!IS_OVERWRT_ALL)
1436
#endif
1438
#endif
1437
                            query = TRUE;
1439
                            query = TRUE;
1438
                    }
1440
                    }
1439
                    break;
1441
                    break;
1440
            }
1442
            }
1441
#ifdef VMS
1443
#ifdef VMS
1442
            /* 2008-07-24 SMS.
1444
            /* 2008-07-24 SMS.
1443
             * On VMS, if the file name includes a version number,
1445
             * On VMS, if the file name includes a version number,
1444
             * and "-V" ("retain VMS version numbers", V_flag) is in
1446
             * and "-V" ("retain VMS version numbers", V_flag) is in
1445
             * effect, then the VMS-specific code will handle any
1447
             * effect, then the VMS-specific code will handle any
1446
             * conflicts with an existing file, making this query
1448
             * conflicts with an existing file, making this query
1447
             * redundant.  (Implicit "y" response here.)
1449
             * redundant.  (Implicit "y" response here.)
1448
             */
1450
             */
1449
            if (query && uO.V_flag) {
1451
            if (query && uO.V_flag) {
1450
                /* Not discarding file versions.  Look for one. */
1452
                /* Not discarding file versions.  Look for one. */
1451
                int cndx = strlen(G.filename) - 1;
1453
                int cndx = strlen(G.filename) - 1;
1452
 
1454
 
1453
                while ((cndx > 0) && (isdigit(G.filename[cndx])))
1455
                while ((cndx > 0) && (isdigit(G.filename[cndx])))
1454
                    cndx--;
1456
                    cndx--;
1455
                if (G.filename[cndx] == ';')
1457
                if (G.filename[cndx] == ';')
1456
                    /* File version found; skip the generic query,
1458
                    /* File version found; skip the generic query,
1457
                     * proceeding with its default response "y".
1459
                     * proceeding with its default response "y".
1458
                     */
1460
                     */
1459
                    query = FALSE;
1461
                    query = FALSE;
1460
            }
1462
            }
1461
#endif /* VMS */
1463
#endif /* VMS */
1462
            if (query) {
1464
            if (query) {
1463
#ifdef WINDLL
1465
#ifdef WINDLL
1464
                switch (G.lpUserFunctions->replace != NULL ?
1466
                switch (G.lpUserFunctions->replace != NULL ?
1465
                        (*G.lpUserFunctions->replace)(G.filename, FILNAMSIZ) :
1467
                        (*G.lpUserFunctions->replace)(G.filename, FILNAMSIZ) :
1466
                        IDM_REPLACE_NONE) {
1468
                        IDM_REPLACE_NONE) {
1467
                    case IDM_REPLACE_RENAME:
1469
                    case IDM_REPLACE_RENAME:
1468
                        _ISO_INTERN(G.filename);
1470
                        _ISO_INTERN(G.filename);
1469
                        renamed = TRUE;
1471
                        renamed = TRUE;
1470
                        goto startover;
1472
                        goto startover;
1471
                    case IDM_REPLACE_ALL:
1473
                    case IDM_REPLACE_ALL:
1472
                        G.overwrite_mode = OVERWRT_ALWAYS;
1474
                        G.overwrite_mode = OVERWRT_ALWAYS;
1473
                        /* FALL THROUGH, extract */
1475
                        /* FALL THROUGH, extract */
1474
                    case IDM_REPLACE_YES:
1476
                    case IDM_REPLACE_YES:
1475
                        break;
1477
                        break;
1476
                    case IDM_REPLACE_NONE:
1478
                    case IDM_REPLACE_NONE:
1477
                        G.overwrite_mode = OVERWRT_NEVER;
1479
                        G.overwrite_mode = OVERWRT_NEVER;
1478
                        /* FALL THROUGH, skip */
1480
                        /* FALL THROUGH, skip */
1479
                    case IDM_REPLACE_NO:
1481
                    case IDM_REPLACE_NO:
1480
                        skip_entry = SKIP_Y_EXISTING;
1482
                        skip_entry = SKIP_Y_EXISTING;
1481
                        break;
1483
                        break;
1482
                }
1484
                }
1483
#else /* !WINDLL */
1485
#else /* !WINDLL */
1484
                extent fnlen;
1486
                extent fnlen;
1485
reprompt:
1487
reprompt:
1486
                Info(slide, 0x81, ((char *)slide,
1488
                Info(slide, 0x81 & 0xFE, ((char *)slide,
1487
                  LoadFarString(ReplaceQuery),
1489
                  LoadFarString(ReplaceQuery),
1488
                  FnFilter1(G.filename)));
1490
                  FnFilter1(G.filename)));
1489
                if (fgets(G.answerbuf, sizeof(G.answerbuf), stdin)
1491
                if (fgets(G.answerbuf, sizeof(G.answerbuf), stdin)
1490
                    == (char *)NULL) {
1492
                    == (char *)NULL) {
1491
                    Info(slide, 1, ((char *)slide,
1493
                    Info(slide, 1 & 0xFE, ((char *)slide,
1492
                      LoadFarString(AssumeNone)));
1494
                      LoadFarString(AssumeNone)));
1493
                    *G.answerbuf = 'N';
1495
                    *G.answerbuf = 'N';
1494
                    if (!error_in_archive)
1496
                    if (!error_in_archive)
1495
                        error_in_archive = 1;  /* not extracted:  warning */
1497
                        error_in_archive = 1;  /* not extracted:  warning */
1496
                }
1498
                }
1497
                switch (*G.answerbuf) {
1499
                switch (*G.answerbuf) {
1498
                    case 'r':
1500
                    case 'r':
1499
                    case 'R':
1501
                    case 'R':
1500
                        do {
1502
                        do {
1501
                            Info(slide, 0x81, ((char *)slide,
1503
                            Info(slide, 0x81 & 0xFE, ((char *)slide,
1502
                              LoadFarString(NewNameQuery)));
1504
                              LoadFarString(NewNameQuery)));
1503
                            fgets(G.filename, FILNAMSIZ, stdin);
1505
                            fgets(G.filename, FILNAMSIZ, stdin);
1504
                            /* usually get \n here:  better check for it */
1506
                            /* usually get \n here:  better check for it */
1505
                            fnlen = strlen(G.filename);
1507
                            fnlen = strlen(G.filename);
1506
                            if (lastchar(G.filename, fnlen) == '\n')
1508
                            if (lastchar(G.filename, fnlen) == '\n')
1507
                                G.filename[--fnlen] = '\0';
1509
                                G.filename[--fnlen] = '\0';
1508
                        } while (fnlen == 0);
1510
                        } while (fnlen == 0);
1509
#ifdef WIN32  /* WIN32 fgets( ... , stdin) returns OEM coded strings */
1511
#ifdef WIN32  /* WIN32 fgets( ... , stdin) returns OEM coded strings */
1510
                        _OEM_INTERN(G.filename);
1512
                        _OEM_INTERN(G.filename);
1511
#endif
1513
#endif
1512
                        renamed = TRUE;
1514
                        renamed = TRUE;
1513
                        goto startover;   /* sorry for a goto */
1515
                        goto startover;   /* sorry for a goto */
1514
                    case 'A':   /* dangerous option:  force caps */
1516
                    case 'A':   /* dangerous option:  force caps */
1515
                        G.overwrite_mode = OVERWRT_ALWAYS;
1517
                        G.overwrite_mode = OVERWRT_ALWAYS;
1516
                        /* FALL THROUGH, extract */
1518
                        /* FALL THROUGH, extract */
1517
                    case 'y':
1519
                    case 'y':
1518
                    case 'Y':
1520
                    case 'Y':
1519
                        break;
1521
                        break;
1520
                    case 'N':
1522
                    case 'N':
1521
                        G.overwrite_mode = OVERWRT_NEVER;
1523
                        G.overwrite_mode = OVERWRT_NEVER;
1522
                        /* FALL THROUGH, skip */
1524
                        /* FALL THROUGH, skip */
1523
                    case 'n':
1525
                    case 'n':
1524
                        /* skip file */
1526
                        /* skip file */
1525
                        skip_entry = SKIP_Y_EXISTING;
1527
                        skip_entry = SKIP_Y_EXISTING;
1526
                        break;
1528
                        break;
1527
                    case '\n':
1529
                    case '\n':
1528
                    case '\r':
1530
                    case '\r':
1529
                        /* Improve echo of '\n' and/or '\r'
1531
                        /* Improve echo of '\n' and/or '\r'
1530
                           (sizeof(G.answerbuf) == 10 (see globals.h), so
1532
                           (sizeof(G.answerbuf) == 10 (see globals.h), so
1531
                           there is enough space for the provided text...) */
1533
                           there is enough space for the provided text...) */
1532
                        strcpy(G.answerbuf, "{ENTER}");
1534
                        strcpy(G.answerbuf, "{ENTER}");
1533
                        /* fall through ... */
1535
                        /* fall through ... */
1534
                    default:
1536
                    default:
1535
                        /* usually get \n here:  remove it for nice display
1537
                        /* usually get \n here:  remove it for nice display
1536
                           (fnlen can be re-used here, we are outside the
1538
                           (fnlen can be re-used here, we are outside the
1537
                           "enter new filename" loop) */
1539
                           "enter new filename" loop) */
1538
                        fnlen = strlen(G.answerbuf);
1540
                        fnlen = strlen(G.answerbuf);
1539
                        if (lastchar(G.answerbuf, fnlen) == '\n')
1541
                        if (lastchar(G.answerbuf, fnlen) == '\n')
1540
                            G.answerbuf[--fnlen] = '\0';
1542
                            G.answerbuf[--fnlen] = '\0';
1541
                        Info(slide, 1, ((char *)slide,
1543
                        Info(slide, 1 & 0xFE, ((char *)slide,
1542
                          LoadFarString(InvalidResponse), G.answerbuf));
1544
                          LoadFarString(InvalidResponse), G.answerbuf));
1543
                        goto reprompt;   /* yet another goto? */
1545
                        goto reprompt;   /* yet another goto? */
1544
                } /* end switch (*answerbuf) */
1546
                } /* end switch (*answerbuf) */
1545
#endif /* ?WINDLL */
1547
#endif /* ?WINDLL */
1546
            } /* end if (query) */
1548
            } /* end if (query) */
1547
            if (skip_entry != SKIP_NO) {
1549
            if (skip_entry != SKIP_NO) {
1548
#ifdef WINDLL
1550
#ifdef WINDLL
1549
                if (skip_entry == SKIP_Y_EXISTING) {
1551
                if (skip_entry == SKIP_Y_EXISTING) {
1550
                    /* report skipping of an existing entry */
1552
                    /* report skipping of an existing entry */
1551
                    Info(slide, 0, ((char *)slide,
1553
                    Info(slide, 0, ((char *)slide,
1552
                      ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
1554
                      ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
1553
                       "Target file exists.  Skipping %s\n" :
1555
                       "Target file exists.  Skipping %s\n" :
1554
                       "Target file newer.  Skipping %s\n"),
1556
                       "Target file newer.  Skipping %s\n"),
1555
                      FnFilter1(G.filename)));
1557
                      FnFilter1(G.filename)));
1556
                }
1558
                }
1557
#endif /* WINDLL */
1559
#endif /* WINDLL */
1558
                continue;
1560
                continue;
1559
            }
1561
            }
1560
        } /* end if (extracting to disk) */
1562
        } /* end if (extracting to disk) */
1561
 
1563
 
1562
#ifdef DLL
1564
#ifdef DLL
1563
        if ((G.statreportcb != NULL) &&
1565
        if ((G.statreportcb != NULL) &&
1564
            (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
1566
            (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
1565
                              G.filename, NULL)) {
1567
                              G.filename, NULL)) {
1566
            return IZ_CTRLC;        /* cancel operation by user request */
1568
            return IZ_CTRLC;        /* cancel operation by user request */
1567
        }
1569
        }
1568
#endif
1570
#endif
1569
#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
1571
#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
1570
        UserStop();
1572
        UserStop();
1571
#endif
1573
#endif
1572
#ifdef AMIGA
1574
#ifdef AMIGA
1573
        G.filenote_slot = i;
1575
        G.filenote_slot = i;
1574
#endif
1576
#endif
1575
        G.disk_full = 0;
1577
        G.disk_full = 0;
1576
        if ((error = extract_or_test_member(__G)) != PK_COOL) {
1578
        if ((error = extract_or_test_member(__G)) != PK_COOL) {
1577
            if (error > error_in_archive)
1579
            if (error > error_in_archive)
1578
                error_in_archive = error;       /* ...and keep going */
1580
                error_in_archive = error;       /* ...and keep going */
1579
#ifdef DLL
1581
#ifdef DLL
1580
            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
1582
            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
1581
#else
1583
#else
1582
            if (G.disk_full > 1) {
1584
            if (G.disk_full > 1) {
1583
#endif
1585
#endif
1584
                return error_in_archive;        /* (unless disk full) */
1586
                return error_in_archive;        /* (unless disk full) */
1585
            }
1587
            }
1586
        }
1588
        }
1587
#ifdef DLL
1589
#ifdef DLL
1588
        if ((G.statreportcb != NULL) &&
1590
        if ((G.statreportcb != NULL) &&
1589
            (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
1591
            (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
1590
                              G.filename, (zvoid *)&G.lrec.ucsize)) {
1592
                              G.filename, (zvoid *)&G.lrec.ucsize)) {
1591
            return IZ_CTRLC;        /* cancel operation by user request */
1593
            return IZ_CTRLC;        /* cancel operation by user request */
1592
        }
1594
        }
1593
#endif
1595
#endif
1594
#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
1596
#ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
1595
        UserStop();
1597
        UserStop();
1596
#endif
1598
#endif
1597
    } /* end for-loop (i:  files in current block) */
1599
    } /* end for-loop (i:  files in current block) */
1598
 
1600
 
1599
    return error_in_archive;
1601
    return error_in_archive;
1600
 
1602
 
1601
} /* end function extract_or_test_entrylist() */
1603
} /* end function extract_or_test_entrylist() */
1602
 
1604
 
1603
 
1605
 
1604
 
1606
 
1605
 
1607
 
1606
 
1608
 
1607
/* wsize is used in extract_or_test_member() and UZbunzip2() */
1609
/* wsize is used in extract_or_test_member() and UZbunzip2() */
1608
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
1610
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
1609
#  define wsize G._wsize    /* wsize is a variable */
1611
#  define wsize G._wsize    /* wsize is a variable */
1610
#else
1612
#else
1611
#  define wsize WSIZE       /* wsize is a constant */
1613
#  define wsize WSIZE       /* wsize is a constant */
1612
#endif
1614
#endif
1613
 
1615
 
1614
/***************************************/
1616
/***************************************/
1615
/*  Function extract_or_test_member()  */
1617
/*  Function extract_or_test_member()  */
1616
/***************************************/
1618
/***************************************/
1617
 
1619
 
1618
static int extract_or_test_member(__G)    /* return PK-type error code */
1620
static int extract_or_test_member(__G)    /* return PK-type error code */
1619
     __GDEF
1621
     __GDEF
1620
{
1622
{
1621
    char *nul="[empty] ", *txt="[text]  ", *bin="[binary]";
1623
    char *nul="[empty] ", *txt="[text]  ", *bin="[binary]";
1622
#ifdef CMS_MVS
1624
#ifdef CMS_MVS
1623
    char *ebc="[ebcdic]";
1625
    char *ebc="[ebcdic]";
1624
#endif
1626
#endif
1625
    register int b;
1627
    register int b;
1626
    int r, error=PK_COOL;
1628
    int r, error=PK_COOL;
1627
 
1629
 
1628
 
1630
 
1629
/*---------------------------------------------------------------------------
1631
/*---------------------------------------------------------------------------
1630
    Initialize variables, buffers, etc.
1632
    Initialize variables, buffers, etc.
1631
  ---------------------------------------------------------------------------*/
1633
  ---------------------------------------------------------------------------*/
1632
 
1634
 
1633
    G.bits_left = 0;
1635
    G.bits_left = 0;
1634
    G.bitbuf = 0L;       /* unreduce and unshrink only */
1636
    G.bitbuf = 0L;       /* unreduce and unshrink only */
1635
    G.zipeof = 0;
1637
    G.zipeof = 0;
1636
    G.newfile = TRUE;
1638
    G.newfile = TRUE;
1637
    G.crc32val = CRCVAL_INITIAL;
1639
    G.crc32val = CRCVAL_INITIAL;
1638
 
1640
 
1639
#ifdef SYMLINKS
1641
#ifdef SYMLINKS
1640
    /* If file is a (POSIX-compatible) symbolic link and we are extracting
1642
    /* If file is a (POSIX-compatible) symbolic link and we are extracting
1641
     * to disk, prepare to restore the link. */
1643
     * to disk, prepare to restore the link. */
1642
    G.symlnk = (G.pInfo->symlink &&
1644
    G.symlnk = (G.pInfo->symlink &&
1643
                !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0));
1645
                !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0));
1644
#endif /* SYMLINKS */
1646
#endif /* SYMLINKS */
1645
 
1647
 
1646
    if (uO.tflag) {
1648
    if (uO.tflag) {
1647
        if (!uO.qflag)
1649
        if (!uO.qflag)
1648
            Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
1650
            Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
1649
              FnFilter1(G.filename), "", ""));
1651
              FnFilter1(G.filename), "", ""));
1650
    } else {
1652
    } else {
1651
#ifdef DLL
1653
#ifdef DLL
1652
        if (uO.cflag && !G.redirect_data)
1654
        if (uO.cflag && !G.redirect_data)
1653
#else
1655
#else
1654
        if (uO.cflag)
1656
        if (uO.cflag)
1655
#endif
1657
#endif
1656
        {
1658
        {
1657
#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
1659
#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
1658
            G.outfile = freopen("", "wb", stdout);   /* VAC++ ignores setmode */
1660
            G.outfile = freopen("", "wb", stdout);   /* VAC++ ignores setmode */
1659
#else
1661
#else
1660
            G.outfile = stdout;
1662
            G.outfile = stdout;
1661
#endif
1663
#endif
1662
#ifdef DOS_FLX_NLM_OS2_W32
1664
#ifdef DOS_FLX_NLM_OS2_W32
1663
#if (defined(__HIGHC__) && !defined(FLEXOS))
1665
#if (defined(__HIGHC__) && !defined(FLEXOS))
1664
            setmode(G.outfile, _BINARY);
1666
            setmode(G.outfile, _BINARY);
1665
#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
1667
#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
1666
            setmode(fileno(G.outfile), O_BINARY);
1668
            setmode(fileno(G.outfile), O_BINARY);
1667
#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
1669
#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
1668
#           define NEWLINE "\r\n"
1670
#           define NEWLINE "\r\n"
1669
#else /* !DOS_FLX_NLM_OS2_W32 */
1671
#else /* !DOS_FLX_NLM_OS2_W32 */
1670
#           define NEWLINE "\n"
1672
#           define NEWLINE "\n"
1671
#endif /* ?DOS_FLX_NLM_OS2_W32 */
1673
#endif /* ?DOS_FLX_NLM_OS2_W32 */
1672
#ifdef VMS
1674
#ifdef VMS
1673
            /* VMS:  required even for stdout! */
1675
            /* VMS:  required even for stdout! */
1674
            if ((r = open_outfile(__G)) != 0)
1676
            if ((r = open_outfile(__G)) != 0)
1675
                switch (r) {
1677
                switch (r) {
1676
                  case OPENOUT_SKIPOK:
1678
                  case OPENOUT_SKIPOK:
1677
                    return PK_OK;
1679
                    return PK_OK;
1678
                  case OPENOUT_SKIPWARN:
1680
                  case OPENOUT_SKIPWARN:
1679
                    return PK_WARN;
1681
                    return PK_WARN;
1680
                  default:
1682
                  default:
1681
                    return PK_DISK;
1683
                    return PK_DISK;
1682
                }
1684
                }
1683
        } else if ((r = open_outfile(__G)) != 0)
1685
        } else if ((r = open_outfile(__G)) != 0)
1684
            switch (r) {
1686
            switch (r) {
1685
              case OPENOUT_SKIPOK:
1687
              case OPENOUT_SKIPOK:
1686
                return PK_OK;
1688
                return PK_OK;
1687
              case OPENOUT_SKIPWARN:
1689
              case OPENOUT_SKIPWARN:
1688
                return PK_WARN;
1690
                return PK_WARN;
1689
              default:
1691
              default:
1690
                return PK_DISK;
1692
                return PK_DISK;
1691
            }
1693
            }
1692
#else /* !VMS */
1694
#else /* !VMS */
1693
        } else if (open_outfile(__G))
1695
        } else if (open_outfile(__G))
1694
            return PK_DISK;
1696
            return PK_DISK;
1695
#endif /* ?VMS */
1697
#endif /* ?VMS */
1696
    }
1698
    }
1697
 
1699
 
1698
/*---------------------------------------------------------------------------
1700
/*---------------------------------------------------------------------------
1699
    Unpack the file.
1701
    Unpack the file.
1700
  ---------------------------------------------------------------------------*/
1702
  ---------------------------------------------------------------------------*/
1701
 
1703
 
1702
    defer_leftover_input(__G);    /* so NEXTBYTE bounds check will work */
1704
    defer_leftover_input(__G);    /* so NEXTBYTE bounds check will work */
1703
    switch (G.lrec.compression_method) {
1705
    switch (G.lrec.compression_method) {
1704
        case STORED:
1706
        case STORED:
1705
            if (!uO.tflag && QCOND2) {
1707
            if (!uO.tflag && QCOND2) {
1706
#ifdef SYMLINKS
1708
#ifdef SYMLINKS
1707
                if (G.symlnk)   /* can also be deflated, but rarer... */
1709
                if (G.symlnk)   /* can also be deflated, but rarer... */
1708
                    Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1710
                    Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1709
                      "link", FnFilter1(G.filename), "", ""));
1711
                      "link", FnFilter1(G.filename), "", ""));
1710
                else
1712
                else
1711
#endif /* SYMLINKS */
1713
#endif /* SYMLINKS */
1712
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1714
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1713
                  "extract", FnFilter1(G.filename),
1715
                  "extract", FnFilter1(G.filename),
1714
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1716
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1715
                  "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
1717
                  "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
1716
                  bin)), uO.cflag? NEWLINE : ""));
1718
                  bin)), uO.cflag? NEWLINE : ""));
1717
            }
1719
            }
1718
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
1720
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
1719
            if (G.redirect_slide) {
1721
            if (G.redirect_slide) {
1720
                wsize = G.redirect_size; redirSlide = G.redirect_buffer;
1722
                wsize = G.redirect_size; redirSlide = G.redirect_buffer;
1721
            } else {
1723
            } else {
1722
                wsize = WSIZE; redirSlide = slide;
1724
                wsize = WSIZE; redirSlide = slide;
1723
            }
1725
            }
1724
#endif
1726
#endif
1725
            G.outptr = redirSlide;
1727
            G.outptr = redirSlide;
1726
            G.outcnt = 0L;
1728
            G.outcnt = 0L;
1727
            while ((b = NEXTBYTE) != EOF) {
1729
            while ((b = NEXTBYTE) != EOF) {
1728
                *G.outptr++ = (uch)b;
1730
                *G.outptr++ = (uch)b;
1729
                if (++G.outcnt == wsize) {
1731
                if (++G.outcnt == wsize) {
1730
                    error = flush(__G__ redirSlide, G.outcnt, 0);
1732
                    error = flush(__G__ redirSlide, G.outcnt, 0);
1731
                    G.outptr = redirSlide;
1733
                    G.outptr = redirSlide;
1732
                    G.outcnt = 0L;
1734
                    G.outcnt = 0L;
1733
                    if (error != PK_COOL || G.disk_full) break;
1735
                    if (error != PK_COOL || G.disk_full) break;
1734
                }
1736
                }
1735
            }
1737
            }
1736
            if (G.outcnt) {        /* flush final (partial) buffer */
1738
            if (G.outcnt) {        /* flush final (partial) buffer */
1737
                r = flush(__G__ redirSlide, G.outcnt, 0);
1739
                r = flush(__G__ redirSlide, G.outcnt, 0);
1738
                if (error < r) error = r;
1740
                if (error < r) error = r;
1739
            }
1741
            }
1740
            break;
1742
            break;
1741
 
1743
 
1742
#ifndef SFX
1744
#ifndef SFX
1743
#ifndef LZW_CLEAN
1745
#ifndef LZW_CLEAN
1744
        case SHRUNK:
1746
        case SHRUNK:
1745
            if (!uO.tflag && QCOND2) {
1747
            if (!uO.tflag && QCOND2) {
1746
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1748
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1747
                  LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
1749
                  LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
1748
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1750
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1749
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1751
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1750
            }
1752
            }
1751
            if ((r = unshrink(__G)) != PK_COOL) {
1753
            if ((r = unshrink(__G)) != PK_COOL) {
1752
                if (r < PK_DISK) {
1754
                if (r < PK_DISK) {
1753
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1755
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1754
                        Info(slide, 0x401, ((char *)slide,
1756
                        Info(slide, 0x401, ((char *)slide,
1755
                          LoadFarStringSmall(ErrUnzipFile), r == PK_MEM3 ?
1757
                          LoadFarStringSmall(ErrUnzipFile), r == PK_MEM3 ?
1756
                          LoadFarString(NotEnoughMem) :
1758
                          LoadFarString(NotEnoughMem) :
1757
                          LoadFarString(InvalidComprData),
1759
                          LoadFarString(InvalidComprData),
1758
                          LoadFarStringSmall2(Unshrink),
1760
                          LoadFarStringSmall2(Unshrink),
1759
                          FnFilter1(G.filename)));
1761
                          FnFilter1(G.filename)));
1760
                    else
1762
                    else
1761
                        Info(slide, 0x401, ((char *)slide,
1763
                        Info(slide, 0x401, ((char *)slide,
1762
                          LoadFarStringSmall(ErrUnzipNoFile), r == PK_MEM3 ?
1764
                          LoadFarStringSmall(ErrUnzipNoFile), r == PK_MEM3 ?
1763
                          LoadFarString(NotEnoughMem) :
1765
                          LoadFarString(NotEnoughMem) :
1764
                          LoadFarString(InvalidComprData),
1766
                          LoadFarString(InvalidComprData),
1765
                          LoadFarStringSmall2(Unshrink)));
1767
                          LoadFarStringSmall2(Unshrink)));
1766
                }
1768
                }
1767
                error = r;
1769
                error = r;
1768
            }
1770
            }
1769
            break;
1771
            break;
1770
#endif /* !LZW_CLEAN */
1772
#endif /* !LZW_CLEAN */
1771
 
1773
 
1772
#ifndef COPYRIGHT_CLEAN
1774
#ifndef COPYRIGHT_CLEAN
1773
        case REDUCED1:
1775
        case REDUCED1:
1774
        case REDUCED2:
1776
        case REDUCED2:
1775
        case REDUCED3:
1777
        case REDUCED3:
1776
        case REDUCED4:
1778
        case REDUCED4:
1777
            if (!uO.tflag && QCOND2) {
1779
            if (!uO.tflag && QCOND2) {
1778
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1780
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1779
                  "unreduc", FnFilter1(G.filename),
1781
                  "unreduc", FnFilter1(G.filename),
1780
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1782
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1781
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1783
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1782
            }
1784
            }
1783
            if ((r = unreduce(__G)) != PK_COOL) {
1785
            if ((r = unreduce(__G)) != PK_COOL) {
1784
                /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
1786
                /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
1785
                error = r;
1787
                error = r;
1786
            }
1788
            }
1787
            break;
1789
            break;
1788
#endif /* !COPYRIGHT_CLEAN */
1790
#endif /* !COPYRIGHT_CLEAN */
1789
 
1791
 
1790
        case IMPLODED:
1792
        case IMPLODED:
1791
            if (!uO.tflag && QCOND2) {
1793
            if (!uO.tflag && QCOND2) {
1792
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1794
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1793
                  "explod", FnFilter1(G.filename),
1795
                  "explod", FnFilter1(G.filename),
1794
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1796
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1795
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1797
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1796
            }
1798
            }
1797
            if ((r = explode(__G)) != 0) {
1799
            if ((r = explode(__G)) != 0) {
1798
                if (r == 5) { /* treat 5 specially */
1800
                if (r == 5) { /* treat 5 specially */
1799
                    int warning = ((zusz_t)G.used_csize <= G.lrec.csize);
1801
                    int warning = ((zusz_t)G.used_csize <= G.lrec.csize);
1800
 
1802
 
1801
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1803
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1802
                        Info(slide, 0x401, ((char *)slide,
1804
                        Info(slide, 0x401, ((char *)slide,
1803
                          LoadFarString(LengthMsg),
1805
                          LoadFarString(LengthMsg),
1804
                          "", warning ? "warning" : "error",
1806
                          "", warning ? "warning" : "error",
1805
                          FmZofft(G.used_csize, NULL, NULL),
1807
                          FmZofft(G.used_csize, NULL, NULL),
1806
                          FmZofft(G.lrec.ucsize, NULL, "u"),
1808
                          FmZofft(G.lrec.ucsize, NULL, "u"),
1807
                          warning ? "  " : "",
1809
                          warning ? "  " : "",
1808
                          FmZofft(G.lrec.csize, NULL, "u"),
1810
                          FmZofft(G.lrec.csize, NULL, "u"),
1809
                          " [", FnFilter1(G.filename), "]"));
1811
                          " [", FnFilter1(G.filename), "]"));
1810
                    else
1812
                    else
1811
                        Info(slide, 0x401, ((char *)slide,
1813
                        Info(slide, 0x401, ((char *)slide,
1812
                          LoadFarString(LengthMsg),
1814
                          LoadFarString(LengthMsg),
1813
                          "\n", warning ? "warning" : "error",
1815
                          "\n", warning ? "warning" : "error",
1814
                          FmZofft(G.used_csize, NULL, NULL),
1816
                          FmZofft(G.used_csize, NULL, NULL),
1815
                          FmZofft(G.lrec.ucsize, NULL, "u"),
1817
                          FmZofft(G.lrec.ucsize, NULL, "u"),
1816
                          warning ? "  " : "",
1818
                          warning ? "  " : "",
1817
                          FmZofft(G.lrec.csize, NULL, "u"),
1819
                          FmZofft(G.lrec.csize, NULL, "u"),
1818
                          "", "", "."));
1820
                          "", "", "."));
1819
                    error = warning ? PK_WARN : PK_ERR;
1821
                    error = warning ? PK_WARN : PK_ERR;
1820
                } else if (r < PK_DISK) {
1822
                } else if (r < PK_DISK) {
1821
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1823
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1822
                        Info(slide, 0x401, ((char *)slide,
1824
                        Info(slide, 0x401, ((char *)slide,
1823
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1825
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1824
                          LoadFarString(NotEnoughMem) :
1826
                          LoadFarString(NotEnoughMem) :
1825
                          LoadFarString(InvalidComprData),
1827
                          LoadFarString(InvalidComprData),
1826
                          LoadFarStringSmall2(Explode),
1828
                          LoadFarStringSmall2(Explode),
1827
                          FnFilter1(G.filename)));
1829
                          FnFilter1(G.filename)));
1828
                    else
1830
                    else
1829
                        Info(slide, 0x401, ((char *)slide,
1831
                        Info(slide, 0x401, ((char *)slide,
1830
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1832
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1831
                          LoadFarString(NotEnoughMem) :
1833
                          LoadFarString(NotEnoughMem) :
1832
                          LoadFarString(InvalidComprData),
1834
                          LoadFarString(InvalidComprData),
1833
                          LoadFarStringSmall2(Explode)));
1835
                          LoadFarStringSmall2(Explode)));
1834
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1836
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1835
                } else {
1837
                } else {
1836
                    error = r;
1838
                    error = r;
1837
                }
1839
                }
1838
            }
1840
            }
1839
            break;
1841
            break;
1840
#endif /* !SFX */
1842
#endif /* !SFX */
1841
 
1843
 
1842
        case DEFLATED:
1844
        case DEFLATED:
1843
#ifdef USE_DEFLATE64
1845
#ifdef USE_DEFLATE64
1844
        case ENHDEFLATED:
1846
        case ENHDEFLATED:
1845
#endif
1847
#endif
1846
            if (!uO.tflag && QCOND2) {
1848
            if (!uO.tflag && QCOND2) {
1847
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1849
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1848
                  "inflat", FnFilter1(G.filename),
1850
                  "inflat", FnFilter1(G.filename),
1849
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1851
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1850
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1852
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1851
            }
1853
            }
1852
#ifndef USE_ZLIB  /* zlib's function is called inflate(), too */
1854
#ifndef USE_ZLIB  /* zlib's function is called inflate(), too */
1853
#  define UZinflate inflate
1855
#  define UZinflate inflate
1854
#endif
1856
#endif
1855
            if ((r = UZinflate(__G__
1857
            if ((r = UZinflate(__G__
1856
                               (G.lrec.compression_method == ENHDEFLATED)))
1858
                               (G.lrec.compression_method == ENHDEFLATED)))
1857
                != 0) {
1859
                != 0) {
1858
                if (r < PK_DISK) {
1860
                if (r < PK_DISK) {
1859
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1861
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1860
                        Info(slide, 0x401, ((char *)slide,
1862
                        Info(slide, 0x401, ((char *)slide,
1861
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1863
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1862
                          LoadFarString(NotEnoughMem) :
1864
                          LoadFarString(NotEnoughMem) :
1863
                          LoadFarString(InvalidComprData),
1865
                          LoadFarString(InvalidComprData),
1864
                          LoadFarStringSmall2(Inflate),
1866
                          LoadFarStringSmall2(Inflate),
1865
                          FnFilter1(G.filename)));
1867
                          FnFilter1(G.filename)));
1866
                    else
1868
                    else
1867
                        Info(slide, 0x401, ((char *)slide,
1869
                        Info(slide, 0x401, ((char *)slide,
1868
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1870
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1869
                          LoadFarString(NotEnoughMem) :
1871
                          LoadFarString(NotEnoughMem) :
1870
                          LoadFarString(InvalidComprData),
1872
                          LoadFarString(InvalidComprData),
1871
                          LoadFarStringSmall2(Inflate)));
1873
                          LoadFarStringSmall2(Inflate)));
1872
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1874
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1873
                } else {
1875
                } else {
1874
                    error = r;
1876
                    error = r;
1875
                }
1877
                }
1876
            }
1878
            }
1877
            break;
1879
            break;
1878
 
1880
 
1879
#ifdef USE_BZIP2
1881
#ifdef USE_BZIP2
1880
        case BZIPPED:
1882
        case BZIPPED:
1881
            if (!uO.tflag && QCOND2) {
1883
            if (!uO.tflag && QCOND2) {
1882
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1884
                Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
1883
                  "bunzipp", FnFilter1(G.filename),
1885
                  "bunzipp", FnFilter1(G.filename),
1884
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1886
                  (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
1885
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1887
                  "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
1886
            }
1888
            }
1887
            if ((r = UZbunzip2(__G)) != 0) {
1889
            if ((r = UZbunzip2(__G)) != 0) {
1888
                if (r < PK_DISK) {
1890
                if (r < PK_DISK) {
1889
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1891
                    if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1890
                        Info(slide, 0x401, ((char *)slide,
1892
                        Info(slide, 0x401, ((char *)slide,
1891
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1893
                          LoadFarStringSmall(ErrUnzipFile), r == 3?
1892
                          LoadFarString(NotEnoughMem) :
1894
                          LoadFarString(NotEnoughMem) :
1893
                          LoadFarString(InvalidComprData),
1895
                          LoadFarString(InvalidComprData),
1894
                          LoadFarStringSmall2(BUnzip),
1896
                          LoadFarStringSmall2(BUnzip),
1895
                          FnFilter1(G.filename)));
1897
                          FnFilter1(G.filename)));
1896
                    else
1898
                    else
1897
                        Info(slide, 0x401, ((char *)slide,
1899
                        Info(slide, 0x401, ((char *)slide,
1898
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1900
                          LoadFarStringSmall(ErrUnzipNoFile), r == 3?
1899
                          LoadFarString(NotEnoughMem) :
1901
                          LoadFarString(NotEnoughMem) :
1900
                          LoadFarString(InvalidComprData),
1902
                          LoadFarString(InvalidComprData),
1901
                          LoadFarStringSmall2(BUnzip)));
1903
                          LoadFarStringSmall2(BUnzip)));
1902
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1904
                    error = ((r == 3) ? PK_MEM3 : PK_ERR);
1903
                } else {
1905
                } else {
1904
                    error = r;
1906
                    error = r;
1905
                }
1907
                }
1906
            }
1908
            }
1907
            break;
1909
            break;
1908
#endif /* USE_BZIP2 */
1910
#endif /* USE_BZIP2 */
1909
 
1911
 
1910
        default:   /* should never get to this point */
1912
        default:   /* should never get to this point */
1911
            Info(slide, 0x401, ((char *)slide,
1913
            Info(slide, 0x401, ((char *)slide,
1912
              LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
1914
              LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
1913
            /* close and delete file before return? */
1915
            /* close and delete file before return? */
1914
            undefer_input(__G);
1916
            undefer_input(__G);
1915
            return PK_WARN;
1917
            return PK_WARN;
1916
 
1918
 
1917
    } /* end switch (compression method) */
1919
    } /* end switch (compression method) */
1918
 
1920
 
1919
/*---------------------------------------------------------------------------
1921
/*---------------------------------------------------------------------------
1920
    Close the file and set its date and time (not necessarily in that order),
1922
    Close the file and set its date and time (not necessarily in that order),
1921
    and make sure the CRC checked out OK.  Logical-AND the CRC for 64-bit
1923
    and make sure the CRC checked out OK.  Logical-AND the CRC for 64-bit
1922
    machines (redundant on 32-bit machines).
1924
    machines (redundant on 32-bit machines).
1923
  ---------------------------------------------------------------------------*/
1925
  ---------------------------------------------------------------------------*/
1924
 
1926
 
1925
#ifdef VMS                  /* VMS:  required even for stdout! (final flush) */
1927
#ifdef VMS                  /* VMS:  required even for stdout! (final flush) */
1926
    if (!uO.tflag)           /* don't close NULL file */
1928
    if (!uO.tflag)           /* don't close NULL file */
1927
        close_outfile(__G);
1929
        close_outfile(__G);
1928
#else
1930
#else
1929
#ifdef DLL
1931
#ifdef DLL
1930
    if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
1932
    if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
1931
        if (G.redirect_data)
1933
        if (G.redirect_data)
1932
            FINISH_REDIRECT();
1934
            FINISH_REDIRECT();
1933
        else
1935
        else
1934
            close_outfile(__G);
1936
            close_outfile(__G);
1935
    }
1937
    }
1936
#else
1938
#else
1937
    if (!uO.tflag && !uO.cflag)   /* don't close NULL file or stdout */
1939
    if (!uO.tflag && !uO.cflag)   /* don't close NULL file or stdout */
1938
        close_outfile(__G);
1940
        close_outfile(__G);
1939
#endif
1941
#endif
1940
#endif /* VMS */
1942
#endif /* VMS */
1941
 
1943
 
1942
            /* GRR: CONVERT close_outfile() TO NON-VOID:  CHECK FOR ERRORS! */
1944
            /* GRR: CONVERT close_outfile() TO NON-VOID:  CHECK FOR ERRORS! */
1943
 
1945
 
1944
 
1946
 
1945
    if (G.disk_full) {            /* set by flush() */
1947
    if (G.disk_full) {            /* set by flush() */
1946
        if (G.disk_full > 1) {
1948
        if (G.disk_full > 1) {
1947
#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
1949
#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
1948
            /* delete the incomplete file if we can */
1950
            /* delete the incomplete file if we can */
1949
            if (unlink(G.filename) != 0)
1951
            if (unlink(G.filename) != 0)
1950
                Trace((stderr, "extract.c:  could not delete %s\n",
1952
                Trace((stderr, "extract.c:  could not delete %s\n",
1951
                  FnFilter1(G.filename)));
1953
                  FnFilter1(G.filename)));
1952
#else
1954
#else
1953
            /* warn user about the incomplete file */
1955
            /* warn user about the incomplete file */
1954
            Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
1956
            Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
1955
              FnFilter1(G.filename)));
1957
              FnFilter1(G.filename)));
1956
#endif
1958
#endif
1957
            error = PK_DISK;
1959
            error = PK_DISK;
1958
        } else {
1960
        } else {
1959
            error = PK_WARN;
1961
            error = PK_WARN;
1960
        }
1962
        }
1961
    }
1963
    }
1962
 
1964
 
1963
    if (error > PK_WARN) {/* don't print redundant CRC error if error already */
1965
    if (error > PK_WARN) {/* don't print redundant CRC error if error already */
1964
        undefer_input(__G);
1966
        undefer_input(__G);
1965
        return error;
1967
        return error;
1966
    }
1968
    }
1967
    if (G.crc32val != G.lrec.crc32) {
1969
    if (G.crc32val != G.lrec.crc32) {
1968
        /* if quiet enough, we haven't output the filename yet:  do it */
1970
        /* if quiet enough, we haven't output the filename yet:  do it */
1969
        if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1971
        if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
1970
            Info(slide, 0x401, ((char *)slide, "%-22s ",
1972
            Info(slide, 0x401, ((char *)slide, "%-22s ",
1971
              FnFilter1(G.filename)));
1973
              FnFilter1(G.filename)));
1972
        Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
1974
        Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
1973
          G.lrec.crc32));
1975
          G.lrec.crc32));
1974
#if CRYPT
1976
#if CRYPT
1975
        if (G.pInfo->encrypted)
1977
        if (G.pInfo->encrypted)
1976
            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
1978
            Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
1977
#endif
1979
#endif
1978
        error = PK_ERR;
1980
        error = PK_ERR;
1979
    } else if (uO.tflag) {
1981
    } else if (uO.tflag) {
1980
#ifndef SFX
1982
#ifndef SFX
1981
        if (G.extra_field) {
1983
        if (G.extra_field) {
1982
            if ((r = TestExtraField(__G__ G.extra_field,
1984
            if ((r = TestExtraField(__G__ G.extra_field,
1983
                                    G.lrec.extra_field_length)) > error)
1985
                                    G.lrec.extra_field_length)) > error)
1984
                error = r;
1986
                error = r;
1985
        } else
1987
        } else
1986
#endif /* !SFX */
1988
#endif /* !SFX */
1987
        if (!uO.qflag)
1989
        if (!uO.qflag)
1988
            Info(slide, 0, ((char *)slide, " OK\n"));
1990
            Info(slide, 0, ((char *)slide, " OK\n"));
1989
    } else {
1991
    } else {
1990
        if (QCOND2 && !error)   /* GRR:  is stdout reset to text mode yet? */
1992
        if (QCOND2 && !error)   /* GRR:  is stdout reset to text mode yet? */
1991
            Info(slide, 0, ((char *)slide, "\n"));
1993
            Info(slide, 0, ((char *)slide, "\n"));
1992
    }
1994
    }
1993
 
1995
 
1994
    undefer_input(__G);
1996
    undefer_input(__G);
1995
    return error;
1997
    return error;
1996
 
1998
 
1997
} /* end function extract_or_test_member() */
1999
} /* end function extract_or_test_member() */
1998
 
2000
 
1999
 
2001
 
2000
 
2002
 
2001
 
2003
 
2002
 
2004
 
2003
#ifndef SFX
2005
#ifndef SFX
2004
 
2006
 
2005
/*******************************/
2007
/*******************************/
2006
/*  Function TestExtraField()  */
2008
/*  Function TestExtraField()  */
2007
/*******************************/
2009
/*******************************/
2008
 
2010
 
2009
static int TestExtraField(__G__ ef, ef_len)
2011
static int TestExtraField(__G__ ef, ef_len)
2010
    __GDEF
2012
    __GDEF
2011
    uch *ef;
2013
    uch *ef;
2012
    unsigned ef_len;
2014
    unsigned ef_len;
2013
{
2015
{
2014
    ush ebID;
2016
    ush ebID;
2015
    unsigned ebLen;
2017
    unsigned ebLen;
2016
    unsigned eb_cmpr_offs = 0;
2018
    unsigned eb_cmpr_offs = 0;
2017
    int r;
2019
    int r;
2018
 
2020
 
2019
    /* we know the regular compressed file data tested out OK, or else we
2021
    /* we know the regular compressed file data tested out OK, or else we
2020
     * wouldn't be here ==> print filename if any extra-field errors found
2022
     * wouldn't be here ==> print filename if any extra-field errors found
2021
     */
2023
     */
2022
    while (ef_len >= EB_HEADSIZE) {
2024
    while (ef_len >= EB_HEADSIZE) {
2023
        ebID = makeword(ef);
2025
        ebID = makeword(ef);
2024
        ebLen = (unsigned)makeword(ef+EB_LEN);
2026
        ebLen = (unsigned)makeword(ef+EB_LEN);
2025
 
2027
 
2026
        if (ebLen > (ef_len - EB_HEADSIZE)) {
2028
        if (ebLen > (ef_len - EB_HEADSIZE)) {
2027
           /* Discovered some extra field inconsistency! */
2029
           /* Discovered some extra field inconsistency! */
2028
            if (uO.qflag)
2030
            if (uO.qflag)
2029
                Info(slide, 1, ((char *)slide, "%-22s ",
2031
                Info(slide, 1, ((char *)slide, "%-22s ",
2030
                  FnFilter1(G.filename)));
2032
                  FnFilter1(G.filename)));
2031
            Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
2033
            Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
2032
              ebLen, (ef_len - EB_HEADSIZE)));
2034
              ebLen, (ef_len - EB_HEADSIZE)));
2033
            return PK_ERR;
2035
            return PK_ERR;
2034
        }
2036
        }
2035
 
2037
 
2036
        switch (ebID) {
2038
        switch (ebID) {
2037
            case EF_OS2:
2039
            case EF_OS2:
2038
            case EF_ACL:
2040
            case EF_ACL:
2039
            case EF_MAC3:
2041
            case EF_MAC3:
2040
            case EF_BEOS:
2042
            case EF_BEOS:
2041
            case EF_ATHEOS:
2043
            case EF_ATHEOS:
2042
                switch (ebID) {
2044
                switch (ebID) {
2043
                  case EF_OS2:
2045
                  case EF_OS2:
2044
                  case EF_ACL:
2046
                  case EF_ACL:
2045
                    eb_cmpr_offs = EB_OS2_HLEN;
2047
                    eb_cmpr_offs = EB_OS2_HLEN;
2046
                    break;
2048
                    break;
2047
                  case EF_MAC3:
2049
                  case EF_MAC3:
2048
                    if (ebLen >= EB_MAC3_HLEN &&
2050
                    if (ebLen >= EB_MAC3_HLEN &&
2049
                        (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
2051
                        (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
2050
                         & EB_M3_FL_UNCMPR) &&
2052
                         & EB_M3_FL_UNCMPR) &&
2051
                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
2053
                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
2052
                        eb_cmpr_offs = 0;
2054
                        eb_cmpr_offs = 0;
2053
                    else
2055
                    else
2054
                        eb_cmpr_offs = EB_MAC3_HLEN;
2056
                        eb_cmpr_offs = EB_MAC3_HLEN;
2055
                    break;
2057
                    break;
2056
                  case EF_BEOS:
2058
                  case EF_BEOS:
2057
                  case EF_ATHEOS:
2059
                  case EF_ATHEOS:
2058
                    if (ebLen >= EB_BEOS_HLEN &&
2060
                    if (ebLen >= EB_BEOS_HLEN &&
2059
                        (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
2061
                        (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
2060
                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
2062
                        (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
2061
                        eb_cmpr_offs = 0;
2063
                        eb_cmpr_offs = 0;
2062
                    else
2064
                    else
2063
                        eb_cmpr_offs = EB_BEOS_HLEN;
2065
                        eb_cmpr_offs = EB_BEOS_HLEN;
2064
                    break;
2066
                    break;
2065
                }
2067
                }
2066
                if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
2068
                if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
2067
                    != PK_OK) {
2069
                    != PK_OK) {
2068
                    if (uO.qflag)
2070
                    if (uO.qflag)
2069
                        Info(slide, 1, ((char *)slide, "%-22s ",
2071
                        Info(slide, 1, ((char *)slide, "%-22s ",
2070
                          FnFilter1(G.filename)));
2072
                          FnFilter1(G.filename)));
2071
                    switch (r) {
2073
                    switch (r) {
2072
                        case IZ_EF_TRUNC:
2074
                        case IZ_EF_TRUNC:
2073
                            Info(slide, 1, ((char *)slide,
2075
                            Info(slide, 1, ((char *)slide,
2074
                              LoadFarString(TruncEAs),
2076
                              LoadFarString(TruncEAs),
2075
                              ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
2077
                              ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
2076
                            break;
2078
                            break;
2077
                        case PK_ERR:
2079
                        case PK_ERR:
2078
                            Info(slide, 1, ((char *)slide,
2080
                            Info(slide, 1, ((char *)slide,
2079
                              LoadFarString(InvalidComprDataEAs)));
2081
                              LoadFarString(InvalidComprDataEAs)));
2080
                            break;
2082
                            break;
2081
                        case PK_MEM3:
2083
                        case PK_MEM3:
2082
                        case PK_MEM4:
2084
                        case PK_MEM4:
2083
                            Info(slide, 1, ((char *)slide,
2085
                            Info(slide, 1, ((char *)slide,
2084
                              LoadFarString(NotEnoughMemEAs)));
2086
                              LoadFarString(NotEnoughMemEAs)));
2085
                            break;
2087
                            break;
2086
                        default:
2088
                        default:
2087
                            if ((r & 0xff) != PK_ERR)
2089
                            if ((r & 0xff) != PK_ERR)
2088
                                Info(slide, 1, ((char *)slide,
2090
                                Info(slide, 1, ((char *)slide,
2089
                                  LoadFarString(UnknErrorEAs)));
2091
                                  LoadFarString(UnknErrorEAs)));
2090
                            else {
2092
                            else {
2091
                                ush m = (ush)(r >> 8);
2093
                                ush m = (ush)(r >> 8);
2092
                                if (m == DEFLATED)            /* GRR KLUDGE! */
2094
                                if (m == DEFLATED)            /* GRR KLUDGE! */
2093
                                    Info(slide, 1, ((char *)slide,
2095
                                    Info(slide, 1, ((char *)slide,
2094
                                      LoadFarString(BadCRC_EAs)));
2096
                                      LoadFarString(BadCRC_EAs)));
2095
                                else
2097
                                else
2096
                                    Info(slide, 1, ((char *)slide,
2098
                                    Info(slide, 1, ((char *)slide,
2097
                                      LoadFarString(UnknComprMethodEAs), m));
2099
                                      LoadFarString(UnknComprMethodEAs), m));
2098
                            }
2100
                            }
2099
                            break;
2101
                            break;
2100
                    }
2102
                    }
2101
                    return r;
2103
                    return r;
2102
                }
2104
                }
2103
                break;
2105
                break;
2104
 
2106
 
2105
            case EF_NTSD:
2107
            case EF_NTSD:
2106
                Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
2108
                Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
2107
                r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
2109
                r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
2108
                    ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
2110
                    ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
2109
                     (PK_WARN | 0x4000) :
2111
                     (PK_WARN | 0x4000) :
2110
                     test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
2112
                     test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
2111
                if (r != PK_OK) {
2113
                if (r != PK_OK) {
2112
                    if (uO.qflag)
2114
                    if (uO.qflag)
2113
                        Info(slide, 1, ((char *)slide, "%-22s ",
2115
                        Info(slide, 1, ((char *)slide, "%-22s ",
2114
                          FnFilter1(G.filename)));
2116
                          FnFilter1(G.filename)));
2115
                    switch (r) {
2117
                    switch (r) {
2116
                        case IZ_EF_TRUNC:
2118
                        case IZ_EF_TRUNC:
2117
                            Info(slide, 1, ((char *)slide,
2119
                            Info(slide, 1, ((char *)slide,
2118
                              LoadFarString(TruncNTSD),
2120
                              LoadFarString(TruncNTSD),
2119
                              ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
2121
                              ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
2120
                            break;
2122
                            break;
2121
#if (defined(WIN32) && defined(NTSD_EAS))
2123
#if (defined(WIN32) && defined(NTSD_EAS))
2122
                        case PK_WARN:
2124
                        case PK_WARN:
2123
                            Info(slide, 1, ((char *)slide,
2125
                            Info(slide, 1, ((char *)slide,
2124
                              LoadFarString(InvalidSecurityEAs)));
2126
                              LoadFarString(InvalidSecurityEAs)));
2125
                            break;
2127
                            break;
2126
#endif
2128
#endif
2127
                        case PK_ERR:
2129
                        case PK_ERR:
2128
                            Info(slide, 1, ((char *)slide,
2130
                            Info(slide, 1, ((char *)slide,
2129
                              LoadFarString(InvalidComprDataEAs)));
2131
                              LoadFarString(InvalidComprDataEAs)));
2130
                            break;
2132
                            break;
2131
                        case PK_MEM3:
2133
                        case PK_MEM3:
2132
                        case PK_MEM4:
2134
                        case PK_MEM4:
2133
                            Info(slide, 1, ((char *)slide,
2135
                            Info(slide, 1, ((char *)slide,
2134
                              LoadFarString(NotEnoughMemEAs)));
2136
                              LoadFarString(NotEnoughMemEAs)));
2135
                            break;
2137
                            break;
2136
                        case (PK_WARN | 0x4000):
2138
                        case (PK_WARN | 0x4000):
2137
                            Info(slide, 1, ((char *)slide,
2139
                            Info(slide, 1, ((char *)slide,
2138
                              LoadFarString(UnsuppNTSDVersEAs),
2140
                              LoadFarString(UnsuppNTSDVersEAs),
2139
                              (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
2141
                              (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
2140
                            r = PK_WARN;
2142
                            r = PK_WARN;
2141
                            break;
2143
                            break;
2142
                        default:
2144
                        default:
2143
                            if ((r & 0xff) != PK_ERR)
2145
                            if ((r & 0xff) != PK_ERR)
2144
                                Info(slide, 1, ((char *)slide,
2146
                                Info(slide, 1, ((char *)slide,
2145
                                  LoadFarString(UnknErrorEAs)));
2147
                                  LoadFarString(UnknErrorEAs)));
2146
                            else {
2148
                            else {
2147
                                ush m = (ush)(r >> 8);
2149
                                ush m = (ush)(r >> 8);
2148
                                if (m == DEFLATED)            /* GRR KLUDGE! */
2150
                                if (m == DEFLATED)            /* GRR KLUDGE! */
2149
                                    Info(slide, 1, ((char *)slide,
2151
                                    Info(slide, 1, ((char *)slide,
2150
                                      LoadFarString(BadCRC_EAs)));
2152
                                      LoadFarString(BadCRC_EAs)));
2151
                                else
2153
                                else
2152
                                    Info(slide, 1, ((char *)slide,
2154
                                    Info(slide, 1, ((char *)slide,
2153
                                      LoadFarString(UnknComprMethodEAs), m));
2155
                                      LoadFarString(UnknComprMethodEAs), m));
2154
                            }
2156
                            }
2155
                            break;
2157
                            break;
2156
                    }
2158
                    }
2157
                    return r;
2159
                    return r;
2158
                }
2160
                }
2159
                break;
2161
                break;
2160
            case EF_PKVMS:
2162
            case EF_PKVMS:
2161
                if (makelong(ef+EB_HEADSIZE) !=
2163
                if (makelong(ef+EB_HEADSIZE) !=
2162
                    crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
2164
                    crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
2163
                          (extent)(ebLen-4)))
2165
                          (extent)(ebLen-4)))
2164
                    Info(slide, 1, ((char *)slide,
2166
                    Info(slide, 1, ((char *)slide,
2165
                      LoadFarString(BadCRC_EAs)));
2167
                      LoadFarString(BadCRC_EAs)));
2166
                break;
2168
                break;
2167
            case EF_PKW32:
2169
            case EF_PKW32:
2168
            case EF_PKUNIX:
2170
            case EF_PKUNIX:
2169
            case EF_ASIUNIX:
2171
            case EF_ASIUNIX:
2170
            case EF_IZVMS:
2172
            case EF_IZVMS:
2171
            case EF_IZUNIX:
2173
            case EF_IZUNIX:
2172
            case EF_VMCMS:
2174
            case EF_VMCMS:
2173
            case EF_MVS:
2175
            case EF_MVS:
2174
            case EF_SPARK:
2176
            case EF_SPARK:
2175
            case EF_TANDEM:
2177
            case EF_TANDEM:
2176
            case EF_THEOS:
2178
            case EF_THEOS:
2177
            case EF_AV:
2179
            case EF_AV:
2178
            default:
2180
            default:
2179
                break;
2181
                break;
2180
        }
2182
        }
2181
        ef_len -= (ebLen + EB_HEADSIZE);
2183
        ef_len -= (ebLen + EB_HEADSIZE);
2182
        ef += (ebLen + EB_HEADSIZE);
2184
        ef += (ebLen + EB_HEADSIZE);
2183
    }
2185
    }
2184
 
2186
 
2185
    if (!uO.qflag)
2187
    if (!uO.qflag)
2186
        Info(slide, 0, ((char *)slide, " OK\n"));
2188
        Info(slide, 0, ((char *)slide, " OK\n"));
2187
 
2189
 
2188
    return PK_COOL;
2190
    return PK_COOL;
2189
 
2191
 
2190
} /* end function TestExtraField() */
2192
} /* end function TestExtraField() */
2191
 
2193
 
2192
 
2194
 
2193
 
2195
 
2194
 
2196
 
2195
 
2197
 
2196
/******************************/
2198
/******************************/
2197
/*  Function test_compr_eb()  */
2199
/*  Function test_compr_eb()  */
2198
/******************************/
2200
/******************************/
2199
 
2201
 
2200
#ifdef PROTO
2202
#ifdef PROTO
2201
static int test_compr_eb(
2203
static int test_compr_eb(
2202
    __GPRO__
2204
    __GPRO__
2203
    uch *eb,
2205
    uch *eb,
2204
    unsigned eb_size,
2206
    unsigned eb_size,
2205
    unsigned compr_offset,
2207
    unsigned compr_offset,
2206
    int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
2208
    int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
2207
                          uch *eb_ucptr, ulg eb_ucsize))
2209
                          uch *eb_ucptr, ulg eb_ucsize))
2208
#else /* !PROTO */
2210
#else /* !PROTO */
2209
static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
2211
static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
2210
    __GDEF
2212
    __GDEF
2211
    uch *eb;
2213
    uch *eb;
2212
    unsigned eb_size;
2214
    unsigned eb_size;
2213
    unsigned compr_offset;
2215
    unsigned compr_offset;
2214
    int (*test_uc_ebdata)();
2216
    int (*test_uc_ebdata)();
2215
#endif /* ?PROTO */
2217
#endif /* ?PROTO */
2216
{
2218
{
2217
    ulg eb_ucsize;
2219
    ulg eb_ucsize;
2218
    uch *eb_ucptr;
2220
    uch *eb_ucptr;
2219
    int r;
2221
    int r;
2220
 
2222
 
2221
    if (compr_offset < 4)                /* field is not compressed: */
2223
    if (compr_offset < 4)                /* field is not compressed: */
2222
        return PK_OK;                    /* do nothing and signal OK */
2224
        return PK_OK;                    /* do nothing and signal OK */
2223
 
2225
 
2224
    if ((eb_size < (EB_UCSIZE_P + 4)) ||
2226
    if ((eb_size < (EB_UCSIZE_P + 4)) ||
2225
        ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
2227
        ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
2226
         eb_size <= (compr_offset + EB_CMPRHEADLEN)))
2228
         eb_size <= (compr_offset + EB_CMPRHEADLEN)))
2227
        return IZ_EF_TRUNC;               /* no compressed data! */
2229
        return IZ_EF_TRUNC;               /* no compressed data! */
2228
 
2230
 
2229
    if (
2231
    if (
2230
#ifdef INT_16BIT
2232
#ifdef INT_16BIT
2231
        (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
2233
        (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
2232
#endif
2234
#endif
2233
        (eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
2235
        (eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
2234
        return PK_MEM4;
2236
        return PK_MEM4;
2235
 
2237
 
2236
    r = memextract(__G__ eb_ucptr, eb_ucsize,
2238
    r = memextract(__G__ eb_ucptr, eb_ucsize,
2237
                   eb + (EB_HEADSIZE + compr_offset),
2239
                   eb + (EB_HEADSIZE + compr_offset),
2238
                   (ulg)(eb_size - compr_offset));
2240
                   (ulg)(eb_size - compr_offset));
2239
 
2241
 
2240
    if (r == PK_OK && test_uc_ebdata != NULL)
2242
    if (r == PK_OK && test_uc_ebdata != NULL)
2241
        r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
2243
        r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
2242
 
2244
 
2243
    free(eb_ucptr);
2245
    free(eb_ucptr);
2244
    return r;
2246
    return r;
2245
 
2247
 
2246
} /* end function test_compr_eb() */
2248
} /* end function test_compr_eb() */
2247
 
2249
 
2248
#endif /* !SFX */
2250
#endif /* !SFX */
2249
 
2251
 
2250
 
2252
 
2251
 
2253
 
2252
 
2254
 
2253
 
2255
 
2254
/***************************/
2256
/***************************/
2255
/*  Function memextract()  */
2257
/*  Function memextract()  */
2256
/***************************/
2258
/***************************/
2257
 
2259
 
2258
int memextract(__G__ tgt, tgtsize, src, srcsize)  /* extract compressed */
2260
int memextract(__G__ tgt, tgtsize, src, srcsize)  /* extract compressed */
2259
    __GDEF                                        /*  extra field block; */
2261
    __GDEF                                        /*  extra field block; */
2260
    uch *tgt;                                     /*  return PK-type error */
2262
    uch *tgt;                                     /*  return PK-type error */
2261
    ulg tgtsize;                                  /*  level */
2263
    ulg tgtsize;                                  /*  level */
2262
    ZCONST uch *src;
2264
    ZCONST uch *src;
2263
    ulg srcsize;
2265
    ulg srcsize;
2264
{
2266
{
2265
    zoff_t old_csize=G.csize;
2267
    zoff_t old_csize=G.csize;
2266
    uch   *old_inptr=G.inptr;
2268
    uch   *old_inptr=G.inptr;
2267
    int    old_incnt=G.incnt;
2269
    int    old_incnt=G.incnt;
2268
    int    r, error=PK_OK;
2270
    int    r, error=PK_OK;
2269
    ush    method;
2271
    ush    method;
2270
    ulg    extra_field_crc;
2272
    ulg    extra_field_crc;
2271
 
2273
 
2272
 
2274
 
2273
    method = makeword(src);
2275
    method = makeword(src);
2274
    extra_field_crc = makelong(src+2);
2276
    extra_field_crc = makelong(src+2);
2275
 
2277
 
2276
    /* compressed extra field exists completely in memory at this location: */
2278
    /* compressed extra field exists completely in memory at this location: */
2277
    G.inptr = (uch *)src + (2 + 4);     /* method and extra_field_crc */
2279
    G.inptr = (uch *)src + (2 + 4);     /* method and extra_field_crc */
2278
    G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
2280
    G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
2279
    G.mem_mode = TRUE;
2281
    G.mem_mode = TRUE;
2280
    G.outbufptr = tgt;
2282
    G.outbufptr = tgt;
2281
    G.outsize = tgtsize;
2283
    G.outsize = tgtsize;
2282
 
2284
 
2283
    switch (method) {
2285
    switch (method) {
2284
        case STORED:
2286
        case STORED:
2285
            memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
2287
            memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
2286
            G.outcnt = (ulg)G.csize;    /* for CRC calculation */
2288
            G.outcnt = (ulg)G.csize;    /* for CRC calculation */
2287
            break;
2289
            break;
2288
        case DEFLATED:
2290
        case DEFLATED:
2289
#ifdef USE_DEFLATE64
2291
#ifdef USE_DEFLATE64
2290
        case ENHDEFLATED:
2292
        case ENHDEFLATED:
2291
#endif
2293
#endif
2292
            G.outcnt = 0L;
2294
            G.outcnt = 0L;
2293
            if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
2295
            if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
2294
                if (!uO.tflag)
2296
                if (!uO.tflag)
2295
                    Info(slide, 0x401, ((char *)slide,
2297
                    Info(slide, 0x401, ((char *)slide,
2296
                      LoadFarStringSmall(ErrUnzipNoFile), r == 3?
2298
                      LoadFarStringSmall(ErrUnzipNoFile), r == 3?
2297
                      LoadFarString(NotEnoughMem) :
2299
                      LoadFarString(NotEnoughMem) :
2298
                      LoadFarString(InvalidComprData),
2300
                      LoadFarString(InvalidComprData),
2299
                      LoadFarStringSmall2(Inflate)));
2301
                      LoadFarStringSmall2(Inflate)));
2300
                error = (r == 3)? PK_MEM3 : PK_ERR;
2302
                error = (r == 3)? PK_MEM3 : PK_ERR;
2301
            }
2303
            }
2302
            if (G.outcnt == 0L)   /* inflate's final FLUSH sets outcnt */
2304
            if (G.outcnt == 0L)   /* inflate's final FLUSH sets outcnt */
2303
                break;
2305
                break;
2304
            break;
2306
            break;
2305
        default:
2307
        default:
2306
            if (uO.tflag)
2308
            if (uO.tflag)
2307
                error = PK_ERR | ((int)method << 8);
2309
                error = PK_ERR | ((int)method << 8);
2308
            else {
2310
            else {
2309
                Info(slide, 0x401, ((char *)slide,
2311
                Info(slide, 0x401, ((char *)slide,
2310
                  LoadFarString(UnsupportedExtraField), method));
2312
                  LoadFarString(UnsupportedExtraField), method));
2311
                error = PK_ERR;  /* GRR:  should be passed on up via SetEAs() */
2313
                error = PK_ERR;  /* GRR:  should be passed on up via SetEAs() */
2312
            }
2314
            }
2313
            break;
2315
            break;
2314
    }
2316
    }
2315
 
2317
 
2316
    G.inptr = old_inptr;
2318
    G.inptr = old_inptr;
2317
    G.incnt = old_incnt;
2319
    G.incnt = old_incnt;
2318
    G.csize = old_csize;
2320
    G.csize = old_csize;
2319
    G.mem_mode = FALSE;
2321
    G.mem_mode = FALSE;
2320
 
2322
 
2321
    if (!error) {
2323
    if (!error) {
2322
        register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
2324
        register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
2323
 
2325
 
2324
        if (crcval != extra_field_crc) {
2326
        if (crcval != extra_field_crc) {
2325
            if (uO.tflag)
2327
            if (uO.tflag)
2326
                error = PK_ERR | (DEFLATED << 8);  /* kludge for now */
2328
                error = PK_ERR | (DEFLATED << 8);  /* kludge for now */
2327
            else {
2329
            else {
2328
                Info(slide, 0x401, ((char *)slide,
2330
                Info(slide, 0x401, ((char *)slide,
2329
                  LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
2331
                  LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
2330
                  extra_field_crc));
2332
                  extra_field_crc));
2331
                error = PK_ERR;
2333
                error = PK_ERR;
2332
            }
2334
            }
2333
        }
2335
        }
2334
    }
2336
    }
2335
    return error;
2337
    return error;
2336
 
2338
 
2337
} /* end function memextract() */
2339
} /* end function memextract() */
2338
 
2340
 
2339
 
2341
 
2340
 
2342
 
2341
 
2343
 
2342
 
2344
 
2343
/*************************/
2345
/*************************/
2344
/*  Function memflush()  */
2346
/*  Function memflush()  */
2345
/*************************/
2347
/*************************/
2346
 
2348
 
2347
int memflush(__G__ rawbuf, size)
2349
int memflush(__G__ rawbuf, size)
2348
    __GDEF
2350
    __GDEF
2349
    ZCONST uch *rawbuf;
2351
    ZCONST uch *rawbuf;
2350
    ulg size;
2352
    ulg size;
2351
{
2353
{
2352
    if (size > G.outsize)
2354
    if (size > G.outsize)
2353
        /* Here, PK_DISK is a bit off-topic, but in the sense of marking
2355
        /* Here, PK_DISK is a bit off-topic, but in the sense of marking
2354
           "overflow of output space", its use may be tolerated. */
2356
           "overflow of output space", its use may be tolerated. */
2355
        return PK_DISK;   /* more data than output buffer can hold */
2357
        return PK_DISK;   /* more data than output buffer can hold */
2356
 
2358
 
2357
 
2359
 
2358
 
2360
 
2359
    memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
2361
    memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
2360
    G.outbufptr += (unsigned int)size;
2362
    G.outbufptr += (unsigned int)size;
2361
    G.outsize -= size;
2363
    G.outsize -= size;
2362
    G.outcnt += size;
2364
    G.outcnt += size;
2363
 
2365
 
2364
    return 0;
2366
    return 0;
2365
 
2367
 
2366
} /* end function memflush() */
2368
} /* end function memflush() */
2367
 
2369
 
2368
 
2370
 
2369
 
2371
 
2370
 
2372
 
2371
 
2373
 
2372
#if (defined(VMS) || defined(VMS_TEXT_CONV))
2374
#if (defined(VMS) || defined(VMS_TEXT_CONV))
2373
 
2375
 
2374
/************************************/
2376
/************************************/
2375
/*  Function extract_izvms_block()  */
2377
/*  Function extract_izvms_block()  */
2376
/************************************/
2378
/************************************/
2377
 
2379
 
2378
/*
2380
/*
2379
 * Extracts block from p. If resulting length is less than needed, fill
2381
 * Extracts block from p. If resulting length is less than needed, fill
2380
 * extra space with corresponding bytes from 'init'.
2382
 * extra space with corresponding bytes from 'init'.
2381
 * Currently understands 3 formats of block compression:
2383
 * Currently understands 3 formats of block compression:
2382
 * - Simple storing
2384
 * - Simple storing
2383
 * - Compression of zero bytes to zero bits
2385
 * - Compression of zero bytes to zero bits
2384
 * - Deflation (see memextract())
2386
 * - Deflation (see memextract())
2385
 * The IZVMS block data is returned in malloc'd space.
2387
 * The IZVMS block data is returned in malloc'd space.
2386
 */
2388
 */
2387
uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
2389
uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
2388
    __GDEF
2390
    __GDEF
2389
    ZCONST uch *ebdata;
2391
    ZCONST uch *ebdata;
2390
    unsigned size;
2392
    unsigned size;
2391
    unsigned *retlen;
2393
    unsigned *retlen;
2392
    ZCONST uch *init;
2394
    ZCONST uch *init;
2393
    unsigned needlen;
2395
    unsigned needlen;
2394
{
2396
{
2395
    uch *ucdata;       /* Pointer to block allocated */
2397
    uch *ucdata;       /* Pointer to block allocated */
2396
    int cmptype;
2398
    int cmptype;
2397
    unsigned usiz, csiz;
2399
    unsigned usiz, csiz;
2398
 
2400
 
2399
    cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
2401
    cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
2400
    csiz = size - EB_IZVMS_HLEN;
2402
    csiz = size - EB_IZVMS_HLEN;
2401
    usiz = (cmptype == EB_IZVMS_BCSTOR ?
2403
    usiz = (cmptype == EB_IZVMS_BCSTOR ?
2402
            csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
2404
            csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
2403
 
2405
 
2404
    if (retlen)
2406
    if (retlen)
2405
        *retlen = usiz;
2407
        *retlen = usiz;
2406
 
2408
 
2407
    if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
2409
    if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
2408
        return NULL;
2410
        return NULL;
2409
 
2411
 
2410
    if (init && (usiz < needlen))
2412
    if (init && (usiz < needlen))
2411
        memcpy((char *)ucdata, (ZCONST char *)init, needlen);
2413
        memcpy((char *)ucdata, (ZCONST char *)init, needlen);
2412
 
2414
 
2413
    switch (cmptype)
2415
    switch (cmptype)
2414
    {
2416
    {
2415
        case EB_IZVMS_BCSTOR: /* The simplest case */
2417
        case EB_IZVMS_BCSTOR: /* The simplest case */
2416
            memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
2418
            memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
2417
            break;
2419
            break;
2418
        case EB_IZVMS_BC00:
2420
        case EB_IZVMS_BC00:
2419
            decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
2421
            decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
2420
            break;
2422
            break;
2421
        case EB_IZVMS_BCDEFL:
2423
        case EB_IZVMS_BCDEFL:
2422
            memextract(__G__ ucdata, (ulg)usiz,
2424
            memextract(__G__ ucdata, (ulg)usiz,
2423
                       ebdata+EB_IZVMS_HLEN, (ulg)csiz);
2425
                       ebdata+EB_IZVMS_HLEN, (ulg)csiz);
2424
            break;
2426
            break;
2425
        default:
2427
        default:
2426
            free(ucdata);
2428
            free(ucdata);
2427
            ucdata = NULL;
2429
            ucdata = NULL;
2428
    }
2430
    }
2429
    return ucdata;
2431
    return ucdata;
2430
 
2432
 
2431
} /* end of extract_izvms_block */
2433
} /* end of extract_izvms_block */
2432
 
2434
 
2433
 
2435
 
2434
 
2436
 
2435
 
2437
 
2436
 
2438
 
2437
/********************************/
2439
/********************************/
2438
/*  Function decompress_bits()  */
2440
/*  Function decompress_bits()  */
2439
/********************************/
2441
/********************************/
2440
/*
2442
/*
2441
 *  Simple uncompression routine. The compression uses bit stream.
2443
 *  Simple uncompression routine. The compression uses bit stream.
2442
 *  Compression scheme:
2444
 *  Compression scheme:
2443
 *
2445
 *
2444
 *  if (byte!=0)
2446
 *  if (byte!=0)
2445
 *      putbit(1),putbyte(byte)
2447
 *      putbit(1),putbyte(byte)
2446
 *  else
2448
 *  else
2447
 *      putbit(0)
2449
 *      putbit(0)
2448
 */
2450
 */
2449
static void decompress_bits(outptr, needlen, bitptr)
2451
static void decompress_bits(outptr, needlen, bitptr)
2450
    uch *outptr;        /* Pointer into output block */
2452
    uch *outptr;        /* Pointer into output block */
2451
    unsigned needlen;   /* Size of uncompressed block */
2453
    unsigned needlen;   /* Size of uncompressed block */
2452
    ZCONST uch *bitptr; /* Pointer into compressed data */
2454
    ZCONST uch *bitptr; /* Pointer into compressed data */
2453
{
2455
{
2454
    ulg bitbuf = 0;
2456
    ulg bitbuf = 0;
2455
    int bitcnt = 0;
2457
    int bitcnt = 0;
2456
 
2458
 
2457
#define _FILL   {       bitbuf |= (*bitptr++) << bitcnt;\
2459
#define _FILL   {       bitbuf |= (*bitptr++) << bitcnt;\
2458
                        bitcnt += 8;                    \
2460
                        bitcnt += 8;                    \
2459
                }
2461
                }
2460
 
2462
 
2461
    while (needlen--)
2463
    while (needlen--)
2462
    {
2464
    {
2463
        if (bitcnt <= 0)
2465
        if (bitcnt <= 0)
2464
            _FILL;
2466
            _FILL;
2465
 
2467
 
2466
        if (bitbuf & 1)
2468
        if (bitbuf & 1)
2467
        {
2469
        {
2468
            bitbuf >>= 1;
2470
            bitbuf >>= 1;
2469
            if ((bitcnt -= 1) < 8)
2471
            if ((bitcnt -= 1) < 8)
2470
                _FILL;
2472
                _FILL;
2471
            *outptr++ = (uch)bitbuf;
2473
            *outptr++ = (uch)bitbuf;
2472
            bitcnt -= 8;
2474
            bitcnt -= 8;
2473
            bitbuf >>= 8;
2475
            bitbuf >>= 8;
2474
        }
2476
        }
2475
        else
2477
        else
2476
        {
2478
        {
2477
            *outptr++ = '\0';
2479
            *outptr++ = '\0';
2478
            bitcnt -= 1;
2480
            bitcnt -= 1;
2479
            bitbuf >>= 1;
2481
            bitbuf >>= 1;
2480
        }
2482
        }
2481
    }
2483
    }
2482
} /* end function decompress_bits() */
2484
} /* end function decompress_bits() */
2483
 
2485
 
2484
#endif /* VMS || VMS_TEXT_CONV */
2486
#endif /* VMS || VMS_TEXT_CONV */
2485
 
2487
 
2486
 
2488
 
2487
 
2489
 
2488
 
2490
 
2489
 
2491
 
2490
#ifdef SYMLINKS
2492
#ifdef SYMLINKS
2491
/***********************************/
2493
/***********************************/
2492
/* Function set_deferred_symlink() */
2494
/* Function set_deferred_symlink() */
2493
/***********************************/
2495
/***********************************/
2494
 
2496
 
2495
static void set_deferred_symlink(__G__ slnk_entry)
2497
static void set_deferred_symlink(__G__ slnk_entry)
2496
    __GDEF
2498
    __GDEF
2497
    slinkentry *slnk_entry;
2499
    slinkentry *slnk_entry;
2498
{
2500
{
2499
    extent ucsize = slnk_entry->targetlen;
2501
    extent ucsize = slnk_entry->targetlen;
2500
    char *linkfname = slnk_entry->fname;
2502
    char *linkfname = slnk_entry->fname;
2501
    char *linktarget = (char *)malloc(ucsize+1);
2503
    char *linktarget = (char *)malloc(ucsize+1);
2502
 
2504
 
2503
    if (!linktarget) {
2505
    if (!linktarget) {
2504
        Info(slide, 0x201, ((char *)slide,
2506
        Info(slide, 0x201, ((char *)slide,
2505
          LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
2507
          LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
2506
        return;
2508
        return;
2507
    }
2509
    }
2508
    linktarget[ucsize] = '\0';
2510
    linktarget[ucsize] = '\0';
2509
    G.outfile = zfopen(linkfname, FOPR); /* open link placeholder for reading */
2511
    G.outfile = zfopen(linkfname, FOPR); /* open link placeholder for reading */
2510
    /* Check that the following conditions are all fulfilled:
2512
    /* Check that the following conditions are all fulfilled:
2511
     * a) the placeholder file exists,
2513
     * a) the placeholder file exists,
2512
     * b) the placeholder file contains exactly "ucsize" bytes
2514
     * b) the placeholder file contains exactly "ucsize" bytes
2513
     *    (read the expected placeholder content length + 1 extra byte, this
2515
     *    (read the expected placeholder content length + 1 extra byte, this
2514
     *    should return the expected content length),
2516
     *    should return the expected content length),
2515
     * c) the placeholder content matches the link target specification as
2517
     * c) the placeholder content matches the link target specification as
2516
     *    stored in the symlink control structure.
2518
     *    stored in the symlink control structure.
2517
     */
2519
     */
2518
    if (!G.outfile ||
2520
    if (!G.outfile ||
2519
        fread(linktarget, 1, ucsize+1, G.outfile) != ucsize ||
2521
        fread(linktarget, 1, ucsize+1, G.outfile) != ucsize ||
2520
        strcmp(slnk_entry->target, linktarget))
2522
        strcmp(slnk_entry->target, linktarget))
2521
    {
2523
    {
2522
        Info(slide, 0x201, ((char *)slide,
2524
        Info(slide, 0x201, ((char *)slide,
2523
          LoadFarString(SymLnkWarnInvalid), FnFilter1(linkfname)));
2525
          LoadFarString(SymLnkWarnInvalid), FnFilter1(linkfname)));
2524
        free(linktarget);
2526
        free(linktarget);
2525
        if (G.outfile)
2527
        if (G.outfile)
2526
            fclose(G.outfile);
2528
            fclose(G.outfile);
2527
        return;
2529
        return;
2528
    }
2530
    }
2529
    fclose(G.outfile);                  /* close "data" file for good... */
2531
    fclose(G.outfile);                  /* close "data" file for good... */
2530
    unlink(linkfname);                  /* ...and delete it */
2532
    unlink(linkfname);                  /* ...and delete it */
2531
    if (QCOND2)
2533
    if (QCOND2)
2532
        Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
2534
        Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
2533
          FnFilter1(linkfname), FnFilter2(linktarget)));
2535
          FnFilter1(linkfname), FnFilter2(linktarget)));
2534
    if (symlink(linktarget, linkfname))  /* create the real link */
2536
    if (symlink(linktarget, linkfname))  /* create the real link */
2535
        perror("symlink error");
2537
        perror("symlink error");
2536
    free(linktarget);
2538
    free(linktarget);
2537
#ifdef SET_SYMLINK_ATTRIBS
2539
#ifdef SET_SYMLINK_ATTRIBS
2538
    set_symlnk_attribs(__G__ slnk_entry);
2540
    set_symlnk_attribs(__G__ slnk_entry);
2539
#endif
2541
#endif
2540
    return;                             /* can't set time on symlinks */
2542
    return;                             /* can't set time on symlinks */
2541
 
2543
 
2542
} /* end function set_deferred_symlink() */
2544
} /* end function set_deferred_symlink() */
2543
#endif /* SYMLINKS */
2545
#endif /* SYMLINKS */
2544
 
2546
 
2545
 
2547
 
2546
 
2548
 
2547
 
2549
 
2548
/*************************/
2550
/*************************/
2549
/*  Function fnfilter()  */        /* here instead of in list.c for SFX */
2551
/*  Function fnfilter()  */        /* here instead of in list.c for SFX */
2550
/*************************/
2552
/*************************/
2551
 
2553
 
2552
char *fnfilter(raw, space, size)   /* convert name to safely printable form */
2554
char *fnfilter(raw, space, size)   /* convert name to safely printable form */
2553
    ZCONST char *raw;
2555
    ZCONST char *raw;
2554
    uch *space;
2556
    uch *space;
2555
    extent size;
2557
    extent size;
2556
{
2558
{
2557
#ifndef NATIVE   /* ASCII:  filter ANSI escape codes, etc. */
2559
#ifndef NATIVE   /* ASCII:  filter ANSI escape codes, etc. */
2558
    ZCONST uch *r=(ZCONST uch *)raw;
2560
    ZCONST uch *r=(ZCONST uch *)raw;
2559
    uch *s=space;
2561
    uch *s=space;
2560
    uch *slim=NULL;
2562
    uch *slim=NULL;
2561
    uch *se=NULL;
2563
    uch *se=NULL;
2562
    int have_overflow = FALSE;
2564
    int have_overflow = FALSE;
2563
 
2565
 
2564
    if (size > 0) {
2566
    if (size > 0) {
2565
        slim = space + size
2567
        slim = space + size
2566
#ifdef _MBCS
2568
#ifdef _MBCS
2567
                     - (MB_CUR_MAX - 1)
2569
                     - (MB_CUR_MAX - 1)
2568
#endif
2570
#endif
2569
                     - 4;
2571
                     - 4;
2570
    }
2572
    }
2571
    while (*r) {
2573
    while (*r) {
2572
        if (size > 0 && s >= slim && se == NULL) {
2574
        if (size > 0 && s >= slim && se == NULL) {
2573
            se = s;
2575
            se = s;
2574
        }
2576
        }
2575
#ifdef QDOS
2577
#ifdef QDOS
2576
        if (qlflag & 2) {
2578
        if (qlflag & 2) {
2577
            if (*r == '/' || *r == '.') {
2579
            if (*r == '/' || *r == '.') {
2578
                if (se != NULL && (s > (space + (size-3)))) {
2580
                if (se != NULL && (s > (space + (size-3)))) {
2579
                    have_overflow = TRUE;
2581
                    have_overflow = TRUE;
2580
                    break;
2582
                    break;
2581
                }
2583
                }
2582
                ++r;
2584
                ++r;
2583
                *s++ = '_';
2585
                *s++ = '_';
2584
                continue;
2586
                continue;
2585
            }
2587
            }
2586
        } else
2588
        } else
2587
#endif
2589
#endif
2588
#ifdef HAVE_WORKING_ISPRINT
2590
#ifdef HAVE_WORKING_ISPRINT
2589
# ifndef UZ_FNFILTER_REPLACECHAR
2591
# ifndef UZ_FNFILTER_REPLACECHAR
2590
    /* A convenient choice for the replacement of unprintable char codes is
2592
    /* A convenient choice for the replacement of unprintable char codes is
2591
     * the "single char wildcard", as this character is quite unlikely to
2593
     * the "single char wildcard", as this character is quite unlikely to
2592
     * appear in filenames by itself.  The following default definition
2594
     * appear in filenames by itself.  The following default definition
2593
     * sets the replacement char to a question mark as the most common
2595
     * sets the replacement char to a question mark as the most common
2594
     * "single char wildcard"; this setting should be overridden in the
2596
     * "single char wildcard"; this setting should be overridden in the
2595
     * appropiate system-specific configuration header when needed.
2597
     * appropiate system-specific configuration header when needed.
2596
     */
2598
     */
2597
#   define UZ_FNFILTER_REPLACECHAR      '?'
2599
#   define UZ_FNFILTER_REPLACECHAR      '?'
2598
# endif
2600
# endif
2599
        if (!isprint(*r)) {
2601
        if (!isprint(*r)) {
2600
            if (*r < 32) {
2602
            if (*r < 32) {
2601
                /* ASCII control codes are escaped as "^{letter}". */
2603
                /* ASCII control codes are escaped as "^{letter}". */
2602
                if (se != NULL && (s > (space + (size-4)))) {
2604
                if (se != NULL && (s > (space + (size-4)))) {
2603
                    have_overflow = TRUE;
2605
                    have_overflow = TRUE;
2604
                    break;
2606
                    break;
2605
                }
2607
                }
2606
                *s++ = '^', *s++ = (uch)(64 + *r++);
2608
                *s++ = '^', *s++ = (uch)(64 + *r++);
2607
            } else {
2609
            } else {
2608
                /* Other unprintable codes are replaced by the
2610
                /* Other unprintable codes are replaced by the
2609
                 * placeholder character. */
2611
                 * placeholder character. */
2610
                if (se != NULL && (s > (space + (size-3)))) {
2612
                if (se != NULL && (s > (space + (size-3)))) {
2611
                    have_overflow = TRUE;
2613
                    have_overflow = TRUE;
2612
                    break;
2614
                    break;
2613
                }
2615
                }
2614
                *s++ = UZ_FNFILTER_REPLACECHAR;
2616
                *s++ = UZ_FNFILTER_REPLACECHAR;
2615
                INCSTR(r);
2617
                INCSTR(r);
2616
            }
2618
            }
2617
#else /* !HAVE_WORKING_ISPRINT */
2619
#else /* !HAVE_WORKING_ISPRINT */
2618
        if (*r < 32) {
2620
        if (*r < 32) {
2619
            /* ASCII control codes are escaped as "^{letter}". */
2621
            /* ASCII control codes are escaped as "^{letter}". */
2620
            if (se != NULL && (s > (space + (size-4)))) {
2622
            if (se != NULL && (s > (space + (size-4)))) {
2621
                have_overflow = TRUE;
2623
                have_overflow = TRUE;
2622
                break;
2624
                break;
2623
            }
2625
            }
2624
            *s++ = '^', *s++ = (uch)(64 + *r++);
2626
            *s++ = '^', *s++ = (uch)(64 + *r++);
2625
#endif /* ?HAVE_WORKING_ISPRINT */
2627
#endif /* ?HAVE_WORKING_ISPRINT */
2626
        } else {
2628
        } else {
2627
#ifdef _MBCS
2629
#ifdef _MBCS
2628
            unsigned i = CLEN(r);
2630
            unsigned i = CLEN(r);
2629
            if (se != NULL && (s > (space + (size-i-2)))) {
2631
            if (se != NULL && (s > (space + (size-i-2)))) {
2630
                have_overflow = TRUE;
2632
                have_overflow = TRUE;
2631
                break;
2633
                break;
2632
            }
2634
            }
2633
            for (; i > 0; i--)
2635
            for (; i > 0; i--)
2634
                *s++ = *r++;
2636
                *s++ = *r++;
2635
#else
2637
#else
2636
            if (se != NULL && (s > (space + (size-3)))) {
2638
            if (se != NULL && (s > (space + (size-3)))) {
2637
                have_overflow = TRUE;
2639
                have_overflow = TRUE;
2638
                break;
2640
                break;
2639
            }
2641
            }
2640
            *s++ = *r++;
2642
            *s++ = *r++;
2641
#endif
2643
#endif
2642
         }
2644
         }
2643
    }
2645
    }
2644
    if (have_overflow) {
2646
    if (have_overflow) {
2645
        strcpy((char *)se, "...");
2647
        strcpy((char *)se, "...");
2646
    } else {
2648
    } else {
2647
        *s = '\0';
2649
        *s = '\0';
2648
    }
2650
    }
2649
 
2651
 
2650
#ifdef WINDLL
2652
#ifdef WINDLL
2651
    INTERN_TO_ISO((char *)space, (char *)space);  /* translate to ANSI */
2653
    INTERN_TO_ISO((char *)space, (char *)space);  /* translate to ANSI */
2652
#else
2654
#else
2653
#if (defined(WIN32) && !defined(_WIN32_WCE))
2655
#if (defined(WIN32) && !defined(_WIN32_WCE))
2654
    /* Win9x console always uses OEM character coding, and
2656
    /* Win9x console always uses OEM character coding, and
2655
       WinNT console is set to OEM charset by default, too */
2657
       WinNT console is set to OEM charset by default, too */
2656
    INTERN_TO_OEM((char *)space, (char *)space);
2658
    INTERN_TO_OEM((char *)space, (char *)space);
2657
#endif /* (WIN32 && !_WIN32_WCE) */
2659
#endif /* (WIN32 && !_WIN32_WCE) */
2658
#endif /* ?WINDLL */
2660
#endif /* ?WINDLL */
2659
 
2661
 
2660
    return (char *)space;
2662
    return (char *)space;
2661
 
2663
 
2662
#else /* NATIVE:  EBCDIC or whatever */
2664
#else /* NATIVE:  EBCDIC or whatever */
2663
    return (char *)raw;
2665
    return (char *)raw;
2664
#endif
2666
#endif
2665
 
2667
 
2666
} /* end function fnfilter() */
2668
} /* end function fnfilter() */
2667
 
2669
 
2668
 
2670
 
2669
 
2671
 
2670
 
2672
 
2671
#ifdef SET_DIR_ATTRIB
2673
#ifdef SET_DIR_ATTRIB
2672
/* must sort saved directories so can set perms from bottom up */
2674
/* must sort saved directories so can set perms from bottom up */
2673
 
2675
 
2674
/************************/
2676
/************************/
2675
/*  Function dircomp()  */
2677
/*  Function dircomp()  */
2676
/************************/
2678
/************************/
2677
 
2679
 
2678
static int Cdecl dircomp(a, b)  /* used by qsort(); swiped from Zip */
2680
static int Cdecl dircomp(a, b)  /* used by qsort(); swiped from Zip */
2679
    ZCONST zvoid *a, *b;
2681
    ZCONST zvoid *a, *b;
2680
{
2682
{
2681
    /* order is significant:  this sorts in reverse order (deepest first) */
2683
    /* order is significant:  this sorts in reverse order (deepest first) */
2682
    return strcmp((*(direntry **)b)->fn, (*(direntry **)a)->fn);
2684
    return strcmp((*(direntry **)b)->fn, (*(direntry **)a)->fn);
2683
 /* return namecmp((*(direntry **)b)->fn, (*(direntry **)a)->fn); */
2685
 /* return namecmp((*(direntry **)b)->fn, (*(direntry **)a)->fn); */
2684
}
2686
}
2685
 
2687
 
2686
#endif /* SET_DIR_ATTRIB */
2688
#endif /* SET_DIR_ATTRIB */
2687
 
2689
 
2688
 
2690
 
2689
#ifdef USE_BZIP2
2691
#ifdef USE_BZIP2
2690
 
2692
 
2691
/**************************/
2693
/**************************/
2692
/*  Function UZbunzip2()  */
2694
/*  Function UZbunzip2()  */
2693
/**************************/
2695
/**************************/
2694
 
2696
 
2695
int UZbunzip2(__G)
2697
int UZbunzip2(__G)
2696
__GDEF
2698
__GDEF
2697
/* decompress a bzipped entry using the libbz2 routines */
2699
/* decompress a bzipped entry using the libbz2 routines */
2698
{
2700
{
2699
    int retval = 0;     /* return code: 0 = "no error" */
2701
    int retval = 0;     /* return code: 0 = "no error" */
2700
    int err=BZ_OK;
2702
    int err=BZ_OK;
2701
    int repeated_buf_err;
2703
    int repeated_buf_err;
2702
    bz_stream bstrm;
2704
    bz_stream bstrm;
2703
 
2705
 
2704
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
2706
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
2705
    if (G.redirect_slide)
2707
    if (G.redirect_slide)
2706
        wsize = G.redirect_size, redirSlide = G.redirect_buffer;
2708
        wsize = G.redirect_size, redirSlide = G.redirect_buffer;
2707
    else
2709
    else
2708
        wsize = WSIZE, redirSlide = slide;
2710
        wsize = WSIZE, redirSlide = slide;
2709
#endif
2711
#endif
2710
 
2712
 
2711
    bstrm.next_out = (char *)redirSlide;
2713
    bstrm.next_out = (char *)redirSlide;
2712
    bstrm.avail_out = wsize;
2714
    bstrm.avail_out = wsize;
2713
 
2715
 
2714
    bstrm.next_in = (char *)G.inptr;
2716
    bstrm.next_in = (char *)G.inptr;
2715
    bstrm.avail_in = G.incnt;
2717
    bstrm.avail_in = G.incnt;
2716
 
2718
 
2717
    {
2719
    {
2718
        /* local buffer for efficiency */
2720
        /* local buffer for efficiency */
2719
        /* $TODO Check for BZIP LIB version? */
2721
        /* $TODO Check for BZIP LIB version? */
2720
 
2722
 
2721
        bstrm.bzalloc = NULL;
2723
        bstrm.bzalloc = NULL;
2722
        bstrm.bzfree = NULL;
2724
        bstrm.bzfree = NULL;
2723
        bstrm.opaque = NULL;
2725
        bstrm.opaque = NULL;
2724
 
2726
 
2725
        Trace((stderr, "initializing bzlib()\n"));
2727
        Trace((stderr, "initializing bzlib()\n"));
2726
        err = BZ2_bzDecompressInit(&bstrm, 0, 0);
2728
        err = BZ2_bzDecompressInit(&bstrm, 0, 0);
2727
 
2729
 
2728
        if (err == BZ_MEM_ERROR)
2730
        if (err == BZ_MEM_ERROR)
2729
            return 3;
2731
            return 3;
2730
        else if (err != BZ_OK)
2732
        else if (err != BZ_OK)
2731
            Trace((stderr, "oops!  (BZ2_bzDecompressInit() err = %d)\n", err));
2733
            Trace((stderr, "oops!  (BZ2_bzDecompressInit() err = %d)\n", err));
2732
    }
2734
    }
2733
 
2735
 
2734
#ifdef FUNZIP
2736
#ifdef FUNZIP
2735
    while (err != BZ_STREAM_END) {
2737
    while (err != BZ_STREAM_END) {
2736
#else /* !FUNZIP */
2738
#else /* !FUNZIP */
2737
    while (G.csize > 0) {
2739
    while (G.csize > 0) {
2738
        Trace((stderr, "first loop:  G.csize = %ld\n", G.csize));
2740
        Trace((stderr, "first loop:  G.csize = %ld\n", G.csize));
2739
#endif /* ?FUNZIP */
2741
#endif /* ?FUNZIP */
2740
        while (bstrm.avail_out > 0) {
2742
        while (bstrm.avail_out > 0) {
2741
            err = BZ2_bzDecompress(&bstrm);
2743
            err = BZ2_bzDecompress(&bstrm);
2742
 
2744
 
2743
            if (err == BZ_DATA_ERROR) {
2745
            if (err == BZ_DATA_ERROR) {
2744
                retval = 2; goto uzbunzip_cleanup_exit;
2746
                retval = 2; goto uzbunzip_cleanup_exit;
2745
            } else if (err == BZ_MEM_ERROR) {
2747
            } else if (err == BZ_MEM_ERROR) {
2746
                retval = 3; goto uzbunzip_cleanup_exit;
2748
                retval = 3; goto uzbunzip_cleanup_exit;
2747
            } else if (err != BZ_OK && err != BZ_STREAM_END)
2749
            } else if (err != BZ_OK && err != BZ_STREAM_END)
2748
                Trace((stderr, "oops!  (bzip(first loop) err = %d)\n", err));
2750
                Trace((stderr, "oops!  (bzip(first loop) err = %d)\n", err));
2749
 
2751
 
2750
#ifdef FUNZIP
2752
#ifdef FUNZIP
2751
            if (err == BZ_STREAM_END)    /* "END-of-entry-condition" ? */
2753
            if (err == BZ_STREAM_END)    /* "END-of-entry-condition" ? */
2752
#else /* !FUNZIP */
2754
#else /* !FUNZIP */
2753
            if (G.csize <= 0L)          /* "END-of-entry-condition" ? */
2755
            if (G.csize <= 0L)          /* "END-of-entry-condition" ? */
2754
#endif /* ?FUNZIP */
2756
#endif /* ?FUNZIP */
2755
                break;
2757
                break;
2756
 
2758
 
2757
            if (bstrm.avail_in == 0) {
2759
            if (bstrm.avail_in == 0) {
2758
                if (fillinbuf(__G) == 0) {
2760
                if (fillinbuf(__G) == 0) {
2759
                    /* no "END-condition" yet, but no more data */
2761
                    /* no "END-condition" yet, but no more data */
2760
                    retval = 2; goto uzbunzip_cleanup_exit;
2762
                    retval = 2; goto uzbunzip_cleanup_exit;
2761
                }
2763
                }
2762
 
2764
 
2763
                bstrm.next_in = (char *)G.inptr;
2765
                bstrm.next_in = (char *)G.inptr;
2764
                bstrm.avail_in = G.incnt;
2766
                bstrm.avail_in = G.incnt;
2765
            }
2767
            }
2766
            Trace((stderr, "     avail_in = %u\n", bstrm.avail_in));
2768
            Trace((stderr, "     avail_in = %u\n", bstrm.avail_in));
2767
        }
2769
        }
2768
        /* flush slide[] */
2770
        /* flush slide[] */
2769
        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
2771
        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
2770
            goto uzbunzip_cleanup_exit;
2772
            goto uzbunzip_cleanup_exit;
2771
        Trace((stderr, "inside loop:  flushing %ld bytes (ptr diff = %ld)\n",
2773
        Trace((stderr, "inside loop:  flushing %ld bytes (ptr diff = %ld)\n",
2772
          (long)(wsize - bstrm.avail_out),
2774
          (long)(wsize - bstrm.avail_out),
2773
          (long)(bstrm.next_out-(char *)redirSlide)));
2775
          (long)(bstrm.next_out-(char *)redirSlide)));
2774
        bstrm.next_out = (char *)redirSlide;
2776
        bstrm.next_out = (char *)redirSlide;
2775
        bstrm.avail_out = wsize;
2777
        bstrm.avail_out = wsize;
2776
    }
2778
    }
2777
 
2779
 
2778
    /* no more input, so loop until we have all output */
2780
    /* no more input, so loop until we have all output */
2779
    Trace((stderr, "beginning final loop:  err = %d\n", err));
2781
    Trace((stderr, "beginning final loop:  err = %d\n", err));
2780
    repeated_buf_err = FALSE;
2782
    repeated_buf_err = FALSE;
2781
    while (err != BZ_STREAM_END) {
2783
    while (err != BZ_STREAM_END) {
2782
        err = BZ2_bzDecompress(&bstrm);
2784
        err = BZ2_bzDecompress(&bstrm);
2783
        if (err == BZ_DATA_ERROR) {
2785
        if (err == BZ_DATA_ERROR) {
2784
            retval = 2; goto uzbunzip_cleanup_exit;
2786
            retval = 2; goto uzbunzip_cleanup_exit;
2785
        } else if (err == BZ_MEM_ERROR) {
2787
        } else if (err == BZ_MEM_ERROR) {
2786
            retval = 3; goto uzbunzip_cleanup_exit;
2788
            retval = 3; goto uzbunzip_cleanup_exit;
2787
        } else if (err != BZ_OK && err != BZ_STREAM_END) {
2789
        } else if (err != BZ_OK && err != BZ_STREAM_END) {
2788
            Trace((stderr, "oops!  (bzip(final loop) err = %d)\n", err));
2790
            Trace((stderr, "oops!  (bzip(final loop) err = %d)\n", err));
2789
            DESTROYGLOBALS();
2791
            DESTROYGLOBALS();
2790
            EXIT(PK_MEM3);
2792
            EXIT(PK_MEM3);
2791
        }
2793
        }
2792
        /* final flush of slide[] */
2794
        /* final flush of slide[] */
2793
        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
2795
        if ((retval = FLUSH(wsize - bstrm.avail_out)) != 0)
2794
            goto uzbunzip_cleanup_exit;
2796
            goto uzbunzip_cleanup_exit;
2795
        Trace((stderr, "final loop:  flushing %ld bytes (ptr diff = %ld)\n",
2797
        Trace((stderr, "final loop:  flushing %ld bytes (ptr diff = %ld)\n",
2796
          (long)(wsize - bstrm.avail_out),
2798
          (long)(wsize - bstrm.avail_out),
2797
          (long)(bstrm.next_out-(char *)redirSlide)));
2799
          (long)(bstrm.next_out-(char *)redirSlide)));
2798
        bstrm.next_out = (char *)redirSlide;
2800
        bstrm.next_out = (char *)redirSlide;
2799
        bstrm.avail_out = wsize;
2801
        bstrm.avail_out = wsize;
2800
    }
2802
    }
2801
#ifdef LARGE_FILE_SUPPORT
2803
#ifdef LARGE_FILE_SUPPORT
2802
    Trace((stderr, "total in = %llu, total out = %llu\n",
2804
    Trace((stderr, "total in = %llu, total out = %llu\n",
2803
      (zusz_t)(bstrm.total_in_lo32) + ((zusz_t)(bstrm.total_in_hi32))<<32,
2805
      (zusz_t)(bstrm.total_in_lo32) + ((zusz_t)(bstrm.total_in_hi32))<<32,
2804
      (zusz_t)(bstrm.total_out_lo32) + ((zusz_t)(bstrm.total_out_hi32))<<32));
2806
      (zusz_t)(bstrm.total_out_lo32) + ((zusz_t)(bstrm.total_out_hi32))<<32));
2805
#else
2807
#else
2806
    Trace((stderr, "total in = %lu, total out = %lu\n", bstrm.total_in_lo32,
2808
    Trace((stderr, "total in = %lu, total out = %lu\n", bstrm.total_in_lo32,
2807
      bstrm.total_out_lo32));
2809
      bstrm.total_out_lo32));
2808
#endif
2810
#endif
2809
 
2811
 
2810
    G.inptr = (uch *)bstrm.next_in;
2812
    G.inptr = (uch *)bstrm.next_in;
2811
    G.incnt = (G.inbuf + INBUFSIZ) - G.inptr;  /* reset for other routines */
2813
    G.incnt = (G.inbuf + INBUFSIZ) - G.inptr;  /* reset for other routines */
2812
 
2814
 
2813
uzbunzip_cleanup_exit:
2815
uzbunzip_cleanup_exit:
2814
    err = BZ2_bzDecompressEnd(&bstrm);
2816
    err = BZ2_bzDecompressEnd(&bstrm);
2815
    if (err != BZ_OK)
2817
    if (err != BZ_OK)
2816
        Trace((stderr, "oops!  (BZ2_bzDecompressEnd() err = %d)\n", err));
2818
        Trace((stderr, "oops!  (BZ2_bzDecompressEnd() err = %d)\n", err));
2817
 
2819
 
2818
    return retval;
2820
    return retval;
2819
} /* end function UZbunzip2() */
2821
} /* end function UZbunzip2() */
2820
#endif /* USE_BZIP2 */
2822
#endif /* USE_BZIP2 */
2821
#else
2823
#else
2822
>
2824
>
2823
#else
2825
#else
2824
>
2826
>
2825
>
2827
>
2826
>
2828
>