Subversion Repositories Kolibri OS

Rev

Rev 6725 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2009-Jan-02 or later
5
  (the contents of which are also included in unzip.h) for terms of use.
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
  unzip.c
12
 
13
  UnZip - a zipfile extraction utility.  See below for make instructions, or
14
  read the comments in Makefile and the various Contents files for more de-
15
  tailed explanations.  To report a bug, submit a *complete* description via
16
  //www.info-zip.org/zip-bug.html; include machine type, operating system and
17
  version, compiler and version, and reasonably detailed error messages or
18
  problem report.  To join Info-ZIP, see the instructions in README.
19
 
20
  UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
21
  which in turn was almost a complete rewrite of version 3.x.  For a detailed
22
  revision history, see UnzpHist.zip at quest.jpl.nasa.gov.  For a list of
23
  the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
24
  distribution.
25
 
26
  UnZip 6.0 adds support for archives larger than 4 GiB using the Zip64
27
  extensions as well as support for Unicode information embedded per the
28
  latest zip standard additions.
29
 
30
  ---------------------------------------------------------------------------
31
 
32
  [from original zipinfo.c]
33
 
34
  This program reads great gobs of totally nifty information, including the
35
  central directory stuff, from ZIP archives ("zipfiles" for short).  It
36
  started as just a testbed for fooling with zipfiles, but at this point it
37
  is actually a useful utility.  It also became the basis for the rewrite of
38
  UnZip (3.16 -> 4.0), using the central directory for processing rather than
39
  the individual (local) file headers.
40
 
41
  As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
42
  If the executable is named "unzip" (or "unzip.exe", depending), it behaves
43
  like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
44
  ZipInfo.  The ZipInfo behavior may also be triggered by use of unzip's -Z
45
  option; for example, "unzip -Z [zipinfo_options] archive.zip".
46
 
47
  Another dandy product from your buddies at Newtware!
48
 
49
  Author:  Greg Roelofs, newt@pobox.com, http://pobox.com/~newt/
50
           23 August 1990 -> April 1997
51
 
52
  ---------------------------------------------------------------------------
53
 
54
  Version:  unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
55
              Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
56
              AtheOS, BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos
57
              and TOPS-20.
58
 
59
  Copyrights:  see accompanying file "LICENSE" in UnZip source distribution.
60
               (This software is free but NOT IN THE PUBLIC DOMAIN.)
61
 
62
  ---------------------------------------------------------------------------*/
63
 
64
 
65
 
66
#define __UNZIP_C       /* identifies this source module */
67
#define UNZIP_INTERNAL
68
#include "unzip.h"      /* includes, typedefs, macros, prototypes, etc. */
69
#include "crypt.h"
70
#include "unzvers.h"
71
 
72
#ifndef WINDLL          /* The WINDLL port uses windll/windll.c instead... */
73
 
74
/***************************/
75
/* Local type declarations */
76
/***************************/
77
 
78
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
79
typedef struct _sign_info
80
    {
81
        struct _sign_info *previous;
82
        void (*sighandler)(int);
83
        int sigtype;
84
    } savsigs_info;
85
#endif
86
 
87
/*******************/
88
/* Local Functions */
89
/*******************/
90
 
91
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
92
static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
93
                                int signal_type, void (*newhandler)(int)));
94
#endif
95
#ifndef SFX
96
static void  help_extended      OF((__GPRO));
97
static void  show_version_info  OF((__GPRO));
98
#endif
99
 
100
 
101
/*************/
102
/* Constants */
103
/*************/
104
 
105
#include "consts.h"  /* all constant global variables are in here */
106
                     /* (non-constant globals were moved to globals.c) */
107
 
108
/* constant local variables: */
109
 
110
#ifndef SFX
111
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
112
   static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
113
   static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
114
   static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
115
   static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
116
#ifdef RISCOS
117
   static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
118
#endif /* RISCOS */
119
  static ZCONST char Far NoMemEnvArguments[] =
120
    "envargs:  cannot get memory for arguments";
121
#endif /* !_WIN32_WCE */
122
  static ZCONST char Far CmdLineParamTooLong[] =
123
    "error:  command line parameter #%d exceeds internal size limit\n";
124
#endif /* !SFX */
125
 
126
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
127
  static ZCONST char Far CantSaveSigHandler[] =
128
    "error:  cannot save signal handler settings\n";
129
#endif
130
 
131
#if (!defined(SFX) || defined(SFX_EXDIR))
132
   static ZCONST char Far NotExtracting[] =
133
     "caution:  not extracting; -d ignored\n";
134
   static ZCONST char Far MustGiveExdir[] =
135
     "error:  must specify directory to which to extract with -d option\n";
136
   static ZCONST char Far OnlyOneExdir[] =
137
     "error:  -d option used more than once (only one exdir allowed)\n";
138
#endif
139
#if (defined(UNICODE_SUPPORT) && !defined(UNICODE_WCHAR))
140
  static ZCONST char Far UTF8EscapeUnSupp[] =
141
    "warning:  -U \"escape all non-ASCII UTF-8 chars\" is not supported\n";
142
#endif
143
 
144
#if CRYPT
145
   static ZCONST char Far MustGivePasswd[] =
146
     "error:  must give decryption password with -P option\n";
147
#endif
148
 
149
#ifndef SFX
150
   static ZCONST char Far Zfirst[] =
151
   "error:  -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
152
#endif
153
static ZCONST char Far InvalidOptionsMsg[] = "error:\
154
  -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
155
static ZCONST char Far IgnoreOOptionMsg[] =
156
  "caution:  both -n and -o specified; ignoring -o\n";
157
 
158
/* usage() strings */
159
#ifndef SFX
160
#ifdef VMS
161
   static ZCONST char Far Example3[] = "vms.c";
162
   static ZCONST char Far Example2[] = "  unzip \"-V\" foo \"Bar\"\
163
 (Quote names to preserve case, unless SET PROC/PARS=EXT)\n";
164
#else /* !VMS */
165
   static ZCONST char Far Example3[] = "ReadMe";
166
#ifdef RISCOS
167
   static ZCONST char Far Example2[] =
168
"  unzip foo -d RAM:$   => extract all files from foo into RAMDisc\n";
169
#else /* !RISCOS */
170
#if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
171
   static ZCONST char Far Example2[] =
172
     "";                /* no room:  too many local3[] items */
173
#else /* !OS2 */
174
#ifdef MACOS
175
   static ZCONST char Far Example2[] = ""; /* not needed */
176
#else /* !MACOS */
177
   static ZCONST char Far Example2[] = " \
178
 unzip -p foo | more  => send contents of foo.zip via pipe into program more\n";
179
#endif /* ?MACOS */
180
#endif /* ?OS2 */
181
#endif /* ?RISCOS */
182
#endif /* ?VMS */
183
 
184
/* local1[]:  command options */
185
#if defined(TIMESTAMP)
186
   static ZCONST char Far local1[] =
187
     "  -T  timestamp archive to latest";
188
#else /* !TIMESTAMP */
189
   static ZCONST char Far local1[] = "";
190
#endif /* ?TIMESTAMP */
191
 
192
/* local2[] and local3[]:  modifier options */
193
#ifdef DOS_FLX_H68_OS2_W32
194
#ifdef FLEXOS
195
   static ZCONST char Far local2[] = "";
196
#else
197
   static ZCONST char Far local2[] =
198
     " -$  label removables (-$$ => fixed disks)";
199
#endif
200
#ifdef OS2
201
#ifdef MORE
202
   static ZCONST char Far local3[] = "\
203
  -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\
204
                                             -M  pipe through \"more\" pager\n";
205
#else
206
   static ZCONST char Far local3[] = " \
207
 -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\n";
208
#endif /* ?MORE */
209
#else /* !OS2 */
210
#ifdef WIN32
211
#ifdef NTSD_EAS
212
#ifdef MORE
213
   static ZCONST char Far local3[] = "\
214
  -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\
215
                                             -M  pipe through \"more\" pager\n";
216
#else
217
   static ZCONST char Far local3[] = " \
218
 -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\n";
219
#endif /* ?MORE */
220
#else /* !NTSD_EAS */
221
#ifdef MORE
222
   static ZCONST char Far local3[] = "\
223
  -M  pipe through \"more\" pager            \
224
  -s  spaces in filenames => '_'\n\n";
225
#else
226
   static ZCONST char Far local3[] = " \
227
                                            -s  spaces in filenames => '_'\n\n";
228
#endif /* ?MORE */
229
#endif /* ?NTSD_EAS */
230
#else /* !WIN32 */
231
#ifdef MORE
232
   static ZCONST char Far local3[] = "  -\
233
M  pipe through \"more\" pager              -s  spaces in filenames => '_'\n\n";
234
#else
235
   static ZCONST char Far local3[] = "\
236
                                             -s  spaces in filenames => '_'\n";
237
#endif
238
#endif /* ?WIN32 */
239
#endif /* ?OS2 || ?WIN32 */
240
#else /* !DOS_FLX_OS2_W32 */
241
#ifdef VMS
242
   static ZCONST char Far local2[] = " -X  restore owner/ACL protection info";
