Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | 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
         */
793
    }
794
# endif /* UTF8_MAYBE_NATIVE */
795
 
796
    /* initialize Unicode */
797
    G.unicode_escape_all = 0;
798
    G.unicode_mismatch = 0;
799
 
800
    G.unipath_version = 0;
801
    G.unipath_checksum = 0;
802
    G.unipath_filename = NULL;
803
#endif /* UNICODE_SUPPORT */
804
 
805
 
806
#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
807
    extern void DebugMalloc(void);
808
 
809
    atexit(DebugMalloc);
810
#endif
811
 
812
#ifdef MALLOC_WORK
813
    /* The following (rather complex) expression determines the allocation
814
       size of the decompression work area.  It simulates what the
815
       combined "union" and "struct" declaration of the "static" work
816
       area reservation achieves automatically at compile time.
817
       Any decent compiler should evaluate this expression completely at
818
       compile time and provide constants to the zcalloc() call.
819
       (For better readability, some subexpressions are encapsulated
820
       in temporarly defined macros.)
821
     */
822
#   define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
823
#   define UZ_NUMOF_CHUNKS \
824
      (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
825
                 (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
826
    G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
827
#   undef UZ_SLIDE_CHUNK
828
#   undef UZ_NUMOF_CHUNKS
829
    G.area.shrink.Parent = (shrint *)G.area.Slide;
830
    G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
831
    G.area.shrink.Stack = G.area.Slide +
832
                           (sizeof(shrint) + sizeof(uch))*(HSIZE);
833
#endif
834
 
835
/*---------------------------------------------------------------------------
836
    Set signal handler for restoring echo, warn of zipfile corruption, etc.
837
  ---------------------------------------------------------------------------*/
838
#ifndef NO_EXCEPT_SIGNALS
839
#ifdef SIGINT
840
    SET_SIGHANDLER(SIGINT, handler);
841
#endif
842
#ifdef SIGTERM                 /* some systems really have no SIGTERM */
843
    SET_SIGHANDLER(SIGTERM, handler);
844
#endif
845
#if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
846
    SET_SIGHANDLER(SIGABRT, handler);
847
#endif
848
#ifdef SIGBREAK
849
    SET_SIGHANDLER(SIGBREAK, handler);
850
#endif
851
#ifdef SIGBUS
852
    SET_SIGHANDLER(SIGBUS, handler);
853
#endif
854
#ifdef SIGILL
855
    SET_SIGHANDLER(SIGILL, handler);
856
#endif
857
#ifdef SIGSEGV
858
    SET_SIGHANDLER(SIGSEGV, handler);
859
#endif
860
#endif /* NO_EXCEPT_SIGNALS */
861
 
862
#if (defined(WIN32) && defined(__RSXNT__))
863
    for (i = 0 ; i < argc; i++) {
864
        _ISO_INTERN(argv[i]);
865
    }
866
#endif
867
 
868
/*---------------------------------------------------------------------------
869
    Macintosh initialization code.
870
  ---------------------------------------------------------------------------*/
871
 
872
#ifdef MACOS
873
    {
874
        int a;
875
 
876
        for (a = 0;  a < 4;  ++a)
877
            G.rghCursor[a] = GetCursor(a+128);
878
        G.giCursor = 0;
879
    }
880
#endif
881
 
882
/*---------------------------------------------------------------------------
883
    NetWare initialization code.
884
  ---------------------------------------------------------------------------*/
885
 
886
#ifdef NLM
887
    InitUnZipConsole();
888
#endif
889
 
890
/*---------------------------------------------------------------------------
891
    Acorn RISC OS initialization code.
892
  ---------------------------------------------------------------------------*/
893
 
894
#ifdef RISCOS
895
    set_prefix();
896
#endif
897
 
898
/*---------------------------------------------------------------------------
899
    Theos initialization code.
900
  ---------------------------------------------------------------------------*/
901
 
902
#ifdef THEOS
903
    /* The easiest way found to force creation of libraries when selected
904
     * members are to be unzipped. Explicitly add libraries names to the
905
     * arguments list before the first member of the library.
906
     */
907
    if (! _setargv(&argc, &argv)) {
908
        Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
909
        retcode = PK_MEM;
910
        goto cleanup_and_exit;
911
    }
912
#endif
913
 
914
/*---------------------------------------------------------------------------
915
    Sanity checks.  Commentary by Otis B. Driftwood and Fiorello:
916
 
917
    D:  It's all right.  That's in every contract.  That's what they
918
        call a sanity clause.
919
 
920
    F:  Ha-ha-ha-ha-ha.  You can't fool me.  There ain't no Sanity
921
        Claus.
922
  ---------------------------------------------------------------------------*/
923
 
924
#ifdef DEBUG
925
# ifdef LARGE_FILE_SUPPORT
926
  /* test if we can support large files - 10/6/04 EG */
927
    if (sizeof(zoff_t) < 8) {
928
        Info(slide, 0x401, ((char *)slide, "LARGE_FILE_SUPPORT set but not supported\n"));
929
        retcode = PK_BADERR;
930
        goto cleanup_and_exit;
931
    }
932
    /* test if we can show 64-bit values */
933
    {
934
        zoff_t z = ~(zoff_t)0;  /* z should be all 1s now */
935
        char *sz;
936
 
937
        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
938
        if ((sz[0] != 'F') || (strlen(sz) != 16))
939
        {
940
            z = 0;
941
        }
942
 
943
        /* shift z so only MSB is set */
944
        z <<= 63;
945
        sz = FmZofft(z, FZOFFT_HEX_DOT_WID, "X");
946
        if ((sz[0] != '8') || (strlen(sz) != 16))
947
        {
948
            Info(slide, 0x401, ((char *)slide,
949
              "Can't show 64-bit values correctly\n"));
950
            retcode = PK_BADERR;
951
            goto cleanup_and_exit;
952
        }
953
    }
954
# endif /* LARGE_FILE_SUPPORT */
955
 
956
    /* 2004-11-30 SMS.
957
       Test the NEXTBYTE macro for proper operation.
958
    */
959
    {
960
        int test_char;
961
        static uch test_buf[2] = { 'a', 'b' };
962
 
963
        G.inptr = test_buf;
964
        G.incnt = 1;
965
 
966
        test_char = NEXTBYTE;           /* Should get 'a'. */
967
        if (test_char == 'a')
968
        {
969
            test_char = NEXTBYTE;       /* Should get EOF, not 'b'. */
970
        }
971
        if (test_char != EOF)
972
        {
973
            Info(slide, 0x401, ((char *)slide,
974
 "NEXTBYTE macro failed.  Try compiling with ALT_NEXTBYTE defined?"));
975
 
976
            retcode = PK_BADERR;
977
            goto cleanup_and_exit;
978
        }
979
    }
980
#endif /* DEBUG */
981
 
982
/*---------------------------------------------------------------------------
983
    First figure out if we're running in UnZip mode or ZipInfo mode, and put
984
    the appropriate environment-variable options into the queue.  Then rip
985
    through any command-line options lurking about...
986
  ---------------------------------------------------------------------------*/
987
 
988
#ifdef SFX
989
    G.argv0 = argv[0];
990
#if (defined(OS2) || defined(WIN32))
991
    G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
992
#else
993
    G.zipfn = G.argv0;
994
#endif
995
 
996
#ifdef VMSCLI
997
    {
998
        ulg status = vms_unzip_cmdline(&argc, &argv);
999
        if (!(status & 1)) {
1000
            retcode = (int)status;
1001
            goto cleanup_and_exit;
1002
        }
1003
    }
1004
#endif /* VMSCLI */
1005
 
1006
    uO.zipinfo_mode = FALSE;
1007
    error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
1008
 
1009
#else /* !SFX */
1010
 
1011
#ifdef RISCOS
1012
    /* get the extensions to swap from environment */
1013
    getRISCOSexts(ENV_UNZIPEXTS);
1014
#endif
1015
 
1016
#ifdef MSDOS
1017
    /* extract MKS extended argument list from environment (before envargs!) */
1018
    mksargs(&argc, &argv);
1019
#endif
1020
 
1021
#ifdef VMSCLI
1022
    {
1023
        ulg status = vms_unzip_cmdline(&argc, &argv);
1024
        if (!(status & 1)) {
1025
            retcode = (int)status;
1026
            goto cleanup_and_exit;
1027
        }
1028
    }
1029
#endif /* VMSCLI */
1030
 
1031
    G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
1032
 
1033
#ifndef NO_ZIPINFO
1034
    for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
1035
        if (*p == DIR_END
1036
#ifdef DIR_END2
1037
            || *p == DIR_END2
1038
#endif
1039
           )
1040
            break;
1041
    }
1042
    ++p;
1043
 
1044
#ifdef THEOS
1045
    if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
1046
        strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
1047
#else
1048
    if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
1049
        STRNICMP(p, "ii", 2) == 0 ||
1050
#endif
1051
        (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
1052
    {
1053
        uO.zipinfo_mode = TRUE;
1054
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
1055
        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
1056
                             LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
1057
            perror(LoadFarString(NoMemEnvArguments));
1058
#endif
1059
    } else
1060
#endif /* !NO_ZIPINFO */
1061
    {
1062
        uO.zipinfo_mode = FALSE;
1063
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
1064
        if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
1065
                             LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
1066
            perror(LoadFarString(NoMemEnvArguments));
1067
#endif
1068
    }
1069
 
1070
    if (!error) {
1071
        /* Check the length of all passed command line parameters.
1072
         * Command arguments might get sent through the Info() message
1073
         * system, which uses the sliding window area as string buffer.
1074
         * As arguments may additionally get fed through one of the FnFilter
1075
         * macros, we require all command line arguments to be shorter than
1076
         * WSIZE/4 (and ca. 2 standard line widths for fixed message text).
1077
         */
1078
        for (i = 1 ; i < argc; i++) {
1079
           if (strlen(argv[i]) > ((WSIZE>>2) - 160)) {
1080
               Info(slide, 0x401, ((char *)slide,
1081
                 LoadFarString(CmdLineParamTooLong), i));
1082
               retcode = PK_PARAM;
1083
               goto cleanup_and_exit;
1084
           }
1085
        }
1086
#ifndef NO_ZIPINFO
1087
        if (uO.zipinfo_mode)
1088
            error = zi_opts(__G__ &argc, &argv);
1089
        else
1090
#endif /* !NO_ZIPINFO */
1091
            error = uz_opts(__G__ &argc, &argv);
1092
    }
1093
 
1094
#endif /* ?SFX */
1095
 
1096
    if ((argc < 0) || error) {
1097
        retcode = error;
1098
        goto cleanup_and_exit;
1099
    }
1100
 
1101
/*---------------------------------------------------------------------------
1102
    Now get the zipfile name from the command line and then process any re-
1103
    maining options and file specifications.
1104
  ---------------------------------------------------------------------------*/
1105
 
1106
#ifdef DOS_FLX_H68_NLM_OS2_W32
1107
    /* convert MSDOS-style 'backward slash' directory separators to Unix-style
1108
     * 'forward slashes' for user's convenience (include zipfile name itself)
1109
     */
1110
#ifdef SFX
1111
    for (G.pfnames = argv, i = argc;  i > 0;  --i) {
1112
#else
1113
    /* argc does not include the zipfile specification */
1114
    for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
1115
#endif
1116
#ifdef __human68k__
1117
        extern char *_toslash(char *);
1118
        _toslash(*G.pfnames);
1119
#else /* !__human68k__ */
1120
        char *q = *G.pfnames;
1121
 
1122
        while (*q != '\0') {
1123
            if (*q == '\\')
1124
                *q = '/';
1125
            INCSTR(q);
1126
        }
1127
#endif /* ?__human68k__ */
1128
        ++G.pfnames;
1129
    }
1130
#endif /* DOS_FLX_H68_NLM_OS2_W32 */
1131
 
1132
#ifndef SFX
1133
    G.wildzipfn = *argv++;
1134
#endif
1135
 
1136
#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
1137
 
1138
    G.filespecs = argc;
1139
    G.xfilespecs = 0;
1140
 
1141
    if (argc > 0) {
1142
        char **pp = argv-1;
1143
 
1144
        G.pfnames = argv;
1145
        while (*++pp)
1146
            if (strcmp(*pp, "-x") == 0) {
1147
                if (pp > argv) {
1148
                    *pp = 0;              /* terminate G.pfnames */
1149
                    G.filespecs = pp - G.pfnames;
1150
                } else {
1151
                    G.pfnames = (char **)fnames;  /* defaults */
1152
                    G.filespecs = 0;
1153
                }
1154
                G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
1155
                G.xfilespecs = argc - G.filespecs - 1;
1156
                break;                    /* skip rest of args */
1157
            }
1158
        G.process_all_files = FALSE;
1159
    } else
1160
        G.process_all_files = TRUE;      /* for speed */
1161
 
1162
#else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
1163
 
1164
    G.filespecs = argc;
1165
    G.xfilespecs = 0;
1166
 
1167
    if (argc > 0) {
1168
        int in_files=FALSE, in_xfiles=FALSE;
1169
        char **pp = argv-1;
1170
 
1171
        G.process_all_files = FALSE;
1172
        G.pfnames = argv;
1173
        while (*++pp) {
1174
            Trace((stderr, "pp - argv = %d\n", pp-argv));
1175
#ifdef CMS_MVS
1176
            if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
1177
#else
1178
            if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
1179
#endif
1180
                int firstarg = (pp == argv);
1181
 
1182
                uO.exdir = (*pp) + 2;
1183
                if (in_files) {      /* ... zipfile ... -d exdir ... */
1184
                    *pp = (char *)NULL;         /* terminate G.pfnames */
1185
                    G.filespecs = pp - G.pfnames;
1186
                    in_files = FALSE;
1187
                } else if (in_xfiles) {
1188
                    *pp = (char *)NULL;         /* terminate G.pxnames */
1189
                    G.xfilespecs = pp - G.pxnames;
1190
                    /* "... -x xlist -d exdir":  nothing left */
1191
                }
1192
                /* first check for "-dexdir", then for "-d exdir" */
1193
                if (*uO.exdir == '\0') {
1194
                    if (*++pp)
1195
                        uO.exdir = *pp;
1196
                    else {
1197
                        Info(slide, 0x401, ((char *)slide,
1198
                          LoadFarString(MustGiveExdir)));
1199
                        /* don't extract here by accident */
1200
                        retcode = PK_PARAM;
1201
                        goto cleanup_and_exit;
1202
                    }
1203
                }
1204
                if (firstarg) { /* ... zipfile -d exdir ... */
1205
                    if (pp[1]) {
1206
                        G.pfnames = pp + 1;  /* argv+2 */
1207
                        G.filespecs = argc - (G.pfnames-argv);  /* for now... */
1208
                    } else {
1209
                        G.process_all_files = TRUE;
1210
                        G.pfnames = (char **)fnames;  /* GRR: necessary? */
1211
                        G.filespecs = 0;     /* GRR: necessary? */
1212
                        break;
1213
                    }
1214
                }
1215
            } else if (!in_xfiles) {
1216
                if (strcmp(*pp, "-x") == 0) {
1217
                    in_xfiles = TRUE;
1218
                    if (pp == G.pfnames) {
1219
                        G.pfnames = (char **)fnames;  /* defaults */
1220
                        G.filespecs = 0;
1221
                    } else if (in_files) {
1222
                        *pp = 0;                   /* terminate G.pfnames */
1223
                        G.filespecs = pp - G.pfnames;  /* adjust count */
1224
                        in_files = FALSE;
1225
                    }
1226
                    G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
1227
                    G.xfilespecs = argc - (G.pxnames-argv);  /* anything left */
1228
                } else
1229
                    in_files = TRUE;
1230
            }
1231
        }
1232
    } else
1233
        G.process_all_files = TRUE;      /* for speed */
1234
 
1235
    if (uO.exdir != (char *)NULL && !G.extract_flag)    /* -d ignored */
1236
        Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
1237
#endif /* ?(SFX && !SFX_EXDIR) */
1238
 
1239
#ifdef UNICODE_SUPPORT
1240
    /* set Unicode-escape-all if option -U used */
1241
    if (uO.U_flag == 1)
1242
# ifdef UNICODE_WCHAR
1243
        G.unicode_escape_all = TRUE;
1244
# else
1245
        Info(slide, 0x401, ((char *)slide, LoadFarString(UTF8EscapeUnSupp)));
1246
# endif
1247
#endif
1248
 
1249
 
1250
/*---------------------------------------------------------------------------
1251
    Okey dokey, we have everything we need to get started.  Let's roll.
1252
  ---------------------------------------------------------------------------*/
1253
 
1254
    retcode = process_zipfiles(__G);
1255
 
1256
cleanup_and_exit:
1257
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
1258
    /* restore all signal handlers back to their state at function entry */
1259
    while (oldsighandlers != NULL) {
1260
        savsigs_info *thissigsav = oldsighandlers;
1261
 
1262
        signal(thissigsav->sigtype, thissigsav->sighandler);
1263
        oldsighandlers = thissigsav->previous;
1264
        free(thissigsav);
1265
    }
1266
#endif
1267
#if (defined(MALLOC_WORK) && !defined(REENTRANT))
1268
    if (G.area.Slide != (uch *)NULL) {
1269
        free(G.area.Slide);
1270
        G.area.Slide = (uch *)NULL;
1271
    }
1272
#endif
1273
#if (defined(MSDOS) && !defined(SFX) && !defined(WINDLL))
1274
    if (retcode != PK_OK)
1275
        check_for_windows("UnZip");
1276
#endif
1277
    return(retcode);
1278
 
1279
} /* end main()/unzip() */
1280
 
