home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip52.zip / unzip.c < prev    next >
C/C++ Source or Header  |  1996-04-27  |  49KB  |  1,403 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   unzip.c
  4.  
  5.   UnZip - a zipfile extraction utility.  See below for make instructions, or
  6.   read the comments in Makefile and the various Contents files for more de-
  7.   tailed explanations.  To report a bug, send a *complete* description to
  8.   Zip-Bugs@wkuvx1.wku.edu; include machine type, operating system and ver-
  9.   sion, compiler and version, and reasonably detailed error messages or prob-
  10.   lem report.  To join Info-ZIP, see the instructions in README.
  11.  
  12.   UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
  13.   which in turn was almost a complete rewrite of version 3.x.  For a detailed
  14.   revision history, see UnzpHist.zip at quest.jpl.nasa.gov.  For a list of
  15.   the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
  16.   distribution.
  17.  
  18.   ---------------------------------------------------------------------------
  19.  
  20.   [from original zipinfo.c]
  21.  
  22.   This program reads great gobs of totally nifty information, including the
  23.   central directory stuff, from ZIP archives ("zipfiles" for short).  It
  24.   started as just a testbed for fooling with zipfiles, but at this point it
  25.   is actually a useful utility.  It also became the basis for the rewrite of
  26.   UnZip (3.16 -> 4.0), using the central directory for processing rather than
  27.   the individual (local) file headers.
  28.  
  29.   As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
  30.   If the executable is named "unzip" (or "unzip.exe", depending), it behaves
  31.   like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
  32.   ZipInfo.  The ZipInfo behavior may also be triggered by use of unzip's -Z
  33.   option; for example, "unzip -Z [zipinfo_options] archive.zip".
  34.  
  35.   Another dandy product from your buddies at Newtware!
  36.  
  37.   Author:  Greg Roelofs, newt@uchicago.edu, 23 August 1990 -> December 1995
  38.  
  39.   ---------------------------------------------------------------------------
  40.  
  41.   Version:  unzip520.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Amiga,
  42.               Atari, Windows 3.x/95/NT, Macintosh, Human68K, Acorn RISC OS,
  43.               VM/CMS, MVS, AOS/VS and TOPS-20.  Decryption requires sources
  44.               in zcrypt26.zip.  See the accompanying "Where" file in the main
  45.               source distribution for ftp, uucp, BBS and mail-server sites.
  46.  
  47.   Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  48.                (This software is free but NOT IN THE PUBLIC DOMAIN.  There
  49.                are some restrictions on commercial use.)
  50.  
  51.   ---------------------------------------------------------------------------*/
  52.  
  53.  
  54.  
  55. #define UNZIP_INTERNAL
  56. #include "unzip.h"        /* includes, typedefs, macros, prototypes, etc. */
  57. #include "crypt.h"
  58. #include "version.h"
  59. #ifdef USE_ZLIB
  60. #  include "zlib.h"
  61. #endif
  62.  
  63.  
  64.  
  65. /*************/
  66. /* Constants */
  67. /*************/
  68.  
  69. #include "consts.h"  /* all constant global variables are in here */
  70.                      /* (non-constant globals were moved to globals.c) */
  71.  
  72. /* constant local variables: */
  73.  
  74. #ifndef SFX
  75.    static char Far EnvUnZip[] = ENV_UNZIP;
  76.    static char Far EnvUnZip2[] = ENV_UNZIP2;
  77.    static char Far EnvZipInfo[] = ENV_ZIPINFO;
  78.    static char Far EnvZipInfo2[] = ENV_ZIPINFO2;
  79. #endif
  80.  
  81. #if (!defined(SFX) || defined(SFX_EXDIR))
  82.    static char Far NotExtracting[] = "caution:  not extracting; -d ignored\n";
  83.    static char Far MustGiveExdir[] =
  84.      "error:  must specify directory to which to extract with -d option\n";
  85.    static char Far OnlyOneExdir[] =
  86.      "error:  -d option used more than once (only one exdir allowed)\n";
  87. #endif
  88.  
  89. static char Far InvalidOptionsMsg[] = "error:\
  90.   -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
  91. static char Far IgnoreOOptionMsg[] =
  92.   "caution:  both -n and -o specified; ignoring -o\n";
  93.  
  94. /* usage() strings */
  95. #ifndef VMSCLI
  96. #ifndef SFX
  97. #ifdef VMS
  98.    static char Far Example3[] = "vms.c";
  99.    static char Far Example2[] = "  unzip\
  100.  \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\n";
  101. #else /* !VMS */
  102.    static char Far Example3[] = "ReadMe";
  103. #ifdef RISCOS
  104.    static char Far Example2[] =
  105. "  unzip foo -d RAM:$   => extract all files from foo into RAMDisc\n";
  106. #else /* !RISCOS */
  107. #if defined(OS2) || (defined(DOS_OS2_W32) && defined(MORE))
  108.    static char Far Example2[] = "";   /* no room:  too many local3[] items */
  109. #else /* !OS2 */
  110.    static char Far Example2[] = " \
  111.  unzip -p foo | more  => send contents of foo.zip via pipe into program more\n";
  112. #endif /* ?OS2 */
  113. #endif /* ?RISCOS */
  114. #endif /* ?VMS */
  115.  
  116. /* local1[]:  command options */
  117. #if (defined(DLL) && defined(API_DOC))
  118.    static char Far local1[] = "  -A  print extended help for API functions";
  119. #else /* !(DLL && API_DOC) */
  120.    static char Far local1[] = "";
  121. #endif /* ?(DLL && API_DOC) */
  122.  
  123. /* local2[] and local3[]:  modifier options */
  124. #ifdef DOS_OS2_W32
  125.    static char Far local2[] = " -$  label removables (-$$ => fixed disks)";
  126. #ifdef OS2
  127. #ifdef MORE
  128.    static char Far local3[] = "\
  129.   -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\
  130.                                              -M  pipe through \"more\" pager\n";
  131. #else
  132.    static char Far local3[] = " \
  133.  -X  restore ACLs if supported              -s  spaces in filenames => '_'\n\n";
  134. #endif
  135. #else /* !OS2 */
  136. #ifdef MORE
  137.    static char Far local3[] = "  -\
  138. M  pipe through \"more\" pager              -s  spaces in filenames => '_'\n\n";
  139. #else
  140.    static char Far local3[] = "\
  141.                                              -s  spaces in filenames => '_'\n";
  142. #endif
  143. #endif /* ?OS2 */
  144. #else /* !DOS_OS2_W32 */
  145. #ifdef VMS
  146.    static char Far local2[] = "\"-X\" restore owner/protection info";
  147. #ifdef MORE
  148.    static char Far local3[] = "  \
  149.                                           \"-M\" pipe through \"more\" pager\n";
  150. #else
  151.    static char Far local3[] = "\n";
  152. #endif
  153. #else /* !VMS */
  154. #ifdef UNIX
  155.    static char Far local2[] = " -X  restore UID/GID info";
  156. #ifdef MORE
  157.    static char Far local3[] = "\
  158.                                              -M  pipe through \"more\" pager\n";
  159. #else
  160.    static char Far local3[] = "\n";
  161. #endif
  162. #else /* !UNIX */
  163. #ifdef AMIGA
  164.     static char Far local2[] = " -N  restore comments as filenotes";
  165. #ifdef MORE
  166.     static char Far local3[] = "\
  167.                                              -M  pipe through \"more\" pager\n";
  168. #else
  169.     static char Far local3[] = "\n";
  170. #endif
  171. #else /* !AMIGA */
  172. #ifdef MORE
  173.     static char Far local2[] = " -M  pipe through \"more\" pager";
  174.     static char Far local3[] = "\n";
  175. #else
  176.     static char Far local2[] = "";   /* Atari, Mac, etc. */
  177.     static char Far local3[] = "";
  178. #endif
  179. #endif /* ?AMIGA */
  180. #endif /* ?UNIX */
  181. #endif /* ?VMS */
  182. #endif /* ?DOS_OS2_W32 */
  183. #endif /* !SFX */
  184.  
  185. #ifndef NO_ZIPINFO
  186. #ifdef VMS
  187.    static char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
  188. #else
  189.    static char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
  190. #endif
  191.  
  192. static char Far ZipInfoUsageLine1[] = "\
  193. ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the fine folks at Info-ZIP.\n\
  194. \n\
  195. List name, date/time, attribute, size, compression method, etc., about files\n\
  196. in list (excluding those in xlist) contained in the specified .zip archive(s).\
  197. \n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
  198.    usage:  zipinfo [-12smlvhMtTz] file[.zip] [list...] [-x xlist...]\n\
  199.       or:  unzip %s-Z%s [-12smlvhMtTz] file[.zip] [list...] [-x xlist...]\n";
  200.  
  201. static char Far ZipInfoUsageLine2[] = "\nmain\
  202.  listing-format options:             -s  short Unix \"ls -l\" format (def.)\n\
  203.   -1  filenames ONLY, one per line       -m  medium Unix \"ls -l\" format\n\
  204.   -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
  205.                                          -v  verbose, multi-page format\n";
  206.  
  207. static char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
  208.   -h  print header line       -t  print totals for listed files or for all\n\
  209.   -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
  210. \n%s\
  211.   -x  exclude filenames that follow from listing\n";
  212. #ifdef MORE
  213. #ifdef VMS
  214.    static char Far ZipInfoUsageLine4[] =
  215.      " \"-M\" page output through built-in \"more\"\n";
  216. #else
  217.    static char Far ZipInfoUsageLine4[] =
  218.      "  -M  page output through built-in \"more\"\n";
  219. #endif
  220. #else /* !MORE */
  221.    static char Far ZipInfoUsageLine4[] = "";
  222. #endif /* ?MORE */
  223. #endif /* !NO_ZIPINFO */
  224. #endif /* !VMSCLI */
  225.  
  226. #ifdef BETA
  227.    static char Far BetaVersion[] = "%s\
  228.       THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
  229. #endif
  230.  
  231. #ifdef SFX
  232.    static char Far UnzipSFXBanner[] =
  233.      "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (Zip-Bugs@wkuvx1.wku.edu).\n";
  234. #  if (defined(SFX_EXDIR) && !defined(VMS))
  235.      static char Far UnzipSFXOpts[] =
  236.     "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
  237. #  else
  238.      static char Far UnzipSFXOpts[] =
  239.        "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
  240. #  endif
  241. #else /* !SFX */
  242.    static char Far CompileOptions[] = "UnZip special compilation options:\n";
  243.    static char Far CompileOptFormat[] = "\t%s\n";
  244.    static char Far EnvOptions[] = "\nUnZip and ZipInfo environment options:\n";
  245.    static char Far EnvOptFormat[] = "%16s:  %s\n";
  246.    static char Far None[] = "[none]";
  247. #  ifdef ASM_CRC
  248.      static char Far AsmCRC[] = "ASM_CRC";
  249. #  endif
  250. #  ifdef ASM_INFLATECODES
  251.      static char Far AsmInflateCodes[] = "ASM_INFLATECODES";
  252. #  endif
  253. #  ifdef CHECK_VERSIONS
  254.      static char Far Check_Versions[] = "CHECK_VERSIONS";
  255. #  endif
  256. #  ifdef COPYRIGHT_CLEAN
  257.      static char Far Copyright_Clean[] =
  258.      "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
  259. #  endif
  260. #  ifdef DEBUG
  261.      static char Far Debug[] = "DEBUG";
  262. #  endif
  263. #  ifdef DEBUG_TIME
  264.      static char Far DebugTime[] = "DEBUG_TIME";
  265. #  endif
  266. #  ifdef DLL
  267.      static char Far Dll[] = "DLL";
  268. #  endif
  269. #  ifdef DOSWILD
  270.      static char Far DosWild[] = "DOSWILD";
  271. #  endif
  272. #  ifndef MORE
  273.      static char Far No_More[] = "NO_MORE";
  274. #  endif
  275. #  ifdef NO_ZIPINFO
  276.      static char Far No_ZipInfo[] = "NO_ZIPINFO";
  277. #  endif
  278. #  ifdef OS2_EAS
  279.      static char Far OS2ExtAttrib[] = "OS2_EAS";
  280. #  endif
  281. #  ifdef REENTRANT
  282.      static char Far Reentrant[] = "REENTRANT";
  283. #  endif
  284. #  ifdef REGARGS
  285.      static char Far RegArgs[] = "REGARGS";
  286. #  endif
  287. #  ifdef RETURN_CODES
  288.      static char Far Return_Codes[] = "RETURN_CODES";
  289. #  endif
  290. #  ifdef TIMESTAMP
  291.      static char Far TimeStamp[] = "TIMESTAMP";
  292. #  endif
  293. #  ifndef COPYRIGHT_CLEAN
  294.      static char Far Use_Smith_Code[] =
  295.      "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
  296. #  endif
  297. #ifdef USE_EF_UX_TIME
  298.      static char Far Use_EF_UX_time[] = "USE_EF_UX_TIME";
  299. #endif
  300. #  ifdef USE_ZLIB
  301.      static char Far UseZlib[] =
  302.      "USE_ZLIB (compiled with version %s; using version %s)";
  303. #  endif
  304. #  ifdef VMSCLI
  305.      static char Far VmsCLI[] = "VMSCLI";
  306. #  endif
  307. #  ifdef VMSWILD
  308.      static char Far VmsWild[] = "VMSWILD";
  309. #  endif
  310. #  ifdef CRYPT
  311. #    ifdef PASSWD_FROM_STDIN
  312.        static char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
  313. #    endif
  314.      static char Far Decryption[] = "\t[decryption, version %d.%d%s of %s]\n";
  315.      static char Far CryptDate[] = CR_VERSION_DATE;
  316. #  endif
  317. #  ifdef __EMX__
  318.      static char Far EnvEMX[] = "EMX";
  319.      static char Far EnvEMXOPT[] = "EMXOPT";
  320. #  endif
  321. #  ifdef __GO32__
  322.      static char Far EnvGO32[] = "GO32";
  323.      static char Far EnvGO32TMP[] = "GO32TMP";
  324. #  endif
  325.  
  326. /* UnzipUsageLine1[] is also used in vms/cmdline.c:  do not make it static */
  327. #ifdef COPYRIGHT_CLEAN
  328.    char Far UnzipUsageLine1[] = "\
  329. UnZip %d.%d%d%s of %s, by Info-ZIP.  Maintained by Greg Roelofs.  Send\n\
  330. bug reports to the authors at Zip-Bugs@wkuvx1.wku.edu; see README for details.\
  331. \n\n";
  332. #else
  333.    char Far UnzipUsageLine1[] = "\
  334. UnZip %d.%d%d%s of %s, by Info-ZIP.  UnReduce (c) 1989 by S. H. Smith.\n\
  335. Send bug reports to authors at Zip-Bugs@wkuvx1.wku.edu; see README for details.\
  336. \n\n";
  337. #endif /* ?COPYRIGHT_CLEAN */
  338.  
  339. static char Far UnzipUsageLine2a[] = "\
  340. Latest sources and executables are always in ftp.uu.net:/pub/archiving/zip, at\
  341. \nleast as of date of this release; see \"Where\" for other ftp and non-ftp \
  342. sites.\n\n";
  343.  
  344. #ifndef VMSCLI
  345. static char Far UnzipUsageLine2[] = "\
  346. Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
  347.  Default action is to extract files in list, except those in xlist, to exdir;\n\
  348.   file[.zip] may be a wildcard.  %s\n\n";
  349.  
  350. #ifdef NO_ZIPINFO
  351. #  define ZIPINFO_MODE_OPTION  ""
  352.    static char Far ZipInfoMode[] =
  353.      "(ZipInfo mode is disabled in this version.)";
  354. #else
  355. #  define ZIPINFO_MODE_OPTION  "[-Z] "
  356. #  ifdef VMS
  357.      static char Far ZipInfoMode[] =
  358.        "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).";
  359. #  else
  360.      static char Far ZipInfoMode[] =
  361.        "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
  362. #  endif
  363. #endif /* ?NO_ZIPINFO */
  364.  
  365. static char Far UnzipUsageLine3[] = "\
  366.   -p  extract files to pipe, no messages     -l  list files (short format)\n\
  367.   -f  freshen existing files, create none    -t  test compressed archive data\n\
  368.   -u  update files, create if necessary      -z  display archive comment\n\
  369.   -x  exclude files which follow (in xlist)  -d  extract files into exdir\n\
  370. %s\n";
  371.  
  372. static char Far UnzipUsageLine4[] = "\
  373. modifiers:                                   -q  quiet mode (-qq => quieter)\n\
  374.   -n  never overwrite existing files         -a  auto-convert any text files\n\
  375.   -o  overwrite files WITHOUT prompting      -aa treat ALL files as text\n \
  376.  -j  junk paths (don't make directories)    -v  be verbose/print version info\n\
  377.  %c-C%c match filenames case-insensitively    %c-L%c make (some) names \
  378. lowercase\n %-42s %c-V%c retain VMS version numbers\n%s";
  379.  
  380. static char Far UnzipUsageLine5[] = "\
  381. Examples (see unzip.doc for more info):\n\
  382.   unzip data1 -x joe   => extract all files except joe from zipfile data1.zip\n\
  383. %s\
  384.   unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
  385. #endif /* !VMSCLI */
  386. #endif /* ?SFX */
  387.  
  388.  
  389.  
  390.  
  391.  
  392. /*****************************/
  393. /*  main() / UzpMain() stub  */
  394. /*****************************/
  395.  
  396. int MAIN(argc, argv)   /* return PK-type error code (except under VMS) */
  397.     int argc;
  398.     char *argv[];
  399. {
  400.     int r;
  401.  
  402.     CONSTRUCTGLOBALS();
  403.     r = unzip(__G__ argc, argv);
  404.     DESTROYGLOBALS()
  405.     RETURN(r);
  406. }
  407.  
  408.  
  409.  
  410.  
  411. /*******************************/
  412. /*  Primary UnZip entry point  */
  413. /*******************************/
  414.  
  415. int unzip(__G__ argc, argv)
  416.     __GDEF
  417.     int argc;
  418.     char *argv[];
  419. {
  420. #ifndef NO_ZIPINFO
  421.     char *p;
  422. #endif
  423.     int i, retcode, error=FALSE;
  424.  
  425. /*---------------------------------------------------------------------------
  426.     Macintosh initialization code.
  427.   ---------------------------------------------------------------------------*/
  428.  
  429. #ifdef MACOS
  430.     int a;
  431.  
  432.     for (a = 0;  a < 4;  ++a)
  433.         G.rghCursor[a] = GetCursor(a+128);
  434.     G.giCursor = 0;
  435.     error = FALSE;
  436. #endif
  437.  
  438. #if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
  439.     extern void DebugMalloc(void);
  440.  
  441.     atexit(DebugMalloc);
  442. #endif
  443.  
  444. #ifdef MALLOC_WORK
  445.     G.area.Slide =(uch *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
  446.     G.area.shrink.Parent = (shrint *)G.area.Slide;
  447.     G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE+1));
  448.     G.area.shrink.Stack = G.area.Slide +
  449.                            (sizeof(shrint) + sizeof(uch))*(HSIZE+1);
  450. #endif
  451.  
  452. /*---------------------------------------------------------------------------
  453.     Human68K initialization code.
  454.   ---------------------------------------------------------------------------*/
  455.  
  456. #ifdef __human68k__
  457.     InitTwentyOne();
  458. #endif
  459.  
  460. /*---------------------------------------------------------------------------
  461.     Acorn RISC OS initialization code.
  462.   ---------------------------------------------------------------------------*/
  463.  
  464. #ifdef RISCOS
  465.     set_prefix();
  466. #endif
  467.  
  468. /*---------------------------------------------------------------------------
  469.     Set signal handler for restoring echo, warn of zipfile corruption, etc.
  470.   ---------------------------------------------------------------------------*/
  471.  
  472. #ifndef CMS_MVS
  473.     signal(SIGINT, handler);
  474. #ifdef SIGTERM                 /* some systems really have no SIGTERM */
  475.     signal(SIGTERM, handler);
  476. #endif
  477. #ifdef SIGBUS
  478.     signal(SIGBUS, handler);
  479. #endif
  480. #ifdef SIGSEGV
  481.     signal(SIGSEGV, handler);
  482. #endif
  483. #endif /* !CMS_MVS */
  484.  
  485. /*---------------------------------------------------------------------------
  486.     First figure out if we're running in UnZip mode or ZipInfo mode, and put
  487.     the appropriate environment-variable options into the queue.  Then rip
  488.     through any command-line options lurking about...
  489.   ---------------------------------------------------------------------------*/
  490.  
  491. #ifdef SFX
  492.     G.argv0 = argv[0];
  493. #if defined(OS2) || defined(WIN32)
  494.     G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
  495. #else
  496.     G.zipfn = G.argv0;
  497. #endif
  498.     G.zipinfo_mode = FALSE;
  499.     if ((error = uz_opts(__G__ &argc, &argv)) != 0)
  500.         return(error);
  501.  
  502. #else /* !SFX */
  503.  
  504. #ifdef RISCOS
  505.     /* get the extensions to swap from environment */
  506.     getRISCOSexts("Unzip$Exts");
  507. #endif
  508.  
  509. #ifdef MSDOS
  510.     /* extract MKS extended argument list from environment (before envargs!) */
  511.     mksargs(&argc, &argv);
  512. #endif
  513.  
  514. #ifdef VMSCLI
  515.     {
  516.         ulg status = vms_unzip_cmdline(&argc, &argv);
  517.         if (!(status & 1))
  518.             return status;
  519.     }
  520. #endif /* VMSCLI */
  521.  
  522. #ifndef NO_ZIPINFO
  523.     if ((p = strrchr(argv[0], DIR_END)) == (char *)NULL)
  524.         p = argv[0];
  525.     else
  526.         ++p;
  527.  
  528.     if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
  529.         STRNICMP(p, "ii", 2) == 0 ||
  530.         (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
  531.     {
  532.         G.zipinfo_mode = TRUE;
  533.         envargs(__G__ &argc, &argv, LoadFarStringSmall(EnvZipInfo),
  534.           LoadFarStringSmall2(EnvZipInfo2));
  535.         error = zi_opts(__G__ &argc, &argv);
  536.     } else
  537. #endif /* NO_ZIPINFO */
  538.     {
  539.         G.zipinfo_mode = FALSE;
  540.         envargs(__G__ &argc, &argv, LoadFarStringSmall(EnvUnZip),
  541.           LoadFarStringSmall2(EnvUnZip2));
  542.         error = uz_opts(__G__ &argc, &argv);
  543.     }
  544.     if ((argc < 0) || error)
  545.         return(error);
  546.  
  547. #endif /* ?SFX */
  548.  
  549. /*---------------------------------------------------------------------------
  550.     Now get the zipfile name from the command line and then process any re-
  551.     maining options and file specifications.
  552.   ---------------------------------------------------------------------------*/
  553.  
  554. #ifdef DOS_H68_OS2_W32
  555.     /* convert MSDOS-style directory separators to Unix-style ones for
  556.      * user's convenience (include zipfile name itself)
  557.      */
  558.     for (G.pfnames = argv, i = argc+1;  i > 0;  --i) {
  559.         char *q;
  560.  
  561.         for (q = *G.pfnames;  *q;  ++q)
  562.             if (*q == '\\')
  563.                 *q = '/';
  564.         ++G.pfnames;
  565.     }
  566. #if 0                          /* old version; depends on argv[last] == NULL */
  567.     G.pfnames = argv;
  568.     while (*G.pfnames != (char *)NULL) {
  569.         char *q;
  570.  
  571.         for (q = *G.pfnames;  *q;  ++q)
  572.             if (*q == '\\')
  573.                 *q = '/';
  574.         ++G.pfnames;
  575.     }
  576. #endif /* 0 */
  577. #endif /* DOS_H68_OS2_W32 */
  578.  
  579. #ifndef SFX
  580.     G.wildzipfn = *argv++;
  581. #endif
  582.  
  583. #if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
  584.  
  585.     G.filespecs = argc;
  586.     G.xfilespecs = 0;
  587.  
  588.     if (argc > 0) {
  589.         char **pp = argv-1;
  590.  
  591.         G.pfnames = argv;
  592.         while (*++pp)
  593.             if (strcmp(*pp, "-x") == 0) {
  594.                 if (pp > argv) {
  595.                     *pp = 0;              /* terminate G.pfnames */
  596.                     G.filespecs = pp - G.pfnames;
  597.                 } else {
  598.                     G.pfnames = fnames;  /* defaults */
  599.                     G.filespecs = 0;
  600.                 }
  601.                 G.pxnames = pp + 1;      /* excluded-names ptr: _after_ -x */
  602.                 G.xfilespecs = argc - G.filespecs - 1;
  603.                 break;                    /* skip rest of args */
  604.             }
  605.         G.process_all_files = FALSE;
  606.     } else
  607.         G.process_all_files = TRUE;      /* for speed */
  608.  
  609. #else /* !SFX || SFX_EXDIR */             /* check for -x or -d */
  610.  
  611.     G.filespecs = argc;
  612.     G.xfilespecs = 0;
  613.  
  614.     if (argc > 0) {
  615.         int in_files=FALSE, in_xfiles=FALSE;
  616.         char **pp = argv-1;
  617.  
  618.         G.process_all_files = FALSE;
  619.         G.pfnames = argv;
  620.         while (*++pp) {
  621.             Trace((stderr, "pp - argv = %d\n", pp-argv));
  622. #ifdef CMS_MVS
  623.             if (!G.dflag && STRNICMP(*pp, "-d", 2) == 0) {
  624. #else
  625.             if (!G.dflag && strncmp(*pp, "-d", 2) == 0) {
  626. #endif
  627.                 char *q = *pp;
  628.                 int firstarg = (pp == argv);
  629.  
  630.                 G.dflag = TRUE;
  631.                 if (in_files) {      /* ... zipfile ... -d exdir ... */
  632.                     *pp = (char *)NULL;         /* terminate G.pfnames */
  633.                     G.filespecs = pp - G.pfnames;
  634.                     in_files = FALSE;
  635.                 } else if (in_xfiles) {
  636.                     *pp = (char *)NULL;         /* terminate G.pxnames */
  637.                     G.xfilespecs = pp - G.pxnames;
  638.                     /* "... -x xlist -d exdir":  nothing left */
  639.                 }
  640.                 /* first check for "-dexdir", then for "-d exdir" */
  641.                 if (q[2])
  642.                     q += 2;
  643.                 else if (*++pp)
  644.                     q = *pp;
  645.                 else {
  646.                     Info(slide, 0x401, ((char *)slide,
  647.                       LoadFarString(MustGiveExdir)));
  648.                     return(PK_PARAM);  /* don't extract here by accident */
  649.                 }
  650.                 if (G.extract_flag) {
  651.                     G.create_dirs = !G.fflag;
  652.                     if ((error = checkdir(__G__ q, ROOT)) > 2) {
  653.                         return(error);  /* out of memory, or file in way */
  654.                     }
  655.                 } else
  656.                     Info(slide, 0x401, ((char *)slide,
  657.                       LoadFarString(NotExtracting)));
  658.                 if (firstarg)   /* ... zipfile -d exdir ... */
  659.                     if (pp[1]) {
  660.                         G.pfnames = pp + 1;  /* argv+2 */
  661.                         G.filespecs = argc - (G.pfnames-argv);  /* for now... */
  662.                     } else {
  663.                         G.process_all_files = TRUE;
  664.                         G.pfnames = fnames;  /* GRR: necessary? */
  665.                         G.filespecs = 0;     /* GRR: necessary? */
  666.                         break;
  667.                     }
  668.             } else if (!in_xfiles) {
  669.                 if (strcmp(*pp, "-x") == 0) {
  670.                     in_xfiles = TRUE;
  671.                     if (pp == G.pfnames) {
  672.                         G.pfnames = fnames;  /* defaults */
  673.                         G.filespecs = 0;
  674.                     } else if (in_files) {
  675.                         *pp = 0;                   /* terminate G.pfnames */
  676.                         G.filespecs = pp - G.pfnames;  /* adjust count */
  677.                         in_files = FALSE;
  678.                     }
  679.                     G.pxnames = pp + 1;  /* excluded-names ptr starts after -x */
  680.                     G.xfilespecs = argc - (G.pxnames-argv);  /* anything left... */
  681.                 } else
  682.                     in_files = TRUE;
  683.             }
  684.         }
  685.     } else
  686.         G.process_all_files = TRUE;      /* for speed */
  687.  
  688. #endif /* ?(SFX && !SFX_EXDIR) */
  689.  
  690. /*---------------------------------------------------------------------------
  691.     Okey dokey, we have everything we need to get started.  Let's roll.
  692.   ---------------------------------------------------------------------------*/
  693.  
  694.     retcode = process_zipfiles(__G);
  695.     return(retcode);
  696.  
  697. } /* end main()/unzip() */
  698.  
  699.  
  700.  
  701.  
  702.  
  703. /**********************/
  704. /* Function uz_opts() */
  705. /**********************/
  706.  
  707. int uz_opts(__G__ pargc, pargv)
  708.     int *pargc;
  709.     char ***pargv;
  710.     __GDEF
  711. {
  712.     char **argv, *s;
  713. #if (!defined(SFX) || defined(SFX_EXDIR))
  714.     char *exdir = NULL;         /* initialized to shut up false GCC warning */
  715. #endif /* !SFX || SFX_EXDIR */
  716.     int argc, c, error=FALSE, negative=0;
  717.  
  718.  
  719.     argc = *pargc;
  720.     argv = *pargv;
  721.  
  722.     while (--argc > 0 && (*++argv)[0] == '-') {
  723.         s = argv[0] + 1;
  724.         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
  725. #ifdef CMS_MVS
  726.             switch (tolower(c)) {
  727. #else
  728.             switch (c) {
  729. #endif
  730.                 case ('-'):
  731.                     ++negative;
  732.                     break;
  733.                 case ('a'):
  734.                     if (negative) {
  735.                         G.aflag = MAX(G.aflag-negative,0);
  736.                         negative = 0;
  737.                     } else
  738.                         ++G.aflag;
  739.                     break;
  740.                 case ('b'):
  741.                     if (negative) {
  742. #ifdef VMS
  743.                         G.bflag = MAX(G.bflag-negative,0);
  744. #endif
  745.                         negative = 0;   /* do nothing:  "-b" is default */
  746.                     } else {
  747. #ifdef VMS
  748.                         if (G.aflag == 0)
  749.                            ++G.bflag;
  750. #endif
  751.                         G.aflag = 0;
  752.                     }
  753.                     break;
  754.                 case ('c'):
  755.                     if (negative) {
  756.                         G.cflag = FALSE, negative = 0;
  757. #ifdef NATIVE
  758.                         G.aflag = 0;
  759. #endif
  760.                     } else {
  761.                         G.cflag = TRUE;
  762. #ifdef NATIVE
  763.                         G.aflag = 2;  /* so you can read it on the screen */
  764. #endif
  765. #ifdef DLL
  766.                         if (G.redirect_text)
  767.                             G.redirect_data = 2;
  768. #endif
  769.                     }
  770.                     break;
  771. #ifndef CMS_MVS
  772.                 case ('C'):    /* -C:  match filenames case-insensitively */
  773.                     if (negative)
  774.                         G.C_flag = FALSE, negative = 0;
  775.                     else
  776.                         G.C_flag = TRUE;
  777.                     break;
  778. #endif /* !CMS_MVS */
  779. #if (!defined(SFX) || defined(SFX_EXDIR))
  780.                 case ('d'):
  781.                     if (negative) {   /* negative not allowed with -d exdir */
  782.                         Info(slide, 0x401, ((char *)slide,
  783.                           LoadFarString(MustGiveExdir)));
  784.                         return(PK_PARAM);  /* don't extract here by accident */
  785.                     }
  786.                     if (G.dflag) {
  787.                         Info(slide, 0x401, ((char *)slide,
  788.                           LoadFarString(OnlyOneExdir)));
  789.                         return(PK_PARAM);    /* GRR:  stupid restriction? */
  790.                     } else {
  791.                         G.dflag = TRUE;
  792.                         /* first check for "-dexdir", then for "-d exdir" */
  793.                         exdir = s;
  794.                         if (*exdir == 0) {
  795.                             if (argc > 1) {
  796.                                 --argc;
  797.                                 exdir = *++argv;
  798.                                 if (*exdir == '-') {
  799.                                     Info(slide, 0x401, ((char *)slide,
  800.                                       LoadFarString(MustGiveExdir)));
  801.                                     return(PK_PARAM);
  802.                                 }
  803.                                 /* else exdir points at extraction dir */
  804.                             } else {
  805.                                 Info(slide, 0x401, ((char *)slide,
  806.                                   LoadFarString(MustGiveExdir)));
  807.                                 return(PK_PARAM);
  808.                             }
  809.                         }
  810.                         /* exdir now points at extraction dir (-dexdir or
  811.                          *  -d exdir); point s at end of exdir to avoid mis-
  812.                          *  interpretation of exdir characters as more options
  813.                          */
  814.                         if (*s != 0)
  815.                             while (*++s != 0)
  816.                                 ;
  817.                     }
  818.                     break;
  819. #endif /* !SFX || SFX_EXDIR */
  820.                 case ('e'):    /* just ignore -e, -x options (extract) */
  821.                     break;
  822.                 case ('f'):    /* "freshen" (extract only newer files) */
  823.                     if (negative)
  824.                         G.fflag = G.uflag = FALSE, negative = 0;
  825.                     else
  826.                         G.fflag = G.uflag = TRUE;
  827.                     break;
  828.                 case ('h'):    /* just print help message and quit */
  829.                     *pargc = -1;
  830.                     return usage(__G__ FALSE);
  831.                 case ('j'):    /* junk pathnames/directory structure */
  832.                     if (negative)
  833.                         G.jflag = FALSE, negative = 0;
  834.                     else
  835.                         G.jflag = TRUE;
  836.                     break;
  837. #ifndef SFX
  838.                 case ('l'):
  839.                     if (negative) {
  840.                         G.vflag = MAX(G.vflag-negative,0);
  841.                         negative = 0;
  842.                     } else
  843.                         ++G.vflag;
  844.                     break;
  845. #endif /* !SFX */
  846. #ifndef CMS_MVS
  847.                 case ('L'):    /* convert (some) filenames to lowercase */
  848.                     if (negative)
  849.                         G.L_flag = FALSE, negative = 0;
  850.                     else
  851.                         G.L_flag = TRUE;
  852.                     break;
  853. #endif /* !CMS_MVS */
  854. #ifdef MORE
  855. #ifdef CMS_MVS
  856.                 case ('m'):
  857. #endif
  858.                 case ('M'):    /* send all screen output through "more" fn. */
  859. /* GRR:  eventually check for numerical argument => height */
  860.                     if (negative)
  861.                         G.M_flag = FALSE, negative = 0;
  862.                     else
  863.                         G.M_flag = TRUE;
  864.                     break;
  865. #endif /* MORE */
  866.                 case ('n'):    /* don't overwrite any files */
  867.                     if (negative)
  868.                         G.overwrite_none = FALSE, negative = 0;
  869.                     else
  870.                         G.overwrite_none = TRUE;
  871.                     break;
  872. #ifdef AMIGA
  873.                 case ('N'):    /* restore comments as filenotes */
  874.                     if (negative)
  875.                         G.N_flag = FALSE, negative = 0;
  876.                     else
  877.                         G.N_flag = TRUE;
  878.                     break;
  879. #endif /* AMIGA */
  880.                 case ('o'):    /* OK to overwrite files without prompting */
  881.                     if (negative) {
  882.                         G.overwrite_all = MAX(G.overwrite_all-negative,0);
  883.                         negative = 0;
  884.                     } else
  885.                         ++G.overwrite_all;
  886.                     break;
  887.                 case ('p'):    /* pipes:  extract to stdout, no messages */
  888.                     if (negative) {
  889.                         G.cflag = FALSE;
  890.                         G.qflag = MAX(G.qflag-999,0);
  891.                         negative = 0;
  892.                     } else {
  893.                         G.cflag = TRUE;
  894.                         G.qflag += 999;
  895.                     }
  896.                     break;
  897.                 case ('q'):    /* quiet:  fewer comments/messages */
  898.                     if (negative) {
  899.                         G.qflag = MAX(G.qflag-negative,0);
  900.                         negative = 0;
  901.                     } else
  902.                         ++G.qflag;
  903.                     break;
  904. #if (defined(DLL) && defined(API_DOC))
  905.                 case ('A'):    /* extended help for API */
  906.                     APIhelp(__G__ argc,argv);
  907.                     return 0;
  908. #endif
  909. #ifdef DOS_OS2_W32
  910.                 case ('s'):    /* spaces in filenames:  allow by default */
  911.                     if (negative)
  912.                         G.sflag = FALSE, negative = 0;
  913.                     else
  914.                         G.sflag = TRUE;
  915.                     break;
  916. #endif /* DOS_OS2_W32 */
  917.                 case ('t'):
  918.                     if (negative)
  919.                         G.tflag = FALSE, negative = 0;
  920.                     else
  921.                         G.tflag = TRUE;
  922.                     break;
  923. #ifdef TIMESTAMP
  924.                 case ('T'):
  925.                     if (negative)
  926.                         G.T_flag = FALSE, negative = 0;
  927.                     else
  928.                         G.T_flag = TRUE;
  929.                     break;
  930. #endif
  931.                 case ('u'):    /* update (extract only new and newer files) */
  932.                     if (negative)
  933.                         G.uflag = FALSE, negative = 0;
  934.                     else
  935.                         G.uflag = TRUE;
  936.                     break;
  937. #ifndef CMS_MVS
  938.                 case ('U'):    /* obsolete; to be removed in version 6.0 */
  939.                     if (negative)
  940.                         G.L_flag = TRUE, negative = 0;
  941.                     else
  942.                         G.L_flag = FALSE;
  943.                     break;
  944. #endif /* !CMS_MVS */
  945. #ifndef SFX
  946.                 case ('v'):    /* verbose */
  947.                     if (negative) {
  948.                         G.vflag = MAX(G.vflag-negative,0);
  949.                         negative = 0;
  950.                     } else if (G.vflag)
  951.                         ++G.vflag;
  952.                     else
  953.                         G.vflag = 2;
  954.                     break;
  955. #endif /* !SFX */
  956. #ifndef CMS_MVS
  957.                 case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
  958.                     if (negative)
  959.                         G.V_flag = FALSE, negative = 0;
  960.                     else
  961.                         G.V_flag = TRUE;
  962.                     break;
  963. #endif /* !CMS_MVS */
  964.                 case ('x'):    /* extract:  default */
  965. #ifdef SFX
  966.                     /* When 'x' is the only option in this argument, and the
  967.                      * next arg is not an option, assume this initiates an
  968.                      * exclusion list (-x xlist): Then, terminate option
  969.                      * scanning; leave uz_opts with still pointing to "-x";
  970.                      * the xlist is processed later.
  971.                      */
  972.                     if (s - argv[0] == 2 && *s == 0 &&
  973.                         argc > 1 && argv[1][0] != '-') {
  974.                         /* break out of nested loops without "++argv;--argc" */
  975.                         goto opts_done;
  976.                     }
  977. #endif
  978.                     break;
  979. #if defined(VMS) || defined(UNIX) || defined(OS2)
  980.                 case ('X'):   /* restore owner/protection info (need privs?) */
  981.                     if (negative)
  982.                         G.X_flag = FALSE, negative = 0;
  983.                     else
  984.                         G.X_flag = TRUE;
  985.                     break;
  986. #endif /* VMS || UNIX || OS2 */
  987.                 case ('z'):    /* display only the archive comment */
  988.                     if (negative) {
  989.                         G.zflag -= negative;
  990.                         negative = 0;
  991.                     } else
  992.                         ++G.zflag;
  993.                     break;
  994. #ifdef DOS_OS2_W32
  995.                 case ('$'):
  996.                     if (negative) {
  997.                         G.volflag = MAX(G.volflag-negative,0);
  998.                         negative = 0;
  999.                     } else
  1000.                         ++G.volflag;
  1001.                     break;
  1002. #endif /* DOS_OS2_W32 */
  1003.                 default:
  1004.                     error = TRUE;
  1005.                     break;
  1006.  
  1007.             } /* end switch */
  1008.         } /* end while (not end of argument string) */
  1009.     } /* end while (not done with switches) */
  1010.  
  1011. /*---------------------------------------------------------------------------
  1012.     Check for nonsensical combinations of options.
  1013.   ---------------------------------------------------------------------------*/
  1014.  
  1015. #ifdef SFX
  1016. opts_done:  /* yes, very ugly...but only used by UnZipSFX with -x xlist */
  1017. #endif
  1018.  
  1019.     if ((G.cflag && G.tflag) || (G.cflag && G.uflag) ||
  1020.         (G.tflag && G.uflag) || (G.fflag && G.overwrite_none))
  1021.     {
  1022.         Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
  1023.         error = TRUE;
  1024.     }
  1025.     if (G.aflag > 2)
  1026.         G.aflag = 2;
  1027. #ifdef VMS
  1028.     if (G.bflag > 2)
  1029.         G.bflag = 2;
  1030. #endif
  1031.     if (G.overwrite_all && G.overwrite_none) {
  1032.         Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
  1033.         G.overwrite_all = FALSE;
  1034.     }
  1035. #ifdef MORE
  1036.     if (G.M_flag && !isatty(1))  /* stdout redirected: "more" func useless */
  1037.         G.M_flag = 0;
  1038. #endif
  1039.  
  1040. #ifdef SFX
  1041.     if (error)
  1042. #else
  1043.     if ((argc-- == 0) || error)
  1044. #endif
  1045.     {
  1046.         *pargc = argc;
  1047.         *pargv = argv;
  1048. #ifndef SFX
  1049.         if (G.vflag >= 2 && argc == -1) {              /* "unzip -v" */
  1050.             if (G.qflag > 3)                           /* "unzip -vqqqq" */
  1051.                 Info(slide, 0, ((char *)slide, "%d\n",
  1052.                   (UZ_MAJORVER*100 + UZ_MINORVER*10 + PATCHLEVEL)));
  1053.             else {
  1054.                 char *envptr, *getenv();
  1055.                 int numopts = 0;
  1056.  
  1057.                 Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1),
  1058.                   UZ_MAJORVER, UZ_MINORVER, PATCHLEVEL, BETALEVEL,
  1059.                   LoadFarStringSmall(VersionDate)));
  1060.                 Info(slide, 0, ((char *)slide,
  1061.                   LoadFarString(UnzipUsageLine2a)));
  1062.                 version(__G);
  1063.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
  1064. #ifdef ASM_CRC
  1065.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1066.                   LoadFarStringSmall(AsmCRC)));
  1067.                 ++numopts;
  1068. #endif
  1069. #ifdef ASM_INFLATECODES
  1070.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1071.                   LoadFarStringSmall(AsmInflateCodes)));
  1072.                 ++numopts;
  1073. #endif
  1074. #ifdef CHECK_VERSIONS
  1075.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1076.                   LoadFarStringSmall(Check_Versions)));
  1077.                 ++numopts;
  1078. #endif
  1079. #ifdef COPYRIGHT_CLEAN
  1080.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1081.                   LoadFarStringSmall(Copyright_Clean)));
  1082.                 ++numopts;
  1083. #endif
  1084. #ifdef DEBUG
  1085.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1086.                   LoadFarStringSmall(Debug)));
  1087.                 ++numopts;
  1088. #endif
  1089. #ifdef DEBUG_TIME
  1090.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1091.                   LoadFarStringSmall(DebugTime)));
  1092.                 ++numopts;
  1093. #endif
  1094. #ifdef DLL
  1095.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1096.                   LoadFarStringSmall(Dll)));
  1097.                 ++numopts;
  1098. #endif
  1099. #ifdef DOSWILD
  1100.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1101.                   LoadFarStringSmall(DosWild)));
  1102.                 ++numopts;
  1103. #endif
  1104. #ifndef MORE
  1105.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1106.                   LoadFarStringSmall(No_More)));
  1107.                 ++numopts;
  1108. #endif
  1109. #ifdef NO_ZIPINFO
  1110.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1111.                   LoadFarStringSmall(No_ZipInfo)));
  1112.                 ++numopts;
  1113. #endif
  1114. #ifdef OS2_EAS
  1115.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1116.                   LoadFarStringSmall(OS2ExtAttrib)));
  1117.                 ++numopts;
  1118. #endif
  1119. #ifdef REENTRANT
  1120.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1121.                   LoadFarStringSmall(Reentrant)));
  1122.                 ++numopts;
  1123. #endif
  1124. #ifdef REGARGS
  1125.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1126.                   LoadFarStringSmall(RegArgs)));
  1127.                 ++numopts;
  1128. #endif
  1129. #ifdef RETURN_CODES
  1130.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1131.                   LoadFarStringSmall(Return_Codes)));
  1132.                 ++numopts;
  1133. #endif
  1134. #ifdef TIMESTAMP
  1135.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1136.                   LoadFarStringSmall(TimeStamp)));
  1137.                 ++numopts;
  1138. #endif
  1139. #ifndef COPYRIGHT_CLEAN
  1140.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1141.                   LoadFarStringSmall(Use_Smith_Code)));
  1142.                 ++numopts;
  1143. #endif
  1144. #ifdef USE_EF_UX_TIME
  1145.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1146.                   LoadFarStringSmall(Use_EF_UX_time)));
  1147.                 ++numopts;
  1148. #endif
  1149. #ifdef USE_ZLIB
  1150.                 sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
  1151.                   ZLIB_VERSION, zlib_version);
  1152.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1153.                   (char *)(slide+256)));
  1154.                 ++numopts;
  1155. #endif
  1156. #ifdef VMSCLI
  1157.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1158.                   LoadFarStringSmall(VmsCLI)));
  1159.                 ++numopts;
  1160. #endif
  1161. #ifdef VMSWILD
  1162.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1163.                   LoadFarStringSmall(VmsWild)));
  1164.                 ++numopts;
  1165. #endif
  1166. #ifdef CRYPT
  1167. # ifdef PASSWD_FROM_STDIN
  1168.                 Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
  1169.                   LoadFarStringSmall(PasswdStdin)));
  1170. # endif
  1171.                 Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
  1172.                   CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
  1173.                   LoadFarStringSmall(CryptDate)));
  1174.                 ++numopts;
  1175. #endif /* CRYPT */
  1176.                 if (numopts == 0)
  1177.                     Info(slide, 0, ((char *)slide,
  1178.                       LoadFarString(CompileOptFormat),
  1179.                       LoadFarStringSmall(None)));
  1180.  
  1181.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
  1182.                 envptr = getenv(LoadFarStringSmall(EnvUnZip));
  1183.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1184.                   LoadFarStringSmall(EnvUnZip),
  1185.                   (envptr == (char *)NULL || *envptr == 0)?
  1186.                   LoadFarStringSmall2(None) : envptr));
  1187.                 envptr = getenv(LoadFarStringSmall(EnvUnZip2));
  1188.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1189.                   LoadFarStringSmall(EnvUnZip2),
  1190.                   (envptr == (char *)NULL || *envptr == 0)?
  1191.                   LoadFarStringSmall2(None) : envptr));
  1192.                 envptr = getenv(LoadFarStringSmall(EnvZipInfo));
  1193.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1194.                   LoadFarStringSmall(EnvZipInfo),
  1195.                   (envptr == (char *)NULL || *envptr == 0)?
  1196.                   LoadFarStringSmall2(None) : envptr));
  1197.                 envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
  1198.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1199.                   LoadFarStringSmall(EnvZipInfo2),
  1200.                   (envptr == (char *)NULL || *envptr == 0)?
  1201.                   LoadFarStringSmall2(None) : envptr));
  1202. #ifdef __EMX__
  1203.                 envptr = getenv(LoadFarStringSmall(EnvEMX));
  1204.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1205.                   LoadFarStringSmall(EnvEMX),
  1206.                   (envptr == (char *)NULL || *envptr == 0)?
  1207.                   LoadFarStringSmall2(None) : envptr));
  1208.                 envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
  1209.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1210.                   LoadFarStringSmall(EnvEMXOPT),
  1211.                   (envptr == (char *)NULL || *envptr == 0)?
  1212.                   LoadFarStringSmall2(None) : envptr));
  1213. #endif /* __EMX__ */
  1214. #ifdef __GO32__
  1215.                 envptr = getenv(LoadFarStringSmall(EnvGO32));
  1216.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1217.                   LoadFarStringSmall(EnvGO32),
  1218.                   (envptr == (char *)NULL || *envptr == 0)?
  1219.                   LoadFarStringSmall2(None) : envptr));
  1220.                 envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
  1221.                 Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
  1222.                   LoadFarStringSmall(EnvGO32TMP),
  1223.                   (envptr == (char *)NULL || *envptr == 0)?
  1224.                   LoadFarStringSmall2(None) : envptr));
  1225. #endif /* __GO32__ */
  1226.             }
  1227.             return 0;
  1228.         } else
  1229. #endif /* !SFX */
  1230.             return usage(__G__ error);
  1231.     }
  1232.  
  1233. #ifdef SFX
  1234.     /* print our banner unless we're being fairly quiet */
  1235.     if (G.qflag < 2)
  1236.         Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
  1237.           UZ_MAJORVER, UZ_MINORVER, PATCHLEVEL, BETALEVEL,
  1238.           LoadFarStringSmall(VersionDate)));
  1239. #ifdef BETA
  1240.     /* always print the beta warning:  no unauthorized distribution!! */
  1241.     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
  1242.       "SFX"));
  1243. #endif
  1244. #endif /* SFX */
  1245.  
  1246.     if (G.cflag || G.tflag || G.vflag)
  1247.         G.extract_flag = FALSE;
  1248.     else
  1249.         G.extract_flag = TRUE;
  1250.  
  1251. #if (!defined(SFX) || defined(SFX_EXDIR))
  1252.     if (G.dflag) {
  1253.         if (G.extract_flag) {
  1254.             G.create_dirs = !G.fflag;
  1255.             if ((error = checkdir(__G__ exdir, ROOT)) > 2) {
  1256.                 return(error);  /* out of memory, or file in way */
  1257.             }
  1258.         } else
  1259.             Info(slide, 0x401, ((char *)slide,
  1260.               LoadFarString(NotExtracting)));  /* -d ignored */
  1261.     }
  1262. #endif /* !SFX || SFX_EXDIR */
  1263.  
  1264.     *pargc = argc;
  1265.     *pargv = argv;
  1266.     return 0;
  1267.  
  1268. } /* end function uz_opts() */
  1269.  
  1270.  
  1271.  
  1272.  
  1273.  
  1274. /********************/
  1275. /* Function usage() */
  1276. /********************/
  1277.  
  1278. #ifdef SFX
  1279. #  ifdef VMS
  1280. #    define LOCAL "X.  Quote uppercase options"
  1281. #  endif
  1282. #  ifdef UNIX
  1283. #    define LOCAL "X"
  1284. #  endif
  1285. #  ifdef DOS_OS2_W32
  1286. #    define LOCAL "s$"
  1287. #  endif
  1288. #  ifdef AMIGA
  1289. #    define LOCAL "N"
  1290. #  endif
  1291.    /* Default for all other systems: */
  1292. #  ifndef LOCAL
  1293. #    define LOCAL ""
  1294. #  endif
  1295.  
  1296. #  ifdef MORE
  1297. #    define SFXOPT1 "M"
  1298. #  else
  1299. #    define SFXOPT1 ""
  1300. #  endif
  1301.  
  1302. int usage(__G__ error)   /* return PK-type error code */
  1303.     int error;
  1304.      __GDEF
  1305. {
  1306.     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
  1307.       UZ_MAJORVER, UZ_MINORVER, PATCHLEVEL, BETALEVEL,
  1308.       LoadFarStringSmall(VersionDate)));
  1309.     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
  1310.       SFXOPT1, LOCAL));
  1311. #ifdef BETA
  1312.     Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
  1313.       "SFX"));
  1314. #endif
  1315.  
  1316.     if (error)
  1317.         return PK_PARAM;
  1318.     else
  1319.         return PK_COOL;     /* just wanted usage screen: no error */
  1320.  
  1321. } /* end function usage() */
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327. #else /* !SFX */
  1328. #ifndef VMSCLI
  1329. #  ifdef VMS
  1330. #    define QUOT '\"'
  1331. #    define QUOTS "\""
  1332. #  else
  1333. #    define QUOT ' '
  1334. #    define QUOTS ""
  1335. #  endif
  1336.  
  1337. int usage(__G__ error)   /* return PK-type error code */
  1338.     int error;
  1339.     __GDEF
  1340. {
  1341.     int flag = (error? 1 : 0);
  1342.  
  1343.  
  1344. /*---------------------------------------------------------------------------
  1345.     Print either ZipInfo usage or UnZip usage, depending on incantation.
  1346.     (Strings must be no longer than 512 bytes for Turbo C, apparently.)
  1347.   ---------------------------------------------------------------------------*/
  1348.  
  1349.     if (G.zipinfo_mode) {
  1350.  
  1351. #ifndef NO_ZIPINFO
  1352.  
  1353.         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
  1354.           ZI_MAJORVER, ZI_MINORVER, PATCHLEVEL, BETALEVEL,
  1355.           LoadFarStringSmall(VersionDate),
  1356.           LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
  1357.         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
  1358.         Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
  1359.           QUOT,QUOT, LoadFarStringSmall(ZipInfoUsageLine4)));
  1360. #ifdef VMS
  1361.         Info(slide, flag, ((char *)slide, "\nRemember that non-lowercase\
  1362.  filespecs must be quoted in VMS (e.g., \"Makefile\").\n"));
  1363. #endif
  1364.  
  1365. #endif /* !NO_ZIPINFO */
  1366.  
  1367.     } else {   /* UnZip mode */
  1368.  
  1369.         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
  1370.           UZ_MAJORVER, UZ_MINORVER, PATCHLEVEL, BETALEVEL,
  1371.           LoadFarStringSmall(VersionDate)));
  1372. #ifdef BETA
  1373.         Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
  1374. #endif
  1375.         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
  1376.           ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
  1377.  
  1378.         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
  1379.           LoadFarStringSmall(local1)));
  1380.  
  1381.         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
  1382.           QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(local2), QUOT,QUOT,
  1383.           LoadFarStringSmall2(local3)));
  1384.  
  1385.         /* This is extra work for SMALL_MEM, but it will work since
  1386.          * LoadFarStringSmall2 uses the same buffer.  Remember, this
  1387.          * is a hack. */
  1388.         Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
  1389.           LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
  1390.           LoadFarStringSmall2(Example3)));
  1391.  
  1392.     } /* end if (G.zipinfo_mode) */
  1393.  
  1394.     if (error)
  1395.         return PK_PARAM;
  1396.     else
  1397.         return PK_COOL;     /* just wanted usage screen: no error */
  1398.  
  1399. } /* end function usage() */
  1400.  
  1401. #endif /* !VMSCLI */
  1402. #endif /* ?SFX */
  1403.