243
#ifdef MORE
244
   static ZCONST char Far local3[] = "\
245
  -Y  treat \".nnn\" as \";nnn\" version         -2  force ODS2 names\n\
246
  --D restore dir (-D: no) timestamps        -M  pipe through \"more\" pager\n\
247
  (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
248
\n\n";
249
#else
250
   static ZCONST char Far local3[] = "\n\
251
  -Y  treat \".nnn\" as \";nnn\" version         -2  force ODS2 names\n\
252
  --D restore dir (-D: no) timestamps\n\
253
  (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
254
\n\n";
255
#endif
256
#else /* !VMS */
257
#ifdef ATH_BEO_UNX
258
   static ZCONST char Far local2[] = " -X  restore UID/GID info";
259
#ifdef MORE
260
   static ZCONST char Far local3[] = "\
261
  -K  keep setuid/setgid/tacky permissions   -M  pipe through \"more\" pager\n";
262
#else
263
   static ZCONST char Far local3[] = "\
264
  -K  keep setuid/setgid/tacky permissions\n";
265
#endif
266
#else /* !ATH_BEO_UNX */
267
#ifdef TANDEM
268
   static ZCONST char Far local2[] = "\
269
 -X  restore Tandem User ID                 -r  remove file extensions\n\
270
  -b  create 'C' (180) text files          ";
271
#ifdef MORE
272
   static ZCONST char Far local3[] = " \
273
                                            -M  pipe through \"more\" pager\n";
274
#else
275
   static ZCONST char Far local3[] = "\n";
276
#endif
277
#else /* !TANDEM */
278
#ifdef AMIGA
279
   static ZCONST char Far local2[] = " -N  restore comments as filenotes";
280
#ifdef MORE
281
   static ZCONST char Far local3[] = " \
282
                                            -M  pipe through \"more\" pager\n";
283
#else
284
   static ZCONST char Far local3[] = "\n";
285
#endif
286
#else /* !AMIGA */
287
#ifdef MACOS
288
   static ZCONST char Far local2[] = " -E  show Mac info during extraction";
289
   static ZCONST char Far local3[] = " \
290
 -i  ignore filenames in mac extra info     -J  junk (ignore) Mac extra info\n\
291
\n";
292
#else /* !MACOS */
293
#ifdef MORE
294
   static ZCONST char Far local2[] = " -M  pipe through \"more\" pager";
295
   static ZCONST char Far local3[] = "\n";
296
#else
297
   static ZCONST char Far local2[] = "";   /* Atari, Mac, CMS/MVS etc. */
298
   static ZCONST char Far local3[] = "";
299
#endif
300
#endif /* ?MACOS */
301
#endif /* ?AMIGA */
302
#endif /* ?TANDEM */
303
#endif /* ?ATH_BEO_UNX */
304
#endif /* ?VMS */
305
#endif /* ?DOS_FLX_OS2_W32 */
306
#endif /* !SFX */
307
 
308
#ifndef NO_ZIPINFO
309
#ifdef VMS
310
   static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
311
#else
312
   static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
313
#endif
314
 
315
static ZCONST char Far ZipInfoUsageLine1[] = "\
316
ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
317
\n\
318
List name, date/time, attribute, size, compression method, etc., about files\n\
319
in list (excluding those in xlist) contained in the specified .zip archive(s).\
320
\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
321
   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
322
      or:  unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
323
 
324
static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
325
 listing-format options:             -s  short Unix \"ls -l\" format (def.)\n\
326
  -1  filenames ONLY, one per line       -m  medium Unix \"ls -l\" format\n\
327
  -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
328
                                         -v  verbose, multi-page format\n";
329
 
330
static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
331
  -h  print header line       -t  print totals for listed files or for all\n\
332
  -z  print zipfile comment   -T  print file times in sortable decimal format\
333
\n  -C  be case-insensitive   %s\
334
  -x  exclude filenames that follow from listing\n";
335
#ifdef MORE
336
   static ZCONST char Far ZipInfoUsageLine4[] =
337
     "  -M  page output through built-in \"more\"\n";
338
#else /* !MORE */
339
   static ZCONST char Far ZipInfoUsageLine4[] = "";
340
#endif /* ?MORE */
341
#endif /* !NO_ZIPINFO */
342
 
343
#ifdef BETA
344
#  ifdef VMSCLI
345
   /* BetaVersion[] is also used in vms/cmdline.c:  do not make it static */
346
     ZCONST char Far BetaVersion[] = "%s\
347
        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
348
#  else
349
     static ZCONST char Far BetaVersion[] = "%s\
350
        THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
351
#  endif
352
#endif
353
 
354
#ifdef SFX
355
#  ifdef VMSCLI
356
   /* UnzipSFXBanner[] is also used in vms/cmdline.c:  do not make it static */
357
     ZCONST char Far UnzipSFXBanner[] =
358
#  else
359
     static ZCONST char Far UnzipSFXBanner[] =
360
#  endif
361
     "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (http://www.info-zip.org).\n";
362
#  ifdef SFX_EXDIR
363
     static ZCONST char Far UnzipSFXOpts[] =
364
    "Valid options are -tfupcz and -d ; modifiers are -abjnoqCL%sV%s.\n";
365
#  else
366
     static ZCONST char Far UnzipSFXOpts[] =
367
       "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
368
#  endif
369
#else /* !SFX */
370
   static ZCONST char Far CompileOptions[] =
371
     "UnZip special compilation options:\n";
372
   static ZCONST char Far CompileOptFormat[] = "        %s\n";
373
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
374
   static ZCONST char Far EnvOptions[] =
375
     "\nUnZip and ZipInfo environment options:\n";
376
   static ZCONST char Far EnvOptFormat[] = "%16s:  %.1024s\n";
377
#endif
378
   static ZCONST char Far None[] = "[none]";
379
#  ifdef ACORN_FTYPE_NFS
380
     static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
381
#  endif
382
#  ifdef ASM_CRC
383
     static ZCONST char Far AsmCRC[] = "ASM_CRC";
384
#  endif
385
#  ifdef ASM_INFLATECODES
386
     static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
387
#  endif
388
#  ifdef CHECK_VERSIONS
389
     static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
390
#  endif
391
#  ifdef COPYRIGHT_CLEAN
392
     static ZCONST char Far Copyright_Clean[] =
393
     "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
394
#  endif
395
#  ifdef DEBUG
396
     static ZCONST char Far UDebug[] = "DEBUG";
397
#  endif
398
#  ifdef DEBUG_TIME
399
     static ZCONST char Far DebugTime[] = "DEBUG_TIME";
400
#  endif
401
#  ifdef DLL
402
     static ZCONST char Far Dll[] = "DLL";
403
#  endif
404
#  ifdef DOSWILD
405
     static ZCONST char Far DosWild[] = "DOSWILD";
406
#  endif
407
#  ifdef LZW_CLEAN
408
     static ZCONST char Far LZW_Clean[] =
409
     "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
410
#  endif
411
#  ifndef MORE
412
     static ZCONST char Far No_More[] = "NO_MORE";
413
#  endif
414
#  ifdef NO_ZIPINFO
415
     static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
416
#  endif
417
#  ifdef NTSD_EAS
418
     static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
419
#  endif
420
#  if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
421
     static ZCONST char Far W32NoIZTimeFix[] = "NO_W32TIMES_IZFIX";
422
#  endif
423
#  ifdef OLD_THEOS_EXTRA
424
     static ZCONST char Far OldTheosExtra[] =
425
     "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
426
#  endif
427
#  ifdef OS2_EAS
428
     static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
429
#  endif
430
#  ifdef QLZIP
431
     static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
432
#  endif
433
#  ifdef REENTRANT
434
     static ZCONST char Far Reentrant[] = "REENTRANT";
435
#  endif
436
#  ifdef REGARGS
437
     static ZCONST char Far RegArgs[] = "REGARGS";
438
#  endif
439
#  ifdef RETURN_CODES
440
     static ZCONST char Far Return_Codes[] = "RETURN_CODES";
441
#  endif
442
#  ifdef SET_DIR_ATTRIB
443
     static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
444
#  endif
445
#  ifdef SYMLINKS
446
     static ZCONST char Far SymLinkSupport[] =
447
     "SYMLINKS (symbolic links supported, if RTL and file system permit)";
448
#  endif
449
#  ifdef TIMESTAMP
450
     static ZCONST char Far TimeStamp[] = "TIMESTAMP";
451
#  endif
452
#  ifdef UNIXBACKUP
453
     static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
454
#  endif
455
#  ifdef USE_EF_UT_TIME
456
     static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
457
#  endif
458
#  ifndef LZW_CLEAN
459
     static ZCONST char Far Use_Unshrink[] =
460
     "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
461
#  endif
462
#  ifndef COPYRIGHT_CLEAN
463
     static ZCONST char Far Use_Smith_Code[] =
464
     "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
465
#  endif
466
#  ifdef USE_DEFLATE64
467
     static ZCONST char Far Use_Deflate64[] =
468
     "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
469
#  endif
470
#  ifdef UNICODE_SUPPORT
471
#   ifdef UTF8_MAYBE_NATIVE
472
#    ifdef UNICODE_WCHAR
473
       /* direct native UTF-8 check AND charset transform via wchar_t */
474
       static ZCONST char Far Use_Unicode[] =
475
       "UNICODE_SUPPORT [wide-chars, char coding: %s] (handle UTF-8 paths)";
476
#    else
477
       /* direct native UTF-8 check, only */
478
       static ZCONST char Far Use_Unicode[] =
479
       "UNICODE_SUPPORT [char coding: %s] (handle UTF-8 paths)";
480
#    endif
481
       static ZCONST char Far SysChUTF8[] = "UTF-8";
482
       static ZCONST char Far SysChOther[] = "other";
483
#   else /* !UTF8_MAYBE_NATIVE */
484
       /* charset transform via wchar_t, no native UTF-8 support */
485
       static ZCONST char Far Use_Unicode[] =
486
       "UNICODE_SUPPORT [wide-chars] (handle UTF-8 paths)";
487
#   endif /* ?UTF8_MAYBE_NATIVE */
488
#  endif /* UNICODE_SUPPORT */
489
#  ifdef _MBCS
490
     static ZCONST char Far Have_MBCS_Support[] =
491
     "MBCS-support (multibyte character support, MB_CUR_MAX = %u)";
492
#  endif
493
#  ifdef MULT_VOLUME
494
     static ZCONST char Far Use_MultiVol[] =
495
     "MULT_VOLUME (multi-volume archives supported)";
496
#  endif
497
#  ifdef LARGE_FILE_SUPPORT
498
     static ZCONST char Far Use_LFS[] =
499
     "LARGE_FILE_SUPPORT (large files over 2 GiB supported)";
500
#  endif
501
#  ifdef ZIP64_SUPPORT
502
     static ZCONST char Far Use_Zip64[] =
503
     "ZIP64_SUPPORT (archives using Zip64 for large files supported)";
504
#  endif
505
#  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
506
#    ifdef USE_DJGPP_ENV
507
       static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
508
#    endif
509
#    ifdef USE_DJGPP_GLOB
510
       static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
511
#    endif
512
#  endif /* __DJGPP__ && (__DJGPP__ >= 2) */
513
#  ifdef USE_VFAT
514
     static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
515
#  endif
516
#  ifdef USE_ZLIB
517
     static ZCONST char Far UseZlib[] =
518
     "USE_ZLIB (compiled with version %s; using version %s)";
519
#  endif
520
#  ifdef USE_BZIP2
521
     static ZCONST char Far UseBZip2[] =
522
     "USE_BZIP2 (PKZIP 4.6+, using bzip2 lib version %s)";
523
#  endif
524
#  ifdef VMS_TEXT_CONV
525
     static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
526
#  endif
527
#  ifdef VMSCLI
528
     static ZCONST char Far VmsCLI[] = "VMSCLI";
529
#  endif
530
#  ifdef VMSWILD
531
     static ZCONST char Far VmsWild[] = "VMSWILD";
532
#  endif
533
#  ifdef WILD_STOP_AT_DIR
534
     static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
535
#  endif
536
#  if CRYPT
537
#    ifdef PASSWD_FROM_STDIN
538
       static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
539
#    endif
540
     static ZCONST char Far Decryption[] =
541
       "        [decryption, version %d.%d%s of %s]\n";
542
     static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
543
#  endif
544
#  ifndef __RSXNT__
545
#    ifdef __EMX__
546
       static ZCONST char Far EnvEMX[] = "EMX";
547
       static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
548
#    endif
549
#    if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
550
       static ZCONST char Far EnvGO32[] = "GO32";
551
       static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
552
#    endif
553
#  endif /* !__RSXNT__ */
554
 
555
#ifdef VMS
556
/* UnzipUsageLine1[] is also used in vms/cmdline.c:  do not make it static */
557
   ZCONST char Far UnzipUsageLine1[] = "\
558
UnZip %d.%d%d%s of %s, by Info-ZIP.  For more details see: unzip -v.\n\n";
559
# ifdef COPYRIGHT_CLEAN
560
   static ZCONST char Far UnzipUsageLine1v[] = "\
561
UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
562
bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
563
\n\n";
564
# else
565
   static ZCONST char Far UnzipUsageLine1v[] = "\
566
UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
567
Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
568
\n\n";
569
# endif /* ?COPYRIGHT_CLEAN */
570
#else /* !VMS */
571
# ifdef COPYRIGHT_CLEAN
572
   static ZCONST char Far UnzipUsageLine1[] = "\
573
UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
574
bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
575
\n\n";
576
# else
577
   static ZCONST char Far UnzipUsageLine1[] = "\
578
UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
579
Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
580
\n\n";
581
# endif /* ?COPYRIGHT_CLEAN */
582
# define UnzipUsageLine1v       UnzipUsageLine1
583
#endif /* ?VMS */
584
 
585
static ZCONST char Far UnzipUsageLine2v[] = "\
586
Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
587
\nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
588
\n\n";
589
 
590
#ifdef MACOS
591
static ZCONST char Far UnzipUsageLine2[] = "\
592
Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n \
593
 Default action is to extract files in list, to exdir;\n\
594
  file[.zip] may be a wildcard.  %s\n";
595
#else /* !MACOS */
596
#ifdef VM_CMS
597
static ZCONST char Far UnzipUsageLine2[] = "\
598
Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n \
599
 Default action is to extract files in list, except those in xlist, to disk fm;\
600
\n  file[.zip] may be a wildcard.  %s\n";
601
#else /* !VM_CMS */
602
static ZCONST char Far UnzipUsageLine2[] = "\
603
Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
604
 Default action is to extract files in list, except those in xlist, to exdir;\n\
605
  file[.zip] may be a wildcard.  %s\n";
606
#endif /* ?VM_CMS */
607
#endif /* ?MACOS */
608
 
609
#ifdef NO_ZIPINFO
610
#  define ZIPINFO_MODE_OPTION  ""
611
   static ZCONST char Far ZipInfoMode[] =
612
     "(ZipInfo mode is disabled in this version.)";
613
#else
614
#  define ZIPINFO_MODE_OPTION  "[-Z] "
615
   static ZCONST char Far ZipInfoMode[] =
616
     "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
617
#endif /* ?NO_ZIPINFO */
618
 
619
#ifdef VMS
620
   static ZCONST char Far VMSusageLine2b[] = "\
621
=> define foreign command symbol in LOGIN.COM:  $ unzip :== $dev:[dir]unzip.exe\
622
\n";
623
#endif
624
 
625
#ifdef MACOS
626
static ZCONST char Far UnzipUsageLine3[] = "\n\
627
  -d  extract files into exdir               -l  list files (short format)\n\
628
  -f  freshen existing files, create none    -t  test compressed archive data\n\
629
  -u  update files, create if necessary      -z  display archive comment only\n\
630
  -v  list verbosely/show version info     %s\n";
631
#else /* !MACOS */
632
#ifdef VM_CMS
633
static ZCONST char Far UnzipUsageLine3[] = "\n\
634
  -p  extract files to pipe, no messages     -l  list files (short format)\n\
635
  -f  freshen existing files, create none    -t  test compressed archive data\n\
636
  -u  update files, create if necessary      -z  display archive comment only\n\
637
  -v  list verbosely/show version info     %s\n\
638
  -x  exclude files that follow (in xlist)   -d  extract files onto disk fm\n";
639
#else /* !VM_CMS */
640
static ZCONST char Far UnzipUsageLine3[] = "\n\
641
  -p  extract files to pipe, no messages     -l  list files (short format)\n\
642
  -f  freshen existing files, create none    -t  test compressed archive data\n\
643
  -u  update files, create if necessary      -z  display archive comment only\n\
644
  -v  list verbosely/show version info     %s\n\
645
  -x  exclude files that follow (in xlist)   -d  extract files into exdir\n";
646
#endif /* ?VM_CMS */
647
#endif /* ?MACOS */
648
 
649
/* There is not enough space on a standard 80x25 Windows console screen for
650
 * the additional line advertising the UTF-8 debugging options. This may
651
 * eventually also be the case for other ports. Probably, the -U option need
652
 * not be shown on the introductory screen at all. [Chr. Spieler, 2008-02-09]
653
 *
654
 * Likely, other advanced options should be moved to an extended help page and
655
 * the option to list that page put here.  [E. Gordon, 2008-3-16]
656
 */
657
#if (defined(UNICODE_SUPPORT) && !defined(WIN32))
658
#ifdef VMS
659
static ZCONST char Far UnzipUsageLine4[] = "\
660
modifiers:\n\
661
  -n  never overwrite or make a new version of an existing file\n\
662
  -o  always make a new version (-oo: overwrite original) of an existing file\n\
663
  -q  quiet mode (-qq => quieter)            -a  auto-convert any text files\n\
664
  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
665
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
666
  -C  match filenames case-insensitively     -L  make (some) names \
667
lowercase\n %-42s  -V  retain VMS version numbers\n%s";
668
#else /* !VMS */
669
static ZCONST char Far UnzipUsageLine4[] = "\
670
modifiers:\n\
671
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
672
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
673
  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
674
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
675
  -C  match filenames case-insensitively     -L  make (some) names \
676
lowercase\n %-42s  -V  retain VMS version numbers\n%s";
677
#endif /* ?VMS */
678
#else /* !UNICODE_SUPPORT */
679
#ifdef VMS
680
static ZCONST char Far UnzipUsageLine4[] = "\
681
modifiers:\n\
682
  -n  never overwrite or make a new version of an existing file\n\
683
  -o  always make a new version (-oo: overwrite original) of an existing file\n\
684
  -q  quiet mode (-qq => quieter)            -a  auto-convert any text files\n\
685
  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
686
  -C  match filenames case-insensitively     -L  make (some) names \
687
lowercase\n %-42s  -V  retain VMS version numbers\n%s";
688
#else /* !VMS */
689
static ZCONST char Far UnzipUsageLine4[] = "\
690
modifiers:\n\
691
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
692
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
693
  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
694
  -C  match filenames case-insensitively     -L  make (some) names \
695
lowercase\n %-42s  -V  retain VMS version numbers\n%s";
696
#endif /* ?VMS */
697
#endif /* ?UNICODE_SUPPORT */
698
 
699
static ZCONST char Far UnzipUsageLine5[] = "\
700
See \"unzip -hh\" or unzip.txt for more help.  Examples:\n\
701
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip\n\
702
%s\
703
  unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
704
#endif /* ?SFX */
705
 
706
 
707
 
708
 
709
 
710
/*****************************/
711
/*  main() / UzpMain() stub  */
712
/*****************************/
713
 
714
int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
715
    int argc;
716
    char *argv[];
717
{
718
    int r;
719
 
720
    CONSTRUCTGLOBALS();
721
    r = unzip(__G__ argc, argv);
722
    DESTROYGLOBALS();
723
    RETURN(r);
724
}
725
 
726
 
727
 
728
 
729
/*******************************/
730
/*  Primary UnZip entry point  */
731
/*******************************/
732
 
733
int unzip(__G__ argc, argv)
734
    __GDEF
735
    int argc;
736
    char *argv[];
737
{
738
#ifndef NO_ZIPINFO
739
    char *p;
740
#endif
741
#if (defined(DOS_FLX_H68_NLM_OS2_W32) || !defined(SFX))
742
    int i;
743
#endif
744
    int retcode, error=FALSE;
745
#ifndef NO_EXCEPT_SIGNALS
746
#ifdef REENTRANT
747
    savsigs_info *oldsighandlers = NULL;
748
#   define SET_SIGHANDLER(sigtype, newsighandler) \
749
      if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
750
                                      (newsighandler))) > PK_WARN) \