1281
 
1282
 
1283
 
1284
 
1285
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
1286
/*******************************/
1287
/* Function setsignalhandler() */
1288
/*******************************/
1289
 
1290
static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
1291
                            newhandler)
1292
    __GDEF
1293
    savsigs_info **p_savedhandler_chain;
1294
    int signal_type;
1295
    void (*newhandler)(int);
1296
{
1297
    savsigs_info *savsig;
1298
 
1299
    savsig = malloc(sizeof(savsigs_info));
1300
    if (savsig == NULL) {
1301
        /* error message and break */
1302
        Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
1303
        return PK_MEM;
1304
    }
1305
    savsig->sigtype = signal_type;
1306
    savsig->sighandler = signal(SIGINT, newhandler);
1307
    if (savsig->sighandler == SIG_ERR) {
1308
        free(savsig);
1309
    } else {
1310
        savsig->previous = *p_savedhandler_chain;
1311
        *p_savedhandler_chain = savsig;
1312
    }
1313
    return PK_OK;
1314
 
1315
} /* end function setsignalhandler() */
1316
 
1317
#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
1318
 
1319
 
1320
 
1321
 
1322
 
1323
/**********************/
1324
/* Function uz_opts() */
1325
/**********************/
1326
 
1327
int uz_opts(__G__ pargc, pargv)
1328
    __GDEF
