xref: /haiku/src/bin/unzip/unzip.c (revision bc3955fea5b07e2e94a27fc05e4bb58fe6f0319b)
1 /*
2   Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
3 
4   See the accompanying file LICENSE, version 2000-Apr-09 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, send a *complete* description to
16   Zip-Bugs@lists.wku.edu; include machine type, operating system and ver-
17   sion, compiler and version, and reasonably detailed error messages or prob-
18   lem 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   ---------------------------------------------------------------------------
27 
28   [from original zipinfo.c]
29 
30   This program reads great gobs of totally nifty information, including the
31   central directory stuff, from ZIP archives ("zipfiles" for short).  It
32   started as just a testbed for fooling with zipfiles, but at this point it
33   is actually a useful utility.  It also became the basis for the rewrite of
34   UnZip (3.16 -> 4.0), using the central directory for processing rather than
35   the individual (local) file headers.
36 
37   As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
38   If the executable is named "unzip" (or "unzip.exe", depending), it behaves
39   like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
40   ZipInfo.  The ZipInfo behavior may also be triggered by use of unzip's -Z
41   option; for example, "unzip -Z [zipinfo_options] archive.zip".
42 
43   Another dandy product from your buddies at Newtware!
44 
45   Author:  Greg Roelofs, newt@pobox.com, http://pobox.com/~newt/
46            23 August 1990 -> April 1997
47 
48   ---------------------------------------------------------------------------
49 
50   Version:  unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
51               Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
52               BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos and
53               TOPS-20.
54 
55   Copyrights:  see accompanying file "LICENSE" in UnZip source distribution.
56                (This software is free but NOT IN THE PUBLIC DOMAIN.)
57 
58   ---------------------------------------------------------------------------*/
59 
60 
61 
62 #define __UNZIP_C       /* identifies this source module */
63 #define UNZIP_INTERNAL
64 #include "unzip.h"      /* includes, typedefs, macros, prototypes, etc. */
65 #include "crypt.h"
66 #include "unzvers.h"
67 
68 #ifndef WINDLL          /* The WINDLL port uses windll/windll.c instead... */
69 
70 /***************************/
71 /* Local type declarations */
72 /***************************/
73 
74 #ifdef REENTRANT
75 typedef struct _sign_info
76     {
77         struct _sign_info *previous;
78         void (*sighandler)(int);
79         int sigtype;
80     } savsigs_info;
81 #endif
82 
83 /*******************/
84 /* Local Functions */
85 /*******************/
86 
87 #ifdef REENTRANT
88 static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
89                                 int signal_type, void (*newhandler)(int)));
90 #endif
91 #ifndef SFX
92 static void  show_version_info  OF((__GPRO));
93 #endif
94 
95 
96 /*************/
97 /* Constants */
98 /*************/
99 
100 #include "consts.h"  /* all constant global variables are in here */
101                      /* (non-constant globals were moved to globals.c) */
102 
103 /* constant local variables: */
104 
105 #ifndef SFX
106    static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
107    static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
108    static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
109    static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
110 #ifdef RISCOS
111    static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
112 #endif /* RISCOS */
113   static ZCONST char Far NoMemArguments[] =
114     "envargs:  cannot get memory for arguments";
115 #endif
116 
117 #ifdef REENTRANT
118   static ZCONST char Far CantSaveSigHandler[] =
119     "error:  cannot save signal handler settings\n";
120 #endif
121 
122 #if (!defined(SFX) || defined(SFX_EXDIR))
123    static ZCONST char Far NotExtracting[] =
124      "caution:  not extracting; -d ignored\n";
125    static ZCONST char Far MustGiveExdir[] =
126      "error:  must specify directory to which to extract with -d option\n";
127    static ZCONST char Far OnlyOneExdir[] =
128      "error:  -d option used more than once (only one exdir allowed)\n";
129 #endif
130 
131 #if CRYPT
132    static ZCONST char Far MustGivePasswd[] =
133      "error:  must give decryption password with -P option\n";
134 #endif
135 
136 #ifndef SFX
137    static ZCONST char Far Zfirst[] =
138    "error:  -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
139 #endif
140 static ZCONST char Far InvalidOptionsMsg[] = "error:\
141   -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
142 static ZCONST char Far IgnoreOOptionMsg[] =
143   "caution:  both -n and -o specified; ignoring -o\n";
144 
145 /* usage() strings */
146 #ifndef SFX
147 #ifdef VMS
148    static ZCONST char Far Example3[] = "vms.c";
149    static ZCONST char Far Example2[] = "  unzip\
150  \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\n";
151 #else /* !VMS */
152    static ZCONST char Far Example3[] = "ReadMe";
153 #ifdef RISCOS
154    static ZCONST char Far Example2[] =
155 "  unzip foo -d RAM:$   => extract all files from foo into RAMDisc\n";
156 #else /* !RISCOS */
157 #if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
158    static ZCONST char Far Example2[] =
159      "";                /* no room:  too many local3[] items */
160 #else /* !OS2 */
161 #ifdef MACOS
162    static ZCONST char Far Example2[] = ""; /* not needed */
163 #else /* !MACOS */
164    static ZCONST char Far Example2[] = " \
165  unzip -p foo | more  => send contents of foo.zip via pipe into program more\n";
166 #endif /* ?MACOS */
167 #endif /* ?OS2 */
168 #endif /* ?RISCOS */
169 #endif /* ?VMS */
170 
171 /* local1[]:  command options */
172 #if (defined(DLL) && defined(API_DOC))
173    static ZCONST char Far local1[] =
174      "  -A  print extended help for API functions";
175 #else /* !(DLL && API_DOC) */
176    static ZCONST char Far local1[] = "";
177 #endif /* ?(DLL && API_DOC) */
178 
179 /* local2[] and local3[]:  modifier options */
180 #ifdef DOS_FLX_H68_OS2_W32
181 #ifdef FLEXOS
182    static ZCONST char Far local2[] = "";
183 #else
184    static ZCONST char Far local2[] =
185      " -$  label removables (-$$ => fixed disks)";
186 #endif
187 #ifdef OS2
188 #ifdef MORE
189    static ZCONST char Far local3[] = "\
190   -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\
191                                              -M  pipe through \"more\" pager\n";
192 #else
193    static ZCONST char Far local3[] = " \
194  -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\n";
195 #endif /* ?MORE */
196 #else /* !OS2 */
197 #ifdef WIN32
198 #ifdef NTSD_EAS
199 #ifdef MORE
200    static ZCONST char Far local3[] = "\
201   -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\
202                                              -M  pipe through \"more\" pager\n";
203 #else
204    static ZCONST char Far local3[] = " \
205  -X  restore ACLs (-XX => use privileges)   -s  spaces in filenames => '_'\n\n";
206 #endif /* ?MORE */
207 #else /* !NTSD_EAS */
208 #ifdef MORE
209    static ZCONST char Far local3[] = "\
210   -M  pipe through \"more\" pager            \
211   -s  spaces in filenames => '_'\n\n";
212 #else
213    static ZCONST char Far local3[] = " \
214                                             -s  spaces in filenames => '_'\n\n";
215 #endif /* ?MORE */
216 #endif /* ?NTSD_EAS */
217 #else /* !WIN32 */
218 #ifdef MORE
219    static ZCONST char Far local3[] = "  -\
220 M  pipe through \"more\" pager              -s  spaces in filenames => '_'\n\n";
221 #else
222    static ZCONST char Far local3[] = "\
223                                              -s  spaces in filenames => '_'\n";
224 #endif
225 #endif /* ?WIN32 */
226 #endif /* ?OS2 || ?WIN32 */
227 #else /* !DOS_FLX_OS2_W32 */
228 #ifdef VMS
229    static ZCONST char Far local2[] = "\"-X\" restore owner/protection info";
230 #ifdef MORE
231    static ZCONST char Far local3[] = "  \
232                                           \"-M\" pipe through \"more\" pager\n";
233 #else
234    static ZCONST char Far local3[] = "\n";
235 #endif
236 #else /* !VMS */
237 #ifdef BEO_UNX
238    static ZCONST char Far local2[] = " -X  restore UID/GID info";
239 #ifdef MORE
240    static ZCONST char Far local3[] = "\
241                                              -M  pipe through \"more\" pager\n";
242 #else
243    static ZCONST char Far local3[] = "\n";
244 #endif
245 #else /* !BEO_UNX */
246 #ifdef TANDEM
247    static ZCONST char Far local2[] = " -X  restore Tandem User ID";
248 #ifdef MORE
249    static ZCONST char Far local3[] = "\
250   -b  create 'C' (180) text files            -M  pipe through \"more\" pager\n";
251 #else
252    static ZCONST char Far local3[] = " -b  create 'C' (180) text files\n";
253 #endif
254 #else /* !TANDEM */
255 #ifdef AMIGA
256    static ZCONST char Far local2[] = " -N  restore comments as filenotes";
257 #ifdef MORE
258    static ZCONST char Far local3[] = " \
259                                             -M  pipe through \"more\" pager\n";
260 #else
261    static ZCONST char Far local3[] = "\n";
262 #endif
263 #else /* !AMIGA */
264 #ifdef MACOS
265    static ZCONST char Far local2[] = " -E  show Mac info during extraction";
266    static ZCONST char Far local3[] = " \
267  -i  ignore filenames in mac extra info     -J  junk (ignore) Mac extra info\n\
268 \n";
269 #else /* !MACOS */
270 #ifdef MORE
271    static ZCONST char Far local2[] = " -M  pipe through \"more\" pager";
272    static ZCONST char Far local3[] = "\n";
273 #else
274    static ZCONST char Far local2[] = "";   /* Atari, Mac, CMS/MVS etc. */
275    static ZCONST char Far local3[] = "";
276 #endif
277 #endif /* ?MACOS */
278 #endif /* ?AMIGA */
279 #endif /* ?TANDEM */
280 #endif /* ?BEO_UNX */
281 #endif /* ?VMS */
282 #endif /* ?DOS_FLX_OS2_W32 */
283 #endif /* !SFX */
284 
285 #ifndef NO_ZIPINFO
286 #ifdef VMS
287    static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
288 #else
289    static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
290 #endif
291 
292 static ZCONST char Far ZipInfoUsageLine1[] = "\
293 ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
294 \n\
295 List name, date/time, attribute, size, compression method, etc., about files\n\
296 in list (excluding those in xlist) contained in the specified .zip archive(s).\
297 \n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
298    usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
299       or:  unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
300 
301 static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
302  listing-format options:             -s  short Unix \"ls -l\" format (def.)\n\
303   -1  filenames ONLY, one per line       -m  medium Unix \"ls -l\" format\n\
304   -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
305                                          -v  verbose, multi-page format\n";
306 
307 static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
308   -h  print header line       -t  print totals for listed files or for all\n\
309   -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
310 \n %c-C%c be case-insensitive   %s\
311   -x  exclude filenames that follow from listing\n";
312 #ifdef MORE
313 #ifdef VMS
314    static ZCONST char Far ZipInfoUsageLine4[] =
315      " \"-M\" page output through built-in \"more\"\n";
316 #else
317    static ZCONST char Far ZipInfoUsageLine4[] =
318      "  -M  page output through built-in \"more\"\n";
319 #endif
320 #else /* !MORE */
321    static ZCONST char Far ZipInfoUsageLine4[] = "";
322 #endif /* ?MORE */
323 #endif /* !NO_ZIPINFO */
324 
325 #ifdef BETA
326 #  ifdef VMSCLI
327    /* BetaVersion[] is also used in vms/cmdline.c:  do not make it static */
328      ZCONST char Far BetaVersion[] = "%s\
329         THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
330 #  else
331      static ZCONST char Far BetaVersion[] = "%s\
332         THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
333 #  endif
334 #endif
335 
336 #ifdef SFX
337 #  ifdef VMSCLI
338    /* UnzipSFXBanner[] is also used in vms/cmdline.c:  do not make it static */
339      ZCONST char Far UnzipSFXBanner[] =
340 #  else
341      static ZCONST char Far UnzipSFXBanner[] =
342 #  endif
343      "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (Zip-Bugs@lists.wku.edu).\n";
344 #  ifdef SFX_EXDIR
345      static ZCONST char Far UnzipSFXOpts[] =
346     "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
347 #  else
348      static ZCONST char Far UnzipSFXOpts[] =
349        "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
350 #  endif
351 #else /* !SFX */
352    static ZCONST char Far CompileOptions[] =
353      "UnZip special compilation options:\n";
354    static ZCONST char Far CompileOptFormat[] = "\t%s\n";
355    static ZCONST char Far EnvOptions[] =
356      "\nUnZip and ZipInfo environment options:\n";
357    static ZCONST char Far EnvOptFormat[] = "%16s:  %s\n";
358    static ZCONST char Far None[] = "[none]";
359 #  ifdef ACORN_FTYPE_NFS
360      static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
361 #  endif
362 #  ifdef ASM_CRC
363      static ZCONST char Far AsmCRC[] = "ASM_CRC";
364 #  endif
365 #  ifdef ASM_INFLATECODES
366      static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
367 #  endif
368 #  ifdef CHECK_VERSIONS
369      static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
370 #  endif
371 #  ifdef COPYRIGHT_CLEAN
372      static ZCONST char Far Copyright_Clean[] =
373      "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
374 #  endif
375 #  ifdef DEBUG
376      static ZCONST char Far UDebug[] = "DEBUG";
377 #  endif
378 #  ifdef DEBUG_TIME
379      static ZCONST char Far DebugTime[] = "DEBUG_TIME";
380 #  endif
381 #  ifdef DLL
382      static ZCONST char Far Dll[] = "DLL";
383 #  endif
384 #  ifdef DOSWILD
385      static ZCONST char Far DosWild[] = "DOSWILD";
386 #  endif
387 #  ifdef LZW_CLEAN
388      static ZCONST char Far LZW_Clean[] =
389      "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
390 #  endif
391 #  ifndef MORE
392      static ZCONST char Far No_More[] = "NO_MORE";
393 #  endif
394 #  ifdef NO_ZIPINFO
395      static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
396 #  endif
397 #  ifdef NTSD_EAS
398      static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
399 #  endif
400 #  ifdef OLD_THEOS_EXTRA
401      static ZCONST char Far OldTheosExtra[] =
402      "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
403 #  endif
404 #  ifdef OS2_EAS
405      static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
406 #  endif
407 #  ifdef QLZIP
408      static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
409 #  endif
410 #  ifdef REENTRANT
411      static ZCONST char Far Reentrant[] = "REENTRANT";
412 #  endif
413 #  ifdef REGARGS
414      static ZCONST char Far RegArgs[] = "REGARGS";
415 #  endif
416 #  ifdef RETURN_CODES
417      static ZCONST char Far Return_Codes[] = "RETURN_CODES";
418 #  endif
419 #  ifdef SET_DIR_ATTRIB
420      static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
421 #  endif
422 #  ifdef TIMESTAMP
423      static ZCONST char Far TimeStamp[] = "TIMESTAMP";
424 #  endif
425 #  ifdef UNIXBACKUP
426      static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
427 #  endif
428 #  ifdef USE_EF_UT_TIME
429      static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
430 #  endif
431 #  ifndef LZW_CLEAN
432      static ZCONST char Far Use_Unshrink[] =
433      "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
434 #  endif
435 #  ifndef COPYRIGHT_CLEAN
436      static ZCONST char Far Use_Smith_Code[] =
437      "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
438 #  endif
439 #  ifdef USE_DEFLATE64
440      static ZCONST char Far Use_Deflate64[] =
441      "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
442 #  endif
443 #  ifdef MULT_VOLUME
444      static ZCONST char Far Use_MultiVol[] =
445      "MULT_VOLUME (multi-volume archives supported)";
446 #  endif
447 #  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
448 #    ifdef USE_DJGPP_ENV
449        static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
450 #    endif
451 #    ifdef USE_DJGPP_GLOB
452        static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
453 #    endif
454 #  endif /* __DJGPP__ && (__DJGPP__ >= 2) */
455 #  ifdef USE_VFAT
456      static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
457 #  endif
458 #  ifdef USE_ZLIB
459      static ZCONST char Far UseZlib[] =
460      "USE_ZLIB (compiled with version %s; using version %s)";
461 #  endif
462 #  ifdef VMS_TEXT_CONV
463      static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
464 #  endif
465 #  ifdef VMSCLI
466      static ZCONST char Far VmsCLI[] = "VMSCLI";
467 #  endif
468 #  ifdef VMSWILD
469      static ZCONST char Far VmsWild[] = "VMSWILD";
470 #  endif
471 #  ifdef WILD_STOP_AT_DIR
472      static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
473 #  endif
474 #  if CRYPT
475 #    ifdef PASSWD_FROM_STDIN
476        static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
477 #    endif
478      static ZCONST char Far Decryption[] =
479        "\t[decryption, version %d.%d%s of %s]\n";
480      static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
481 #  endif
482 #  ifndef __RSXNT__
483 #    ifdef __EMX__
484        static ZCONST char Far EnvEMX[] = "EMX";
485        static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
486 #    endif
487 #    if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
488        static ZCONST char Far EnvGO32[] = "GO32";
489        static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
490 #    endif
491 #  endif /* !__RSXNT__ */
492 
493 #ifdef VMS
494 /* UnzipUsageLine1[] is also used in vms/cmdline.c:  do not make it static */
495    ZCONST char Far UnzipUsageLine1[] = "\
496 UnZip %d.%d%d%s of %s, by Info-ZIP.  For more details see: unzip -v.\n\n";
497 #ifdef COPYRIGHT_CLEAN
498    static ZCONST char Far UnzipUsageLine1v[] = "\
499 UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
500 bug reports to the authors at Zip-Bugs@lists.wku.edu; see README for details.\
501 \n\n";
502 #else
503    static ZCONST char Far UnzipUsageLine1v[] = "\
504 UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
505 Send bug reports to authors at Zip-Bugs@lists.wku.edu; see README for details.\
506 \n\n";
507 #endif /* ?COPYRIGHT_CLEAN */
508 #else /* !VMS */
509 #ifdef COPYRIGHT_CLEAN
510    static ZCONST char Far UnzipUsageLine1[] = "\
511 UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by C. Spieler.  Send\n\
512 bug reports to the authors at Zip-Bugs@lists.wku.edu; see README for details.\
513 \n\n";
514 #else
515    static ZCONST char Far UnzipUsageLine1[] = "\
516 UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
517 Send bug reports to authors at Zip-Bugs@lists.wku.edu; see README for details.\
518 \n\n";
519 #endif /* ?COPYRIGHT_CLEAN */
520 #define UnzipUsageLine1v        UnzipUsageLine1
521 #endif /* ?VMS */
522 
523 static ZCONST char Far UnzipUsageLine2v[] = "\
524 Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
525 \nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
526 \n\n";
527 
528 #ifdef MACOS
529 static ZCONST char Far UnzipUsageLine2[] = "\
530 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n \
531  Default action is to extract files in list, to exdir;\n\
532   file[.zip] may be a wildcard.  %s\n";
533 #else /* !MACOS */
534 #ifdef VM_CMS
535 static ZCONST char Far UnzipUsageLine2[] = "\
536 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n \
537  Default action is to extract files in list, except those in xlist, to disk fm;\
538 \n  file[.zip] may be a wildcard.  %s\n";
539 #else /* !VM_CMS */
540 static ZCONST char Far UnzipUsageLine2[] = "\
541 Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
542  Default action is to extract files in list, except those in xlist, to exdir;\n\
543   file[.zip] may be a wildcard.  %s\n";
544 #endif /* ?VM_CMS */
545 #endif /* ?MACOS */
546 
547 #ifdef NO_ZIPINFO
548 #  define ZIPINFO_MODE_OPTION  ""
549    static ZCONST char Far ZipInfoMode[] =
550      "(ZipInfo mode is disabled in this version.)";
551 #else
552 #  define ZIPINFO_MODE_OPTION  "[-Z] "
553 #  ifdef VMS
554      static ZCONST char Far ZipInfoMode[] =
555        "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).";
556 #  else
557      static ZCONST char Far ZipInfoMode[] =
558        "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
559 #  endif
560 #endif /* ?NO_ZIPINFO */
561 
562 #ifdef VMS
563    static ZCONST char Far VMSusageLine2b[] = "\
564 => define foreign command symbol in LOGIN.COM:  $ unzip :== $dev:[dir]unzip.exe\
565 \n";
566 #endif
567 
568 #ifdef MACOS
569 static ZCONST char Far UnzipUsageLine3[] = "\n\
570   -d  extract files into exdir               -l  list files (short format)\n\
571   -f  freshen existing files, create none    -t  test compressed archive data\n\
572   -u  update files, create if necessary      -z  display archive comment\n\
573 %s\n";
574 #else /* !MACOS */
575 #ifdef VM_CMS
576 static ZCONST char Far UnzipUsageLine3[] = "\n\
577   -p  extract files to pipe, no messages     -l  list files (short format)\n\
578   -f  freshen existing files, create none    -t  test compressed archive data\n\
579   -u  update files, create if necessary      -z  display archive comment\n\
580   -x  exclude files that follow (in xlist)   -d  extract files onto disk fm\n\
581 %s\n";
582 #else /* !VM_CMS */
583 static ZCONST char Far UnzipUsageLine3[] = "\n\
584   -p  extract files to pipe, no messages     -l  list files (short format)\n\
585   -f  freshen existing files, create none    -t  test compressed archive data\n\
586   -u  update files, create if necessary      -z  display archive comment\n\
587   -x  exclude files that follow (in xlist)   -d  extract files into exdir\n\
588 %s\n";
589 #endif /* ?VM_CMS */
590 #endif /* ?MACOS */
591 
592 static ZCONST char Far UnzipUsageLine4[] = "\
593 modifiers:                                   -q  quiet mode (-qq => quieter)\n\
594   -n  never overwrite existing files         -a  auto-convert any text files\n\
595   -o  overwrite files WITHOUT prompting      -aa treat ALL files as text\n \
596  -j  junk paths (do not make directories)   -v  be verbose/print version info\n\
597  %c-C%c match filenames case-insensitively    %c-L%c make (some) names \
598 lowercase\n %-42s %c-V%c retain VMS version numbers\n%s";
599 
600 static ZCONST char Far UnzipUsageLine5[] = "\
601 Examples (see unzip.txt for more info):\n\
602   unzip data1 -x joe   => extract all files except joe from zipfile data1.zip\n\
603 %s\
604   unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
605 #endif /* ?SFX */
606 
607 
608 
609 
610 
611 /*****************************/
612 /*  main() / UzpMain() stub  */
613 /*****************************/
614 
MAIN(argc,argv)615 int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
616     int argc;
617     char *argv[];
618 {
619     int r;
620 
621     CONSTRUCTGLOBALS();
622     r = unzip(__G__ argc, argv);
623     DESTROYGLOBALS();
624     RETURN(r);
625 }
626 
627 
628 
629 
630 /*******************************/
631 /*  Primary UnZip entry point  */
632 /*******************************/
633 
634 int unzip(__G__ argc, argv)
635     __GDEF
636     int argc;
637     char *argv[];
638 {
639 #ifndef NO_ZIPINFO
640     char *p;
641 #endif
642 #ifdef DOS_FLX_H68_NLM_OS2_W32
643     int i;
644 #endif
645     int retcode, error=FALSE;
646 #ifdef REENTRANT
647     savsigs_info *oldsighandlers = NULL;
648 #   define SET_SIGHANDLER(sigtype, newsighandler) \
649       if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
650                                       (newsighandler))) > PK_WARN) \
651           goto cleanup_and_exit
652 #else
653 #   define SET_SIGHANDLER(sigtype, newsighandler) \
654       signal((sigtype), (newsighandler))
655 #endif
656 
657     SETLOCALE(LC_CTYPE,"");
658 
659 #if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
660     extern void DebugMalloc(void);
661 
662     atexit(DebugMalloc);
663 #endif
664 
665 #ifdef MALLOC_WORK
666     /* The following (rather complex) expression determines the allocation
667        size of the decompression work area.  It simulates what the
668        combined "union" and "struct" declaration of the "static" work
669        area reservation achieves automatically at compile time.
670        Any decent compiler should evaluate this expression completely at
671        compile time and provide constants to the zcalloc() call.
672        (For better readability, some subexpressions are encapsulated
673        in temporarly defined macros.)
674      */
675 #   define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
676 #   define UZ_NUMOF_CHUNKS \
677       (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
678                  (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
679     G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
680 #   undef UZ_SLIDE_CHUNK
681 #   undef UZ_NUMOF_CHUNKS
682     G.area.shrink.Parent = (shrint *)G.area.Slide;
683     G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
684     G.area.shrink.Stack = G.area.Slide +
685                            (sizeof(shrint) + sizeof(uch))*(HSIZE);
686 #endif
687 
688 /*---------------------------------------------------------------------------
689     Set signal handler for restoring echo, warn of zipfile corruption, etc.
690   ---------------------------------------------------------------------------*/
691 
692 #ifdef SIGINT
693     SET_SIGHANDLER(SIGINT, handler);
694 #endif
695 #ifdef SIGTERM                 /* some systems really have no SIGTERM */
696     SET_SIGHANDLER(SIGTERM, handler);
697 #endif
698 #ifdef SIGBUS
699     SET_SIGHANDLER(SIGBUS, handler);
700 #endif
701 #ifdef SIGSEGV
702     SET_SIGHANDLER(SIGSEGV, handler);
703 #endif
704 
705 #if (defined(WIN32) && defined(__RSXNT__))
706     for (i = 0 ; i < argc; i++) {
707        _ISO_INTERN(argv[i]);
708     }
709 #endif
710 
711 /*---------------------------------------------------------------------------
712     Macintosh initialization code.
713   ---------------------------------------------------------------------------*/
714 
715 #ifdef MACOS
716     {
717         int a;
718 
719         for (a = 0;  a < 4;  ++a)
720             G.rghCursor[a] = GetCursor(a+128);
721         G.giCursor = 0;
722     }
723 #endif
724 
725 /*---------------------------------------------------------------------------
726     NetWare initialization code.
727   ---------------------------------------------------------------------------*/
728 
729 #ifdef NLM
730     InitUnZipConsole();
731 #endif
732 
733 /*---------------------------------------------------------------------------
734     Acorn RISC OS initialization code.
735   ---------------------------------------------------------------------------*/
736 
737 #ifdef RISCOS
738     set_prefix();
739 #endif
740 
741 /*---------------------------------------------------------------------------
742     Theos initialization code.
743   ---------------------------------------------------------------------------*/
744 
745 #ifdef THEOS
746     /* The easiest way found to force creation of libraries when selected
747      * members are to be unzipped. Explicitely add libraries names to the
748      * arguments list before the first member of the library.
749      */
750     if (! _setargv(&argc, &argv)) {
751         Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
752         retcode = PK_MEM;
753         goto cleanup_and_exit;
754     }
755 #endif
756 
757 /*---------------------------------------------------------------------------
758     First figure out if we're running in UnZip mode or ZipInfo mode, and put
759     the appropriate environment-variable options into the queue.  Then rip
760     through any command-line options lurking about...
761   ---------------------------------------------------------------------------*/
762 
763 #ifdef SFX
764     G.argv0 = argv[0];
765 #if (defined(OS2) || defined(WIN32))
766     G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
767 #else
768     G.zipfn = G.argv0;
769 #endif
770 
771 #ifdef VMSCLI
772     {
773         ulg status = vms_unzip_cmdline(&argc, &argv);
774         if (!(status & 1)) {
775             retcode = (int)status;
776             goto cleanup_and_exit;
777         }
778     }
779 #endif /* VMSCLI */
780 
781     uO.zipinfo_mode = FALSE;
782     error = uz_opts(__G__ &argc, &argv);   /* UnZipSFX call only */
783 
784 #else /* !SFX */
785 
786 #ifdef RISCOS
787     /* get the extensions to swap from environment */
788     getRISCOSexts(ENV_UNZIPEXTS);
789 #endif
790 
791 #ifdef MSDOS
792     /* extract MKS extended argument list from environment (before envargs!) */
793     mksargs(&argc, &argv);
794 #endif
795 
796 #ifdef VMSCLI
797     {
798         ulg status = vms_unzip_cmdline(&argc, &argv);
799         if (!(status & 1)) {
800             retcode = (int)status;
801             goto cleanup_and_exit;
802         }
803     }
804 #endif /* VMSCLI */
805 
806     G.noargs = (argc == 1);   /* no options, no zipfile, no anything */
807 
808 #ifndef NO_ZIPINFO
809     for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
810         if (*p == DIR_END
811 #ifdef DIR_END2
812             || *p == DIR_END2
813 #endif
814            )
815             break;
816     }
817     ++p;
818 
819 #ifdef THEOS
820     if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
821         strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
822 #else
823     if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
824         STRNICMP(p, "ii", 2) == 0 ||
825 #endif
826         (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
827     {
828         uO.zipinfo_mode = TRUE;
829         if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
830                              LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
831             perror(LoadFarString(NoMemArguments));
832         else
833             error = zi_opts(__G__ &argc, &argv);
834     } else
835 #endif /* NO_ZIPINFO */
836     {
837         uO.zipinfo_mode = FALSE;
838         if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
839                              LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
840             perror(LoadFarString(NoMemArguments));
841         else
842             error = uz_opts(__G__ &argc, &argv);
843     }
844 
845 #endif /* ?SFX */
846 
847     if ((argc < 0) || error) {
848         retcode = error;
849         goto cleanup_and_exit;
850     }
851 
852 /*---------------------------------------------------------------------------
853     Now get the zipfile name from the command line and then process any re-
854     maining options and file specifications.
855   ---------------------------------------------------------------------------*/
856 
857 #ifdef DOS_FLX_H68_NLM_OS2_W32
858     /* convert MSDOS-style 'backward slash' directory separators to Unix-style
859      * 'forward slashes' for user's convenience (include zipfile name itself)
860      */
861 #ifdef SFX
862     for (G.pfnames = argv, i = argc;  i > 0;  --i) {
863 #else
864     /* argc does not include the zipfile specification */
865     for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
866 #endif
867 #ifdef __human68k__
868         extern char *_toslash(char *);
869         _toslash(*G.pfnames);
870 #else /* !__human68k__ */
871         char *q;
872 
873         for (q = *G.pfnames;  *q;  ++q)
874             if (*q == '\\')
875                 *q = '/';
876         ++G.pfnames;
877 #endif /* ?__human68k__ */
878     }
879 #endif /* DOS_FLX_H68_NLM_OS2_W32 */
880 
881 #ifndef SFX
882     G.wildzipfn = *argv++;
883 #endif
884 
885 #if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
886 
887     G.filespecs = argc;
888     G.xfilespecs = 0;
889 
890     if (argc > 0) {
891         char **pp = argv-1;
892 
893         G.pfnames = argv;
894         while (*++pp)
895             if (strcmp(*pp, "-x") == 0) {
896                 if (pp > argv) {
897                     *pp = 0;              /* terminate G.pfnames */
898                     G.filespecs = pp - G.pfnames;
899                 } else {
900                     G.pfnames = (char **)fnames;  /* defaults */
901                     G.filespecs = 0;
902                 }
903                 G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
904                 G.xfilespecs = argc - G.filespecs - 1;
905                 break;                    /* skip rest of args */
906             }
907         G.process_all_files = FALSE;
908     } else
909         G.process_all_files = TRUE;      /* for speed */
910 
911 #else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
912 
913     G.filespecs = argc;
914     G.xfilespecs = 0;
915 
916     if (argc > 0) {
917         int in_files=FALSE, in_xfiles=FALSE;
918         char **pp = argv-1;
919 
920         G.process_all_files = FALSE;
921         G.pfnames = argv;
922         while (*++pp) {
923             Trace((stderr, "pp - argv = %d\n", pp-argv));
924 #ifdef CMS_MVS
925             if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
926 #else
927             if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
928 #endif
929                 int firstarg = (pp == argv);
930 
931                 uO.exdir = (*pp) + 2;
932                 if (in_files) {      /* ... zipfile ... -d exdir ... */
933                     *pp = (char *)NULL;         /* terminate G.pfnames */
934                     G.filespecs = pp - G.pfnames;
935                     in_files = FALSE;
936                 } else if (in_xfiles) {
937                     *pp = (char *)NULL;         /* terminate G.pxnames */
938                     G.xfilespecs = pp - G.pxnames;
939                     /* "... -x xlist -d exdir":  nothing left */
940                 }
941                 /* first check for "-dexdir", then for "-d exdir" */
942                 if (*uO.exdir == '\0') {
943                     if (*++pp)
944                         uO.exdir = *pp;
945                     else {
946                         Info(slide, 0x401, ((char *)slide,
947                           LoadFarString(MustGiveExdir)));
948                         /* don't extract here by accident */
949                         retcode = PK_PARAM;
950                         goto cleanup_and_exit;
951                     }
952                 }
953                 if (firstarg) { /* ... zipfile -d exdir ... */
954                     if (pp[1]) {
955                         G.pfnames = pp + 1;  /* argv+2 */
956                         G.filespecs = argc - (G.pfnames-argv);  /* for now... */
957                     } else {
958                         G.process_all_files = TRUE;
959                         G.pfnames = (char **)fnames;  /* GRR: necessary? */
960                         G.filespecs = 0;     /* GRR: necessary? */
961                         break;
962                     }
963                 }
964             } else if (!in_xfiles) {
965                 if (strcmp(*pp, "-x") == 0) {
966                     in_xfiles = TRUE;
967                     if (pp == G.pfnames) {
968                         G.pfnames = (char **)fnames;  /* defaults */
969                         G.filespecs = 0;
970                     } else if (in_files) {
971                         *pp = 0;                   /* terminate G.pfnames */
972                         G.filespecs = pp - G.pfnames;  /* adjust count */
973                         in_files = FALSE;
974                     }
975                     G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
976                     G.xfilespecs = argc - (G.pxnames-argv);  /* anything left */
977                 } else
978                     in_files = TRUE;
979             }
980         }
981     } else
982         G.process_all_files = TRUE;      /* for speed */
983 
984     if (uO.exdir != (char *)NULL && !G.extract_flag)    /* -d ignored */
985         Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
986 #endif /* ?(SFX && !SFX_EXDIR) */
987 
988 /*---------------------------------------------------------------------------
989     Okey dokey, we have everything we need to get started.  Let's roll.
990   ---------------------------------------------------------------------------*/
991 
992     retcode = process_zipfiles(__G);
993 
994 cleanup_and_exit:
995 #ifdef REENTRANT
996     /* restore all signal handlers back to their state at function entry */
997     while (oldsighandlers != NULL) {
998         savsigs_info *thissigsav = oldsighandlers;
999 
1000         signal(thissigsav->sigtype, thissigsav->sighandler);
1001         oldsighandlers = thissigsav->previous;
1002         free(thissigsav);
1003     }
1004 #endif
1005 #if (defined(MALLOC_WORK) && !defined(REENTRANT))
1006     if (G.area.Slide != (uch *)NULL) {
1007         free(G.area.Slide);
1008         G.area.Slide = (uch *)NULL;
1009     }
1010 #endif
1011     return(retcode);
1012 
1013 } /* end main()/unzip() */
1014 
1015 
1016 
1017 
1018 
1019 #ifdef REENTRANT
1020 /*******************************/
1021 /* Function setsignalhandler() */
1022 /*******************************/
1023 
1024 static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
1025                             newhandler)
1026     __GDEF
1027     savsigs_info **p_savedhandler_chain;
1028     int signal_type;
1029     void (*newhandler)(int);
1030 {
1031     savsigs_info *savsig;
1032 
1033     savsig = malloc(sizeof(savsigs_info));
1034     if (savsig == NULL) {
1035         /* error message and break */
1036         Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
1037         return PK_MEM;
1038     }
1039     savsig->sigtype = signal_type;
1040     savsig->sighandler = signal(SIGINT, newhandler);
1041     if (savsig->sighandler == SIG_ERR) {
1042         free(savsig);
1043     } else {
1044         savsig->previous = *p_savedhandler_chain;
1045         *p_savedhandler_chain = savsig;
1046     }
1047     return PK_OK;
1048 
1049 } /* end function setsignalhandler() */
1050 
1051 #endif /* REENTRANT */
1052 
1053 
1054 
1055 
1056 
1057 /**********************/
1058 /* Function uz_opts() */
1059 /**********************/
1060 
1061 int uz_opts(__G__ pargc, pargv)
1062     __GDEF
1063     int *pargc;
1064     char ***pargv;
1065 {
1066     char **argv, *s;
1067     int argc, c, error=FALSE, negative=0;
1068 
1069 
1070     argc = *pargc;
1071     argv = *pargv;
1072 
1073     while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
1074         s = *argv + 1;
1075         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
1076 #ifdef CMS_MVS
1077             switch (tolower(c))
1078 #else
1079             switch (c)
1080 #endif
1081             {
1082                 case ('-'):
1083                     ++negative;
1084                     break;
1085 #ifdef RISCOS
1086                 case ('/'):
1087                     if (negative) {   /* negative not allowed with -/ swap */
1088                         Info(slide, 0x401, ((char *)slide,
1089                           "error:  must give extensions list"));
1090                         return(PK_PARAM);  /* don't extract here by accident */
1091                     }
1092                     exts2swap = s; /* override Unzip$Exts */
1093                     s += strlen(s);
1094                     break;
1095 #endif
1096                 case ('a'):
1097                     if (negative) {
1098                         uO.aflag = MAX(uO.aflag-negative,0);
1099                         negative = 0;
1100                     } else
1101                         ++uO.aflag;
1102                     break;
1103 #if (defined(DLL) && defined(API_DOC))
1104                 case ('A'):    /* extended help for API */
1105                     APIhelp(__G__ argc, argv);
1106                     *pargc = -1;  /* signal to exit successfully */
1107                     return 0;
1108 #endif
1109                 case ('b'):
1110                     if (negative) {
1111 #if (defined(TANDEM) || defined(VMS))
1112                         uO.bflag = MAX(uO.bflag-negative,0);
1113 #endif
1114                         negative = 0;   /* do nothing:  "-b" is default */
1115                     } else {
1116 #ifdef VMS
1117                         if (uO.aflag == 0)
1118                            ++uO.bflag;
1119 #endif
1120 #ifdef TANDEM
1121                         ++uO.bflag;
1122 #endif
1123                         uO.aflag = 0;
1124                     }
1125                     break;
1126 #ifdef UNIXBACKUP
1127                 case ('B'): /* -B: back up existing files */
1128                     if (negative)
1129                         uO.B_flag = FALSE, negative = 0;
1130                     else
1131                         uO.B_flag = TRUE;
1132                     break;
1133 #endif
1134                 case ('c'):
1135                     if (negative) {
1136                         uO.cflag = FALSE, negative = 0;
1137 #ifdef NATIVE
1138                         uO.aflag = 0;
1139 #endif
1140                     } else {
1141                         uO.cflag = TRUE;
1142 #ifdef NATIVE
1143                         uO.aflag = 2;   /* so you can read it on the screen */
1144 #endif
1145 #ifdef DLL
1146                         if (G.redirect_text)
1147                             G.redirect_data = 2;
1148 #endif
1149                     }
1150                     break;
1151 #ifndef CMS_MVS
1152                 case ('C'):    /* -C:  match filenames case-insensitively */
1153                     if (negative)
1154                         uO.C_flag = FALSE, negative = 0;
1155                     else
1156                         uO.C_flag = TRUE;
1157                     break;
1158 #endif /* !CMS_MVS */
1159 #if (!defined(SFX) || defined(SFX_EXDIR))
1160                 case ('d'):
1161                     if (negative) {   /* negative not allowed with -d exdir */
1162                         Info(slide, 0x401, ((char *)slide,
1163                           LoadFarString(MustGiveExdir)));
1164                         return(PK_PARAM);  /* don't extract here by accident */
1165                     }
1166                     if (uO.exdir != (char *)NULL) {
1167                         Info(slide, 0x401, ((char *)slide,
1168                           LoadFarString(OnlyOneExdir)));
1169                         return(PK_PARAM);    /* GRR:  stupid restriction? */
1170                     } else {
1171                         /* first check for "-dexdir", then for "-d exdir" */
1172                         uO.exdir = s;
1173                         if (*uO.exdir == '\0') {
1174                             if (argc > 1) {
1175                                 --argc;
1176                                 uO.exdir = *++argv;
1177                                 if (*uO.exdir == '-') {
1178                                     Info(slide, 0x401, ((char *)slide,
1179                                       LoadFarString(MustGiveExdir)));
1180                                     return(PK_PARAM);
1181                                 }
1182                                 /* else uO.exdir points at extraction dir */
1183                             } else {
1184                                 Info(slide, 0x401, ((char *)slide,
1185                                   LoadFarString(MustGiveExdir)));
1186                                 return(PK_PARAM);
1187                             }
1188                         }
1189                         /* uO.exdir now points at extraction dir (-dexdir or
1190                          *  -d exdir); point s at end of exdir to avoid mis-
1191                          *  interpretation of exdir characters as more options
1192                          */
1193                         if (*s != 0)
1194                             while (*++s != 0)
1195                                 ;
1196                     }
1197                     break;
1198 #endif /* !SFX || SFX_EXDIR */
1199                 case ('e'):    /* just ignore -e, -x options (extract) */
1200                     break;
1201 #ifdef MACOS
1202                 case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
1203                     if( negative ) {
1204                         uO.E_flag = FALSE, negative = 0;
1205                     } else {
1206                         uO.E_flag = TRUE;
1207                     }
1208                     break;
1209 #endif /* MACOS */
1210                 case ('f'):    /* "freshen" (extract only newer files) */
1211                     if (negative)
1212                         uO.fflag = uO.uflag = FALSE, negative = 0;
1213                     else
1214                         uO.fflag = uO.uflag = TRUE;
1215                     break;
1216 #if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
1217                 case ('F'):    /* Acorn filetype & NFS extension handling */
1218                     if (negative)
1219                         uO.acorn_nfs_ext = FALSE, negative = 0;
1220                     else
1221                         uO.acorn_nfs_ext = TRUE;
1222                     break;
1223 #endif /* RISCOS || ACORN_FTYPE_NFS */
1224                 case ('h'):    /* just print help message and quit */
1225                     *pargc = -1;
1226                     return USAGE(PK_OK);
1227 #ifdef MACOS
1228                 case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
1229                     if( negative ) {
1230                         uO.i_flag = FALSE, negative = 0;
1231                     } else {
1232                         uO.i_flag = TRUE;
1233                     }
1234                     break;
1235 #endif  /* MACOS */
1236                 case ('j'):    /* junk pathnames/directory structure */
1237                     if (negative)
1238                         uO.jflag = FALSE, negative = 0;
1239                     else
1240                         uO.jflag = TRUE;
1241                     break;
1242 #if ((defined(__BEOS__) || defined(__HAIKU__)) || defined(MACOS) || defined(HAS_JUNK_EXTRA_FIELD_OPTION))
1243                 case ('J'):    /* Junk BeOS or MacOS file attributes */
1244                     if( negative ) {
1245                         uO.J_flag = FALSE, negative = 0;
1246                     } else {
1247                         uO.J_flag = TRUE;
1248                     }
1249                     break;
1250 #endif /* __BEOS__ || MACOS */
1251 #ifndef SFX
1252                 case ('l'):
1253                     if (negative) {
1254                         uO.vflag = MAX(uO.vflag-negative,0);
1255                         negative = 0;
1256                     } else
1257                         ++uO.vflag;
1258                     break;
1259 #endif /* !SFX */
1260 #ifndef CMS_MVS
1261                 case ('L'):    /* convert (some) filenames to lowercase */
1262                     if (negative) {
1263                         uO.L_flag = MAX(uO.L_flag-negative,0);
1264                         negative = 0;
1265                     } else
1266                         ++uO.L_flag;
1267                     break;
1268 #endif /* !CMS_MVS */
1269 #ifdef MORE
1270 #ifdef CMS_MVS
1271                 case ('m'):
1272 #endif
1273                 case ('M'):    /* send all screen output through "more" fn. */
1274 /* GRR:  eventually check for numerical argument => height */
1275                     if (negative)
1276                         G.M_flag = FALSE, negative = 0;
1277                     else
1278                         G.M_flag = TRUE;
1279                     break;
1280 #endif /* MORE */
1281                 case ('n'):    /* don't overwrite any files */
1282                     if (negative)
1283                         uO.overwrite_none = FALSE, negative = 0;
1284                     else
1285                         uO.overwrite_none = TRUE;
1286                     break;
1287 #ifdef AMIGA
1288                 case ('N'):    /* restore comments as filenotes */
1289                     if (negative)
1290                         uO.N_flag = FALSE, negative = 0;
1291                     else
1292                         uO.N_flag = TRUE;
1293                     break;
1294 #endif /* AMIGA */
1295                 case ('o'):    /* OK to overwrite files without prompting */
1296                     if (negative) {
1297                         uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
1298                         negative = 0;
1299                     } else
1300                         ++uO.overwrite_all;
1301                     break;
1302                 case ('p'):    /* pipes:  extract to stdout, no messages */
1303                     if (negative) {
1304                         uO.cflag = FALSE;
1305                         uO.qflag = MAX(uO.qflag-999,0);
1306                         negative = 0;
1307                     } else {
1308                         uO.cflag = TRUE;
1309                         uO.qflag += 999;
1310                     }
1311                     break;
1312 #if CRYPT
1313                 /* GRR:  yes, this is highly insecure, but dozens of people
1314                  * have pestered us for this, so here we go... */
1315                 case ('P'):
1316                     if (negative) {   /* negative not allowed with -P passwd */
1317                         Info(slide, 0x401, ((char *)slide,
1318                           LoadFarString(MustGivePasswd)));
1319                         return(PK_PARAM);  /* don't extract here by accident */
1320                     }
1321                     if (uO.pwdarg != (char *)NULL) {
1322 /*
1323                         GRR:  eventually support multiple passwords?
1324                         Info(slide, 0x401, ((char *)slide,
1325                           LoadFarString(OnlyOnePasswd)));
1326                         return(PK_PARAM);
1327  */
1328                     } else {
1329                         /* first check for "-Ppasswd", then for "-P passwd" */
1330                         uO.pwdarg = s;
1331                         if (*uO.pwdarg == '\0') {
1332                             if (argc > 1) {
1333                                 --argc;
1334                                 uO.pwdarg = *++argv;
1335                                 if (*uO.pwdarg == '-') {
1336                                     Info(slide, 0x401, ((char *)slide,
1337                                       LoadFarString(MustGivePasswd)));
1338                                     return(PK_PARAM);
1339                                 }
1340                                 /* else pwdarg points at decryption password */
1341                             } else {
1342                                 Info(slide, 0x401, ((char *)slide,
1343                                   LoadFarString(MustGivePasswd)));
1344                                 return(PK_PARAM);
1345                             }
1346                         }
1347                         /* pwdarg now points at decryption password (-Ppasswd or
1348                          *  -P passwd); point s at end of passwd to avoid mis-
1349                          *  interpretation of passwd characters as more options
1350                          */
1351                         if (*s != 0)
1352                             while (*++s != 0)
1353                                 ;
1354                     }
1355                     break;
1356 #endif /* CRYPT */
1357                 case ('q'):    /* quiet:  fewer comments/messages */
1358                     if (negative) {
1359                         uO.qflag = MAX(uO.qflag-negative,0);
1360                         negative = 0;
1361                     } else
1362                         ++uO.qflag;
1363                     break;
1364 #ifdef QDOS
1365                 case ('Q'):   /* QDOS flags */
1366                     qlflag ^= strtol(s, &s, 10);
1367                     break;    /* we XOR this as we can config qlflags */
1368 #endif
1369 #ifdef DOS_FLX_NLM_OS2_W32
1370                 case ('s'):    /* spaces in filenames:  allow by default */
1371                     if (negative)
1372                         uO.sflag = FALSE, negative = 0;
1373                     else
1374                         uO.sflag = TRUE;
1375                     break;
1376 #endif /* DOS_FLX_NLM_OS2_W32 */
1377                 case ('t'):
1378                     if (negative)
1379                         uO.tflag = FALSE, negative = 0;
1380                     else
1381                         uO.tflag = TRUE;
1382                     break;
1383 #ifdef TIMESTAMP
1384                 case ('T'):
1385                     if (negative)
1386                         uO.T_flag = FALSE, negative = 0;
1387                     else
1388                         uO.T_flag = TRUE;
1389                     break;
1390 #endif
1391                 case ('u'):    /* update (extract only new and newer files) */
1392                     if (negative)
1393                         uO.uflag = FALSE, negative = 0;
1394                     else
1395                         uO.uflag = TRUE;
1396                     break;
1397 #ifndef CMS_MVS
1398                 case ('U'):    /* obsolete; to be removed in version 6.0 */
1399                     if (negative)
1400                         uO.L_flag = TRUE, negative = 0;
1401                     else
1402                         uO.L_flag = FALSE;
1403                     break;
1404 #endif /* !CMS_MVS */
1405 #ifndef SFX
1406                 case ('v'):    /* verbose */
1407                     if (negative) {
1408                         uO.vflag = MAX(uO.vflag-negative,0);
1409                         negative = 0;
1410                     } else if (uO.vflag)
1411                         ++uO.vflag;
1412                     else
1413                         uO.vflag = 2;
1414                     break;
1415 #endif /* !SFX */
1416 #ifndef CMS_MVS
1417                 case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
1418                     if (negative)
1419                         uO.V_flag = FALSE, negative = 0;
1420                     else
1421                         uO.V_flag = TRUE;
1422                     break;
1423 #endif /* !CMS_MVS */
1424                 case ('x'):    /* extract:  default */
1425 #ifdef SFX
1426                     /* when 'x' is the only option in this argument, and the
1427                      * next arg is not an option, assume this initiates an
1428                      * exclusion list (-x xlist):  terminate option-scanning
1429                      * and leave uz_opts with argv still pointing to "-x";
1430                      * the xlist is processed later
1431                      */
1432                     if (s - argv[0] == 2 && *s == '\0' &&
1433                         argc > 1 && argv[1][0] != '-') {
1434                         /* break out of nested loops without "++argv;--argc" */
1435                         goto opts_done;
1436                     }
1437 #endif /* SFX */
1438                     break;
1439 #if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
1440                 case ('X'):   /* restore owner/protection info (need privs?) */
1441                     if (negative) {
1442                         uO.X_flag = MAX(uO.X_flag-negative,0);
1443                         negative = 0;
1444                     } else
1445                         ++uO.X_flag;
1446                     break;
1447 #endif /* RESTORE_UIDGID || RESTORE_ACL */
1448                 case ('z'):    /* display only the archive comment */
1449                     if (negative) {
1450                         uO.zflag = MAX(uO.zflag-negative,0);
1451                         negative = 0;
1452                     } else
1453                         ++uO.zflag;
1454                     break;
1455 #ifndef SFX
1456                 case ('Z'):    /* should have been first option (ZipInfo) */
1457                     Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
1458                     error = TRUE;
1459                     break;
1460 #endif /* !SFX */
1461 #ifdef DOS_H68_OS2_W32
1462                 case ('$'):
1463                     if (negative) {
1464                         uO.volflag = MAX(uO.volflag-negative,0);
1465                         negative = 0;
1466                     } else
1467                         ++uO.volflag;
1468                     break;
1469 #endif /* DOS_H68_OS2_W32 */
1470 #if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
1471                 case (':'):
1472                     if (negative) {
1473                         uO.ddotflag = MAX(uO.ddotflag-negative,0);
1474                         negative = 0;
1475                     } else
1476                         ++uO.ddotflag;
1477                     break;
1478 #endif /* !RISCOS && !CMS_MVS && !TANDEM */
1479                 default:
1480                     error = TRUE;
1481                     break;
1482 
1483             } /* end switch */
1484         } /* end while (not end of argument string) */
1485     } /* end while (not done with switches) */
1486 
1487 /*---------------------------------------------------------------------------
1488     Check for nonsensical combinations of options.
1489   ---------------------------------------------------------------------------*/
1490 
1491 #ifdef SFX
1492 opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
1493 #endif
1494 
1495     if ((uO.cflag && uO.tflag) || (uO.cflag && uO.uflag) ||
1496         (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
1497     {
1498         Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
1499         error = TRUE;
1500     }
1501     if (uO.aflag > 2)
1502         uO.aflag = 2;
1503 #ifdef VMS
1504     if (uO.bflag > 2)
1505         uO.bflag = 2;
1506 #endif
1507     if (uO.overwrite_all && uO.overwrite_none) {
1508         Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
1509         uO.overwrite_all = FALSE;
1510     }
1511 #ifdef MORE
1512     if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func. useless */
1513         G.M_flag = 0;
1514 #endif
1515 
1516 #ifdef SFX
1517     if (error)
1518 #else
1519     if ((argc-- == 0) || error)
1520 #endif
1521     {
1522         *pargc = argc;
1523         *pargv = argv;
1524 #ifndef SFX
1525         if (uO.vflag >= 2 && argc == -1) {              /* "unzip -v" */
1526             show_version_info(__G);
1527             return PK_OK;
1528         }
1529         if (!G.noargs && !error)
1530             error = PK_PARAM;   /* had options (not -h or -v) but no zipfile */
1531 #endif /* !SFX */
1532         return USAGE(error);
1533     }
1534 
1535 #ifdef SFX
1536     /* print our banner unless we're being fairly quiet */
1537     if (uO.qflag < 2)
1538         Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1539           UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1540           LoadFarStringSmall(VersionDate)));
1541 #ifdef BETA
1542     /* always print the beta warning:  no unauthorized distribution!! */
1543     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1544       "SFX"));
1545 #endif
1546 #endif /* SFX */
1547 
1548     if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
1549 #ifdef TIMESTAMP
1550                                                      || uO.T_flag
1551 #endif
1552                                                                  )
1553         G.extract_flag = FALSE;
1554     else
1555         G.extract_flag = TRUE;
1556 
1557     *pargc = argc;
1558     *pargv = argv;
1559     return PK_OK;
1560 
1561 } /* end function uz_opts() */
1562 
1563 
1564 
1565 
1566 /********************/
1567 /* Function usage() */
1568 /********************/
1569 
1570 #ifdef SFX
1571 #  ifdef VMS
1572 #    define LOCAL "X.  Quote uppercase options"
1573 #  endif
1574 #  ifdef UNIX
1575 #    define LOCAL "X"
1576 #  endif
1577 #  ifdef DOS_OS2_W32
1578 #    define LOCAL "s$"
1579 #  endif
1580 #  if (defined(FLEXOS) || defined(NLM))
1581 #    define LOCAL "s"
1582 #  endif
1583 #  ifdef AMIGA
1584 #    define LOCAL "N"
1585 #  endif
1586    /* Default for all other systems: */
1587 #  ifndef LOCAL
1588 #    define LOCAL ""
1589 #  endif
1590 
1591 #  ifdef MORE
1592 #    define SFXOPT1 "M"
1593 #  else
1594 #    define SFXOPT1 ""
1595 #  endif
1596 
1597 int usage(__G__ error)   /* return PK-type error code */
1598     __GDEF
1599     int error;
1600 {
1601     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
1602       UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1603       LoadFarStringSmall(VersionDate)));
1604     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
1605       SFXOPT1, LOCAL));
1606 #ifdef BETA
1607     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
1608       "SFX"));
1609 #endif
1610 
1611     if (error)
1612         return PK_PARAM;
1613     else
1614         return PK_COOL;     /* just wanted usage screen: no error */
1615 
1616 } /* end function usage() */
1617 
1618 
1619 
1620 
1621 
1622 #else /* !SFX */
1623 #  ifdef VMS
1624 #    define QUOT '\"'
1625 #    define QUOTS "\""
1626 #  else
1627 #    define QUOT ' '
1628 #    define QUOTS ""
1629 #  endif
1630 
1631 int usage(__G__ error)   /* return PK-type error code */
1632     __GDEF
1633     int error;
1634 {
1635     int flag = (error? 1 : 0);
1636 
1637 
1638 /*---------------------------------------------------------------------------
1639     Print either ZipInfo usage or UnZip usage, depending on incantation.
1640     (Strings must be no longer than 512 bytes for Turbo C, apparently.)
1641   ---------------------------------------------------------------------------*/
1642 
1643     if (uO.zipinfo_mode) {
1644 
1645 #ifndef NO_ZIPINFO
1646 
1647         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
1648           ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1649           LoadFarStringSmall(VersionDate),
1650           LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
1651         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
1652         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
1653           QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(ZipInfoUsageLine4)));
1654 #ifdef VMS
1655         Info(slide, flag, ((char *)slide, "\nRemember that non-lowercase\
1656  filespecs must be quoted in VMS (e.g., \"Makefile\").\n"));
1657 #endif
1658 
1659 #endif /* !NO_ZIPINFO */
1660 
1661     } else {   /* UnZip mode */
1662 
1663         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
1664           UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1665           LoadFarStringSmall(VersionDate)));
1666 #ifdef BETA
1667         Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
1668 #endif
1669 
1670         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
1671           ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
1672 #ifdef VMS
1673         if (!error)  /* maybe no command-line tail found; show extra help */
1674             Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
1675 #endif
1676 
1677         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
1678           LoadFarStringSmall(local1)));
1679 
1680         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
1681           QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(local2), QUOT,QUOT,
1682           LoadFarStringSmall2(local3)));
1683 
1684         /* This is extra work for SMALL_MEM, but it will work since
1685          * LoadFarStringSmall2 uses the same buffer.  Remember, this
1686          * is a hack. */
1687         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
1688           LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
1689           LoadFarStringSmall2(Example3)));
1690 
1691     } /* end if (uO.zipinfo_mode) */
1692 
1693     if (error)
1694         return PK_PARAM;
1695     else
1696         return PK_COOL;     /* just wanted usage screen: no error */
1697 
1698 } /* end function usage() */
1699 
1700 #endif /* ?SFX */
1701 
1702 
1703 
1704 
1705 #ifndef SFX
1706 
1707 /********************************/
1708 /* Function show_version_info() */
1709 /********************************/
1710 
show_version_info(__G)1711 static void show_version_info(__G)
1712     __GDEF
1713 {
1714     if (uO.qflag > 3)                           /* "unzip -vqqqq" */
1715         Info(slide, 0, ((char *)slide, "%d\n",
1716           (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
1717     else {
1718         char *envptr, *getenv();
1719         int numopts = 0;
1720 
1721         Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
1722           UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
1723           LoadFarStringSmall(VersionDate)));
1724         Info(slide, 0, ((char *)slide,
1725           LoadFarString(UnzipUsageLine2v)));
1726         version(__G);
1727         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
1728 #ifdef ACORN_FTYPE_NFS
1729         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1730           LoadFarStringSmall(AcornFtypeNFS)));
1731         ++numopts;
1732 #endif
1733 #ifdef ASM_CRC
1734         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1735           LoadFarStringSmall(AsmCRC)));
1736         ++numopts;
1737 #endif
1738 #ifdef ASM_INFLATECODES
1739         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1740           LoadFarStringSmall(AsmInflateCodes)));
1741         ++numopts;
1742 #endif
1743 #ifdef CHECK_VERSIONS
1744         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1745           LoadFarStringSmall(Check_Versions)));
1746         ++numopts;
1747 #endif
1748 #ifdef COPYRIGHT_CLEAN
1749         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1750           LoadFarStringSmall(Copyright_Clean)));
1751         ++numopts;
1752 #endif
1753 #ifdef DEBUG
1754         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1755           LoadFarStringSmall(UDebug)));
1756         ++numopts;
1757 #endif
1758 #ifdef DEBUG_TIME
1759         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1760           LoadFarStringSmall(DebugTime)));
1761         ++numopts;
1762 #endif
1763 #ifdef DLL
1764         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1765           LoadFarStringSmall(Dll)));
1766         ++numopts;
1767 #endif
1768 #ifdef DOSWILD
1769         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1770           LoadFarStringSmall(DosWild)));
1771         ++numopts;
1772 #endif
1773 #ifdef LZW_CLEAN
1774         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1775           LoadFarStringSmall(LZW_Clean)));
1776         ++numopts;
1777 #endif
1778 #ifndef MORE
1779         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1780           LoadFarStringSmall(No_More)));
1781         ++numopts;
1782 #endif
1783 #ifdef NO_ZIPINFO
1784         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1785           LoadFarStringSmall(No_ZipInfo)));
1786         ++numopts;
1787 #endif
1788 #ifdef NTSD_EAS
1789         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1790           LoadFarStringSmall(NTSDExtAttrib)));
1791         ++numopts;
1792 #endif
1793 #ifdef OLD_THEOS_EXTRA
1794         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1795           LoadFarStringSmall(OldTheosExtra)));
1796         ++numopts;
1797 #endif
1798 #ifdef OS2_EAS
1799         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1800           LoadFarStringSmall(OS2ExtAttrib)));
1801         ++numopts;
1802 #endif
1803 #ifdef QLZIP
1804         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1805           LoadFarStringSmall(SMSExFldOnUnix)));
1806         ++numopts;
1807 #endif
1808 #ifdef REENTRANT
1809         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1810           LoadFarStringSmall(Reentrant)));
1811         ++numopts;
1812 #endif
1813 #ifdef REGARGS
1814         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1815           LoadFarStringSmall(RegArgs)));
1816         ++numopts;
1817 #endif
1818 #ifdef RETURN_CODES
1819         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1820           LoadFarStringSmall(Return_Codes)));
1821         ++numopts;
1822 #endif
1823 #ifdef SET_DIR_ATTRIB
1824         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1825           LoadFarStringSmall(SetDirAttrib)));
1826         ++numopts;
1827 #endif
1828 #ifdef TIMESTAMP
1829         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1830           LoadFarStringSmall(TimeStamp)));
1831         ++numopts;
1832 #endif
1833 #ifdef UNIXBACKUP
1834         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1835           LoadFarStringSmall(UnixBackup)));
1836         ++numopts;
1837 #endif
1838 #ifdef USE_EF_UT_TIME
1839         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1840           LoadFarStringSmall(Use_EF_UT_time)));
1841         ++numopts;
1842 #endif
1843 #ifndef COPYRIGHT_CLEAN
1844         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1845           LoadFarStringSmall(Use_Smith_Code)));
1846         ++numopts;
1847 #endif
1848 #ifndef LZW_CLEAN
1849         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1850           LoadFarStringSmall(Use_Unshrink)));
1851         ++numopts;
1852 #endif
1853 #ifdef USE_DEFLATE64
1854         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1855           LoadFarStringSmall(Use_Deflate64)));
1856         ++numopts;
1857 #endif
1858 #ifdef MULT_VOLUME
1859         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1860           LoadFarStringSmall(Use_MultiVol)));
1861         ++numopts;
1862 #endif
1863 #  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
1864 #    ifdef USE_DJGPP_ENV
1865         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1866           LoadFarStringSmall(Use_DJGPP_Env)));
1867         ++numopts;
1868 #    endif
1869 #    ifdef USE_DJGPP_GLOB
1870         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1871           LoadFarStringSmall(Use_DJGPP_Glob)));
1872         ++numopts;
1873 #    endif
1874 #  endif /* __DJGPP__ && (__DJGPP__ >= 2) */
1875 #ifdef USE_VFAT
1876         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1877           LoadFarStringSmall(Use_VFAT_support)));
1878         ++numopts;
1879 #endif
1880 #ifdef USE_ZLIB
1881         sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
1882           ZLIB_VERSION, zlib_version);
1883         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1884           (char *)(slide+256)));
1885         ++numopts;
1886 #endif
1887 #ifdef VMS_TEXT_CONV
1888         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1889           LoadFarStringSmall(VmsTextConv)));
1890         ++numopts;
1891 #endif
1892 #ifdef VMSCLI
1893         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1894           LoadFarStringSmall(VmsCLI)));
1895         ++numopts;
1896 #endif
1897 #ifdef VMSWILD
1898         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1899           LoadFarStringSmall(VmsWild)));
1900         ++numopts;
1901 #endif
1902 #ifdef WILD_STOP_AT_DIR
1903         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1904           LoadFarStringSmall(WildStopAtDir)));
1905         ++numopts;
1906 #endif
1907 #if CRYPT
1908 # ifdef PASSWD_FROM_STDIN
1909         Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
1910           LoadFarStringSmall(PasswdStdin)));
1911 # endif
1912         Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
1913           CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
1914           LoadFarStringSmall(CryptDate)));
1915         ++numopts;
1916 #endif /* CRYPT */
1917         if (numopts == 0)
1918             Info(slide, 0, ((char *)slide,
1919               LoadFarString(CompileOptFormat),
1920               LoadFarStringSmall(None)));
1921 
1922         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
1923         envptr = getenv(LoadFarStringSmall(EnvUnZip));
1924         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1925           LoadFarStringSmall(EnvUnZip),
1926           (envptr == (char *)NULL || *envptr == 0)?
1927           LoadFarStringSmall2(None) : envptr));
1928         envptr = getenv(LoadFarStringSmall(EnvUnZip2));
1929         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1930           LoadFarStringSmall(EnvUnZip2),
1931           (envptr == (char *)NULL || *envptr == 0)?
1932           LoadFarStringSmall2(None) : envptr));
1933         envptr = getenv(LoadFarStringSmall(EnvZipInfo));
1934         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1935           LoadFarStringSmall(EnvZipInfo),
1936           (envptr == (char *)NULL || *envptr == 0)?
1937           LoadFarStringSmall2(None) : envptr));
1938         envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
1939         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1940           LoadFarStringSmall(EnvZipInfo2),
1941           (envptr == (char *)NULL || *envptr == 0)?
1942           LoadFarStringSmall2(None) : envptr));
1943 #ifndef __RSXNT__
1944 #ifdef __EMX__
1945         envptr = getenv(LoadFarStringSmall(EnvEMX));
1946         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1947           LoadFarStringSmall(EnvEMX),
1948           (envptr == (char *)NULL || *envptr == 0)?
1949           LoadFarStringSmall2(None) : envptr));
1950         envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
1951         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1952           LoadFarStringSmall(EnvEMXOPT),
1953           (envptr == (char *)NULL || *envptr == 0)?
1954           LoadFarStringSmall2(None) : envptr));
1955 #endif /* __EMX__ */
1956 #if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
1957         envptr = getenv(LoadFarStringSmall(EnvGO32));
1958         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1959           LoadFarStringSmall(EnvGO32),
1960           (envptr == (char *)NULL || *envptr == 0)?
1961           LoadFarStringSmall2(None) : envptr));
1962         envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
1963         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1964           LoadFarStringSmall(EnvGO32TMP),
1965           (envptr == (char *)NULL || *envptr == 0)?
1966           LoadFarStringSmall2(None) : envptr));
1967 #endif /* __GO32__ && !(__DJGPP__ >= 2) */
1968 #endif /* !__RSXNT__ */
1969 #ifdef RISCOS
1970         envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
1971         Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
1972           LoadFarStringSmall(EnvUnZipExts),
1973           (envptr == (char *)NULL || *envptr == 0)?
1974           LoadFarStringSmall2(None) : envptr));
1975 #endif /* RISCOS */
1976     }
1977 } /* end function show_version() */
1978 
1979 #endif /* !SFX */
1980 #endif /* !WINDLL */
1981