751
          goto cleanup_and_exit
752
#else
753
#   define SET_SIGHANDLER(sigtype, newsighandler) \
754
      signal((sigtype), (newsighandler))
755
#endif
756
#endif /* NO_EXCEPT_SIGNALS */
757
 
758
    /* initialize international char support to the current environment */
759
    SETLOCALE(LC_CTYPE, "");
760
 
761
#ifdef UNICODE_SUPPORT
762
    /* see if can use UTF-8 Unicode locale */
763
# ifdef UTF8_MAYBE_NATIVE
764
    {
765
        char *codeset;
766
#  if !(defined(NO_NL_LANGINFO) || defined(NO_LANGINFO_H))
767
        /* get the codeset (character set encoding) currently used */
768
#       include 
769
 
770
        codeset = nl_langinfo(CODESET);
771
#  else /* NO_NL_LANGINFO || NO_LANGINFO_H */
772
        /* query the current locale setting for character classification */
773
        codeset = setlocale(LC_CTYPE, NULL);
774
        if (codeset != NULL) {
775
            /* extract the codeset portion of the locale name */
776
            codeset = strchr(codeset, '.');
777
            if (codeset != NULL) ++codeset;
778
        }
779
#  endif /* ?(NO_NL_LANGINFO || NO_LANGINFO_H) */
780
        /* is the current codeset UTF-8 ? */
781
        if ((codeset != NULL) && (strcmp(codeset, "UTF-8") == 0)) {
782
            /* successfully found UTF-8 char coding */
783
            G.native_is_utf8 = TRUE;
784
        } else {
785
            /* Current codeset is not UTF-8 or cannot be determined. */
786
            G.native_is_utf8 = FALSE;
787
        }
788
        /* Note: At least for UnZip, trying to change the process codeset to
789
         *       UTF-8 does not work.  For the example Linux setup of the
790
         *       UnZip maintainer, a successful switch to "en-US.UTF-8"
791
         *       resulted in garbage display of all non-basic ASCII characters.
792
         */
6764 siemargl 793
#ifdef KOS32
794
        /* manual override */
795
        G.native_is_utf8 = TRUE;
796
#endif
6725 siemargl 797
    }
798
# endif /* UTF8_MAYBE_NATIVE */
799
 
800
    /* initialize Unicode */
801
    G.unicode_escape_all = 0;
802
    G.unicode_mismatch = 0;
803
 
804
    G.unipath_version = 0;
805
    G.unipath_checksum = 0;
806
    G.unipath_filename = NULL;
807
#endif /* UNICODE_SUPPORT */
808
 
809
 
810
#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
811
    extern void DebugMalloc(void);
812
 
813
    atexit(DebugMalloc);
814
#endif
815
 
816
#ifdef MALLOC_WORK
817
    /* The following (rather complex) expression determines the allocation
818
       size of the decompression work area.  It simulates what the
819
       combined "union" and "struct" declaration of the "static" work
820
       area reservation achieves automatically at compile time.
821
       Any decent compiler should evaluate this expression completely at
822
       compile time and provide constants to the zcalloc() call.
823
       (For better readability, some subexpressions are encapsulated
824
       in temporarly defined macros.)
825
     */