1329
    int *pargc;
1330
    char ***pargv;
1331
{
1332
    char **argv, *s;
1333
    int argc, c, error=FALSE, negative=0, showhelp=0;
1334
 
1335
 
1336
    argc = *pargc;
1337
    argv = *pargv;
1338
 
1339
    while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
1340
        s = *argv + 1;
1341
        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
1342
#ifdef CMS_MVS
1343
            switch (tolower(c))
1344
#else
1345
            switch (c)
1346
#endif
1347
            {
1348
                case ('-'):
1349
                    ++negative;
1350
                    break;
1351
#ifdef RISCOS
1352
                case ('/'):
1353
                    if (negative) {   /* negative not allowed with -/ swap */
1354
                        Info(slide, 0x401, ((char *)slide,
1355
                          "error:  must give extensions list"));
1356
                        return(PK_PARAM);  /* don't extract here by accident */
1357
                    }
1358
                    exts2swap = s; /* override Unzip$Exts */
1359
                    s += strlen(s);
1360
                    break;
1361
#endif
1362
                case ('a'):
1363
                    if (negative) {
1364
                        uO.aflag = MAX(uO.aflag-negative,0);
1365
                        negative = 0;
1366
                    } else
1367
                        ++uO.aflag;
1368
                    break;
1369
#if (defined(DLL) && defined(API_DOC))
1370
                case ('A'):    /* extended help for API */
1371
                    APIhelp(__G__ argc, argv);
1372
                    *pargc = -1;  /* signal to exit successfully */
1373
                    return 0;
1374
#endif
1375
                case ('b'):
1376
                    if (negative) {
1377
#if (defined(TANDEM) || defined(VMS))
1378
                        uO.bflag = MAX(uO.bflag-negative,0);
1379
#endif
1380
                        negative = 0;   /* do nothing:  "-b" is default */
1381
                    } else {
1382
#ifdef VMS
1383
                        if (uO.aflag == 0)
1384
                           ++uO.bflag;
1385
#endif
1386
#ifdef TANDEM
1387
                        ++uO.bflag;
1388
#endif
1389
                        uO.aflag = 0;
1390
                    }
1391
                    break;
1392
#ifdef UNIXBACKUP
1393
                case ('B'): /* -B: back up existing files */
1394
                    if (negative)
1395
                        uO.B_flag = FALSE, negative = 0;
1396
                    else
1397
                        uO.B_flag = TRUE;
1398
                    break;
1399
#endif
1400
                case ('c'):
1401
                    if (negative) {
1402
                        uO.cflag = FALSE, negative = 0;
1403
#ifdef NATIVE
1404
                        uO.aflag = 0;
1405
#endif
1406
                    } else {
1407
                        uO.cflag = TRUE;
1408
#ifdef NATIVE
1409
                        uO.aflag = 2;   /* so you can read it on the screen */
1410
#endif
1411
#ifdef DLL
1412
                        if (G.redirect_text)
1413
                            G.redirect_data = 2;
1414
#endif
1415
                    }
1416
                    break;
1417
#ifndef CMS_MVS
1418
                case ('C'):    /* -C:  match filenames case-insensitively */
1419
                    if (negative)
1420
                        uO.C_flag = FALSE, negative = 0;
1421
                    else
1422
                        uO.C_flag = TRUE;
1423
                    break;
1424
#endif /* !CMS_MVS */
1425
#if (!defined(SFX) || defined(SFX_EXDIR))
1426
                case ('d'):
1427
                    if (negative) {   /* negative not allowed with -d exdir */
1428
                        Info(slide, 0x401, ((char *)slide,
1429
                          LoadFarString(MustGiveExdir)));
1430
                        return(PK_PARAM);  /* don't extract here by accident */
1431
                    }
1432
                    if (uO.exdir != (char *)NULL) {
1433
                        Info(slide, 0x401, ((char *)slide,
1434
                          LoadFarString(OnlyOneExdir)));
1435
                        return(PK_PARAM);    /* GRR:  stupid restriction? */
1436
                    } else {
1437
                        /* first check for "-dexdir", then for "-d exdir" */
1438
                        uO.exdir = s;
1439
                        if (*uO.exdir == '\0') {
1440
                            if (argc > 1) {
1441
                                --argc;
1442
                                uO.exdir = *++argv;
1443
                                if (*uO.exdir == '-') {
1444
                                    Info(slide, 0x401, ((char *)slide,
1445
                                      LoadFarString(MustGiveExdir)));
1446
                                    return(PK_PARAM);
1447
                                }
1448
                                /* else uO.exdir points at extraction dir */
1449
                            } else {
1450
                                Info(slide, 0x401, ((char *)slide,
1451
                                  LoadFarString(MustGiveExdir)));
1452
                                return(PK_PARAM);
1453
                            }
1454
                        }
1455
                        /* uO.exdir now points at extraction dir (-dexdir or
1456
                         *  -d exdir); point s at end of exdir to avoid mis-
1457
                         *  interpretation of exdir characters as more options
1458
                         */
1459
                        if (*s != 0)
1460
                            while (*++s != 0)
1461
                                ;
1462
                    }
1463
                    break;
1464
#endif /* !SFX || SFX_EXDIR */
1465
#if (!defined(NO_TIMESTAMPS))
1466
                case ('D'):    /* -D: Skip restoring dir (or any) timestamp. */
1467
                    if (negative) {
1468
                        uO.D_flag = MAX(uO.D_flag-negative,0);
1469
                        negative = 0;
1470
                    } else
1471
                        uO.D_flag++;
1472
                    break;
1473
#endif /* (!NO_TIMESTAMPS) */
1474
                case ('e'):    /* just ignore -e, -x options (extract) */
1475
                    break;
1476
#ifdef MACOS
1477
                case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
1478
                    if( negative ) {
1479
                        uO.E_flag = FALSE, negative = 0;
1480
                    } else {
1481
                        uO.E_flag = TRUE;
1482
                    }
1483
                    break;
1484
#endif /* MACOS */
1485
                case ('f'):    /* "freshen" (extract only newer files) */
1486
                    if (negative)
1487
                        uO.fflag = uO.uflag = FALSE, negative = 0;
1488
                    else
1489
                        uO.fflag = uO.uflag = TRUE;
1490
                    break;
1491
#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
1492
                case ('F'):    /* Acorn filetype & NFS extension handling */
1493
                    if (negative)
1494
                        uO.acorn_nfs_ext = FALSE, negative = 0;
1495
                    else
1496
                        uO.acorn_nfs_ext = TRUE;
1497
                    break;
1498
#endif /* RISCOS || ACORN_FTYPE_NFS */
1499
                case ('h'):    /* just print help message and quit */
1500
                    if (showhelp == 0) {
1501
#ifndef SFX
1502
                        if (*s == 'h')
1503
                            showhelp = 2;
1504
                        else
1505
#endif /* !SFX */
1506
                        {
1507
                            showhelp = 1;
1508
                        }
1509
                    }
1510
                    break;
1511
#ifdef MACOS
1512
                case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
1513
                    if( negative ) {
1514
                        uO.i_flag = FALSE, negative = 0;
1515
                    } else {
1516
                        uO.i_flag = TRUE;
1517
                    }
1518
                    break;
1519
#endif  /* MACOS */
1520
                case ('j'):    /* junk pathnames/directory structure */
1521
                    if (negative)
1522
                        uO.jflag = FALSE, negative = 0;
1523
                    else
1524
                        uO.jflag = TRUE;
1525
                    break;
1526
#if (defined(ATH_BEO) || defined(MACOS))
1527
                case ('J'):    /* Junk AtheOS, BeOS or MacOS file attributes */
1528
                    if( negative ) {
1529
                        uO.J_flag = FALSE, negative = 0;
1530
                    } else {
1531
                        uO.J_flag = TRUE;
1532
                    }
1533
                    break;
1534
#endif /* ATH_BEO || MACOS */
1535
#ifdef ATH_BEO_UNX
1536
                case ('K'):
1537
                    if (negative) {
1538
                        uO.K_flag = FALSE, negative = 0;
1539
                    } else {
1540
                        uO.K_flag = TRUE;
1541
                    }
1542
                    break;
1543
#endif /* ATH_BEO_UNX */
1544
#ifndef SFX
1545
                case ('l'):
1546
                    if (negative) {
1547
                        uO.vflag = MAX(uO.vflag-negative,0);
1548
                        negative = 0;
1549
                    } else
1550
                        ++uO.vflag;
1551
                    break;
1552
#endif /* !SFX */
1553
#ifndef CMS_MVS
1554
                case ('L'):    /* convert (some) filenames to lowercase */
1555
                    if (negative) {
1556
                        uO.L_flag = MAX(uO.L_flag-negative,0);
1557
                        negative = 0;
1558
                    } else
1559
                        ++uO.L_flag;
1560
                    break;
1561
#endif /* !CMS_MVS */
1562
#ifdef MORE
1563
#ifdef CMS_MVS
1564
                case ('m'):
1565
#endif
1566
                case ('M'):    /* send all screen output through "more" fn. */
1567
/* GRR:  eventually check for numerical argument => height */
1568
                    if (negative)
1569
                        G.M_flag = FALSE, negative = 0;
1570
                    else
1571
                        G.M_flag = TRUE;
1572
                    break;
1573
#endif /* MORE */
1574
                case ('n'):    /* don't overwrite any files */
1575
                    if (negative)
1576
                        uO.overwrite_none = FALSE, negative = 0;
1577
                    else
1578
                        uO.overwrite_none = TRUE;
1579
                    break;
1580
#ifdef AMIGA
1581
                case ('N'):    /* restore comments as filenotes */
1582
                    if (negative)
1583
                        uO.N_flag = FALSE, negative = 0;
1584
                    else
1585
                        uO.N_flag = TRUE;
1586
                    break;
1587
#endif /* AMIGA */
1588
                case ('o'):    /* OK to overwrite files without prompting */
1589
                    if (negative) {
1590
                        uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
1591
                        negative = 0;
1592
                    } else
1593
                        ++uO.overwrite_all;
1594
                    break;
1595
                case ('p'):    /* pipes:  extract to stdout, no messages */
1596
                    if (negative) {
1597
                        uO.cflag = FALSE;
1598
                        uO.qflag = MAX(uO.qflag-999,0);
1599
                        negative = 0;
1600
                    } else {
1601
                        uO.cflag = TRUE;
1602
                        uO.qflag += 999;
1603
                    }
1604
                    break;
1605
#if CRYPT
1606
                /* GRR:  yes, this is highly insecure, but dozens of people
1607
                 * have pestered us for this, so here we go... */
1608
                case ('P'):
1609
                    if (negative) {   /* negative not allowed with -P passwd */
1610
                        Info(slide, 0x401, ((char *)slide,
1611
                          LoadFarString(MustGivePasswd)));
1612
                        return(PK_PARAM);  /* don't extract here by accident */
1613
                    }
1614
                    if (uO.pwdarg != (char *)NULL) {
1615
/*
1616
                        GRR:  eventually support multiple passwords?
1617
                        Info(slide, 0x401, ((char *)slide,
1618
                          LoadFarString(OnlyOnePasswd)));
1619
                        return(PK_PARAM);
1620
 */
1621
                    } else {
1622
                        /* first check for "-Ppasswd", then for "-P passwd" */
1623
                        uO.pwdarg = s;
1624
                        if (*uO.pwdarg == '\0') {
1625
                            if (argc > 1) {
1626
                                --argc;
1627
                                uO.pwdarg = *++argv;
1628
                                if (*uO.pwdarg == '-') {
1629
                                    Info(slide, 0x401, ((char *)slide,
1630
                                      LoadFarString(MustGivePasswd)));
1631
                                    return(PK_PARAM);
1632
                                }
1633
                                /* else pwdarg points at decryption password */
1634
                            } else {
1635
                                Info(slide, 0x401, ((char *)slide,
1636
                                  LoadFarString(MustGivePasswd)));
1637
                                return(PK_PARAM);
1638
                            }
1639
                        }
1640
                        /* pwdarg now points at decryption password (-Ppasswd or
1641
                         *  -P passwd); point s at end of passwd to avoid mis-
1642
                         *  interpretation of passwd characters as more options
1643
                         */
1644
                        if (*s != 0)
1645
                            while (*++s != 0)
1646
                                ;
1647
                    }
1648
                    break;
1649
#endif /* CRYPT */
1650
                case ('q'):    /* quiet:  fewer comments/messages */
1651
                    if (negative) {
1652
                        uO.qflag = MAX(uO.qflag-negative,0);
1653
                        negative = 0;
1654
                    } else
1655
                        ++uO.qflag;
1656
                    break;
1657
#ifdef QDOS
1658
                case ('Q'):   /* QDOS flags */
1659
                    qlflag ^= strtol(s, &s, 10);
1660
                    break;    /* we XOR this as we can config qlflags */
1661
#endif
1662
#ifdef TANDEM
1663
                case ('r'):    /* remove file extensions */
1664
                    if (negative)
1665
                        uO.rflag = FALSE, negative = 0;
1666
                    else
1667
                        uO.rflag = TRUE;
1668
                    break;
1669
#endif /* TANDEM */
1670
#ifdef DOS_FLX_NLM_OS2_W32
1671
                case ('s'):    /* spaces in filenames:  allow by default */
1672
                    if (negative)
1673
                        uO.sflag = FALSE, negative = 0;
1674
                    else
1675
                        uO.sflag = TRUE;
1676
                    break;
1677
#endif /* DOS_FLX_NLM_OS2_W32 */
1678
#ifdef VMS
1679
                /* VMS:  extract "text" files in Stream_LF format (-a[a]) */
1680
                case ('S'):
1681
                    if (negative)
1682
                        uO.S_flag = FALSE, negative = 0;
1683
                    else
1684
                        uO.S_flag = TRUE;
1685
                    break;
1686
#endif /* VMS */
1687
                case ('t'):
1688
                    if (negative)
1689
                        uO.tflag = FALSE, negative = 0;
1690
                    else
1691
                        uO.tflag = TRUE;
1692
                    break;
1693
#ifdef TIMESTAMP
1694
                case ('T'):
1695
                    if (negative)
1696
                        uO.T_flag = FALSE, negative = 0;
1697
                    else
1698
                        uO.T_flag = TRUE;
1699
                    break;
1700
#endif
1701
                case ('u'):    /* update (extract only new and newer files) */
1702
                    if (negative)
1703
                        uO.uflag = FALSE, negative = 0;
1704
                    else
1705
                        uO.uflag = TRUE;
1706
                    break;
1707
#ifdef UNICODE_SUPPORT
1708
                case ('U'):    /* escape UTF-8, or disable UTF-8 support */
1709
                    if (negative) {
1710
                        uO.U_flag = MAX(uO.U_flag-negative,0);
1711
                        negative = 0;
1712
                    } else
1713
                        uO.U_flag++;
1714
                    break;
1715
#else /* !UNICODE_SUPPORT */
1716
#ifndef CMS_MVS
1717
                case ('U'):    /* obsolete; to be removed in version 6.0 */
1718
                    if (negative)
1719
                        uO.L_flag = TRUE, negative = 0;
1720
                    else
1721
                        uO.L_flag = FALSE;
1722
                    break;
1723
#endif /* !CMS_MVS */
1724
#endif /* ?UNICODE_SUPPORT */
1725
#ifndef SFX
1726
                case ('v'):    /* verbose */
1727
                    if (negative) {
1728
                        uO.vflag = MAX(uO.vflag-negative,0);
1729
                        negative = 0;
1730
                    } else if (uO.vflag)
1731
                        ++uO.vflag;
1732
                    else
1733
                        uO.vflag = 2;
1734
                    break;
1735
#endif /* !SFX */
1736
#ifndef CMS_MVS
1737
                case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
1738
                    if (negative)
1739
                        uO.V_flag = FALSE, negative = 0;
1740
                    else
1741
                        uO.V_flag = TRUE;
1742
                    break;
1743
#endif /* !CMS_MVS */
1744
#ifdef WILD_STOP_AT_DIR
1745
                case ('W'):    /* Wildcard interpretation (stop at '/'?) */
1746
                    if (negative)
1747
                        uO.W_flag = FALSE, negative = 0;
1748
                    else
1749
                        uO.W_flag = TRUE;
1750
                    break;
1751
#endif /* WILD_STOP_AT_DIR */
1752
                case ('x'):    /* extract:  default */
1753
#ifdef SFX
1754
                    /* when 'x' is the only option in this argument, and the
1755
                     * next arg is not an option, assume this initiates an
1756
                     * exclusion list (-x xlist):  terminate option-scanning
1757
                     * and leave uz_opts with argv still pointing to "-x";
1758
                     * the xlist is processed later
1759
                     */
1760
                    if (s - argv[0] == 2 && *s == '\0' &&
1761
                        argc > 1 && argv[1][0] != '-') {
1762
                        /* break out of nested loops without "++argv;--argc" */
1763
                        goto opts_done;
1764
                    }
1765
#endif /* SFX */
1766
                    break;
1767
#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
1768
                case ('X'):   /* restore owner/protection info (need privs?) */
1769
                    if (negative) {
1770
                        uO.X_flag = MAX(uO.X_flag-negative,0);
1771
                        negative = 0;
1772
                    } else
1773
                        ++uO.X_flag;
1774
                    break;
1775
#endif /* RESTORE_UIDGID || RESTORE_ACL */
1776
#ifdef VMS
1777
                case ('Y'):    /* Treat ".nnn" as ";nnn" version. */
1778
                    if (negative)
1779
                        uO.Y_flag = FALSE, negative = 0;
1780
                    else
1781
                        uO.Y_flag = TRUE;
1782
                    break;
1783
#endif /* VMS */
1784
                case ('z'):    /* display only the archive comment */
1785
                    if (negative) {
1786
                        uO.zflag = MAX(uO.zflag-negative,0);
1787
                        negative = 0;
1788
                    } else
1789
                        ++uO.zflag;
1790
                    break;
1791
#ifndef SFX
1792
                case ('Z'):    /* should have been first option (ZipInfo) */
1793
                    Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
1794
                    error = TRUE;
1795
                    break;
1796
#endif /* !SFX */
1797
#ifdef VMS
1798
                case ('2'):    /* Force ODS2-compliant names. */
1799
                    if (negative)
1800
                        uO.ods2_flag = FALSE, negative = 0;
1801
                    else
1802
                        uO.ods2_flag = TRUE;
1803
                    break;
1804
#endif /* VMS */
1805
#ifdef DOS_H68_OS2_W32
1806
                case ('$'):
1807
                    if (negative) {
1808
                        uO.volflag = MAX(uO.volflag-negative,0);
1809
                        negative = 0;
1810
                    } else
1811
                        ++uO.volflag;
1812
                    break;
1813
#endif /* DOS_H68_OS2_W32 */
1814
#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
1815
                case (':'):    /* allow "parent dir" path components */
1816
                    if (negative) {
1817
                        uO.ddotflag = MAX(uO.ddotflag-negative,0);
1818
                        negative = 0;
1819
                    } else
1820
                        ++uO.ddotflag;
1821
                    break;
1822
#endif /* !RISCOS && !CMS_MVS && !TANDEM */
1823
#ifdef UNIX
1824
                case ('^'):    /* allow control chars in filenames */
1825
                    if (negative) {
1826
                        uO.cflxflag = MAX(uO.cflxflag-negative,0);
1827
                        negative = 0;
1828
                    } else
1829
                        ++uO.cflxflag;
1830
                    break;
1831
#endif /* UNIX */
1832
                default:
1833
                    error = TRUE;
1834
                    break;
1835
 
1836
            } /* end switch */
1837
        } /* end while (not end of argument string) */
