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