826
#   define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
827
#   define UZ_NUMOF_CHUNKS \
828
      (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
829
                 (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
830
    G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
831
#   undef UZ_SLIDE_CHUNK
832
#   undef UZ_NUMOF_CHUNKS
833
    G.area.shrink.Parent = (shrint *)G.area.Slide;
834
    G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
835
    G.area.shrink.Stack = G.area.Slide +
836
                           (sizeof(shrint) + sizeof(uch))*(HSIZE);
837
#endif
838
 
839
/*---------------------------------------------------------------------------
840
    Set signal handler for restoring echo, warn of zipfile corruption, etc.
841
  ---------------------------------------------------------------------------*/
842
#ifndef NO_EXCEPT_SIGNALS
843
#ifdef SIGINT
844
    SET_SIGHANDLER(SIGINT, handler);
845
#endif
846
#ifdef SIGTERM                 /* some systems really have no SIGTERM */
847
    SET_SIGHANDLER(SIGTERM, handler);
848
#endif
849
#if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
850
    SET_SIGHANDLER(SIGABRT, handler);
851
#endif
852
#ifdef SIGBREAK
853
    SET_SIGHANDLER(SIGBREAK, handler);
854
#endif
855
#ifdef SIGBUS
856
    SET_SIGHANDLER(SIGBUS, handler);
857
#endif
858
#ifdef SIGILL
859
    SET_SIGHANDLER(SIGILL, handler);
860
#endif
861
#ifdef SIGSEGV
862
    SET_SIGHANDLER(SIGSEGV, handler);
863
#endif
864
#endif /* NO_EXCEPT_SIGNALS */
865
 
866
#if (defined(WIN32) && defined(__RSXNT__))
867
    for (i = 0 ; i < argc; i++) {
868
        _ISO_INTERN(argv[i]);
869
    }
870
#endif
871
 
872
/*---------------------------------------------------------------------------
873
    Macintosh initialization code.
874
  ---------------------------------------------------------------------------*/
875
 
876
#ifdef MACOS
877
    {
878
        int a;
879
 
880
        for (a = 0;  a < 4;  ++a)
881
            G.rghCursor[a] = GetCursor(a+128);
882
        G.giCursor = 0;
883
    }
884
#endif
885
 
886
/*---------------------------------------------------------------------------
887
    NetWare initialization code.
888
  ---------------------------------------------------------------------------*/
889
 
890
#ifdef NLM
891
    InitUnZipConsole();
892
#endif
893
 
894
/*---------------------------------------------------------------------------
895
    Acorn RISC OS initialization code.
896
  ---------------------------------------------------------------------------*/
897
 
898
#ifdef RISCOS
899
    set_prefix();
900
#endif
901
 
902
/*---------------------------------------------------------------------------
903
    Theos initialization code.
904
  ---------------------------------------------------------------------------*/
905
 
906
#ifdef THEOS
907
    /* The easiest way found to force creation of libraries when selected
908
     * members are to be unzipped. Explicitly add libraries names to the
909
     * arguments list before the first member of the library.
910
     */
911
    if (! _setargv(&argc, &argv)) {
912
        Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
913
        retcode = PK_MEM;
914
        goto cleanup_and_exit;
915
    }
916
#endif
917
 
918
/*---------------------------------------------------------------------------
919
    Sanity checks.  Commentary by Otis B. Driftwood and Fiorello:
920
 
921
    D:  It's all right.  That's in every contract.  That's what they
922
        call a sanity clause.
923
 
924
    F:  Ha-ha-ha-ha-ha.  You can't fool me.  There ain't no Sanity
925
        Claus.
926
  ---------------------------------------------------------------------------*/
927
 
928
#ifdef DEBUG
929
# ifdef LARGE_FILE_SUPPORT
930
  /* test if we can support large files - 10/6/04 EG */
931
    if (sizeof(zoff_t) < 8) {
932
        Info(slide, 0x401, ((char *)slide, "LARGE_FILE_SUPPORT set but not supported\n"));
933
        retcode = PK_BADERR;
934
        goto cleanup_and_exit;
935
    }
936
    /* test if we can show 64-bit values */
937
    {
938
        zoff_t z = ~(zoff_t)0;  /* z should be all 1s now */
939
        char *sz;
940
 
941
        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
942
        if ((sz[0] != 'F') || (strlen(sz) != 16))
943
        {
944
            z = 0;
945
        }
946
 
947
        /* shift z so only MSB is set */
948
        z <<= 63;
949
        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
950
        if ((sz[0] != '8') || (strlen(sz) != 16))
951
        {
952
            Info(slide, 0x401, ((char *)slide,
953
              "Can't show 64-bit values correctly\n"));
954
            retcode = PK_BADERR;
955
            goto cleanup_and_exit;
956
        }
957
    }
958
# endif /* LARGE_FILE_SUPPORT */
959
 
960
    /* 2004-11-30 SMS.
961
       Test the NEXTBYTE macro for proper operation.
962
    */
963
    {
964
        int test_char;
965
        static uch test_buf[2] = { 'a', 'b' };
966
 
967
        G.inptr = test_buf;
968
        G.incnt = 1;
969
 
970
        test_char = NEXTBYTE;           /* Should get 'a'. */
971
        if (test_char == 'a')
972
        {
973
            test_char = NEXTBYTE;       /* Should get EOF, not 'b'. */
974
        }
975
        if (test_char != EOF)
976
        {
977
            Info(slide, 0x401, ((char *)slide,
978
 "NEXTBYTE macro failed.  Try compiling with ALT_NEXTBYTE defined?"));
979
 
980
            retcode = PK_BADERR;
981
            goto cleanup_and_exit;
982
        }
983
    }
984
#endif /* DEBUG */
985
 
986
/*---------------------------------------------------------------------------
987
    First figure out if we're running in UnZip mode or ZipInfo mode, and put
988
    the appropriate environment-variable options into the queue.  Then rip
989
    through any command-line options lurking about...
990
  ---------------------------------------------------------------------------*/
991
 
992
#ifdef SFX
993
    G.argv0 = argv[0];
994
#if (defined(OS2) || defined(WIN32))
995
    G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
996
#else
997
    G.zipfn = G.argv0;
998
#endif
999
 
1000
#ifdef VMSCLI
1001
    {
1002
        ulg status = vms_unzip_cmdline(&argc, &argv);
1003
        if (!(status & 1)) {
1004
            retcode = (int)status;
1005
            goto cleanup_and_exit;
1006
        }
1007
    }
1008
#endif /* VMSCLI */
1009
 
1010
    uO.zipinfo_mode = FALSE;
1011
    error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
1012
 
1013
#else /* !SFX */
1014
 
1015
#ifdef RISCOS
1016
    /* get the extensions to swap from environment */
1017
    getRISCOSexts(ENV_UNZIPEXTS);
1018
#endif
1019
 
1020
#ifdef MSDOS
1021
    /* extract MKS extended argument list from environment (before envargs!) */
1022
    mksargs(&argc, &argv);
1023
#endif
1024
 
1025
#ifdef VMSCLI
1026
    {
1027
        ulg status = vms_unzip_cmdline(&argc, &argv);
1028
        if (!(status & 1)) {
1029
            retcode = (int)status;
1030
            goto cleanup_and_exit;
1031
        }
1032
    }
1033
#endif /* VMSCLI */
1034
 
1035
    G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
1036
 
1037
#ifndef NO_ZIPINFO
1038
    for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
1039
        if (*p == DIR_END
1040
#ifdef DIR_END2
1041
            || *p == DIR_END2
1042
#endif
1043
           )
1044
            break;
1045
    }
1046
    ++p;
1047
 
1048
#ifdef THEOS
1049
    if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
1050
        strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
1051
#else
1052
    if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
1053
        STRNICMP(p, "ii", 2) == 0 ||
1054
#endif
1055
        (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
1056
    {
1057
        uO.zipinfo_mode = TRUE;
1058
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
1059
        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
1060
                             LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
1061
            perror(LoadFarString(NoMemEnvArguments));
1062
#endif
1063
    } else
1064
#endif /* !NO_ZIPINFO */
1065
    {
1066
        uO.zipinfo_mode = FALSE;
1067
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
1068
        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
1069
                             LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
1070
            perror(LoadFarString(NoMemEnvArguments));
1071
#endif
1072
    }
1073
 
1074
    if (!error) {
1075
        /* Check the length of all passed command line parameters.
1076
         * Command arguments might get sent through the Info() message
1077
         * system, which uses the sliding window area as string buffer.
1078
         * As arguments may additionally get fed through one of the FnFilter
1079
         * macros, we require all command line arguments to be shorter than
1080
         * WSIZE/4 (and ca. 2 standard line widths for fixed message text).
1081
         */
1082
        for (i = 1 ; i < argc; i++) {
1083
           if (strlen(argv[i]) > ((WSIZE>>2) - 160)) {
1084
               Info(slide, 0x401, ((char *)slide,
1085
                 LoadFarString(CmdLineParamTooLong), i));
1086
               retcode = PK_PARAM;
1087
               goto cleanup_and_exit;
1088
           }
1089
        }
1090
#ifndef NO_ZIPINFO
1091
        if (uO.zipinfo_mode)
1092
            error = zi_opts(__G__ &argc, &argv);
1093
        else
1094
#endif /* !NO_ZIPINFO */
1095
            error = uz_opts(__G__ &argc, &argv);
1096
    }
1097
 
1098
#endif /* ?SFX */
1099
 
1100
    if ((argc < 0) || error) {
1101
        retcode = error;
1102
        goto cleanup_and_exit;
1103
    }
1104
 
1105
/*---------------------------------------------------------------------------
1106
    Now get the zipfile name from the command line and then process any re-
1107
    maining options and file specifications.
1108
  ---------------------------------------------------------------------------*/
1109
 
1110
#ifdef DOS_FLX_H68_NLM_OS2_W32
1111
    /* convert MSDOS-style 'backward slash' directory separators to Unix-style
1112
     * 'forward slashes' for user's convenience (include zipfile name itself)
1113
     */
1114
#ifdef SFX
1115
    for (G.pfnames = argv, i = argc;  i > 0;  --i) {
1116
#else
1117
    /* argc does not include the zipfile specification */
1118
    for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
1119
#endif
1120
#ifdef __human68k__
1121
        extern char *_toslash(char *);
1122
        _toslash(*G.pfnames);
1123
#else /* !__human68k__ */
1124
        char *q = *G.pfnames;
1125
 
1126
        while (*q != '\0') {
1127
            if (*q == '\\')
1128
                *q = '/';
1129
            INCSTR(q);
1130
        }
1131
#endif /* ?__human68k__ */
1132
        ++G.pfnames;
1133
    }
1134
#endif /* DOS_FLX_H68_NLM_OS2_W32 */
1135
 
1136
#ifndef SFX
1137
    G.wildzipfn = *argv++;
1138
#endif
1139
 
1140
#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
1141
 
1142
    G.filespecs = argc;
1143
    G.xfilespecs = 0;
1144
 
1145
    if (argc > 0) {
1146
        char **pp = argv-1;
1147
 
1148
        G.pfnames = argv;
1149
        while (*++pp)
1150
            if (strcmp(*pp, "-x") == 0) {
1151
                if (pp > argv) {
1152
                    *pp = 0;              /* terminate G.pfnames */
1153
                    G.filespecs = pp - G.pfnames;
1154
                } else {
1155
                    G.pfnames = (char **)fnames;  /* defaults */
1156
                    G.filespecs = 0;
1157
                }
1158
                G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
1159
                G.xfilespecs = argc - G.filespecs - 1;
1160
                break;                    /* skip rest of args */
1161
            }
1162
        G.process_all_files = FALSE;
1163
    } else
1164
        G.process_all_files = TRUE;      /* for speed */
1165
 
1166
#else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
1167
 
1168
    G.filespecs = argc;
1169
    G.xfilespecs = 0;
1170
 
1171
    if (argc > 0) {
1172
        int in_files=FALSE, in_xfiles=FALSE;
1173
        char **pp = argv-1;
1174
 
1175
        G.process_all_files = FALSE;
1176
        G.pfnames = argv;
1177
        while (*++pp) {
1178
            Trace((stderr, "pp - argv = %d\n", pp-argv));
1179
#ifdef CMS_MVS
1180
            if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
1181
#else
1182
            if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
1183
#endif
1184
                int firstarg = (pp == argv);
1185
 
1186
                uO.exdir = (*pp) + 2;
1187
                if (in_files) {      /* ... zipfile ... -d exdir ... */
1188
                    *pp = (char *)NULL;         /* terminate G.pfnames */
1189
                    G.filespecs = pp - G.pfnames;
1190
                    in_files = FALSE;
1191
                } else if (in_xfiles) {
1192
                    *pp = (char *)NULL;         /* terminate G.pxnames */
1193
                    G.xfilespecs = pp - G.pxnames;
1194
                    /* "... -x xlist -d exdir":  nothing left */
1195
                }
1196
                /* first check for "-dexdir", then for "-d exdir" */
1197
                if (*uO.exdir == '\0') {
1198
                    if (*++pp)
1199
                        uO.exdir = *pp;
1200
                    else {
1201
                        Info(slide, 0x401, ((char *)slide,
1202
                          LoadFarString(MustGiveExdir)));
1203
                        /* don't extract here by accident */
1204
                        retcode = PK_PARAM;
1205
                        goto cleanup_and_exit;
1206
                    }
1207
                }
1208
                if (firstarg) { /* ... zipfile -d exdir ... */
1209
                    if (pp[1]) {
1210
                        G.pfnames = pp + 1;  /* argv+2 */
1211
                        G.filespecs = argc - (G.pfnames-argv);  /* for now... */
1212
                    } else {
1213
                        G.process_all_files = TRUE;
1214
                        G.pfnames = (char **)fnames;  /* GRR: necessary? */
1215
                        G.filespecs = 0;     /* GRR: necessary? */
1216
                        break;
1217
                    }
1218
                }
1219
            } else if (!in_xfiles) {
1220
                if (strcmp(*pp, "-x") == 0) {
1221
                    in_xfiles = TRUE;
1222
                    if (pp == G.pfnames) {
1223
                        G.pfnames = (char **)fnames;  /* defaults */
1224
                        G.filespecs = 0;
1225
                    } else if (in_files) {
1226
                        *pp = 0;                   /* terminate G.pfnames */
1227
                        G.filespecs = pp - G.pfnames;  /* adjust count */
1228
                        in_files = FALSE;
1229
                    }
1230
                    G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
1231
                    G.xfilespecs = argc - (G.pxnames-argv);  /* anything left */
1232
                } else
1233
                    in_files = TRUE;
1234
            }
1235
        }
1236
    } else
1237
        G.process_all_files = TRUE;      /* for speed */
1238
 
1239
    if (uO.exdir != (char *)NULL && !G.extract_flag)    /* -d ignored */
1240
        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
1241
#endif /* ?(SFX && !SFX_EXDIR) */
1242
 
1243
#ifdef UNICODE_SUPPORT
1244
    /* set Unicode-escape-all if option -U used */
1245
    if (uO.U_flag == 1)
1246
# ifdef UNICODE_WCHAR
1247
        G.unicode_escape_all = TRUE;
1248
# else
1249
        Info(slide, 0x401, ((char *)slide, LoadFarString(UTF8EscapeUnSupp)));
1250
# endif
1251
#endif
1252
 
1253
 
1254
/*---------------------------------------------------------------------------
1255
    Okey dokey, we have everything we need to get started.  Let's roll.
1256
  ---------------------------------------------------------------------------*/
1257
 
1258
    retcode = process_zipfiles(__G);
1259
 
1260
cleanup_and_exit:
1261
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
1262
    /* restore all signal handlers back to their state at function entry */
1263
    while (oldsighandlers != NULL) {
1264
        savsigs_info *thissigsav = oldsighandlers;
1265
 
1266
        signal(thissigsav->sigtype, thissigsav->sighandler);
1267
        oldsighandlers = thissigsav->previous;
1268
        free(thissigsav);
1269
    }
1270
#endif
1271
#if (defined(MALLOC_WORK) && !defined(REENTRANT))
1272
    if (G.area.Slide != (uch *)NULL) {
1273
        free(G.area.Slide);
1274
        G.area.Slide = (uch *)NULL;
1275
    }
1276
#endif
1277
#if (defined(MSDOS) && !defined(SFX) && !defined(WINDLL))
1278
    if (retcode != PK_OK)
1279
        check_for_windows("UnZip");
1280
#endif
1281
    return(retcode);
1282
 
1283
} /* end main()/unzip() */
1284
 
1285
 
1286
 
1287
 
1288
 
1289
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
1290
/*******************************/
1291
/* Function setsignalhandler() */
1292
/*******************************/
1293
 
1294
static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
1295
                            newhandler)
1296
    __GDEF
1297
    savsigs_info **p_savedhandler_chain;
1298
    int signal_type;
1299
    void (*newhandler)(int);
1300
{
1301
    savsigs_info *savsig;
1302
 
1303
    savsig = malloc(sizeof(savsigs_info));
1304
    if (savsig == NULL) {
1305
        /* error message and break */
1306
        Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
1307
        return PK_MEM;
1308
    }
1309
    savsig->sigtype = signal_type;
1310
    savsig->sighandler = signal(SIGINT, newhandler);
1311
    if (savsig->sighandler == SIG_ERR) {
1312
        free(savsig);
1313
    } else {
1314
        savsig->previous = *p_savedhandler_chain;
1315
        *p_savedhandler_chain = savsig;
1316
    }
1317
    return PK_OK;
1318
 
1319
} /* end function setsignalhandler() */
1320
 
1321
#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
1322
 
1323
 
1324
 
1325
 
1326
 
1327
/**********************/
1328
/* Function uz_opts() */
1329
/**********************/
1330
 
1331
int uz_opts(__G__ pargc, pargv)
1332
    __GDEF
1333
    int *pargc;
1334
    char ***pargv;