1838
    } /* end while (not done with switches) */
1839
 
1840
/*---------------------------------------------------------------------------
1841
    Check for nonsensical combinations of options.
1842
  ---------------------------------------------------------------------------*/
1843
 
1844
#ifdef SFX
1845
opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
1846
#endif
1847
 
1848
    if (showhelp > 0) {         /* just print help message and quit */
1849
        *pargc = -1;
1850
#ifndef SFX
1851
        if (showhelp == 2) {
1852
            help_extended(__G);
1853
            return PK_OK;
1854
        } else
1855
#endif /* !SFX */
1856
        {
1857
            return USAGE(PK_OK);
1858
        }
1859
    }
1860
 
1861
    if ((uO.cflag && (uO.tflag || uO.uflag)) ||
1862
        (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
1863
    {
1864
        Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
1865
        error = TRUE;
1866
    }
1867
    if (uO.aflag > 2)
1868
        uO.aflag = 2;
1869
#ifdef VMS
1870
    if (uO.bflag > 2)
1871
        uO.bflag = 2;
1872
    /* Clear -s flag when converting text files. */
1873
    if (uO.aflag <= 0)
1874
        uO.S_flag = 0;
1875
#endif /* VMS */
1876
    if (uO.overwrite_all && uO.overwrite_none) {
1877
        Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
1878
        uO.overwrite_all = FALSE;
1879
    }
1880
#ifdef MORE
1881
    if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func. useless */
1882
        G.M_flag = 0;
1883
#endif
1884
 
1885
#ifdef SFX
1886
    if (error)
1887
#else
1888
    if ((argc-- == 0) || error)
1889
#endif
1890
    {
1891
        *pargc = argc;
1892
        *pargv = argv;
1893
#ifndef SFX
1894
        if (uO.vflag >= 2 && argc == -1) {              /* "unzip -v" */
1895
            show_version_info(__G);
1896
            return PK_OK;
1897
        }
1898
        if (!G.noargs && !error)
1899
            error = TRUE;       /* had options (not -h or -v) but no zipfile */
1900
#endif /* !SFX */
1901
        return USAGE(error);
1902
    }
1903
 
1904
#ifdef SFX
1905
    /* print our banner unless we're being fairly quiet */
1906
    if (uO.qflag < 2)
1907
        Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1908
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1909
          LoadFarStringSmall(VersionDate)));