1335
{
1336
    char **argv, *s;
1337
    int argc, c, error=FALSE, negative=0, showhelp=0;
1338
 
1339
 
1340
    argc = *pargc;
1341
    argv = *pargv;
1342
 
1343
    while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
1344
        s = *argv + 1;
1345
        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
1346
#ifdef CMS_MVS
1347
            switch (tolower(c))
1348
#else
1349
            switch (c)
1350
#endif
1351
            {
1352
                case ('-'):
1353
                    ++negative;
1354
                    break;
1355
#ifdef RISCOS
1356
                case ('/'):
1357
                    if (negative) {   /* negative not allowed with -/ swap */
1358
                        Info(slide, 0x401, ((char *)slide,
1359
                          "error:  must give extensions list"));
1360
                        return(PK_PARAM);  /* don't extract here by accident */
1361
                    }
1362
                    exts2swap = s; /* override Unzip$Exts */
1363
                    s += strlen(s);
1364
                    break;
1365
#endif
1366
                case ('a'):
1367
                    if (negative) {
1368
                        uO.aflag = MAX(uO.aflag-negative,0);
1369
                        negative = 0;
1370
                    } else
1371
                        ++uO.aflag;
1372
                    break;
1373
#if (defined(DLL) && defined(API_DOC))
1374
                case ('A'):    /* extended help for API */
1375
                    APIhelp(__G__ argc, argv);
1376
                    *pargc = -1;  /* signal to exit successfully */
1377
                    return 0;
1378
#endif
1379
                case ('b'):
1380
                    if (negative) {
1381
#if (defined(TANDEM) || defined(VMS))
1382
                        uO.bflag = MAX(uO.bflag-negative,0);
1383
#endif
1384
                        negative = 0;   /* do nothing:  "-b" is default */
1385
                    } else {
1386
#ifdef VMS
1387
                        if (uO.aflag == 0)
1388
                           ++uO.bflag;
1389
#endif
1390
#ifdef TANDEM
1391
                        ++uO.bflag;
1392
#endif
1393
                        uO.aflag = 0;
1394
                    }
1395
                    break;
1396
#ifdef UNIXBACKUP
1397
                case ('B'): /* -B: back up existing files */
1398
                    if (negative)
1399
                        uO.B_flag = FALSE, negative = 0;
1400
                    else
1401
                        uO.B_flag = TRUE;
1402
                    break;
1403
#endif
1404
                case ('c'):
1405
                    if (negative) {
1406
                        uO.cflag = FALSE, negative = 0;
1407
#ifdef NATIVE
1408
                        uO.aflag = 0;
1409
#endif
1410
                    } else {
1411
                        uO.cflag = TRUE;
1412
#ifdef NATIVE
1413
                        uO.aflag = 2;   /* so you can read it on the screen */
1414
#endif
1415
#ifdef DLL
1416
                        if (G.redirect_text)
1417
                            G.redirect_data = 2;
1418
#endif
1419
                    }
1420
                    break;
1421
#ifndef CMS_MVS
1422
                case ('C'):    /* -C:  match filenames case-insensitively */
1423
                    if (negative)
1424
                        uO.C_flag = FALSE, negative = 0;
1425
                    else
1426
                        uO.C_flag = TRUE;
1427
                    break;
1428
#endif /* !CMS_MVS */
1429
#if (!defined(SFX) || defined(SFX_EXDIR))
1430
                case ('d'):
1431
                    if (negative) {   /* negative not allowed with -d exdir */
1432
                        Info(slide, 0x401, ((char *)slide,
1433
                          LoadFarString(MustGiveExdir)));
1434
                        return(PK_PARAM);  /* don't extract here by accident */
1435
                    }
1436
                    if (uO.exdir != (char *)NULL) {
1437
                        Info(slide, 0x401, ((char *)slide,
1438
                          LoadFarString(OnlyOneExdir)));
1439
                        return(PK_PARAM);    /* GRR:  stupid restriction? */
1440
                    } else {
1441
                        /* first check for "-dexdir", then for "-d exdir" */
1442
                        uO.exdir = s;
1443
                        if (*uO.exdir == '\0') {
1444
                            if (argc > 1) {
1445
                                --argc;
1446
                                uO.exdir = *++argv;
1447
                                if (*uO.exdir == '-') {
1448
                                    Info(slide, 0x401, ((char *)slide,
1449
                                      LoadFarString(MustGiveExdir)));
1450
                                    return(PK_PARAM);
1451
                                }
1452
                                /* else uO.exdir points at extraction dir */
1453
                            } else {
1454
                                Info(slide, 0x401, ((char *)slide,
1455
                                  LoadFarString(MustGiveExdir)));
1456
                                return(PK_PARAM);
1457
                            }
1458
                        }
1459
                        /* uO.exdir now points at extraction dir (-dexdir or
1460
                         *  -d exdir); point s at end of exdir to avoid mis-
1461
                         *  interpretation of exdir characters as more options
1462
                         */
1463
                        if (*s != 0)
1464
                            while (*++s != 0)
1465
                                ;
1466
                    }
1467
                    break;
1468
#endif /* !SFX || SFX_EXDIR */
1469
#if (!defined(NO_TIMESTAMPS))
1470
                case ('D'):    /* -D: Skip restoring dir (or any) timestamp. */
1471
                    if (negative) {
1472
                        uO.D_flag = MAX(uO.D_flag-negative,0);
1473
                        negative = 0;
1474
                    } else
1475
                        uO.D_flag++;
1476
                    break;
1477
#endif /* (!NO_TIMESTAMPS) */
1478
                case ('e'):    /* just ignore -e, -x options (extract) */
1479
                    break;
1480
#ifdef MACOS
1481
                case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
1482
                    if( negative ) {
1483
                        uO.E_flag = FALSE, negative = 0;
1484
                    } else {
1485
                        uO.E_flag = TRUE;
1486
                    }
1487
                    break;
1488
#endif /* MACOS */
1489
                case ('f'):    /* "freshen" (extract only newer files) */
1490
                    if (negative)
1491
                        uO.fflag = uO.uflag = FALSE, negative = 0;
1492
                    else
1493
                        uO.fflag = uO.uflag = TRUE;
1494
                    break;
1495
#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
1496
                case ('F'):    /* Acorn filetype & NFS extension handling */
1497
                    if (negative)
1498
                        uO.acorn_nfs_ext = FALSE, negative = 0;
1499
                    else
1500
                        uO.acorn_nfs_ext = TRUE;
1501
                    break;
1502
#endif /* RISCOS || ACORN_FTYPE_NFS */
1503
                case ('h'):    /* just print help message and quit */
1504
                    if (showhelp == 0) {
1505
#ifndef SFX
1506
                        if (*s == 'h')
1507
                            showhelp = 2;
1508
                        else
1509
#endif /* !SFX */
1510
                        {
1511
                            showhelp = 1;
1512
                        }
1513
                    }
1514
                    break;
1515
#ifdef MACOS
1516
                case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
1517
                    if( negative ) {
1518
                        uO.i_flag = FALSE, negative = 0;
1519
                    } else {
1520
                        uO.i_flag = TRUE;
1521
                    }
1522
                    break;
1523
#endif  /* MACOS */
1524
                case ('j'):    /* junk pathnames/directory structure */
1525
                    if (negative)
1526
                        uO.jflag = FALSE, negative = 0;
1527
                    else
1528
                        uO.jflag = TRUE;
1529
                    break;
1530
#if (defined(ATH_BEO) || defined(MACOS))
1531
                case ('J'):    /* Junk AtheOS, BeOS or MacOS file attributes */
1532
                    if( negative ) {
1533
                        uO.J_flag = FALSE, negative = 0;
1534
                    } else {
1535
                        uO.J_flag = TRUE;
1536
                    }
1537
                    break;
1538
#endif /* ATH_BEO || MACOS */
1539
#ifdef ATH_BEO_UNX
1540
                case ('K'):
1541
                    if (negative) {
1542
                        uO.K_flag = FALSE, negative = 0;
1543
                    } else {
1544
                        uO.K_flag = TRUE;
1545
                    }
1546
                    break;
1547
#endif /* ATH_BEO_UNX */
1548
#ifndef SFX
1549
                case ('l'):
1550
                    if (negative) {
1551
                        uO.vflag = MAX(uO.vflag-negative,0);
1552
                        negative = 0;
1553
                    } else
1554
                        ++uO.vflag;
1555
                    break;
1556
#endif /* !SFX */
1557
#ifndef CMS_MVS
1558
                case ('L'):    /* convert (some) filenames to lowercase */
1559
                    if (negative) {
1560
                        uO.L_flag = MAX(uO.L_flag-negative,0);
1561
                        negative = 0;
1562
                    } else
1563
                        ++uO.L_flag;
1564
                    break;
1565
#endif /* !CMS_MVS */
1566
#ifdef MORE
1567
#ifdef CMS_MVS
1568
                case ('m'):
1569
#endif
1570
                case ('M'):    /* send all screen output through "more" fn. */
1571
/* GRR:  eventually check for numerical argument => height */
1572
                    if (negative)
1573
                        G.M_flag = FALSE, negative = 0;
1574
                    else
1575
                        G.M_flag = TRUE;
1576
                    break;
1577
#endif /* MORE */
1578
                case ('n'):    /* don't overwrite any files */
1579
                    if (negative)
1580
                        uO.overwrite_none = FALSE, negative = 0;
1581
                    else
1582
                        uO.overwrite_none = TRUE;
1583
                    break;
1584
#ifdef AMIGA
1585
                case ('N'):    /* restore comments as filenotes */
1586
                    if (negative)
1587
                        uO.N_flag = FALSE, negative = 0;
1588
                    else
1589
                        uO.N_flag = TRUE;
1590
                    break;
1591
#endif /* AMIGA */
1592
                case ('o'):    /* OK to overwrite files without prompting */
1593
                    if (negative) {
1594
                        uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
1595
                        negative = 0;
1596
                    } else
1597
                        ++uO.overwrite_all;
1598
                    break;
1599
                case ('p'):    /* pipes:  extract to stdout, no messages */
1600
                    if (negative) {
1601
                        uO.cflag = FALSE;
1602
                        uO.qflag = MAX(uO.qflag-999,0);
1603
                        negative = 0;
1604
                    } else {
1605
                        uO.cflag = TRUE;
1606
                        uO.qflag += 999;
1607
                    }
1608
                    break;
1609
#if CRYPT
1610
                /* GRR:  yes, this is highly insecure, but dozens of people
1611
                 * have pestered us for this, so here we go... */
1612
                case ('P'):
1613
                    if (negative) {   /* negative not allowed with -P passwd */
1614
                        Info(slide, 0x401, ((char *)slide,
1615
                          LoadFarString(MustGivePasswd)));
1616
                        return(PK_PARAM);  /* don't extract here by accident */
1617
                    }
1618
                    if (uO.pwdarg != (char *)NULL) {
1619
/*
1620
                        GRR:  eventually support multiple passwords?
1621
                        Info(slide, 0x401, ((char *)slide,
1622
                          LoadFarString(OnlyOnePasswd)));
1623
                        return(PK_PARAM);
1624
 */
1625
                    } else {
1626
                        /* first check for "-Ppasswd", then for "-P passwd" */
1627
                        uO.pwdarg = s;
1628
                        if (*uO.pwdarg == '\0') {
1629
                            if (argc > 1) {
1630
                                --argc;
1631
                                uO.pwdarg = *++argv;
1632
                                if (*uO.pwdarg == '-') {
1633
                                    Info(slide, 0x401, ((char *)slide,
1634
                                      LoadFarString(MustGivePasswd)));
1635
                                    return(PK_PARAM);
1636
                                }
1637
                                /* else pwdarg points at decryption password */
1638
                            } else {
1639
                                Info(slide, 0x401, ((char *)slide,
1640
                                  LoadFarString(MustGivePasswd)));
1641
                                return(PK_PARAM);
1642
                            }
1643
                        }
1644
                        /* pwdarg now points at decryption password (-Ppasswd or
1645
                         *  -P passwd); point s at end of passwd to avoid mis-
1646
                         *  interpretation of passwd characters as more options
1647
                         */
1648
                        if (*s != 0)
1649
                            while (*++s != 0)
1650
                                ;
1651
                    }
1652
                    break;
1653
#endif /* CRYPT */
1654
                case ('q'):    /* quiet:  fewer comments/messages */
1655
                    if (negative) {
1656
                        uO.qflag = MAX(uO.qflag-negative,0);
1657
                        negative = 0;
1658
                    } else
1659
                        ++uO.qflag;
1660
                    break;
1661
#ifdef QDOS
1662
                case ('Q'):   /* QDOS flags */
1663
                    qlflag ^= strtol(s, &s, 10);
1664
                    break;    /* we XOR this as we can config qlflags */
1665
#endif
1666
#ifdef TANDEM
1667
                case ('r'):    /* remove file extensions */
1668
                    if (negative)
1669
                        uO.rflag = FALSE, negative = 0;
1670
                    else
1671
                        uO.rflag = TRUE;
1672
                    break;
1673
#endif /* TANDEM */
1674
#ifdef DOS_FLX_NLM_OS2_W32
1675
                case ('s'):    /* spaces in filenames:  allow by default */
1676
                    if (negative)
1677
                        uO.sflag = FALSE, negative = 0;
1678
                    else
1679
                        uO.sflag = TRUE;
1680
                    break;
1681
#endif /* DOS_FLX_NLM_OS2_W32 */
1682
#ifdef VMS
1683
                /* VMS:  extract "text" files in Stream_LF format (-a[a]) */
1684
                case ('S'):
1685
                    if (negative)
1686
                        uO.S_flag = FALSE, negative = 0;
1687
                    else
1688
                        uO.S_flag = TRUE;
1689
                    break;
1690
#endif /* VMS */
1691
                case ('t'):
1692
                    if (negative)
1693
                        uO.tflag = FALSE, negative = 0;
1694
                    else
1695
                        uO.tflag = TRUE;
1696
                    break;
1697
#ifdef TIMESTAMP
1698
                case ('T'):
1699
                    if (negative)
1700
                        uO.T_flag = FALSE, negative = 0;
1701
                    else
1702
                        uO.T_flag = TRUE;
1703
                    break;
1704
#endif
1705
                case ('u'):    /* update (extract only new and newer files) */
1706
                    if (negative)
1707
                        uO.uflag = FALSE, negative = 0;
1708
                    else
1709
                        uO.uflag = TRUE;
1710
                    break;
1711
#ifdef UNICODE_SUPPORT
1712
                case ('U'):    /* escape UTF-8, or disable UTF-8 support */
1713
                    if (negative) {
1714
                        uO.U_flag = MAX(uO.U_flag-negative,0);
1715
                        negative = 0;
1716
                    } else
1717
                        uO.U_flag++;
1718
                    break;
1719
#else /* !UNICODE_SUPPORT */
1720
#ifndef CMS_MVS
1721
                case ('U'):    /* obsolete; to be removed in version 6.0 */
1722
                    if (negative)
1723
                        uO.L_flag = TRUE, negative = 0;
1724
                    else
1725
                        uO.L_flag = FALSE;
1726
                    break;
1727
#endif /* !CMS_MVS */
1728
#endif /* ?UNICODE_SUPPORT */
1729
#ifndef SFX
1730
                case ('v'):    /* verbose */
1731
                    if (negative) {
1732
                        uO.vflag = MAX(uO.vflag-negative,0);
1733
                        negative = 0;
1734
                    } else if (uO.vflag)
1735
                        ++uO.vflag;
1736
                    else
1737
                        uO.vflag = 2;
1738
                    break;
1739
#endif /* !SFX */
1740
#ifndef CMS_MVS
1741
                case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
1742
                    if (negative)
1743
                        uO.V_flag = FALSE, negative = 0;
1744
                    else
1745
                        uO.V_flag = TRUE;
1746
                    break;
1747
#endif /* !CMS_MVS */
1748
#ifdef WILD_STOP_AT_DIR
1749
                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
1750
                    if (negative)
1751
                        uO.W_flag = FALSE, negative = 0;
1752
                    else
1753
                        uO.W_flag = TRUE;
1754
                    break;
1755
#endif /* WILD_STOP_AT_DIR */
1756
                case ('x'):    /* extract:  default */
1757
#ifdef SFX
1758
                    /* when 'x' is the only option in this argument, and the
1759
                     * next arg is not an option, assume this initiates an
1760
                     * exclusion list (-x xlist):  terminate option-scanning
1761
                     * and leave uz_opts with argv still pointing to "-x";
1762
                     * the xlist is processed later
1763
                     */
1764
                    if (s - argv[0] == 2 && *s == '\0' &&
1765
                        argc > 1 && argv[1][0] != '-') {
1766
                        /* break out of nested loops without "++argv;--argc" */
1767
                        goto opts_done;
1768
                    }
1769
#endif /* SFX */
1770
                    break;
1771
#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
1772
                case ('X'):   /* restore owner/protection info (need privs?) */
1773
                    if (negative) {
1774
                        uO.X_flag = MAX(uO.X_flag-negative,0);
1775
                        negative = 0;
1776
                    } else
1777
                        ++uO.X_flag;
1778
                    break;
1779
#endif /* RESTORE_UIDGID || RESTORE_ACL */
1780
#ifdef VMS
1781
                case ('Y'):    /* Treat ".nnn" as ";nnn" version. */
1782
                    if (negative)
1783
                        uO.Y_flag = FALSE, negative = 0;
1784
                    else
1785
                        uO.Y_flag = TRUE;
1786
                    break;
1787
#endif /* VMS */
1788
                case ('z'):    /* display only the archive comment */
1789
                    if (negative) {
1790
                        uO.zflag = MAX(uO.zflag-negative,0);
1791
                        negative = 0;
1792
                    } else
1793
                        ++uO.zflag;
1794
                    break;
1795
#ifndef SFX
1796
                case ('Z'):    /* should have been first option (ZipInfo) */
1797
                    Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
1798
                    error = TRUE;
1799
                    break;
1800
#endif /* !SFX */
1801
#ifdef VMS
1802
                case ('2'):    /* Force ODS2-compliant names. */
1803
                    if (negative)
1804
                        uO.ods2_flag = FALSE, negative = 0;
1805
                    else
1806
                        uO.ods2_flag = TRUE;
1807
                    break;
1808
#endif /* VMS */
1809
#ifdef DOS_H68_OS2_W32
1810
                case ('$'):
1811
                    if (negative) {
1812
                        uO.volflag = MAX(uO.volflag-negative,0);
1813
                        negative = 0;
1814
                    } else
1815
                        ++uO.volflag;
1816
                    break;
1817
#endif /* DOS_H68_OS2_W32 */
1818
#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
1819
                case (':'):    /* allow "parent dir" path components */
1820
                    if (negative) {
1821
                        uO.ddotflag = MAX(uO.ddotflag-negative,0);
1822
                        negative = 0;
1823
                    } else
1824
                        ++uO.ddotflag;
1825
                    break;
1826
#endif /* !RISCOS && !CMS_MVS && !TANDEM */
1827
#ifdef UNIX
1828
                case ('^'):    /* allow control chars in filenames */
1829
                    if (negative) {
1830
                        uO.cflxflag = MAX(uO.cflxflag-negative,0);
1831
                        negative = 0;
1832
                    } else
1833
                        ++uO.cflxflag;
1834
                    break;
1835
#endif /* UNIX */
1836
                default:
1837
                    error = TRUE;
1838
                    break;
1839
 
1840
            } /* end switch */
1841
        } /* end while (not end of argument string) */