1910
#ifdef BETA
1911
    /* always print the beta warning:  no unauthorized distribution!! */
1912
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1913
      "SFX"));
1914
#endif
1915
#endif /* SFX */
1916
 
1917
    if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
1918
#ifdef TIMESTAMP
1919
                                                     || uO.T_flag
1920
#endif
1921
                                                                 )
1922
        G.extract_flag = FALSE;
1923
    else
1924
        G.extract_flag = TRUE;
1925
 
1926
    *pargc = argc;
1927
    *pargv = argv;
1928
    return PK_OK;
1929
 
1930
} /* end function uz_opts() */
1931
 
1932
 
1933
 
1934
 
1935
/********************/
1936
/* Function usage() */
1937
/********************/
1938
 
1939
#ifdef SFX
1940
#  ifdef VMS
1941
#    define LOCAL "X.\n\
1942
(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
1943
#  endif
1944
#  ifdef UNIX
1945
#    define LOCAL "X"
1946
#  endif
1947
#  ifdef DOS_OS2_W32
1948
#    define LOCAL "s$"
1949
#  endif
1950
#  if (defined(FLEXOS) || defined(NLM))
1951
#    define LOCAL "s"
1952
#  endif
1953
#  ifdef AMIGA
1954
#    define LOCAL "N"
1955
#  endif
1956
   /* Default for all other systems: */
1957
#  ifndef LOCAL
1958
#    define LOCAL ""
1959
#  endif
1960
 
1961
#  ifndef NO_TIMESTAMP
1962
#    ifdef MORE
1963
#      define SFXOPT1 "DM"
1964
#    else
1965
#      define SFXOPT1 "D"
1966
#    endif
1967
#  else
1968
#    ifdef MORE
1969
#      define SFXOPT1 "M"
1970
#    else
1971
#      define SFXOPT1 ""
1972
#    endif
1973
#  endif
1974
 
1975
int usage(__G__ error)   /* return PK-type error code */
1976
    __GDEF
1977
    int error;
1978
{
1979
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1980
      UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1981
      LoadFarStringSmall(VersionDate)));
1982
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
1983
      SFXOPT1, LOCAL));
1984
#ifdef BETA
1985
    Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1986
      "SFX"));
1987
#endif
1988
 
1989
    if (error)
1990
        return PK_PARAM;
1991
    else
1992
        return PK_COOL;     /* just wanted usage screen: no error */
1993
 
1994
} /* end function usage() */
1995
 
1996
 
1997
 
1998
 
1999
 
2000
#else /* !SFX */
2001
#  ifdef VMS
2002
#    define QUOT '\"'
2003
#    define QUOTS "\""
2004
#  else
2005
#    define QUOT ' '
2006
#    define QUOTS ""
2007
#  endif
2008
 
2009
int usage(__G__ error)   /* return PK-type error code */
2010
    __GDEF
2011
    int error;
2012
{
2013
    int flag = (error? 1 : 0);
2014
 
2015
 
2016
/*---------------------------------------------------------------------------
2017
    Print either ZipInfo usage or UnZip usage, depending on incantation.
2018
    (Strings must be no longer than 512 bytes for Turbo C, apparently.)
2019
  ---------------------------------------------------------------------------*/
2020
 
2021
    if (uO.zipinfo_mode) {
2022
 
2023
#ifndef NO_ZIPINFO
2024
 
2025
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
2026
          ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2027
          LoadFarStringSmall(VersionDate),
2028
          LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
2029
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
2030
        Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
2031
          LoadFarStringSmall(ZipInfoUsageLine4)));
2032
#ifdef VMS
2033
        Info(slide, flag, ((char *)slide, "\n\
2034
You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
2035
\n"));
2036
#endif
2037
 
2038
#endif /* !NO_ZIPINFO */
2039
 
2040
    } else {   /* UnZip mode */
2041
 
2042
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
2043
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2044
          LoadFarStringSmall(VersionDate)));
2045
#ifdef BETA
2046
        Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
2047
#endif
2048
 
2049
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
2050
          ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
2051
#ifdef VMS
2052
        if (!error)  /* maybe no command-line tail found; show extra help */
2053
            Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
2054
#endif
2055
 
2056
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
2057
          LoadFarStringSmall(local1)));
2058
 
2059
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
2060
          LoadFarStringSmall(local2), LoadFarStringSmall2(local3)));
2061
 
2062
        /* This is extra work for SMALL_MEM, but it will work since
2063
         * LoadFarStringSmall2 uses the same buffer.  Remember, this
2064
         * is a hack. */
2065
        Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
2066
          LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
2067
          LoadFarStringSmall2(Example3)));
2068
 
2069
    } /* end if (uO.zipinfo_mode) */
2070
 
2071
    if (error)
2072
        return PK_PARAM;
2073
    else
2074
        return PK_COOL;     /* just wanted usage screen: no error */
2075
 
2076
} /* end function usage() */
2077
 
2078
#endif /* ?SFX */
2079
 
2080
 
2081
 
2082
 
2083
#ifndef SFX
2084
 
2085
/* Print extended help to stdout. */
2086
static void help_extended(__G)
2087
    __GDEF
2088
{
2089
    extent i;             /* counter for help array */
2090
 
2091
    /* help array */
2092
    static ZCONST char *text[] = {
2093
  "",
2094
  "Extended Help for UnZip",
2095
  "",
2096
  "See the UnZip Manual for more detailed help",
2097
  "",
2098
  "",
2099
  "UnZip lists and extracts files in zip archives.  The default action is to",
2100
  "extract zipfile entries to the current directory, creating directories as",
2101
  "needed.  With appropriate options, UnZip lists the contents of archives",
2102
  "instead.",
2103
  "",
2104
  "Basic unzip command line:",
2105
  "  unzip [-Z] options archive[.zip] [file ...] [-x xfile ...] [-d exdir]",
2106
  "",
2107
  "Some examples:",
2108
  "  unzip -l foo.zip        - list files in short format in archive foo.zip",
2109
  "",
2110
  "  unzip -t foo            - test the files in archive foo",
2111
  "",
2112
  "  unzip -Z foo            - list files using more detailed zipinfo format",
2113
  "",
2114
  "  unzip foo               - unzip the contents of foo in current dir",
2115
  "",
2116
  "  unzip -a foo            - unzip foo and convert text files to local OS",
2117
  "",
2118
  "If unzip is run in zipinfo mode, a more detailed list of archive contents",
2119
  "is provided.  The -Z option sets zipinfo mode and changes the available",
2120
  "options.",
2121
  "",
2122
  "Basic zipinfo command line:",
2123
  "  zipinfo options archive[.zip] [file ...] [-x xfile ...]",
2124
  "  unzip -Z options archive[.zip] [file ...] [-x xfile ...]",
2125
  "",
2126
  "Below, Mac OS refers to Mac OS before Mac OS X.  Mac OS X is a Unix based",
2127
  "port and is referred to as Unix Apple.",
2128
  "",
2129
  "",
2130
  "unzip options:",
2131
  "  -Z   Switch to zipinfo mode.  Must be first option.",
2132
  "  -hh  Display extended help.",
2133
  "  -A   [OS/2, Unix DLL] Print extended help for DLL.",
2134
  "  -c   Extract files to stdout/screen.  As -p but include names.  Also,",
2135
  "         -a allowed and EBCDIC conversions done if needed.",
2136
  "  -f   Freshen by extracting only if older file on disk.",
2137
  "  -l   List files using short form.",
2138
  "  -p   Extract files to pipe (stdout).  Only file data is output and all",
2139
  "         files extracted in binary mode (as stored).",
2140
  "  -t   Test archive files.",
2141
  "  -T   Set timestamp on archive(s) to that of newest file.  Similar to",
2142
  "       zip -o but faster.",
2143
  "  -u   Update existing older files on disk as -f and extract new files.",
2144
  "  -v   Use verbose list format.  If given alone as unzip -v show version",
2145
  "         information.  Also can be added to other list commands for more",
2146
  "         verbose output.",
2147
  "  -z   Display only archive comment.",
2148
  "",
2149
  "unzip modifiers:",
2150
  "  -a   Convert text files to local OS format.  Convert line ends, EOF",
2151
  "         marker, and from or to EBCDIC character set as needed.",
2152
  "  -b   Treat all files as binary.  [Tandem] Force filecode 180 ('C').",
2153
  "         [VMS] Autoconvert binary files.  -bb forces convert of all files.",
2154
  "  -B   [UNIXBACKUP compile option enabled] Save a backup copy of each",
2155
  "         overwritten file in foo~ or foo~99999 format.",
2156
  "  -C   Use case-insensitive matching.",
2157
  "  -D   Skip restoration of timestamps for extracted directories.  On VMS this",
2158
  "         is on by default and -D essentially becames -DD.",
2159
  "  -DD  Skip restoration of timestamps for all entries.",
2160
  "  -E   [MacOS (not Unix Apple)]  Display contents of MacOS extra field during",
2161
  "         restore.",
2162
  "  -F   [Acorn] Suppress removal of NFS filetype extension.  [Non-Acorn if",
2163
  "         ACORN_FTYPE_NFS] Translate filetype and append to name.",
2164
  "  -i   [MacOS] Ignore filenames in MacOS extra field.  Instead, use name in",
2165
  "         standard header.",
2166
  "  -j   Junk paths and deposit all files in extraction directory.",
2167
  "  -J   [BeOS] Junk file attributes.  [MacOS] Ignore MacOS specific info.",
2168
  "  -K   [AtheOS, BeOS, Unix] Restore SUID/SGID/Tacky file attributes.",
2169
  "  -L   Convert to lowercase any names from uppercase only file system.",
2170
  "  -LL  Convert all files to lowercase.",
2171
  "  -M   Pipe all output through internal pager similar to Unix more(1).",
2172
  "  -n   Never overwrite existing files.  Skip extracting that file, no prompt.",
2173
  "  -N   [Amiga] Extract file comments as Amiga filenotes.",
2174
  "  -o   Overwrite existing files without prompting.  Useful with -f.  Use with",
2175
  "         care.",
2176
  "  -P p Use password p to decrypt files.  THIS IS INSECURE!  Some OS show",
2177
  "         command line to other users.",
2178
  "  -q   Perform operations quietly.  The more q (as in -qq) the quieter.",
2179
  "  -s   [OS/2, NT, MS-DOS] Convert spaces in filenames to underscores.",
2180
  "  -S   [VMS] Convert text files (-a, -aa) into Stream_LF format.",
2181
  "  -U   [UNICODE enabled] Show non-local characters as #Uxxxx or #Lxxxxxx ASCII",
2182
  "         text escapes where x is hex digit.  [Old] -U used to leave names",
2183
  "         uppercase if created on MS-DOS, VMS, etc.  See -L.",
2184
  "  -UU  [UNICODE enabled] Disable use of stored UTF-8 paths.  Note that UTF-8",
2185
  "         paths stored as native local paths are still processed as Unicode.",
2186
  "  -V   Retain VMS file version numbers.",
2187
  "  -W   [Only if WILD_STOP_AT_DIR] Modify pattern matching so ? and * do not",
2188
  "         match directory separator /, but ** does.  Allows matching at specific",
2189
  "         directory levels.",
2190
  "  -X   [VMS, Unix, OS/2, NT, Tandem] Restore UICs and ACL entries under VMS,",
2191
  "         or UIDs/GIDs under Unix, or ACLs under certain network-enabled",
2192
  "         versions of OS/2, or security ACLs under Windows NT.  Can require",
2193
  "         user privileges.",
2194
  "  -XX  [NT] Extract NT security ACLs after trying to enable additional",
2195
  "         system privileges.",
2196
  "  -Y   [VMS] Treat archived name endings of .nnn as VMS version numbers.",
2197
  "  -$   [MS-DOS, OS/2, NT] Restore volume label if extraction medium is",
2198
  "         removable.  -$$ allows fixed media (hard drives) to be labeled.",
2199
  "  -/ e [Acorn] Use e as extension list.",
2200
  "  -:   [All but Acorn, VM/CMS, MVS, Tandem] Allow extract archive members into",
2201
  "         locations outside of current extraction root folder.  This allows",
2202
  "         paths such as ../foo to be extracted above the current extraction",
2203
  "         directory, which can be a security problem.",
2204
  "  -^   [Unix] Allow control characters in names of extracted entries.  Usually",
2205
  "         this is not a good thing and should be avoided.",
2206
  "  -2   [VMS] Force unconditional conversion of names to ODS-compatible names.",
2207
  "         Default is to exploit destination file system, preserving cases and",
2208
  "         extended name characters on ODS5 and applying ODS2 filtering on ODS2.",
2209
  "",
2210
  "",
2211
  "Wildcards:",
2212
  "  Internally unzip supports the following wildcards:",
2213
  "    ?       (or %% or #, depending on OS) matches any single character",
2214
  "    *       matches any number of characters, including zero",
2215
  "    [list]  matches char in list (regex), can do range [ac-f], all but [!bf]",
2216
  "  If port supports [], must escape [ as [[]",
2217
  "  For shells that expand wildcards, escape (\\* or \"*\") so unzip can recurse.",
2218
  "",
2219
  "Include and Exclude:",
2220
  "  -i pattern pattern ...   include files that match a pattern",
2221
  "  -x pattern pattern ...   exclude files that match a pattern",
2222
  "  Patterns are paths with optional wildcards and match paths as stored in",
2223
  "  archive.  Exclude and include lists end at next option or end of line.",
2224
  "    unzip archive -x pattern pattern ...",
2225
  "",
2226
  "Multi-part (split) archives (archives created as a set of split files):",
2227
  "  Currently split archives are not readable by unzip.  A workaround is",
2228
  "  to use zip to convert the split archive to a single-file archive and",
2229
  "  use unzip on that.  See the manual page for Zip 3.0 or later.",
2230
  "",
2231
  "Streaming (piping into unzip):",
2232
  "  Currently unzip does not support streaming.  The funzip utility can be",
2233
  "  used to process the first entry in a stream.",
2234
  "    cat archive | funzip",
2235
  "",
2236
  "Testing archives:",
2237
  "  -t        test contents of archive",
2238
  "  This can be modified using -q for quieter operation, and -qq for even",
2239
  "  quieter operation.",
2240
  "",
2241
  "Unicode:",
2242
  "  If compiled with Unicode support, unzip automatically handles archives",
2243
  "  with Unicode entries.  Currently Unicode on Win32 systems is limited.",
2244
  "  Characters not in the current character set are shown as ASCII escapes",
2245
  "  in the form #Uxxxx where the Unicode character number fits in 16 bits,",
2246
  "  or #Lxxxxxx where it doesn't, where x is the ASCII character for a hex",
2247
  "  digit.",
2248
  "",
2249
  "",
2250
  "zipinfo options (these are used in zipinfo mode (unzip -Z ...)):",
2251
  "  -1  List names only, one per line.  No headers/trailers.  Good for scripts.",
2252
  "  -2  List names only as -1, but include headers, trailers, and comments.",
2253
  "  -s  List archive entries in short Unix ls -l format.  Default list format.",
2254
  "  -m  List in long Unix ls -l format.  As -s, but includes compression %.",
2255
  "  -l  List in long Unix ls -l format.  As -m, but compression in bytes.",
2256
  "  -v  List zipfile information in verbose, multi-page format.",
2257
  "  -h  List header line.  Includes archive name, actual size, total files.",
2258
  "  -M  Pipe all output through internal pager similar to Unix more(1) command.",
2259
  "  -t  List totals for files listed or for all files.  Includes uncompressed",
2260
  "        and compressed sizes, and compression factors.",
2261
  "  -T  Print file dates and times in a sortable decimal format (yymmdd.hhmmss)",
2262
  "        Default date and time format is a more human-readable version.",
2263
  "  -U  [UNICODE] If entry has a UTF-8 Unicode path, display any characters",
2264
  "        not in current character set as text #Uxxxx and #Lxxxxxx escapes",
2265
  "        representing the Unicode character number of the character in hex.",
2266
  "  -UU [UNICODE]  Disable use of any UTF-8 path information.",
2267
  "  -z  Include archive comment if any in listing.",
2268
  "",
2269
  "",
2270
  "funzip stream extractor:",
2271
  "  funzip extracts the first member in an archive to stdout.  Typically",
2272
  "  used to unzip the first member of a stream or pipe.  If a file argument",
2273
  "  is given, read from that file instead of stdin.",
2274
  "",
2275
  "funzip command line:",
2276
  "  funzip [-password] [input[.zip|.gz]]",
2277
  "",
2278
  "",
2279
  "unzipsfx self extractor:",
2280
  "  Self-extracting archives made with unzipsfx are no more (or less)",
2281
  "  portable across different operating systems than unzip executables.",
2282
  "  In general, a self-extracting archive made on a particular Unix system,",
2283
  "  for example, will only self-extract under the same flavor of Unix.",
2284
  "  Regular unzip may still be used to extract embedded archive however.",
2285
  "",
2286
  "unzipsfx command line:",
2287
  "    [-options] [file(s) ... [-x xfile(s) ...]]",
2288
  "",
2289
  "unzipsfx options:",
2290
  "  -c, -p - Output to pipe.  (See above for unzip.)",
2291
  "  -f, -u - Freshen and Update, as for unzip.",
2292
  "  -t     - Test embedded archive.  (Can be used to list contents.)",
2293
  "  -z     - Print archive comment.  (See unzip above.)",
2294
  "",
2295
  "unzipsfx modifiers:",
2296
  "  Most unzip modifiers are supported.  These include",
2297
  "  -a     - Convert text files.",
2298
  "  -n     - Never overwrite.",
2299
  "  -o     - Overwrite without prompting.",
2300
  "  -q     - Quiet operation.",
2301
  "  -C     - Match names case-insensitively.",
2302
  "  -j     - Junk paths.",
2303
  "  -V     - Keep version numbers.",
2304
  "  -s     - Convert spaces to underscores.",
2305
  "  -$     - Restore volume label.",
2306
  "",
2307
  "If unzipsfx compiled with SFX_EXDIR defined, -d option also available:",
2308
  "  -d exd - Extract to directory exd.",
2309
  "By default, all files extracted to current directory.  This option",
2310
  "forces extraction to specified directory.",
2311
  "",
2312
  "See unzipsfx manual page for more information.",
2313
  ""
2314
    };
2315
 
2316
    for (i = 0; i < sizeof(text)/sizeof(char *); i++)
2317
    {
2318
        Info(slide, 0, ((char *)slide, "%s\n", text[i]));
2319
    }
2320
} /* end function help_extended() */
2321
 