1842
    } /* end while (not done with switches) */
1843
 
1844
/*---------------------------------------------------------------------------
1845
    Check for nonsensical combinations of options.
1846
  ---------------------------------------------------------------------------*/
1847
 
1848
#ifdef SFX
1849
opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
1850
#endif
1851
 
1852
    if (showhelp > 0) {         /* just print help message and quit */
1853
        *pargc = -1;
1854
#ifndef SFX
1855
        if (showhelp == 2) {
1856
            help_extended(__G);
1857
            return PK_OK;
1858
        } else
1859
#endif /* !SFX */
1860
        {
1861
            return USAGE(PK_OK);
1862
        }
1863
    }
1864
 
1865
    if ((uO.cflag && (uO.tflag || uO.uflag)) ||
1866
        (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
1867
    {
1868
        Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
1869
        error = TRUE;
1870
    }
1871
    if (uO.aflag > 2)
1872
        uO.aflag = 2;
1873
#ifdef VMS
1874
    if (uO.bflag > 2)
1875
        uO.bflag = 2;
1876
    /* Clear -s flag when converting text files. */
1877
    if (uO.aflag <= 0)
1878
        uO.S_flag = 0;
1879
#endif /* VMS */
1880
    if (uO.overwrite_all && uO.overwrite_none) {
1881
        Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
1882
        uO.overwrite_all = FALSE;
1883
    }
1884
#ifdef MORE
1885
    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func. useless */
1886
        G.M_flag = 0;
1887
#endif
1888
 
1889
#ifdef SFX
1890
    if (error)
1891
#else
1892
    if ((argc-- == 0) || error)
1893
#endif
1894
    {
1895
        *pargc = argc;
1896
        *pargv = argv;
1897
#ifndef SFX
1898
        if (uO.vflag >= 2 && argc == -1) {              /* "unzip -v" */
1899
            show_version_info(__G);
1900
            return PK_OK;
1901
        }
1902
        if (!G.noargs && !error)
1903
            error = TRUE;       /* had options (not -h or -v) but no zipfile */
1904
#endif /* !SFX */
1905
        return USAGE(error);
1906
    }
1907
 
1908
#ifdef SFX
1909
    /* print our banner unless we're being fairly quiet */
1910
    if (uO.qflag < 2)
1911
        Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1912
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1913
          LoadFarStringSmall(VersionDate)));
1914
#ifdef BETA
1915
    /* always print the beta warning:  no unauthorized distribution!! */
1916
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1917
      "SFX"));
1918
#endif
1919
#endif /* SFX */
1920
 
1921
    if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
1922
#ifdef TIMESTAMP
1923
                                                     || uO.T_flag
1924
#endif
1925
                                                                 )
1926
        G.extract_flag = FALSE;
1927
    else
1928
        G.extract_flag = TRUE;
1929
 
1930
    *pargc = argc;
1931
    *pargv = argv;
1932
    return PK_OK;
1933
 
1934
} /* end function uz_opts() */
1935
 
1936
 
1937
 
1938
 
1939
/********************/
1940
/* Function usage() */
1941
/********************/
1942
 
1943
#ifdef SFX
1944
#  ifdef VMS
1945
#    define LOCAL "X.\n\
1946
(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
1947
#  endif
1948
#  ifdef UNIX
1949
#    define LOCAL "X"
1950
#  endif
1951
#  ifdef DOS_OS2_W32
1952
#    define LOCAL "s$"
1953
#  endif
1954
#  if (defined(FLEXOS) || defined(NLM))
1955
#    define LOCAL "s"
1956
#  endif
1957
#  ifdef AMIGA
1958
#    define LOCAL "N"
1959
#  endif
1960
   /* Default for all other systems: */
1961
#  ifndef LOCAL
1962
#    define LOCAL ""
1963
#  endif
1964
 
1965
#  ifndef NO_TIMESTAMP
1966
#    ifdef MORE
1967
#      define SFXOPT1 "DM"
1968
#    else
1969
#      define SFXOPT1 "D"
1970
#    endif
1971
#  else
1972
#    ifdef MORE
1973
#      define SFXOPT1 "M"
1974
#    else
1975
#      define SFXOPT1 ""
1976
#    endif
1977
#  endif
1978
 
1979
int usage(__G__ error)   /* return PK-type error code */
1980
    __GDEF
1981
    int error;
1982
{
1983
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1984
      UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1985
      LoadFarStringSmall(VersionDate)));
1986
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
1987
      SFXOPT1, LOCAL));
1988
#ifdef BETA
1989
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1990
      "SFX"));
1991
#endif
1992
 
1993
    if (error)
1994
        return PK_PARAM;
1995
    else
1996
        return PK_COOL;     /* just wanted usage screen: no error */
1997
 
1998
} /* end function usage() */
1999
 
2000
 
2001
 
2002
 
2003
 
2004
#else /* !SFX */
2005
#  ifdef VMS
2006
#    define QUOT '\"'
2007
#    define QUOTS "\""
2008
#  else
2009
#    define QUOT ' '
2010
#    define QUOTS ""
2011
#  endif
2012
 
2013
int usage(__G__ error)   /* return PK-type error code */
2014
    __GDEF
2015
    int error;
2016
{
2017
    int flag = (error? 1 : 0);
2018
 
2019
 
2020
/*---------------------------------------------------------------------------
2021
    Print either ZipInfo usage or UnZip usage, depending on incantation.
2022
    (Strings must be no longer than 512 bytes for Turbo C, apparently.)
2023
  ---------------------------------------------------------------------------*/
2024
 
2025
    if (uO.zipinfo_mode) {
2026
 
2027
#ifndef NO_ZIPINFO
2028
 
2029
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
2030
          ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2031
          LoadFarStringSmall(VersionDate),
2032
          LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
2033
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
2034
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
2035
          LoadFarStringSmall(ZipInfoUsageLine4)));
2036
#ifdef VMS
2037
        Info(slide, flag, ((char *)slide, "\n\
2038
You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
2039
\n"));
2040
#endif
2041
 
2042
#endif /* !NO_ZIPINFO */
2043
 
2044
    } else {   /* UnZip mode */
2045
 
2046
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
2047
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2048
          LoadFarStringSmall(VersionDate)));
2049
#ifdef BETA
2050
        Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
2051
#endif
2052
 
2053
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
2054
          ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
2055
#ifdef VMS
2056
        if (!error)  /* maybe no command-line tail found; show extra help */
2057
            Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
2058
#endif
2059
 
2060
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
2061
          LoadFarStringSmall(local1)));
2062
 
2063
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
2064
          LoadFarStringSmall(local2), LoadFarStringSmall2(local3)));
2065
 
2066
        /* This is extra work for SMALL_MEM, but it will work since
2067
         * LoadFarStringSmall2 uses the same buffer.  Remember, this
2068
         * is a hack. */
2069
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
2070
          LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
2071
          LoadFarStringSmall2(Example3)));