2322
 
2323
 
2324
 
2325
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2326
#if (!defined(MODERN) || defined(NO_STDLIB_H))
2327
/* Declare getenv() to be sure (might be missing in some environments) */
2328
extern char *getenv();
2329
#endif
2330
#endif
2331
 
2332
/********************************/
2333
/* Function show_version_info() */
2334
/********************************/
2335
 
2336
static void show_version_info(__G)
2337
    __GDEF
2338
{
2339
    if (uO.qflag > 3)                           /* "unzip -vqqqq" */
2340
        Info(slide, 0, ((char *)slide, "%d\n",
2341
          (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
2342
    else {
2343
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2344
        char *envptr;
2345
#endif
2346
        int numopts = 0;
2347
 
2348
        Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
2349
          UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
2350
          LoadFarStringSmall(VersionDate)));
2351
        Info(slide, 0, ((char *)slide,
2352
          LoadFarString(UnzipUsageLine2v)));
2353
        version(__G);
2354
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
2355
#ifdef ACORN_FTYPE_NFS
2356
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2357
          LoadFarStringSmall(AcornFtypeNFS)));
2358
        ++numopts;
2359
#endif
2360
#ifdef ASM_CRC
2361
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2362
          LoadFarStringSmall(AsmCRC)));
2363
        ++numopts;
2364
#endif
2365
#ifdef ASM_INFLATECODES
2366
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2367
          LoadFarStringSmall(AsmInflateCodes)));
2368
        ++numopts;
2369
#endif
2370
#ifdef CHECK_VERSIONS
2371
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2372
          LoadFarStringSmall(Check_Versions)));
2373
        ++numopts;
2374
#endif
2375
#ifdef COPYRIGHT_CLEAN
2376
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2377
          LoadFarStringSmall(Copyright_Clean)));
2378
        ++numopts;
2379
#endif
2380
#ifdef DEBUG
2381
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2382
          LoadFarStringSmall(UDebug)));
2383
        ++numopts;
2384
#endif
2385
#ifdef DEBUG_TIME
2386
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2387
          LoadFarStringSmall(DebugTime)));
2388
        ++numopts;
2389
#endif
2390
#ifdef DLL
2391
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2392
          LoadFarStringSmall(Dll)));
2393
        ++numopts;
2394
#endif
2395
#ifdef DOSWILD
2396
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2397
          LoadFarStringSmall(DosWild)));
2398
        ++numopts;
2399
#endif
2400
#ifdef LZW_CLEAN
2401
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2402
          LoadFarStringSmall(LZW_Clean)));
2403
        ++numopts;
2404
#endif
2405
#ifndef MORE
2406
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2407
          LoadFarStringSmall(No_More)));
2408
        ++numopts;
2409
#endif
2410
#ifdef NO_ZIPINFO
2411
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2412
          LoadFarStringSmall(No_ZipInfo)));
2413
        ++numopts;
2414
#endif
2415
#ifdef NTSD_EAS
2416
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2417
          LoadFarStringSmall(NTSDExtAttrib)));
2418
        ++numopts;
2419
#endif
2420
#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
2421
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2422
          LoadFarStringSmall(W32NoIZTimeFix)));
2423
        ++numopts;
2424
#endif
2425
#ifdef OLD_THEOS_EXTRA
2426
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2427
          LoadFarStringSmall(OldTheosExtra)));
2428
        ++numopts;
2429
#endif
2430
#ifdef OS2_EAS
2431
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2432
          LoadFarStringSmall(OS2ExtAttrib)));
2433
        ++numopts;
2434
#endif
2435
#ifdef QLZIP
2436
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2437
          LoadFarStringSmall(SMSExFldOnUnix)));
2438
        ++numopts;
2439
#endif
2440
#ifdef REENTRANT
2441
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2442
          LoadFarStringSmall(Reentrant)));
2443
        ++numopts;
2444
#endif
2445
#ifdef REGARGS
2446
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2447
          LoadFarStringSmall(RegArgs)));
2448
        ++numopts;
2449
#endif
2450
#ifdef RETURN_CODES
2451
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2452
          LoadFarStringSmall(Return_Codes)));
2453
        ++numopts;
2454
#endif
2455
#ifdef SET_DIR_ATTRIB
2456
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2457
          LoadFarStringSmall(SetDirAttrib)));
2458
        ++numopts;
2459
#endif
2460
#ifdef SYMLINKS
2461
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2462
          LoadFarStringSmall(SymLinkSupport)));
2463
        ++numopts;
2464
#endif
2465
#ifdef TIMESTAMP
2466
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2467
          LoadFarStringSmall(TimeStamp)));
2468
        ++numopts;
2469
#endif
2470
#ifdef UNIXBACKUP
2471
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2472
          LoadFarStringSmall(UnixBackup)));
2473
        ++numopts;
2474
#endif
2475
#ifdef USE_EF_UT_TIME
2476
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2477
          LoadFarStringSmall(Use_EF_UT_time)));
2478
        ++numopts;
2479
#endif
2480
#ifndef COPYRIGHT_CLEAN
2481
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2482
          LoadFarStringSmall(Use_Smith_Code)));
2483
        ++numopts;
2484
#endif
2485
#ifndef LZW_CLEAN
2486
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2487
          LoadFarStringSmall(Use_Unshrink)));
2488
        ++numopts;
2489
#endif
2490
#ifdef USE_DEFLATE64
2491
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2492
          LoadFarStringSmall(Use_Deflate64)));
2493
        ++numopts;
2494
#endif
2495
#ifdef UNICODE_SUPPORT
2496
# ifdef UTF8_MAYBE_NATIVE
2497
        sprintf((char *)(slide+256), LoadFarStringSmall(Use_Unicode),
2498
          LoadFarStringSmall2(G.native_is_utf8 ? SysChUTF8 : SysChOther));
2499
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2500
          (char *)(slide+256)));
2501
# else
2502
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2503
          LoadFarStringSmall(Use_Unicode)));
2504
# endif
2505
        ++numopts;
2506
#endif
2507
#ifdef _MBCS
2508
        sprintf((char *)(slide+256), LoadFarStringSmall(Have_MBCS_Support),
2509
          (unsigned int)MB_CUR_MAX);
2510
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2511
          (char *)(slide+256)));
2512
        ++numopts;
2513
#endif
2514
#ifdef MULT_VOLUME
2515
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2516
          LoadFarStringSmall(Use_MultiVol)));
2517
        ++numopts;
2518
#endif
2519
#ifdef LARGE_FILE_SUPPORT
2520
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2521
          LoadFarStringSmall(Use_LFS)));
2522
        ++numopts;
2523
#endif
2524
#ifdef ZIP64_SUPPORT
2525
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2526
          LoadFarStringSmall(Use_Zip64)));
2527
        ++numopts;
2528
#endif
2529
#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
2530
#  ifdef USE_DJGPP_ENV
2531
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2532
          LoadFarStringSmall(Use_DJGPP_Env)));
2533
        ++numopts;
2534
#  endif
2535
#  ifdef USE_DJGPP_GLOB
2536
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2537
          LoadFarStringSmall(Use_DJGPP_Glob)));
2538
        ++numopts;
2539
#  endif
2540
#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
2541
#ifdef USE_VFAT
2542
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2543
          LoadFarStringSmall(Use_VFAT_support)));
2544
        ++numopts;
2545
#endif
2546
#ifdef USE_ZLIB
2547
        sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
2548
          ZLIB_VERSION, zlibVersion());
2549
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2550
          (char *)(slide+256)));
2551
        ++numopts;
2552
#endif
2553
#ifdef USE_BZIP2
2554
        sprintf((char *)(slide+256), LoadFarStringSmall(UseBZip2),
2555
          BZ2_bzlibVersion());
2556
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2557
          (char *)(slide+256)));
2558
        ++numopts;
2559
#endif
2560
#ifdef VMS_TEXT_CONV
2561
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2562
          LoadFarStringSmall(VmsTextConv)));
2563
        ++numopts;
2564
#endif
2565
#ifdef VMSCLI
2566
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2567
          LoadFarStringSmall(VmsCLI)));
2568
        ++numopts;
2569
#endif
2570
#ifdef VMSWILD
2571
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2572
          LoadFarStringSmall(VmsWild)));
2573
        ++numopts;
2574
#endif
2575
#ifdef WILD_STOP_AT_DIR
2576
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2577
          LoadFarStringSmall(WildStopAtDir)));
2578
        ++numopts;
2579
#endif
2580
#if CRYPT
2581
# ifdef PASSWD_FROM_STDIN
2582
        Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
2583
          LoadFarStringSmall(PasswdStdin)));
2584
# endif
2585
        Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
2586
          CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
2587
          LoadFarStringSmall(CryptDate)));
2588
        ++numopts;
2589
#endif /* CRYPT */
2590
        if (numopts == 0)
2591
            Info(slide, 0, ((char *)slide,
2592
              LoadFarString(CompileOptFormat),
2593
              LoadFarStringSmall(None)));
2594
 
2595
#ifndef _WIN32_WCE /* Win CE does not support environment variables */
2596
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
2597
        envptr = getenv(LoadFarStringSmall(EnvUnZip));
2598
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2599
          LoadFarStringSmall(EnvUnZip),
2600
          (envptr == (char *)NULL || *envptr == 0)?
2601
          LoadFarStringSmall2(None) : envptr));
2602
        envptr = getenv(LoadFarStringSmall(EnvUnZip2));
2603
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2604
          LoadFarStringSmall(EnvUnZip2),
2605
          (envptr == (char *)NULL || *envptr == 0)?
2606
          LoadFarStringSmall2(None) : envptr));
2607
        envptr = getenv(LoadFarStringSmall(EnvZipInfo));
2608
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2609
          LoadFarStringSmall(EnvZipInfo),
2610
          (envptr == (char *)NULL || *envptr == 0)?
2611
          LoadFarStringSmall2(None) : envptr));
2612
        envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
2613
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2614
          LoadFarStringSmall(EnvZipInfo2),
2615
          (envptr == (char *)NULL || *envptr == 0)?
2616
          LoadFarStringSmall2(None) : envptr));
2617
#ifndef __RSXNT__
2618
#ifdef __EMX__
2619
        envptr = getenv(LoadFarStringSmall(EnvEMX));
2620
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2621
          LoadFarStringSmall(EnvEMX),
2622
          (envptr == (char *)NULL || *envptr == 0)?
2623
          LoadFarStringSmall2(None) : envptr));
2624
        envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
2625
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2626
          LoadFarStringSmall(EnvEMXOPT),
2627
          (envptr == (char *)NULL || *envptr == 0)?
2628
          LoadFarStringSmall2(None) : envptr));
2629
#endif /* __EMX__ */
2630
#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
2631
        envptr = getenv(LoadFarStringSmall(EnvGO32));
2632
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2633
          LoadFarStringSmall(EnvGO32),
2634
          (envptr == (char *)NULL || *envptr == 0)?
2635
          LoadFarStringSmall2(None) : envptr));
2636
        envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
2637
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2638
          LoadFarStringSmall(EnvGO32TMP),
2639
          (envptr == (char *)NULL || *envptr == 0)?
2640
          LoadFarStringSmall2(None) : envptr));
2641
#endif /* __GO32__ && !(__DJGPP__ >= 2) */
2642
#endif /* !__RSXNT__ */
2643
#ifdef RISCOS
2644
        envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
2645
        Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
2646
          LoadFarStringSmall(EnvUnZipExts),
2647
          (envptr == (char *)NULL || *envptr == 0)?
2648
          LoadFarStringSmall2(None) : envptr));
2649
#endif /* RISCOS */
2650
#endif /* !_WIN32_WCE */
2651
    }
2652
} /* end function show_version() */
2653
 
2654
#endif /* !SFX */
2655
#endif /* !WINDLL */