2072
 
2073
    } /* end if (uO.zipinfo_mode) */
2074
 
2075
    if (error)
2076
        return PK_PARAM;
2077
    else
2078
        return PK_COOL;     /* just wanted usage screen: no error */
2079
 
2080
} /* end function usage() */
2081
 
2082
#endif /* ?SFX */
2083
 
2084
 
2085
 
2086
 
2087
#ifndef SFX
2088
 
2089
/* Print extended help to stdout. */
2090
static void help_extended(__G)
2091
    __GDEF
2092
{
2093
    extent i;             /* counter for help array */
2094
 
2095
    /* help array */
2096
    static ZCONST char *text[] = {
2097
  "",
2098
  "Extended Help for UnZip",
2099
  "",
2100
  "See the UnZip Manual for more detailed help",
2101
  "",
2102
  "",
2103
  "UnZip lists and extracts files in zip archives.  The default action is to",
2104
  "extract zipfile entries to the current directory, creating directories as",
2105
  "needed.  With appropriate options, UnZip lists the contents of archives",
2106
  "instead.",
2107
  "",
2108
  "Basic unzip command line:",
2109
  "  unzip [-Z] options archive[.zip] [file ...] [-x xfile ...] [-d exdir]",
2110
  "",
2111
  "Some examples:",
2112
  "  unzip -l foo.zip        - list files in short format in archive foo.zip",
2113
  "",
2114
  "  unzip -t foo            - test the files in archive foo",
2115
  "",
2116
  "  unzip -Z foo            - list files using more detailed zipinfo format",
2117
  "",
2118
  "  unzip foo               - unzip the contents of foo in current dir",
2119
  "",
2120
  "  unzip -a foo            - unzip foo and convert text files to local OS",
2121
  "",
2122
  "If unzip is run in zipinfo mode, a more detailed list of archive contents",
2123
  "is provided.  The -Z option sets zipinfo mode and changes the available",
2124
  "options.",
2125
  "",
2126
  "Basic zipinfo command line:",
2127
  "  zipinfo options archive[.zip] [file ...] [-x xfile ...]",
2128
  "  unzip -Z options archive[.zip] [file ...] [-x xfile ...]",
2129
  "",
2130
  "Below, Mac OS refers to Mac OS before Mac OS X.  Mac OS X is a Unix based",
2131
  "port and is referred to as Unix Apple.",
2132
  "",
2133
  "",
2134
  "unzip options:",
2135
  "  -Z   Switch to zipinfo mode.  Must be first option.",
2136
  "  -hh  Display extended help.",
2137
  "  -A   [OS/2, Unix DLL] Print extended help for DLL.",
2138
  "  -c   Extract files to stdout/screen.  As -p but include names.  Also,",
2139
  "         -a allowed and EBCDIC conversions done if needed.",
2140
  "  -f   Freshen by extracting only if older file on disk.",
2141
  "  -l   List files using short form.",
2142
  "  -p   Extract files to pipe (stdout).  Only file data is output and all",
2143
  "         files extracted in binary mode (as stored).",
2144
  "  -t   Test archive files.",
2145
  "  -T   Set timestamp on archive(s) to that of newest file.  Similar to",
2146
  "       zip -o but faster.",
2147
  "  -u   Update existing older files on disk as -f and extract new files.",
2148
  "  -v   Use verbose list format.  If given alone as unzip -v show version",
2149
  "         information.  Also can be added to other list commands for more",
2150
  "         verbose output.",
2151
  "  -z   Display only archive comment.",
2152
  "",
2153
  "unzip modifiers:",
2154
  "  -a   Convert text files to local OS format.  Convert line ends, EOF",
2155
  "         marker, and from or to EBCDIC character set as needed.",
2156
  "  -b   Treat all files as binary.  [Tandem] Force filecode 180 ('C').",
2157
  "         [VMS] Autoconvert binary files.  -bb forces convert of all files.",
2158
  "  -B   [UNIXBACKUP compile option enabled] Save a backup copy of each",
2159
  "         overwritten file in foo~ or foo~99999 format.",
2160
  "  -C   Use case-insensitive matching.",
2161
  "  -D   Skip restoration of timestamps for extracted directories.  On VMS this",
2162
  "         is on by default and -D essentially becames -DD.",
2163
  "  -DD  Skip restoration of timestamps for all entries.",
2164
  "  -E   [MacOS (not Unix Apple)]  Display contents of MacOS extra field during",
2165
  "         restore.",
2166
  "  -F   [Acorn] Suppress removal of NFS filetype extension.  [Non-Acorn if",
2167
  "         ACORN_FTYPE_NFS] Translate filetype and append to name.",
2168
  "  -i   [MacOS] Ignore filenames in MacOS extra field.  Instead, use name in",
2169
  "         standard header.",
2170
  "  -j   Junk paths and deposit all files in extraction directory.",
2171
  "  -J   [BeOS] Junk file attributes.  [MacOS] Ignore MacOS specific info.",
2172
  "  -K   [AtheOS, BeOS, Unix] Restore SUID/SGID/Tacky file attributes.",
2173
  "  -L   Convert to lowercase any names from uppercase only file system.",
2174
  "  -LL  Convert all files to lowercase.",
2175
  "  -M   Pipe all output through internal pager similar to Unix more(1).",
2176
  "  -n   Never overwrite existing files.  Skip extracting that file, no prompt.",
2177
  "  -N   [Amiga] Extract file comments as Amiga filenotes.",
2178
  "  -o   Overwrite existing files without prompting.  Useful with -f.  Use with",
2179
  "         care.",
2180
  "  -P p Use password p to decrypt files.  THIS IS INSECURE!  Some OS show",
2181
  "         command line to other users.",
2182
  "  -q   Perform operations quietly.  The more q (as in -qq) the quieter.",
2183
  "  -s   [OS/2, NT, MS-DOS] Convert spaces in filenames to underscores.",
2184
  "  -S   [VMS] Convert text files (-a, -aa) into Stream_LF format.",
2185
  "  -U   [UNICODE enabled] Show non-local characters as #Uxxxx or #Lxxxxxx ASCII",
2186
  "         text escapes where x is hex digit.  [Old] -U used to leave names",
2187
  "         uppercase if created on MS-DOS, VMS, etc.  See -L.",
2188
  "  -UU  [UNICODE enabled] Disable use of stored UTF-8 paths.  Note that UTF-8",
2189
  "         paths stored as native local paths are still processed as Unicode.",
2190
  "  -V   Retain VMS file version numbers.",
2191
  "  -W   [Only if WILD_STOP_AT_DIR] Modify pattern matching so ? and * do not",
2192
  "         match directory separator /, but ** does.  Allows matching at specific",
2193
  "         directory levels.",
2194
  "  -X   [VMS, Unix, OS/2, NT, Tandem] Restore UICs and ACL entries under VMS,",
2195
  "         or UIDs/GIDs under Unix, or ACLs under certain network-enabled",
2196
  "         versions of OS/2, or security ACLs under Windows NT.  Can require",
2197
  "         user privileges.",
2198
  "  -XX  [NT] Extract NT security ACLs after trying to enable additional",
2199
  "         system privileges.",
2200
  "  -Y   [VMS] Treat archived name endings of .nnn as VMS version numbers.",
2201
  "  -$   [MS-DOS, OS/2, NT] Restore volume label if extraction medium is",
2202
  "         removable.  -$$ allows fixed media (hard drives) to be labeled.",
2203
  "  -/ e [Acorn] Use e as extension list.",
2204
  "  -:   [All but Acorn, VM/CMS, MVS, Tandem] Allow extract archive members into",
2205
  "         locations outside of current extraction root folder.  This allows",
2206
  "         paths such as ../foo to be extracted above the current extraction",
2207
  "         directory, which can be a security problem.",
2208
  "  -^   [Unix] Allow control characters in names of extracted entries.  Usually",
2209
  "         this is not a good thing and should be avoided.",
2210
  "  -2   [VMS] Force unconditional conversion of names to ODS-compatible names.",
2211
  "         Default is to exploit destination file system, preserving cases and",
2212
  "         extended name characters on ODS5 and applying ODS2 filtering on ODS2.",
2213
  "",
2214
  "",
2215
  "Wildcards:",
2216
  "  Internally unzip supports the following wildcards:",
2217
  "    ?       (or %% or #, depending on OS) matches any single character",
2218
  "    *       matches any number of characters, including zero",
2219
  "    [list]  matches char in list (regex), can do range [ac-f], all but [!bf]",
2220
  "  If port supports [], must escape [ as [[]",
2221
  "  For shells that expand wildcards, escape (\\* or \"*\") so unzip can recurse.",
2222
  "",
2223
  "Include and Exclude:",
2224
  "  -i pattern pattern ...   include files that match a pattern",
2225
  "  -x pattern pattern ...   exclude files that match a pattern",
2226
  "  Patterns are paths with optional wildcards and match paths as stored in",
2227
  "  archive.  Exclude and include lists end at next option or end of line.",
2228
  "    unzip archive -x pattern pattern ...",
2229
  "",
2230
  "Multi-part (split) archives (archives created as a set of split files):",
2231
  "  Currently split archives are not readable by unzip.  A workaround is",
2232
  "  to use zip to convert the split archive to a single-file archive and",
2233
  "  use unzip on that.  See the manual page for Zip 3.0 or later.",
2234
  "",
2235
  "Streaming (piping into unzip):",
2236
  "  Currently unzip does not support streaming.  The funzip utility can be",
2237
  "  used to process the first entry in a stream.",
2238
  "    cat archive | funzip",
2239
  "",
2240
  "Testing archives:",
2241
  "  -t        test contents of archive",
2242
  "  This can be modified using -q for quieter operation, and -qq for even",
2243
  "  quieter operation.",
2244
  "",
2245
  "Unicode:",
2246
  "  If compiled with Unicode support, unzip automatically handles archives",
2247
  "  with Unicode entries.  Currently Unicode on Win32 systems is limited.",
2248
  "  Characters not in the current character set are shown as ASCII escapes",
2249
  "  in the form #Uxxxx where the Unicode character number fits in 16 bits,",
2250
  "  or #Lxxxxxx where it doesn't, where x is the ASCII character for a hex",
2251
  "  digit.",
2252
  "",
2253
  "",
2254
  "zipinfo options (these are used in zipinfo mode (unzip -Z ...)):",
2255
  "  -1  List names only, one per line.  No headers/trailers.  Good for scripts.",
2256
  "  -2  List names only as -1, but include headers, trailers, and comments.",
2257
  "  -s  List archive entries in short Unix ls -l format.  Default list format.",
2258
  "  -m  List in long Unix ls -l format.  As -s, but includes compression %.",
2259
  "  -l  List in long Unix ls -l format.  As -m, but compression in bytes.",
2260
  "  -v  List zipfile information in verbose, multi-page format.",
2261
  "  -h  List header line.  Includes archive name, actual size, total files.",
2262
  "  -M  Pipe all output through internal pager similar to Unix more(1) command.",
2263
  "  -t  List totals for files listed or for all files.  Includes uncompressed",
2264
  "        and compressed sizes, and compression factors.",
2265
  "  -T  Print file dates and times in a sortable decimal format (yymmdd.hhmmss)",
2266
  "        Default date and time format is a more human-readable version.",
2267
  "  -U  [UNICODE] If entry has a UTF-8 Unicode path, display any characters",
2268
  "        not in current character set as text #Uxxxx and #Lxxxxxx escapes",
2269
  "        representing the Unicode character number of the character in hex.",
2270
  "  -UU [UNICODE]  Disable use of any UTF-8 path information.",
2271
  "  -z  Include archive comment if any in listing.",
2272
  "",
2273
  "",
2274
  "funzip stream extractor:",
2275
  "  funzip extracts the first member in an archive to stdout.  Typically",
2276
  "  used to unzip the first member of a stream or pipe.  If a file argument",
2277
  "  is given, read from that file instead of stdin.",
2278
  "",
2279
  "funzip command line:",
2280
  "  funzip [-password] [input[.zip|.gz]]",
2281
  "",
2282
  "",
2283
  "unzipsfx self extractor:",
2284
  "  Self-extracting archives made with unzipsfx are no more (or less)",
2285
  "  portable across different operating systems than unzip executables.",
2286
  "  In general, a self-extracting archive made on a particular Unix system,",
2287
  "  for example, will only self-extract under the same flavor of Unix.",
2288
  "  Regular unzip may still be used to extract embedded archive however.",
2289
  "",
2290
  "unzipsfx command line:",
2291
  "    [-options] [file(s) ... [-x xfile(s) ...]]",
2292
  "",
2293
  "unzipsfx options:",
2294
  "  -c, -p - Output to pipe.  (See above for unzip.)",
2295
  "  -f, -u - Freshen and Update, as for unzip.",
2296
  "  -t     - Test embedded archive.  (Can be used to list contents.)",
2297
  "  -z     - Print archive comment.  (See unzip above.)",
2298
  "",
2299
  "unzipsfx modifiers:",
2300
  "  Most unzip modifiers are supported.  These include",
2301
  "  -a     - Convert text files.",
2302
  "  -n     - Never overwrite.",
2303
  "  -o     - Overwrite without prompting.",
2304
  "  -q     - Quiet operation.",
2305
  "  -C     - Match names case-insensitively.",
2306
  "  -j     - Junk paths.",
2307
  "  -V     - Keep version numbers.",
2308
  "  -s     - Convert spaces to underscores.",
2309
  "  -$     - Restore volume label.",
2310
  "",
2311
  "If unzipsfx compiled with SFX_EXDIR defined, -d option also available:",
2312
  "  -d exd - Extract to directory exd.",
2313
  "By default, all files extracted to current directory.  This option",
2314
  "forces extraction to specified directory.",
2315
  "",
2316
  "See unzipsfx manual page for more information.",
2317
  ""
2318
    };
2319
 
2320
    for (i = 0; i < sizeof(text)/sizeof(char *); i++)
2321
    {
2322
        Info(slide, 0, ((char *)slide, "%s\n", text[i]));
2323
    }
2324
} /* end function help_extended() */
2325
 
2326
 
2327
 
2328
 
2329
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2330
#if (!defined(MODERN) || defined(NO_STDLIB_H))
2331
/* Declare getenv() to be sure (might be missing in some environments) */
2332
extern char *getenv();
2333
#endif
2334
#endif
2335
 
2336
/********************************/
2337
/* Function show_version_info() */
2338
/********************************/
2339
 
2340
static void show_version_info(__G)
2341
    __GDEF
2342
{
2343
    if (uO.qflag > 3)                           /* "unzip -vqqqq" */
2344
        Info(slide, 0, ((char *)slide, "%d\n",
2345
          (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
2346
    else {
2347
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2348
        char *envptr;
2349
#endif
2350
        int numopts = 0;
2351
 
2352
        Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
2353
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2354
          LoadFarStringSmall(VersionDate)));
2355
        Info(slide, 0, ((char *)slide,
2356
          LoadFarString(UnzipUsageLine2v)));
2357
        version(__G);
2358
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
2359
#ifdef ACORN_FTYPE_NFS
2360
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2361
          LoadFarStringSmall(AcornFtypeNFS)));
2362
        ++numopts;
2363
#endif
2364
#ifdef ASM_CRC
2365
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2366
          LoadFarStringSmall(AsmCRC)));
2367
        ++numopts;
2368
#endif
2369
#ifdef ASM_INFLATECODES
2370
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2371
          LoadFarStringSmall(AsmInflateCodes)));
2372
        ++numopts;
2373
#endif
2374
#ifdef CHECK_VERSIONS
2375
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2376
          LoadFarStringSmall(Check_Versions)));
2377
        ++numopts;
2378
#endif
2379
#ifdef COPYRIGHT_CLEAN
2380
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2381
          LoadFarStringSmall(Copyright_Clean)));
2382
        ++numopts;
2383
#endif
2384
#ifdef DEBUG
2385
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2386
          LoadFarStringSmall(UDebug)));
2387
        ++numopts;
2388
#endif
2389
#ifdef DEBUG_TIME
2390
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2391
          LoadFarStringSmall(DebugTime)));
2392
        ++numopts;
2393
#endif
2394
#ifdef DLL
2395
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2396
          LoadFarStringSmall(Dll)));
2397
        ++numopts;
2398
#endif
2399
#ifdef DOSWILD
2400
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2401
          LoadFarStringSmall(DosWild)));
2402
        ++numopts;
2403
#endif
2404
#ifdef LZW_CLEAN
2405
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2406
          LoadFarStringSmall(LZW_Clean)));
2407
        ++numopts;
2408
#endif
2409
#ifndef MORE
2410
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2411
          LoadFarStringSmall(No_More)));
2412
        ++numopts;
2413
#endif
2414
#ifdef NO_ZIPINFO
2415
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2416
          LoadFarStringSmall(No_ZipInfo)));
2417
        ++numopts;
2418
#endif
2419
#ifdef NTSD_EAS
2420
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2421
          LoadFarStringSmall(NTSDExtAttrib)));
2422
        ++numopts;
2423
#endif
2424
#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
2425
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2426
          LoadFarStringSmall(W32NoIZTimeFix)));
2427
        ++numopts;
2428
#endif
2429
#ifdef OLD_THEOS_EXTRA
2430
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2431
          LoadFarStringSmall(OldTheosExtra)));
2432
        ++numopts;
2433
#endif
2434
#ifdef OS2_EAS
2435
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2436
          LoadFarStringSmall(OS2ExtAttrib)));
2437
        ++numopts;
2438
#endif
2439
#ifdef QLZIP
2440
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2441
          LoadFarStringSmall(SMSExFldOnUnix)));
2442
        ++numopts;
2443
#endif
2444
#ifdef REENTRANT
2445
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2446
          LoadFarStringSmall(Reentrant)));
2447
        ++numopts;
2448
#endif
2449
#ifdef REGARGS
2450
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2451
          LoadFarStringSmall(RegArgs)));
2452
        ++numopts;
2453
#endif
2454
#ifdef RETURN_CODES
2455
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2456
          LoadFarStringSmall(Return_Codes)));
2457
        ++numopts;
2458
#endif
2459
#ifdef SET_DIR_ATTRIB
2460
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2461
          LoadFarStringSmall(SetDirAttrib)));
2462
        ++numopts;
2463
#endif
2464
#ifdef SYMLINKS
2465
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2466
          LoadFarStringSmall(SymLinkSupport)));
2467
        ++numopts;
2468
#endif
2469
#ifdef TIMESTAMP
2470
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2471
          LoadFarStringSmall(TimeStamp)));
2472
        ++numopts;
2473
#endif
2474
#ifdef UNIXBACKUP
2475
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2476
          LoadFarStringSmall(UnixBackup)));
2477
        ++numopts;
2478
#endif
2479
#ifdef USE_EF_UT_TIME
2480
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2481
          LoadFarStringSmall(Use_EF_UT_time)));
2482
        ++numopts;
2483
#endif
2484
#ifndef COPYRIGHT_CLEAN
2485
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2486
          LoadFarStringSmall(Use_Smith_Code)));
2487
        ++numopts;
2488
#endif
2489
#ifndef LZW_CLEAN
2490
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2491
          LoadFarStringSmall(Use_Unshrink)));
2492
        ++numopts;
2493
#endif
2494
#ifdef USE_DEFLATE64
2495
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2496
          LoadFarStringSmall(Use_Deflate64)));
2497
        ++numopts;
2498
#endif
2499
#ifdef UNICODE_SUPPORT
2500
# ifdef UTF8_MAYBE_NATIVE
2501
        sprintf((char *)(slide+256), LoadFarStringSmall(Use_Unicode),
2502
          LoadFarStringSmall2(G.native_is_utf8 ? SysChUTF8 : SysChOther));
2503
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2504
          (char *)(slide+256)));
2505
# else
2506
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2507
          LoadFarStringSmall(Use_Unicode)));
2508
# endif
2509
        ++numopts;
2510
#endif
2511
#ifdef _MBCS
2512
        sprintf((char *)(slide+256), LoadFarStringSmall(Have_MBCS_Support),
2513
          (unsigned int)MB_CUR_MAX);
2514
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2515
          (char *)(slide+256)));
2516
        ++numopts;
2517
#endif
2518
#ifdef MULT_VOLUME
2519
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2520
          LoadFarStringSmall(Use_MultiVol)));
2521
        ++numopts;
2522
#endif
2523
#ifdef LARGE_FILE_SUPPORT
2524
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2525
          LoadFarStringSmall(Use_LFS)));
2526
        ++numopts;
2527
#endif
2528
#ifdef ZIP64_SUPPORT
2529
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2530
          LoadFarStringSmall(Use_Zip64)));
2531
        ++numopts;
2532
#endif
2533
#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
2534
#  ifdef USE_DJGPP_ENV
2535
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2536
          LoadFarStringSmall(Use_DJGPP_Env)));
2537
        ++numopts;
2538
#  endif
2539
#  ifdef USE_DJGPP_GLOB
2540
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2541
          LoadFarStringSmall(Use_DJGPP_Glob)));
2542
        ++numopts;
2543
#  endif
2544
#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
2545
#ifdef USE_VFAT
2546
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2547
          LoadFarStringSmall(Use_VFAT_support)));
2548
        ++numopts;
2549
#endif
2550
#ifdef USE_ZLIB
2551
        sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
2552
          ZLIB_VERSION, zlibVersion());
2553
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2554
          (char *)(slide+256)));
2555
        ++numopts;
2556
#endif
2557
#ifdef USE_BZIP2
2558
        sprintf((char *)(slide+256), LoadFarStringSmall(UseBZip2),
2559
          BZ2_bzlibVersion());
2560
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2561
          (char *)(slide+256)));
2562
        ++numopts;
2563
#endif
2564
#ifdef VMS_TEXT_CONV
2565
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2566
          LoadFarStringSmall(VmsTextConv)));
2567
        ++numopts;
2568
#endif
2569
#ifdef VMSCLI
2570
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2571
          LoadFarStringSmall(VmsCLI)));
2572
        ++numopts;
2573
#endif
2574
#ifdef VMSWILD
2575
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2576
          LoadFarStringSmall(VmsWild)));
2577
        ++numopts;
2578
#endif
2579
#ifdef WILD_STOP_AT_DIR
2580
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2581
          LoadFarStringSmall(WildStopAtDir)));
2582
        ++numopts;
2583
#endif
2584
#if CRYPT
2585
# ifdef PASSWD_FROM_STDIN
2586
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2587
          LoadFarStringSmall(PasswdStdin)));
2588
# endif
2589
        Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
2590
          CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
2591
          LoadFarStringSmall(CryptDate)));
2592
        ++numopts;
2593
#endif /* CRYPT */
2594
        if (numopts == 0)
2595
            Info(slide, 0, ((char *)slide,
2596
              LoadFarString(CompileOptFormat),
2597
              LoadFarStringSmall(None)));
2598
 
2599
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2600
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
2601
        envptr = getenv(LoadFarStringSmall(EnvUnZip));
2602
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2603
          LoadFarStringSmall(EnvUnZip),
2604
          (envptr == (char *)NULL || *envptr == 0)?
2605
          LoadFarStringSmall2(None) : envptr));
2606
        envptr = getenv(LoadFarStringSmall(EnvUnZip2));
2607
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2608
          LoadFarStringSmall(EnvUnZip2),
2609
          (envptr == (char *)NULL || *envptr == 0)?
2610
          LoadFarStringSmall2(None) : envptr));
2611
        envptr = getenv(LoadFarStringSmall(EnvZipInfo));
2612
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2613
          LoadFarStringSmall(EnvZipInfo),
2614
          (envptr == (char *)NULL || *envptr == 0)?
2615
          LoadFarStringSmall2(None) : envptr));
2616
        envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
2617
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2618
          LoadFarStringSmall(EnvZipInfo2),
2619
          (envptr == (char *)NULL || *envptr == 0)?
2620
          LoadFarStringSmall2(None) : envptr));
2621
#ifndef __RSXNT__
2622
#ifdef __EMX__
2623
        envptr = getenv(LoadFarStringSmall(EnvEMX));
2624
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2625
          LoadFarStringSmall(EnvEMX),
2626
          (envptr == (char *)NULL || *envptr == 0)?
2627
          LoadFarStringSmall2(None) : envptr));
2628
        envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
2629
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2630
          LoadFarStringSmall(EnvEMXOPT),
2631
          (envptr == (char *)NULL || *envptr == 0)?
2632
          LoadFarStringSmall2(None) : envptr));
2633
#endif /* __EMX__ */
2634
#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
2635
        envptr = getenv(LoadFarStringSmall(EnvGO32));
2636
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2637
          LoadFarStringSmall(EnvGO32),
2638
          (envptr == (char *)NULL || *envptr == 0)?
2639
          LoadFarStringSmall2(None) : envptr));
2640
        envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
2641
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2642
          LoadFarStringSmall(EnvGO32TMP),
2643
          (envptr == (char *)NULL || *envptr == 0)?
2644
          LoadFarStringSmall2(None) : envptr));
2645
#endif /* __GO32__ && !(__DJGPP__ >= 2) */
2646
#endif /* !__RSXNT__ */
2647
#ifdef RISCOS
2648
        envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
2649
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2650
          LoadFarStringSmall(EnvUnZipExts),
2651
          (envptr == (char *)NULL || *envptr == 0)?
2652
          LoadFarStringSmall2(None) : envptr));
2653
#endif /* RISCOS */
2654
#endif /* !_WIN32_WCE */
2655
    }
2656
} /* end function show_version() */
2657
 
2658
#endif /* !SFX */
2659
#endif /* !WINDLL */